//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 "commands_recording.sch" #IF IS_DEBUG_BUILD USING "select_mission_stage.sch" #ENDIF // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : Barry3C.sc // AUTHOR : Tom Waters // DESCRIPTION : Franklin collects an old banger for Barry. // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** //************************************************************************************************************************************************* // :ENUMS: //************************************************************************************************************************************************* // Mission stages ENUM MISSION_STAGE MS_STAGE_ENTER_STASH_CAR, MS_STAGE_START_STASH_CAR, MS_STAGE_CALL_BARRY, MS_STAGE_FIND_TOWTRUCK, MS_STAGE_TOW_VEHICLE, MS_STAGE_RETURN_VEHICLE, MS_STAGE_UNHOOK_VEHICLE, MS_STAGE_LEAVE, MS_STAGE_GET_TRUCK_BACK, MS_STAGE_REATTACH_VEHICLE, MS_STAGE_REDELIVER, MS_STAGE_LOSE_WANTED, MS_STAGE_DELIVERY_PHONE_CALL, MS_STAGE_FAIL_FADE ENDENUM // Progression within a stage ENUM STAGE_PROGRESS SP_SETUP, SP_RUNNING, SP_CLEANUP ENDENUM // Trying to start the car event ENUM START_CAR_EVENT SCE_ASSETS, SCE_WAIT_FOR_INPUT, // Used in ambient car staring SCE_TRIGGER_ANIM, SCE_IGNITION_SOUND, SCE_WAIT_TO_REPEAT, SCE_ANNOYED_HORN, SCE_COMMENT, SCE_EXIT_CAR, SCE_END ENDENUM //************************************************************************************************************************************************* // :STRUCTURES: //************************************************************************************************************************************************* // Objectives STRUCT MISSION_OBJECTIVE INT iDisplayMax INT iDisplayCount STRING sTextLabel ENDSTRUCT // Vehicles STRUCT COLLECT_VEHICLE VECTOR location FLOAT heading VEHICLE_INDEX vehicle MODEL_NAMES modelName BOOL bPlayerBeenInThis ENDSTRUCT //************************************************************************************************************************************************* // :CONSTANTS: //************************************************************************************************************************************************* // Checkpoints CONST_INT CP_START_TOW 1 CONST_INT CP_DELIVERY 2 CONST_INT CP_MISSION_COMPLETE 3 // SHITSKIP only - do not set CPs for this // Distances CONST_FLOAT ABANDON_DISTANCE 200.0 CONST_FLOAT WARNING_DISTANCE 85.0 CONST_FLOAT LEAVE_DISTANCE 150.0 // Helper truck stuff CONST_FLOAT TRUCK_SPAWN_DISTANCE 100.0 CONST_FLOAT TRUCK_DESPAWN_DISTANCE 175.0 CONST_INT INITIAL_SCENE_TRUCK 6 CONST_INT NUM_HELPER_TRUCKS 8 // Delay Franklin's comments and Barry's helper call CONST_INT PUSH_MUTTER_DELAY 8000 CONST_INT BARRY_CALL_DELAY 120000 CONST_INT TRUCK_MUTTER_DELAY 160000 // Objective constants CONST_INT MO_B3CENTV 0 // Get in the ~b~stash car.~s~ CONST_INT MO_B3CDELV 1 // Go to Barry's ~y~apartment.~s~ CONST_INT MO_B3CWAN1 2 // Lose the cops. CONST_INT MO_B3CNOGO 3 // Find a way to move the stash car. CONST_INT MO_B3CREVRS 4 // Hook the ~b~stash car.~s~ CONST_INT MO_B3CLEAVE 5 // Leave the area CONST_INT MO_B3CRTTT 6 // Get back in the ~b~tow truck.~s~ CONST_INT MO_B3CGBTB 7 // The ~b~stash car~s~ has broken loose, hook it with the tow truck. CONST_INT MO_B3CRTCB 8 // Get back in the ~b~cargobob.~s~ CONST_INT NUM_MISSION_OBJECTIVES 9 // For readibility of anim dict string array CONST_INT ANM_DICT 0 CONST_INT ANM_NAME 1 // Vehicle restriction CONST_INT RESTRICTION_STASHVEH 0 //************************************************************************************************************************************************* // :VARIABLES: //************************************************************************************************************************************************* // Launcher vars g_structRCScriptArgs sRCLauncherDataLocal SCENARIO_BLOCKING_INDEX mScenarioBlocker #IF IS_DEBUG_BUILD // STAGE SKIPPING/CHECKPOINT STUFF // Mission specific z-skip enum ENUM MISSION_SKIP_STAGE MSS_RESTART, MSS_IN_CAR, MSS_CALL_SKIP, MSS_TOWING, MSS_WARP_NEAR_END, MSS_DELIVERY, MSS_MISSION_COMPLETE ENDENUM MISSION_SKIP_STAGE eTargetStage CONST_INT MAX_SKIP_MENU_LENGTH 7 MissionStageMenuTextStruct mSkipMenu[MAX_SKIP_MENU_LENGTH] WIDGET_GROUP_ID widgetGroup BOOL bDebugCheatCarLocation = FALSE BOOL bDebugCarStartSpew = FALSE #ENDIF // Conversation/objective text interrupt handling RC_CONV_RESTORE_STATE stateRestoreConversation TEXT_LABEL_23 tSavedConversationRoot TEXT_LABEL_23 tSavedConversationLabel // Mission progression MISSION_STAGE mStage = MS_STAGE_ENTER_STASH_CAR // 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 biGotoBlip // The vehicle COLLECT_VEHICLE stStashCar BOOL bStashCarOnRoofLastFrame = FALSE BOOL bTowTruckOnRoofLastFrame = FALSE BOOL bTruckStuckCheckActive = FALSE BOOL bStashStuckCheckActive = FALSE INT iStashCarStuckTimer INT iTowTruckStuckTimer OBJECT_INDEX oiStashBox VECTOR vecStashOffset = << -0.10, -0.85, 0.23 >> VECTOR vecStashRotate = << 8.0, 0.5, 0.0 >> MODEL_NAMES mnStashBox = Prop_Weed_Tub_01 // Has stash car been hooked so far? (used for objective control) BOOL bStashCarHasBeenHooked = FALSE BOOL bStashCarHasComeUnhooked = FALSE // Vehicle delivery destinations VECTOR vecApartment SCENARIO_BLOCKING_INDEX sbCarPark[2] // Scenario blocker to stop parking scenario // Tow truck bits VEHICLE_INDEX vehTowTruck MODEL_NAMES truckSkipModel = TOWTRUCK INT iTruckColourScheme // Truck colour scheme is saved for recreating truck in skips COLLECT_VEHICLE stTruck[NUM_HELPER_TRUCKS] // Towtrucks that are spawned to help player BOOL bPlayerInTruckLastFrame // Track player entering/exiting truck in some mission steps // Player snapshot car BOOL bSetupVehGen = FALSE // general utility counter INT iCount // Conversation struct structPedsForConversation mConversationStruct // Tracking which conversations have triggered in the truck-hunting stage BOOL bFranklinPushMuttered = FALSE // Has Franklin muttered about needing to move the broken down car BOOL bBarryCalledAboutTruck = FALSE // Has Barry called player suggesting tow truck BOOL bFranklinTruckMuttered = FALSE // Has Franklin muttered about needing to jack a truck // Event tracking bools BOOL bShowedRaiseLowerHelp = FALSE // Has tow truck help message been displayed? BOOL bShowedDetachHelp = FALSE // Timers INT iCarEventsTimer INT iCallDelayTimer INT iHelpTimer // Car starting CONST_INT NUM_IGNITION_ATTEMPTS 4 START_CAR_EVENT sceProgress INT iIgnitionAttempts INT iIgnitionSoundID BOOL bPlayerWantsOut BOOL bPlayerInStashCar STRING sIgnitionAnims = "rcm_barry3c" SEQUENCE_INDEX seqCarStart // Franklin unhook complaints CONST_INT NUM_FRANKLIN_COMPLAINTS 4 // Number of different complaint comments we have STAGE_PROGRESS spFranklinUnhook // State progression for start/wait for comment/idle STRING sComplaintLabel[NUM_FRANKLIN_COMPLAINTS] // Complaint labels array INT iComplaintCount // Which was the last comment we played (they cycle) // Hook monitoring BOOL bShouldPlayUnhookComment // Store dropoff zone behind Barry's VECTOR vecDropoff[2][2] FLOAT fDropoffWidth[2] // Has the delivery phone call been triggered BOOL bDeliveryCallTriggered // Objective struct MISSION_OBJECTIVE moObjectives[NUM_MISSION_OBJECTIVES] BOOL bObjectiveNeeded // Used when we have to delay objectives // Failure reason STRING sFailReason // For new checkpoint method VECTOR vecRespawnTruck FLOAT fRespawnTruck //************************************************************************************************************************************************* // Objectives functions/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: /// 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 moObjectives[iObj].iDisplayCount < moObjectives[iObj].iDisplayMax OR moObjectives[iObj].iDisplayMax = -1 PRINT_NOW(moObjectives[iObj].sTextLabel, DEFAULT_GOD_TEXT_TIME, 1) CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation) moObjectives[iObj].iDisplayCount++ ENDIF ENDPROC /// 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: /// 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: /// Are any mission objectives currently on screen? /// RETURNS: /// True if there is currently an objective from this mission on screen FUNC BOOL MISSION_OBJECTIVES_CURRENTLY_DISPLAYED() FOR iCount = 0 TO NUM_MISSION_OBJECTIVES-1 IF IS_THIS_PRINT_BEING_DISPLAYED(moObjectives[iCount].sTextLabel) RETURN TRUE ENDIF ENDFOR // Didn't find an objective RETURN FALSE 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!") ELSE moObjectives[iObj].iDisplayCount = moObjectives[iObj].iDisplayMax ENDIF ENDPROC /// PURPOSE: /// Set up all the mission objectives PROC STORE_MISSION_OBJECTIVE_DATA() moObjectives[MO_B3CENTV] = CREATE_MISSION_OBJECTIVE("B3CENTV", 1) // Get in the ~b~stash car.~s~ moObjectives[MO_B3CDELV] = CREATE_MISSION_OBJECTIVE("B3CDELV", 1) // Go to Barry's ~y~apartment.~s~ moObjectives[MO_B3CWAN1] = CREATE_MISSION_OBJECTIVE("B3CWAN1", -1) // Lose the cops. moObjectives[MO_B3CNOGO] = CREATE_MISSION_OBJECTIVE("B3CNOGO", 1) // Find a way to move the stash car. moObjectives[MO_B3CREVRS] = CREATE_MISSION_OBJECTIVE("B3CREVRS", 1) // Hook the ~b~stash car.~s~ moObjectives[MO_B3CLEAVE] = CREATE_MISSION_OBJECTIVE("B3CLEAVE", 1) // Leave the area. moObjectives[MO_B3CRTTT] = CREATE_MISSION_OBJECTIVE("B3CRTTT", 1) // Get back in the ~b~tow truck.~s~ moObjectives[MO_B3CGBTB] = CREATE_MISSION_OBJECTIVE("B3CGBTB", 1) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. moObjectives[MO_B3CRTCB] = CREATE_MISSION_OBJECTIVE("B3CRTCB", 1) // Get back in the ~b~cargobob.~s~ ENDPROC /// PURPOSE: /// Stores the labels for Franklin's complaint comments PROC STORE_COMPLAINT_STRINGS() sComplaintLabel[0] = "BAR3C_Z1" sComplaintLabel[1] = "BAR3C_Z2" sComplaintLabel[2] = "BAR3C_Z3" sComplaintLabel[3] = "BAR3C_Z4" ENDPROC /// PURPOSE: /// Toggle all the car mod shops in one go /// PARAMS: /// bToggleFlag - Pass TRUE to toggle off, FALSE to toggle back on PROC TOGGLE_CAR_MOD_SHOPS_UNAVAILABLE(BOOL bToggleFlag) SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_01_AP, bToggleFlag) SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_05_ID2, bToggleFlag) SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_06_BT1, bToggleFlag) SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_07_CS1, bToggleFlag) SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_08_CS6, bToggleFlag) SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_SUPERMOD, bToggleFlag) ENDPROC //************************************************************************************************************************************************* // Utility functions/procs //************************************************************************************************************************************************* /// PURPOSE: /// Cleanup /// PARAMS: /// If bDeleteEntities is FALSE the entities will be released instead of deleted PROC COLLECT_AREA_CLEANUP() IF IS_ENTITY_ALIVE(stStashCar.vehicle) SET_ENTITY_LOAD_COLLISION_FLAG(stStashCar.vehicle, FALSE) ENDIF SAFE_RELEASE_VEHICLE(vehTowTruck) SAFE_RELEASE_VEHICLE(stStashCar.vehicle) SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, FALSE) TOGGLE_CAR_MOD_SHOPS_UNAVAILABLE(FALSE) RC_CleanupSceneEntities(sRCLauncherDataLocal) ENDPROC /// PURPOSE: /// Tests whether player is currently using a cargobob despite Franklin's dubious flying ability and readily available towtrucks /// Do not call this unless you have already checked IS_PLAYER_IN_TOWTRUCK or similar /// RETURNS: /// TRUE if we are on the path of wrongness FUNC BOOL TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() MODEL_NAMES mTmp = GET_ENTITY_MODEL(vehTowTruck) IF mTmp = CARGOBOB OR mTmp = CARGOBOB2 OR mTmp = CARGOBOB3 RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Checks the stash car's roll to see if it's probably on its roof /// RETURNS: /// TRUE if reasonably sure the car is upside down FUNC BOOL STASH_CAR_UPSIDE_DOWN() IF IS_ENTITY_ALIVE(stStashCar.vehicle) FLOAT fStashRoll = WRAP(GET_ENTITY_ROLL(stStashCar.vehicle), 0, 360) IF fStashRoll > 150 AND fStashRoll < 210 // CPRINTLN(DEBUG_MISSION, "Clamped 0-360 stash car roll is ", fStashRoll) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Check for either vehicle being destroyed or dead player /// RETURNS: /// TRUE if either vehicle exists but is dead or stuck FUNC BOOL MISSION_FAIL_CHECKS() // Is the player dead IF NOT IS_ENTITY_ALIVE(PLAYER_PED_ID()) RETURN TRUE ENDIF // Check for stash car destruction if currently spawned IF DOES_ENTITY_EXIST(stStashCar.vehicle) // Basic trashed checks IF IS_ENTITY_DEAD(stStashCar.vehicle) sFailReason = "B3CVHDEST" // The stash car was wrecked sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE RETURN TRUE // Keep track of vehicle on roof ELIF bStashStuckCheckActive // IF STASH_CAR_UPSIDE_DOWN() IF IS_VEHICLE_STUCK_ON_ROOF(stStashCar.vehicle) IF bStashCarOnRoofLastFrame IF GET_GAME_TIMER() - iStashCarStuckTimer > ROOF_TIME sFailReason = "B3CVHSTUCK" // The stash car is stuck sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE RETURN TRUE ENDIF ELSE CPRINTLN(DEBUG_MISSION, "Stash car is now on roof!") bStashCarOnRoofLastFrame = TRUE iStashCarStuckTimer = GET_GAME_TIMER() ENDIF ELSE #IF IS_DEBUG_BUILD IF bStashCarOnRoofLastFrame CPRINTLN(DEBUG_MISSION, "Stash car is no longer on roof") ENDIF #ENDIF bStashCarOnRoofLastFrame = FALSE ENDIF ENDIF ENDIF // Check for tow truck destruction if currently spawned IF DOES_ENTITY_EXIST(vehTowTruck) // Basic trashed checks IF IS_ENTITY_DEAD(vehTowTruck) AND bDeliveryCallTriggered = FALSE // Tow truck fails temp. disabled after delivery IF TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() sFailReason = "B3CCBDEST" // The cargobob was destroyed ELSE sFailReason = "B3CTWDEST" // The tow truck was destroyed ENDIF sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE RETURN TRUE // Keep track of vehicle on roof ELIF bTruckStuckCheckActive AND bDeliveryCallTriggered = FALSE // Tow truck fails temp. disabled after delivery IF IS_VEHICLE_STUCK_ON_ROOF(vehTowTruck) IF bTowTruckOnRoofLastFrame IF GET_GAME_TIMER() - iTowTruckStuckTimer > ROOF_TIME IF TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() sFailReason = "B3CCBSTUCK" // The cargobob got stuck ELSE sFailReason = "B3CTWSTUCK" // The tow truck got stuck ENDIF sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE RETURN TRUE ENDIF ELSE bTowTruckOnRoofLastFrame = TRUE iTowTruckStuckTimer = GET_GAME_TIMER() ENDIF ELSE bTowTruckOnRoofLastFrame = FALSE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Check whether the stash car is attached to the tow truck /// RETURNS: /// TRUE if currently attached FUNC BOOL IS_STASH_CAR_HOOKED() // THIS IS USED IN SKIPS, IT MUST CHECK ENTITIES! // Check if player has hooked car IF IS_ENTITY_ALIVE(vehTowTruck) AND IS_ENTITY_ALIVE(stStashCar.vehicle) IF TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() IF DOES_CARGOBOB_HAVE_PICK_UP_ROPE(vehTowTruck) AND IS_VEHICLE_ATTACHED_TO_CARGOBOB(vehTowTruck, stStashCar.vehicle) bStashCarHasBeenHooked = TRUE RETURN TRUE ENDIF ELSE IF IS_VEHICLE_ATTACHED_TO_TOW_TRUCK(vehTowTruck, stStashCar.vehicle) bStashCarHasBeenHooked = TRUE RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Check if the player is in any valid tow truck (TOWTRUCK, TOWTRUCK2) /// If the player changes trucks, this will update the entity to point at the current one /// RETURNS: /// TRUE if player is in any valid tow truck FUNC BOOL IS_PLAYER_IN_TOWTRUCK() // Is player in the currently preferred towtruck IF DOES_ENTITY_EXIST(vehTowTruck) AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehTowTruck) RETURN TRUE // Is player in some other vehicle ELIF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) // Get player vehicle VEHICLE_INDEX tmpVehicle tmpVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) IF IS_ENTITY_ALIVE(tmpVehicle) // Is vehicle a valid towtruck or cargobob? MODEL_NAMES mTmp = GET_ENTITY_MODEL(tmpVehicle) IF mTmp = TOWTRUCK OR mTmp = TOWTRUCK2 OR mTmp = CARGOBOB OR mTmp = CARGOBOB2 OR mTmp = CARGOBOB3 CPRINTLN(DEBUG_MISSION, "IS_PLAYER_IN_TOWTRUCK grabbing a new vehicle") BOOL bOneOfOurs = FALSE // Tracks if the vehicle is one of our helper trucks #IF IS_DEBUG_BUILD truckSkipModel = mTmp iTruckColourScheme = GET_VEHICLE_COLOUR_COMBINATION(tmpVehicle) #ENDIF // Ditch the current towtruck IF DOES_ENTITY_EXIST(vehTowTruck) IF bTruckStuckCheckActive REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehTowTruck) bTruckStuckCheckActive = FALSE ENDIF SET_VEHICLE_AS_NO_LONGER_NEEDED(vehTowTruck) ENDIF // Check whether the entered vehicle is one of the helper trucks FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 IF IS_ENTITY_ALIVE(stTruck[iCount].vehicle) AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stTruck[iCount].vehicle) bOneOfOurs = TRUE stTruck[iCount].bPlayerBeenInThis = TRUE ASSIGN_VEHICLE_INDEX(vehTowTruck, stTruck[iCount].vehicle) CPRINTLN(DEBUG_MISSION, "IS_PLAYER_IN_TOWTRUCK grabbed helper truck ", iCount, " as the one true truck") ENDIF ENDFOR // Make truck player is in our truck if it hasn't already been grabbed from the helper trucks IF NOT bOneOfOurs SET_ENTITY_AS_MISSION_ENTITY(tmpVehicle, TRUE, TRUE) vehTowTruck = tmpVehicle ENDIF ADD_VEHICLE_UPSIDEDOWN_CHECK(vehTowTruck) bTruckStuckCheckActive = TRUE // make truck unhookable to prevent craziness SET_VEHICLE_AUTOMATICALLY_ATTACHES(vehTowTruck, FALSE) // Mark the comment as invalid or it will fire spuriously bShouldPlayUnhookComment = FALSE RETURN TRUE ENDIF ENDIF ENDIF // Player isn't in a towtruck then RETURN FALSE ENDFUNC /// PURPOSE: /// Checks whether it's reasonably likely that the player's about to be in a towtruck /// RETURNS: /// TRUE if entering a towtruck or close to a spawn FUNC BOOL PLAYER_ABOUT_TO_GET_IN_TOWTRUCK() // Check if player is entering a tow truck IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE) VEHICLE_INDEX tmpVehicle tmpVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE) IF GET_ENTITY_MODEL(tmpVehicle) = TOWTRUCK OR GET_ENTITY_MODEL(tmpVehicle) = TOWTRUCK2 RETURN TRUE ENDIF ENDIF // Check if player is right on top of an active tow truck spawn FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 IF NOT stTruck[iCount].bPlayerBeenInThis AND IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), stTruck[iCount].location, 8.0) RETURN TRUE ENDIF ENDFOR RETURN FALSE ENDFUNC /// PURPOSE: /// Prevents the stash car from being towed /// PARAMS: /// bShouldBeNobbled - TRUE makes the stash car untowable PROC NOBBLE_TOWING(BOOL bShouldBeNobbled) IF bShouldBeNobbled CPRINTLN(DEBUG_MISSION, "NOBBLE_TOWING: Setting stash car as untowable") SET_VEHICLE_AUTOMATICALLY_ATTACHES(stStashCar.vehicle, FALSE) SET_VEHICLE_DISABLE_TOWING(stStashCar.vehicle, TRUE) ELSE CPRINTLN(DEBUG_MISSION, "NOBBLE_TOWING: Setting stash car back to towable") SET_VEHICLE_AUTOMATICALLY_ATTACHES(stStashCar.vehicle, TRUE) SET_VEHICLE_DISABLE_TOWING(stStashCar.vehicle, FALSE) ENDIF ENDPROC /// PURPOSE: /// Disables select inputs during the car ignition attempt event PROC DISABLE_INPUTS_FOR_CAR_SEQUENCE() // DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_MOVE_LR) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK) ENDPROC /// PURPOSE: /// Set up vehicle gen PROC CHECK_VEHGEN_CREATION() IF NOT bSetupVehGen SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(<<0,0,0>>, 0, FALSE) bSetupVehGen = TRUE ENDIF ENDPROC /// PURPOSE: /// Debug proc for printing out enum stage FUNC STRING PRINT_STARTUP_ENUM_NAME(START_CAR_EVENT eCarStart) SWITCH eCarStart CASE SCE_ASSETS RETURN "SCE_ASSETS" CASE SCE_WAIT_FOR_INPUT RETURN "SCE_WAIT_FOR_INPUT" CASE SCE_TRIGGER_ANIM RETURN "SCE_TRIGGER_ANIM" CASE SCE_IGNITION_SOUND RETURN "SCE_IGNITION_SOUND" CASE SCE_WAIT_TO_REPEAT RETURN "SCE_WAIT_TO_REPEAT" CASE SCE_ANNOYED_HORN RETURN "SCE_ANNOYED_HORN" CASE SCE_COMMENT RETURN "SCE_COMMENT" CASE SCE_EXIT_CAR RETURN "SCE_EXIT_CAR" CASE SCE_END RETURN "SCE_END" ENDSWITCH RETURN "***Unknown START_CAR_EVENT value for PRINT_STARTUP_ENUM_NAME***" ENDFUNC /// PURPOSE: /// Monitor player in stash car so we can have pressing the accelerator try the starter. /// OK to call this when player isn't in car but probably as well to avoid ijn mission stages where we wouldn't want it. PROC STASH_CAR_STARTFAIL_HANDLER() IF NOT bPlayerInStashCar IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER detecting player in car, disabling controls") bPlayerInStashCar = TRUE bPlayerWantsOut = FALSE sceProgress = SCE_ASSETS SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON) DISABLE_INPUTS_FOR_CAR_SEQUENCE() // For some reason there STILL seemed to be a window where tweaking the wheel was allowed? ELIF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle, TRUE) DISABLE_INPUTS_FOR_CAR_SEQUENCE() ENDIF ELSE DISABLE_INPUTS_FOR_CAR_SEQUENCE() IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) #IF IS_DEBUG_BUILD IF bDebugCarStartSpew CPRINTLN(DEBUG_MISSION, "Startfail spew: Ped not in vehicle in step ", PRINT_STARTUP_ENUM_NAME(sceProgress), ", setting bools FALSE") ENDIF #ENDIF IF bPlayerInStashCar SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) // Script fix for B*1760196 ENDIF bPlayerInStashCar = FALSE bPlayerWantsOut = FALSE ELSE IF NOT bPlayerWantsOut AND IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_EXIT) CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER - Player wants out! Current stage is ", PRINT_STARTUP_ENUM_NAME(sceProgress)) bPlayerWantsOut = TRUE ENDIF SWITCH sceProgress CASE SCE_ASSETS IF bPlayerWantsOut CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_ASSETS: Allowing vehicle exit") sceProgress = SCE_EXIT_CAR ELSE // Check sounds and assets loaded... REQUEST_ANIM_DICT(sIgnitionAnims) IF REQUEST_SCRIPT_AUDIO_BANK("BARRY3C_IGNITION_FAIL") AND HAS_ANIM_DICT_LOADED(sIgnitionAnims) // Don't go on before player is in driver seat IF GET_PED_IN_VEHICLE_SEAT(stStashCar.vehicle) = PLAYER_PED_ID() CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_ASSETS: Got assets, ready to detect input") sceProgress = SCE_WAIT_FOR_INPUT ENDIF #IF IS_DEBUG_BUILD ELSE IF bDebugCarStartSpew CPRINTLN(DEBUG_MISSION, "Startfail spew: SCE_ASSETS waiting on assets") ENDIF #ENDIF ENDIF ENDIF BREAK // Wait for input CASE SCE_WAIT_FOR_INPUT IF bPlayerWantsOut CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_WAIT_FOR_INPUT: Allowing vehicle exit") sceProgress = SCE_EXIT_CAR // Check for accelerator press ELIF IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_ACCELERATE) CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_WAIT_FOR_INPUT: Received input, start anim") sceProgress = SCE_TRIGGER_ANIM #IF IS_DEBUG_BUILD ELSE IF bDebugCarStartSpew CPRINTLN(DEBUG_MISSION, "Startfail spew: SCE_WAIT_FOR_INPUT waiting for input") ENDIF #ENDIF ENDIF BREAK CASE SCE_TRIGGER_ANIM CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_TRIGGER_ANIM: Triggering anim, going to SCE_IGNITION_SOUND") // Special long attempt then go to annoyance reaction OPEN_SEQUENCE_TASK(seqCarStart) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_enter", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 2000, AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_loop", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 1500, AF_LOOPING|AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_exit", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 766, AF_NOT_INTERRUPTABLE) CLOSE_SEQUENCE_TASK(seqCarStart) CLEAR_PED_TASKS(PLAYER_PED_ID()) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seqCarStart) CLEAR_SEQUENCE_TASK(seqCarStart) iCarEventsTimer = GET_GAME_TIMER() + 2000 sceProgress = SCE_IGNITION_SOUND BREAK CASE SCE_IGNITION_SOUND IF GET_GAME_TIMER() > iCarEventsTimer CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_IGNITION_SOUND: Triggering sound, going to SCE_WAIT_TO_REPEAT") PLAY_SOUND_FROM_ENTITY(iIgnitionSoundID, "IGNITION_FAIL", stStashCar.vehicle, "BARRY_03_SOUNDSET") SET_VARIABLE_ON_SOUND(iIgnitionSoundID, "HOLD TIME", 1.5) iCarEventsTimer = GET_GAME_TIMER() + 2400 sceProgress = SCE_WAIT_TO_REPEAT #IF IS_DEBUG_BUILD ELSE IF bDebugCarStartSpew CPRINTLN(DEBUG_MISSION, "Startfail spew: SCE_IGNITION_SOUND waiting for timer ", iCarEventsTimer-GET_GAME_TIMER()) ENDIF #ENDIF ENDIF BREAK CASE SCE_WAIT_TO_REPEAT IF GET_GAME_TIMER() > iCarEventsTimer IF bPlayerWantsOut CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_WAIT_TO_REPEAT: Going on to exit") sceProgress = SCE_EXIT_CAR ELSE CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_WAIT_TO_REPEAT: Going to wait for input") sceProgress = SCE_WAIT_FOR_INPUT ENDIF #IF IS_DEBUG_BUILD ELSE IF bDebugCarStartSpew CPRINTLN(DEBUG_MISSION, "Startfail spew: SCE_WAIT_TO_REPEAT waiting for timer ", iCarEventsTimer-GET_GAME_TIMER()) ENDIF #ENDIF ENDIF BREAK CASE SCE_EXIT_CAR IF GET_GAME_TIMER() > iCarEventsTimer AND NOT GET_IS_TASK_ACTIVE(PLAYER_PED_ID(), CODE_TASK_EXIT_VEHICLE) CPRINTLN(DEBUG_MISSION, "STASH_CAR_STARTFAIL_HANDLER: SCE_EXIT_CAR: Exit the car") CLEAR_PED_TASKS(PLAYER_PED_ID()) TASK_LEAVE_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) #IF IS_DEBUG_BUILD ELSE IF bDebugCarStartSpew CPRINTLN(DEBUG_MISSION, "Startfail spew: SCE_EXIT_CAR waiting for timer ", iCarEventsTimer-GET_GAME_TIMER()) ENDIF #ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDPROC /// PURPOSE: /// Turns off engine and lights 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: /// Trigger Franklin complaint conversations PROC FRANKLIN_UNHOOK_COMPLAINT() SWITCH spFranklinUnhook CASE SP_SETUP // Don't allow "tow" comment if we're in a cargobob IF iComplaintCount = 3 AND TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() CPRINTLN(DEBUG_MISSION, "Franklin complaint is at 3 but we're in a cargobob - set back to 0") iComplaintCount = 0 ENDIF IF MISSION_OBJECTIVES_CURRENTLY_DISPLAYED() // Play conversation with no subtitles IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", sComplaintLabel[iComplaintCount], CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES) CPRINTLN(DEBUG_MISSION, "Franklin complaint ", sComplaintLabel[iComplaintCount]) spFranklinUnhook = SP_RUNNING ENDIF ELSE // Play conversation with subtitles IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", sComplaintLabel[iComplaintCount], CONV_PRIORITY_MEDIUM) CPRINTLN(DEBUG_MISSION, "Franklin complaint ", sComplaintLabel[iComplaintCount]) spFranklinUnhook = SP_RUNNING ENDIF ENDIF BREAK CASE SP_RUNNING IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() // Roll on the complaint counter iComplaintCount++ CPRINTLN(DEBUG_MISSION, "Franklin complaint counter set to ", iComplaintCount) IF iComplaintCount >= NUM_FRANKLIN_COMPLAINTS iComplaintCount = 0 CPRINTLN(DEBUG_MISSION, " - and then reset to zero") ENDIF spFranklinUnhook = SP_CLEANUP ENDIF BREAK CASE SP_CLEANUP // Do nothing BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Creates a filled in vehicle struct for a possible towtruck spawn FUNC COLLECT_VEHICLE MAKE_TOWTRUCK_SPAWN(VECTOR vLoc, FLOAT fHead) COLLECT_VEHICLE stTmp stTmp.location = vLoc stTmp.heading = fHead stTmp.modelName = TOWTRUCK stTmp.bPlayerBeenInThis = FALSE RETURN stTmp ENDFUNC /// PURPOSE: /// Controls spawning and despawning of helper towtrucks PROC TRUCK_SPAWNER(BOOL bForceCleanup = FALSE) IF bForceCleanup // We've finished looking for trucks - force cleanup FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 SAFE_RELEASE_VEHICLE(stTruck[iCount].vehicle) ENDFOR ELSE // Check whether any of the trucks need spawning or deleting FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 // Check whether truck exists IF DOES_ENTITY_EXIST(stTruck[iCount].vehicle) // Must use this method - B*1128499 // See if the player is now too far away and this needs deleting IF NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), stTruck[iCount].location, TRUCK_DESPAWN_DISTANCE) AND GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), stTruck[iCount].vehicle) > TRUCK_DESPAWN_DISTANCE // Need to use a command that has dead checks or you'll get an assert SAFE_DELETE_VEHICLE(stTruck[iCount].vehicle) ENDIF ELSE // If we have already been in this truck it won't spawn again - otherwise OK IF NOT stTruck[iCount].bPlayerBeenInThis AND IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), stTruck[iCount].location, TRUCK_SPAWN_DISTANCE) stTruck[iCount].vehicle = CREATE_VEHICLE(TOWTRUCK, stTruck[iCount].location, stTruck[iCount].heading) IF iCount = INITIAL_SCENE_TRUCK SET_VEHICLE_COLOURS(stTruck[iCount].vehicle, 39, 43) ELSE SET_VEHICLE_COLOUR_COMBINATION(stTruck[iCount].vehicle, 0) ENDIF SET_VEHICLE_ON_GROUND_PROPERLY(stTruck[iCount].vehicle) SET_VEHICLE_AUTOMATICALLY_ATTACHES(stTruck[iCount].vehicle, FALSE) SET_VEHICLE_HAS_STRONG_AXLES(stTruck[iCount].vehicle, TRUE) ENDIF ENDIF ENDFOR ENDIF ENDPROC //************************************************************************************************************************************************* // // SKIP PROCS // //************************************************************************************************************************************************* /// PURPOSE: /// Clears any objective that are being displayed, clear help, stop conversations, kill phone calls PROC SKIP_CLEAR_ALL_MISSION_OBJECTIVES() CLEAR_PRINTS() CLEAR_HELP(TRUE) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF HANG_UP_AND_PUT_AWAY_PHONE() ENDPROC /// PURPOSE: /// Clear wanted level when skipping PROC SKIP_CLEAR_WANTED() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) 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: /// Recreates the truck PROC SKIP_RESPAWN_TRUCK(VECTOR vecRSLoc, FLOAT fRSHead, BOOL bInsertPlayer = TRUE) IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF bInsertPlayer SET_ENTITY_COORDS(PLAYER_PED_ID(), vecRSLoc) ENDIF ENDIF IF DOES_ENTITY_EXIST(vehTowTruck) IF bTruckStuckCheckActive REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehTowTruck) bTruckStuckCheckActive = FALSE ENDIF SAFE_DELETE_VEHICLE(vehTowTruck) ENDIF REQUEST_MODEL(truckSkipModel) WHILE NOT HAS_MODEL_LOADED(truckSkipModel) WAIT(0) ENDWHILE vehTowTruck = CREATE_VEHICLE(truckSkipModel, vecRSLoc, fRSHead) SET_MODEL_AS_NO_LONGER_NEEDED(truckSkipModel) SET_VEHICLE_COLOUR_COMBINATION(vehTowTruck, iTruckColourScheme) SET_VEHICLE_ON_GROUND_PROPERLY(vehTowTruck) IF bInsertPlayer SAFE_SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vehTowTruck) ENDIF SET_VEHICLE_CAN_LEAK_OIL(vehTowTruck, FALSE) SET_VEHICLE_CAN_LEAK_PETROL(vehTowTruck, FALSE) SET_VEHICLE_HAS_STRONG_AXLES(vehTowTruck, TRUE) IF NOT IS_ENTITY_DEAD(vehTowTruck) ADD_VEHICLE_UPSIDEDOWN_CHECK(vehTowTruck) bTruckStuckCheckActive = TRUE ENDIF ENDPROC /// PURPOSE: /// Recreates the stash car PROC SKIP_RESPAWN_STASH_CAR(VECTOR vecRSLoc, FLOAT fRSHead) REQUEST_MODEL(stStashCar.modelName) IF DOES_ENTITY_EXIST(stStashCar.vehicle) IF bStashStuckCheckActive REMOVE_VEHICLE_UPSIDEDOWN_CHECK(stStashCar.vehicle) bStashStuckCheckActive = FALSE ENDIF ENDIF WHILE NOT HAS_MODEL_LOADED(stStashCar.modelName) CPRINTLN(DEBUG_MISSION, "Waiting to load stash car model...") WAIT(0) ENDWHILE SAFE_DELETE_OBJECT(oiStashBox) SAFE_DELETE_VEHICLE(stStashCar.vehicle) stStashCar.vehicle = CREATE_VEHICLE(stStashCar.modelName, vecRSLoc, fRSHead) SET_MODEL_AS_NO_LONGER_NEEDED(stStashCar.modelName) SET_VEHICLE_ON_GROUND_PROPERLY(stStashCar.vehicle) SET_VEHICLE_CAN_LEAK_OIL(stStashCar.vehicle, FALSE) SET_VEHICLE_CAN_LEAK_PETROL(stStashCar.vehicle, FALSE) SET_VEHICLE_COLOUR_COMBINATION(stStashCar.vehicle, 1) SET_VEHICLE_UNDRIVEABLE(stStashCar.vehicle, TRUE) SET_VEHICLE_HAS_STRONG_AXLES(stStashCar.vehicle, TRUE) SET_ENTITY_LOAD_COLLISION_FLAG(stStashCar.vehicle, TRUE) IF NOT IS_ENTITY_DEAD(stStashCar.vehicle) ADD_VEHICLE_UPSIDEDOWN_CHECK(stStashCar.vehicle) bStashStuckCheckActive = TRUE ENDIF oiStashBox = CREATE_OBJECT(mnStashBox, vecRSLoc+vecStashOffset) ATTACH_ENTITY_TO_ENTITY(oiStashBox, stStashCar.vehicle, 0, vecStashOffset, vecStashRotate) ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: /// Restart the mission PROC SKIP_TO_MS_INIT() CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: restart mission") SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, FALSE) SKIP_CLEAR_ALL_MISSION_OBJECTIVES() SKIP_CLEAR_WANTED() SAFE_REMOVE_BLIP(biGotoBlip) // Progression stuff mStage = MS_STAGE_ENTER_STASH_CAR sProgress = SP_SETUP // Teleport player out of vehicle, recreate it IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), stStashCar.location) ENDIF SKIP_RESPAWN_STASH_CAR(stStashCar.location, stStashCar.heading) // Place player CLEAR_AREA_OF_VEHICLES(<<-451.4656, -1702.8058, 17.8676>>, 7.0) SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-451.4656, -1702.8058, 17.8676>>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 117.2) // Clear up towtruck(s) IF DOES_ENTITY_EXIST(vehTowTruck) SAFE_DELETE_VEHICLE(vehTowTruck) ENDIF FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 IF DOES_ENTITY_EXIST(stTruck[iCount].vehicle) SAFE_DELETE_VEHICLE(stTruck[iCount].vehicle) ENDIF stTruck[iCount].bPlayerBeenInThis = FALSE ENDFOR // Has stash car been hooked yet? bStashCarHasBeenHooked = FALSE // Reset Franklin's unhook complaints spFranklinUnhook = SP_CLEANUP iComplaintCount = 0 bFranklinPushMuttered = FALSE // Has Franklin muttered about needing to move the broken down car bBarryCalledAboutTruck = FALSE // Has Barry called player suggesting tow truck bFranklinTruckMuttered = FALSE // Has Franklin muttered about needing to jack a truck bDeliveryCallTriggered = FALSE MISSION_OBJECTIVE_RESET(MO_B3CENTV) // Get in the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CDELV) // Go to Barry's ~y~apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3CWAN1) // Lose the cops. MISSION_OBJECTIVE_RESET(MO_B3CNOGO) // Find a way to move the stash car. MISSION_OBJECTIVE_RESET(MO_B3CREVRS) // Hook the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CLEAVE) // Leave the area MISSION_OBJECTIVE_RESET(MO_B3CRTTT) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // Rehook the ~b~stash car~s~. ENDPROC #ENDIF /// PURPOSE: /// Z-SKIP /// Set player into car to start it up PROC SKIP_TO_START_CAR(BOOL bIsACheckpoint = FALSE) CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: SKIP_TO_START_CAR") IF bIsACheckPoint START_REPLAY_SETUP(stStashCar.location, stStashCar.heading) ENDIF SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, FALSE) SKIP_CLEAR_ALL_MISSION_OBJECTIVES() SKIP_CLEAR_WANTED() SAFE_REMOVE_BLIP(biGotoBlip) // Progression stuff mStage = MS_STAGE_START_STASH_CAR sProgress = SP_SETUP // Has stash car been hooked yet? bStashCarHasBeenHooked = FALSE // Reset Franklin's unhook complaints spFranklinUnhook = SP_CLEANUP iComplaintCount = 0 bFranklinPushMuttered = FALSE // Has Franklin muttered about needing to move the broken down car bBarryCalledAboutTruck = FALSE // Has Barry called player suggesting tow truck bFranklinTruckMuttered = FALSE // Has Franklin muttered about needing to jack a truck bDeliveryCallTriggered = FALSE MISSION_OBJECTIVE_EXPIRE(MO_B3CENTV) // Get in the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CDELV) // Go to Barry's ~y~apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3CWAN1) // Lose the cops. MISSION_OBJECTIVE_RESET(MO_B3CNOGO) // Find a way to move the stash car. MISSION_OBJECTIVE_RESET(MO_B3CREVRS) // Hook the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CLEAVE) // Leave the area MISSION_OBJECTIVE_RESET(MO_B3CRTTT) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // Rehook the ~b~stash car~s~. // Clear up towtruck(s) IF DOES_ENTITY_EXIST(vehTowTruck) SAFE_DELETE_VEHICLE(vehTowTruck) ENDIF FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 IF DOES_ENTITY_EXIST(stTruck[iCount].vehicle) SAFE_DELETE_VEHICLE(stTruck[iCount].vehicle) ENDIF stTruck[iCount].bPlayerBeenInThis = FALSE ENDFOR // Replay or not? IF bIsACheckPoint IF NOT DOES_ENTITY_EXIST(stStashCar.vehicle) // On initial repeat play checkpoint, car will exist from initial scene SKIP_RESPAWN_STASH_CAR(stStashCar.location, stStashCar.heading) ENDIF WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE END_REPLAY_SETUP(stStashCar.vehicle, VS_DRIVER, FALSE) ELSE // Teleport player out of vehicle, recreate it IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), stStashCar.location) ENDIF SKIP_RESPAWN_STASH_CAR(stStashCar.location, stStashCar.heading) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) ENDIF ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: /// Z-SKIP /// jump to point after the initial phone call to Barry PROC SKIP_TO_AFTER_CALL() CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: skip to after phone call") SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, FALSE) SKIP_CLEAR_ALL_MISSION_OBJECTIVES() SKIP_CLEAR_WANTED() SAFE_REMOVE_BLIP(biGotoBlip) // Progression stuff mStage = MS_STAGE_CALL_BARRY sProgress = SP_CLEANUP // Set player near car IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), << -464.8707, -1710.4111, 17.6895 >>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 287.46) ENDIF // Remake the stash car (locked) SKIP_RESPAWN_STASH_CAR(stStashCar.location, stStashCar.heading) WAIT(0) // Clear up towtruck(s) IF DOES_ENTITY_EXIST(vehTowTruck) SAFE_DELETE_VEHICLE(vehTowTruck) ENDIF FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 IF DOES_ENTITY_EXIST(stTruck[iCount].vehicle) SAFE_DELETE_VEHICLE(stTruck[iCount].vehicle) ENDIF stTruck[iCount].bPlayerBeenInThis = FALSE ENDFOR // Reset Franklin's unhook complaints spFranklinUnhook = SP_CLEANUP iComplaintCount = 0 bFranklinPushMuttered = FALSE // Has Franklin muttered about needing to move the broken down car bBarryCalledAboutTruck = FALSE // Has Barry called player suggesting tow truck bFranklinTruckMuttered = FALSE // Has Franklin muttered about needing to jack a truck bDeliveryCallTriggered = FALSE MISSION_OBJECTIVE_EXPIRE(MO_B3CENTV) // Get in the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CDELV) // Go to Barry's ~y~apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3CWAN1) // Lose the cops. MISSION_OBJECTIVE_RESET(MO_B3CNOGO) // Find a way to move the stash car. MISSION_OBJECTIVE_RESET(MO_B3CREVRS) // Hook the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CLEAVE) // Leave the area MISSION_OBJECTIVE_RESET(MO_B3CRTTT) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // Rehook the ~b~stash car~s~. // If we are checkpointing need to wait for text WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE ENDPROC #ENDIF /// PURPOSE: /// Skip to start of towing section PROC SKIP_START_TOWING_SECTION(BOOL bIsCheckPoint = FALSE) CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: skip to start of tow in barry3c") // Need to determine the truck coordinates before we can do the load wait IF bIsCheckPoint IF IS_REPLAY_CHECKPOINT_VEHICLE_AVAILABLE() truckSkipModel = GET_REPLAY_CHECKPOINT_VEHICLE_MODEL() // Only towtrucks and cargobobs are valid for this checkpoint, so change invalid vehicle types to be TOWTRUCK IF truckSkipModel <> TOWTRUCK2 AND truckSkipModel <> CARGOBOB AND truckSkipModel <> CARGOBOB2 AND truckSkipModel <> CARGOBOB3 truckSkipModel = TOWTRUCK ENDIF ELSE truckSkipModel = TOWTRUCK ENDIF START_REPLAY_SETUP(stStashCar.location, stStashCar.heading) ENDIF // Get spawn coordinates for truck IF truckSkipModel = TOWTRUCK CPRINTLN(DEBUG_MISSION, "Spawning truck at position for TOWTRUCK") vecRespawnTruck = << -462.0807, -1711.6804, 17.6454 >> fRespawnTruck = 277.92 ELIF truckSkipModel = TOWTRUCK2 CPRINTLN(DEBUG_MISSION, "Spawning truck at position for TOWTRUCK2") vecRespawnTruck = << -463.5672, -1712.2842, 17.6392 >> fRespawnTruck = 272.29 ELIF truckSkipModel = CARGOBOB OR truckSkipModel = CARGOBOB2 OR truckSkipModel = CARGOBOB3 CPRINTLN(DEBUG_MISSION, "Spawning cargobob at position for CARGOBOB") vecRespawnTruck = <<-455.4628, -1712.2817, 17.6420>> fRespawnTruck = 0.7 ENDIF IF bIsCheckPoint START_REPLAY_SETUP(vecRespawnTruck, fRespawnTruck) ELSE // If player is in the stash car get them out of it so it can be deleted IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) SET_ENTITY_COORDS(PLAYER_PED_ID(), stStashCar.location) ENDIF ENDIF SKIP_CLEAR_ALL_MISSION_OBJECTIVES() SKIP_CLEAR_WANTED() SAFE_REMOVE_BLIP(biGotoBlip) // Progression stuff mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP // Clear up towtruck(s) FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 SAFE_DELETE_VEHICLE(stTruck[iCount].vehicle) ENDFOR SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, TRUE) // Reset Franklin's unhook complaints spFranklinUnhook = SP_CLEANUP iComplaintCount = 0 bFranklinPushMuttered = TRUE // Has Franklin muttered about needing to move the broken down car bBarryCalledAboutTruck = TRUE // Has Barry called player suggesting tow truck bFranklinTruckMuttered = TRUE // Has Franklin muttered about needing to jack a truck bDeliveryCallTriggered = FALSE MISSION_OBJECTIVE_EXPIRE(MO_B3CENTV) // Get in the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CDELV) // Go to Barry's ~y~apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3CWAN1) // Lose the cops. MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) // Find a way to move the stash car. MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) // Hook the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CLEAVE) // Leave the area MISSION_OBJECTIVE_RESET(MO_B3CRTTT) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_RESET(MO_B3CRTCB) // Get back in the ~b~cargobob.~s~ MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // Rehook the ~b~stash car~s~. // Remake the stash car SKIP_RESPAWN_STASH_CAR(stStashCar.location, stStashCar.heading) IF bIsCheckpoint SKIP_RESPAWN_TRUCK(vecRespawnTruck, fRespawnTruck, FALSE) // Reattach car to truck IF IS_ENTITY_ALIVE(vehTowTruck) AND truckSkipModel = TOWTRUCK SET_VEHICLE_TOW_TRUCK_ARM_POSITION(vehTowTruck, 0.0) ENDIF WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE END_REPLAY_SETUP(vehTowTruck, VS_DRIVER, FALSE) ELSE SKIP_RESPAWN_TRUCK(vecRespawnTruck, fRespawnTruck, TRUE) // Reattach car to truck IF IS_ENTITY_ALIVE(vehTowTruck) AND truckSkipModel = TOWTRUCK SET_VEHICLE_TOW_TRUCK_ARM_POSITION(vehTowTruck, 0.0) ENDIF ENDIF // Wait until car is hooked - on checkpoints this check won't work before player is in truck and it's placed IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 WHILE NOT IS_STASH_CAR_HOOKED() CPRINTLN(DEBUG_MISSION, "DEBUG SKIP::: Waiting until car is attached to truck...") WAIT(0) ENDWHILE ENDIF SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_START_TOW, "Start of towing stage") ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: /// DEBUG SKIP - Warp near to ending PROC SKIP_WARP_NEAR_END() CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: warp near delivery location") SKIP_CLEAR_ALL_MISSION_OBJECTIVES() SKIP_CLEAR_WANTED() SAFE_REMOVE_BLIP(biGotoBlip) // Progression stuff mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP // Clear up towtruck(s) FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 IF DOES_ENTITY_EXIST(stTruck[iCount].vehicle) SAFE_DELETE_VEHICLE(stTruck[iCount].vehicle) ENDIF ENDFOR SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, TRUE) // Teleport player out of vehicle, recreate it IF truckSkipModel = TOWTRUCK CPRINTLN(DEBUG_MISSION, "truckSkipModel = TOWTRUCK - respawning") SKIP_RESPAWN_TRUCK(<< -1050.8541, -1267.1842, 5.2005 >>, 119.77) ELIF truckSkipModel = TOWTRUCK2 CPRINTLN(DEBUG_MISSION, "truckSkipModel = TOWTRUCK2 - respawning") SKIP_RESPAWN_TRUCK(<< -1049.7117, -1266.5262, 5.2119 >>, 120.05) ELIF truckSkipModel = CARGOBOB OR truckSkipModel = CARGOBOB2 OR truckSkipModel = CARGOBOB3 CPRINTLN(DEBUG_MISSION, "truckSkipModel is a cargobob - respawning") SKIP_RESPAWN_TRUCK(<<-1074.1339, -1250.2921, 4.5293>>, 199.5) ELSE CPRINTLN(DEBUG_MISSION, "truckSkipModel wasn't a known type - respawning a towtruck") truckSkipModel = TOWTRUCK SKIP_RESPAWN_TRUCK(<< -1050.8541, -1267.1842, 5.2005 >>, 119.77) ENDIF // Remake the stash car SKIP_RESPAWN_STASH_CAR(<< -1045.25, -1263.94, 5.75 >>, 119.5) WAIT(0) // Reattach car to truck IF truckSkipModel = TOWTRUCK AND IS_ENTITY_ALIVE(vehTowTruck) SET_VEHICLE_TOW_TRUCK_ARM_POSITION(vehTowTruck, 0.0) ENDIF // Reset Franklin's unhook complaints spFranklinUnhook = SP_CLEANUP iComplaintCount = 0 bFranklinPushMuttered = TRUE // Has Franklin muttered about needing to move the broken down car bBarryCalledAboutTruck = TRUE // Has Barry called player suggesting tow truck bFranklinTruckMuttered = TRUE // Has Franklin muttered about needing to jack a truck bDeliveryCallTriggered = FALSE MISSION_OBJECTIVE_EXPIRE(MO_B3CENTV) // Get in the ~b~stash car.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3CDELV) // Go to Barry's ~y~apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3CWAN1) // Lose the cops. MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) // Find a way to move the stash car. MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) // Hook the ~b~stash car.~s~ MISSION_OBJECTIVE_RESET(MO_B3CLEAVE) // Leave the area MISSION_OBJECTIVE_RESET(MO_B3CRTTT) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_RESET(MO_B3CRTCB) // Get back in the ~b~cargobob.~s~ MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // Rehook the ~b~stash car~s~. // Wait until car is hooked IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 WHILE NOT IS_STASH_CAR_HOOKED() CPRINTLN(DEBUG_MISSION, "DEBUG SKIP::: Waiting until car is attached to truck...") WAIT(0) ENDWHILE ENDIF ENDPROC #ENDIF /// PURPOSE: /// DEBUG SKIP/CHECKPOINT - to leave the area stage PROC SKIP_TRIGGER_DELIVERY(BOOL bIsACheckpoint = FALSE) CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: trigger delivery event") IF bIsACheckpoint IF IS_REPLAY_CHECKPOINT_VEHICLE_AVAILABLE() truckSkipModel = GET_REPLAY_CHECKPOINT_VEHICLE_MODEL() // Only towtrucks and cargobobs are valid for this checkpoint, so change vehicle types apart from TOWTRUCK2 to be TOWTRUCK IF truckSkipModel <> TOWTRUCK2 AND truckSkipModel <> CARGOBOB AND truckSkipModel <> CARGOBOB2 AND truckSkipModel <> CARGOBOB3 truckSkipModel = TOWTRUCK ENDIF ELSE truckSkipModel = TOWTRUCK ENDIF IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 START_REPLAY_SETUP(<<-1154.2244, -1234.3102, 5.7174>>, 12.45) ELSE // Cargobob on garage roof START_REPLAY_SETUP(<<-1148.1831, -1227.0050, 8.4468>>, 19.2) ENDIF ENDIF SKIP_CLEAR_ALL_MISSION_OBJECTIVES() SKIP_CLEAR_WANTED() SAFE_REMOVE_BLIP(biGotoBlip) // Progression stuff // Checkpoint won't replay the phonecall - but if the player has shitskipped they should get the call IF bIsACheckpoint AND NOT g_bShitskipAccepted bDeliveryCallTriggered = TRUE // Skip phone call mStage = MS_STAGE_LEAVE ELSE bDeliveryCallTriggered = FALSE iCallDelayTimer = GET_GAME_TIMER() + 3000 mStage = MS_STAGE_DELIVERY_PHONE_CALL ENDIF sProgress = SP_SETUP // Clear up towtruck(s) FOR iCount = 0 TO NUM_HELPER_TRUCKS-1 IF DOES_ENTITY_EXIST(stTruck[iCount].vehicle) SAFE_DELETE_VEHICLE(stTruck[iCount].vehicle) ENDIF ENDFOR SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, TRUE) bFranklinPushMuttered = TRUE // Has Franklin muttered about needing to move the broken down car bBarryCalledAboutTruck = TRUE // Has Barry called player suggesting tow truck bFranklinTruckMuttered = TRUE // Has Franklin muttered about needing to jack a truck MISSION_OBJECTIVE_EXPIRE(MO_B3CENTV) // Get in the ~b~stash car.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3CDELV) // Go to Barry's ~y~apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3CWAN1) // Lose the cops. MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) // Get the car to Barry's apartment. MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) // Hook the ~b~stash car~s~ with the tow truck. MISSION_OBJECTIVE_RESET(MO_B3CLEAVE) // Leave the area MISSION_OBJECTIVE_RESET(MO_B3CRTTT) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_RESET(MO_B3CRTCB) // Get back in the ~b~cargobob.~s~ MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. MISSION_OBJECTIVE_RESET(MO_B3CGBTB) // Rehook the ~b~stash car~s~. // Remake the stash car - not attatched to truck SKIP_RESPAWN_STASH_CAR(<< -1151.36, -1243.57, 6.52 >>, 25.18) IF bIsACheckpoint // Teleport player out of vehicle, recreate it IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 SKIP_RESPAWN_TRUCK(<<-1154.2244, -1234.3102, 5.7174>>, 12.45, FALSE) ELSE // Cargobob on garage roof SKIP_RESPAWN_TRUCK(<<-1148.1831, -1227.0050, 8.4468>>, 19.2, FALSE) ENDIF WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE END_REPLAY_SETUP(vehTowTruck, VS_DRIVER, FALSE) ELSE // Teleport player out of vehicle, recreate it IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 SKIP_RESPAWN_TRUCK(<<-1154.2244, -1234.3102, 5.7174>>, 12.45) ELSE // Cargobob on garage roof SKIP_RESPAWN_TRUCK(<<-1148.1831, -1227.0050, 8.4468>>, 19.2) ENDIF ENDIF SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_DELIVERY, "Delivered vehicle", TRUE) ENDPROC /// PURPOSE: /// DEBUG SKIP - Trigger the completion PROC SKIP_MISSION_COMPLETE(BOOL bIsACheckpoint = FALSE) CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: Trigger mission complete") IF bIsACheckpoint IF IS_REPLAY_CHECKPOINT_VEHICLE_AVAILABLE() truckSkipModel = GET_REPLAY_CHECKPOINT_VEHICLE_MODEL() // Only towtrucks and cargobobs are valid for this checkpoint, so change vehicle types apart from TOWTRUCK2 to be TOWTRUCK IF truckSkipModel <> TOWTRUCK2 AND truckSkipModel <> CARGOBOB AND truckSkipModel <> CARGOBOB2 AND truckSkipModel <> CARGOBOB3 truckSkipModel = TOWTRUCK ENDIF ELSE truckSkipModel = TOWTRUCK ENDIF // Start the load IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 START_REPLAY_SETUP(<< -1237.9617, -1035.1941, 7.2466 >>, 110.0) ELSE START_REPLAY_SETUP(<<-1074.1339, -1250.2921, 4.5293>>, 199.5) ENDIF ENDIF SKIP_CLEAR_ALL_MISSION_OBJECTIVES() SKIP_CLEAR_WANTED() SAFE_REMOVE_BLIP(biGotoBlip) // Progression stuff mStage = MS_STAGE_LEAVE sProgress = SP_SETUP MISSION_OBJECTIVE_EXPIRE(MO_B3CENTV) // Get in the ~b~stash car.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3CDELV) // Go to Barry's ~y~apartment.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3CWAN1) // Lose the cops. MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) // Find a way to move the stash car. MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) // Hook the ~b~stash car~s~ with the tow truck. MISSION_OBJECTIVE_EXPIRE(MO_B3CLEAVE) // Leave the area MISSION_OBJECTIVE_EXPIRE(MO_B3CRTTT) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3CRTCB) // Get back in the ~b~tow truck.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3CGBTB) // The ~b~stash car~s~ has broken loose, hook it with the tow truck. MISSION_OBJECTIVE_EXPIRE(MO_B3CGBTB) // Rehook the ~b~stash car~s~. // Remake the stash car - at drop-off location SKIP_RESPAWN_STASH_CAR(<< -1151.36, -1243.57, 6.52 >>, 25.18) IF bIsACheckpoint // Spawn vehicle IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 SKIP_RESPAWN_TRUCK(<< -1237.9617, -1035.1941, 7.2466 >>, 110.0, FALSE) ELSE SKIP_RESPAWN_TRUCK(<<-1074.1339, -1250.2921, 4.5293>>, 199.5, FALSE) ENDIF WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE END_REPLAY_SETUP(vehTowTruck, VS_DRIVER, FALSE) ELSE // Teleport player out of vehicle, recreate it IF truckSkipModel = TOWTRUCK OR truckSkipModel = TOWTRUCK2 SKIP_RESPAWN_TRUCK(<< -1237.9617, -1035.1941, 7.2466 >>, 110.0) ELSE SKIP_RESPAWN_TRUCK(<<-1074.1339, -1250.2921, 4.5293>>, 199.5) ENDIF 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: /// Debug skip forward PROC SKIP_FORWARD() RC_START_Z_SKIP() SWITCH mStage CASE MS_STAGE_ENTER_STASH_CAR SKIP_TO_START_CAR() BREAK CASE MS_STAGE_START_STASH_CAR CASE MS_STAGE_CALL_BARRY CASE MS_STAGE_FIND_TOWTRUCK CASE MS_STAGE_TOW_VEHICLE SKIP_START_TOWING_SECTION() BREAK CASE MS_STAGE_RETURN_VEHICLE CASE MS_STAGE_GET_TRUCK_BACK CASE MS_STAGE_REATTACH_VEHICLE // Check whether we're already close to end IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vecApartment) < 200 SKIP_TRIGGER_DELIVERY() ELSE SKIP_WARP_NEAR_END() ENDIF ENDIF BREAK CASE MS_STAGE_DELIVERY_PHONE_CALL CASE MS_STAGE_LEAVE SKIP_MISSION_COMPLETE() BREAK ENDSWITCH RC_END_Z_SKIP() ENDPROC /// PURPOSE: /// Skips backward PROC SKIP_BACKWARD() RC_START_Z_SKIP() SWITCH mStage CASE MS_STAGE_ENTER_STASH_CAR CASE MS_STAGE_START_STASH_CAR SKIP_TO_MS_INIT() BREAK CASE MS_STAGE_CALL_BARRY CASE MS_STAGE_FIND_TOWTRUCK CASE MS_STAGE_TOW_VEHICLE SKIP_TO_START_CAR() BREAK CASE MS_STAGE_RETURN_VEHICLE IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), stStashCar.location) < 10 SKIP_TO_START_CAR() ELSE SKIP_START_TOWING_SECTION() ENDIF ENDIF BREAK CASE MS_STAGE_GET_TRUCK_BACK CASE MS_STAGE_REATTACH_VEHICLE SKIP_START_TOWING_SECTION() BREAK CASE MS_STAGE_UNHOOK_VEHICLE CASE MS_STAGE_DELIVERY_PHONE_CALL SKIP_WARP_NEAR_END() BREAK CASE MS_STAGE_LEAVE SKIP_TRIGGER_DELIVERY() BREAK ENDSWITCH RC_END_Z_SKIP() ENDPROC /// PURPOSE: /// Handle Z-skips and checkpoints PROC DO_Z_SKIP(INT iZSkip) RC_START_Z_SKIP() eTargetStage = INT_TO_ENUM(MISSION_SKIP_STAGE, iZSkip) // Checkpoints IF eTargetStage = MSS_RESTART SKIP_TO_MS_INIT() ELIF eTargetStage = MSS_IN_CAR SKIP_TO_START_CAR() ELIF eTargetStage = MSS_CALL_SKIP SKIP_TO_AFTER_CALL() ELIF eTargetStage = MSS_TOWING SKIP_START_TOWING_SECTION() ELIF eTargetStage = MSS_WARP_NEAR_END SKIP_WARP_NEAR_END() ELIF eTargetStage = MSS_DELIVERY SKIP_TRIGGER_DELIVERY() ELIF eTargetStage = MSS_MISSION_COMPLETE SKIP_MISSION_COMPLETE() ENDIF RC_END_Z_SKIP() ENDPROC #ENDIF // =========================================================================================================== // Termination // =========================================================================================================== // ----------------------------------------------------------------------------------------------------------- // Script Cleanup // ----------------------------------------------------------------------------------------------------------- PROC Script_Cleanup() // 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 #IF IS_DEBUG_BUILD // Widgets IF DOES_WIDGET_GROUP_EXIST(widgetGroup) DELETE_WIDGET_GROUP(widgetGroup) ENDIF #ENDIF // Return wanted level to normal SET_WANTED_LEVEL_MULTIPLIER(1.0) RC_CleanupSceneEntities(sRCLauncherDataLocal) REMOVE_SCENARIO_BLOCKING_AREA(mScenarioBlocker) REMOVE_SCENARIO_BLOCKING_AREA(sbCarPark[0]) REMOVE_SCENARIO_BLOCKING_AREA(sbCarPark[1]) SET_GPS_DISABLED_ZONE(<< 0, 0, 0 >>, << 0, 0, 0 >>) COLLECT_AREA_CLEANUP() SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE) TERMINATE_THIS_THREAD() ENDPROC // ----------------------------------------------------------------------------------------------------------- // Script Pass // ----------------------------------------------------------------------------------------------------------- PROC Script_Passed() Random_Character_Passed(CP_RAND_C_BAR3,FALSE) Script_Cleanup() ENDPROC //************************************************************************************************************************************************* // // DATA SETUP // //************************************************************************************************************************************************* /// PURPOSE: /// Setup initial data and entity/variable states PROC DATA_INIT() // Note: This proc is called before the main loop, you must do dead checks! SET_WANTED_LEVEL_MULTIPLIER(0.2) // Reduced from 0.5 - B*1164227 SET_GPS_DISABLED_ZONE(<< -1188.4091, -1233.0059, 0.0 >>, << -1165.7822, -1214.3778, 15.0 >>) REQUEST_ADDITIONAL_TEXT("BARR3C", MISSION_TEXT_SLOT) vecApartment = << -1152.4301, -1238.8237, 5.9752 >> mScenarioBlocker = Barry3C_Scenario_Blocker() 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 >>) // Stash vehicle info stStashCar.modelName = EMPEROR2 stStashCar.location = << -468.90, -1713.06, 18.21 >> stStashCar.heading = -76.20 // stTruck[0] = MAKE_TOWTRUCK_SPAWN(<< -587.61, -1637.06, 18.88 >>, 240.9) stTruck[0] = MAKE_TOWTRUCK_SPAWN(<< -552.67, -1698.84, 18.16 >>, 205.7) // Made position more obvious - B*1165092 stTruck[1] = MAKE_TOWTRUCK_SPAWN(<< -317.14, -1540.72, 26.67 >>, 336.5) stTruck[2] = MAKE_TOWTRUCK_SPAWN(<< -104.41, -1984.91, 17.02 >>, 171.6) stTruck[3] = MAKE_TOWTRUCK_SPAWN(<< -586.69, -1774.59, 21.67 >>, 145.8) stTruck[4] = MAKE_TOWTRUCK_SPAWN(<< -1207.90, -1334.87, 3.77 >>, 204.1) stTruck[5] = MAKE_TOWTRUCK_SPAWN(<< -1253.67, -1210.30, 6.03 >>, 10.7) stTruck[INITIAL_SCENE_TRUCK] = MAKE_TOWTRUCK_SPAWN(<< -426.56, -1717.89, 18.20 >>, 43.5) // HELPER TRUCK FROM INITIAL SCENE - BE CAREFUL IF YOU HAVE TO MESS WITH THIS! stTruck[7] = MAKE_TOWTRUCK_SPAWN(<< 401.64, -1633.30, 28.29 >>, 231.5) // Towing compound IF IS_ENTITY_ALIVE(stStashCar.vehicle) SET_VEHICLE_CAN_LEAK_OIL(stStashCar.vehicle, FALSE) SET_VEHICLE_CAN_LEAK_PETROL(stStashCar.vehicle, FALSE) SET_VEHICLE_UNDRIVEABLE(stStashCar.vehicle, TRUE) SET_VEHICLE_HAS_STRONG_AXLES(stStashCar.vehicle, TRUE) ENDIF REQUEST_MODEL(TOWTRUCK) REQUEST_ANIM_DICT(sIgnitionAnims) IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) ADD_PED_FOR_DIALOGUE(mConversationStruct, 1, PLAYER_PED_ID(), "FRANKLIN") ENDIF ADD_PED_FOR_DIALOGUE(mConversationStruct, 3, NULL, "BARRY") #IF IS_DEBUG_BUILD mSkipMenu[0].sTxtLabel = "Restart" mSkipMenu[1].sTxtLabel = "Trying to start car" mSkipMenu[2].sTxtLabel = "Skip after initial phone call" mSkipMenu[3].sTxtLabel = "Start towing section (CP1)" mSkipMenu[4].sTxtLabel = "Warp near end" mSkipMenu[5].sTxtLabel = "Delivered vehicle (CP2)" mSkipMenu[6].sTxtLabel = "Mission Complete" IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup) widgetGroup = START_WIDGET_GROUP("Barry 3C") ADD_WIDGET_BOOL("Cheat the car location for cargobob", bDebugCheatCarLocation) ADD_WIDGET_BOOL("Toggle STASH_CAR_STARTFAIL_HANDLER debug spew", bDebugCarStartSpew) ADD_WIDGET_VECTOR_SLIDER("Stash prop offset", vecStashOffset, -4.0, 4.0, 0.05) ADD_WIDGET_VECTOR_SLIDER("Stash prop rotate", vecStashRotate, -180.0, 180.0, 0.5) STOP_WIDGET_GROUP() ENDIF #ENDIF // Init tow truck help bShowedRaiseLowerHelp = FALSE // Init objectives STORE_MISSION_OBJECTIVE_DATA() // Init fail reason sFailReason = "DEFAULT" // Setup Franklin's unhook complaint bits iComplaintCount = 0 STORE_COMPLAINT_STRINGS() spFranklinUnhook = SP_CLEANUP // Store dropoff area vecDropoff[0][0] = << -1161.11, -1217.32, 5.65 >> vecDropoff[0][1] = << -1147.86, -1251.60, 10.01 >> fDropoffWidth[0] = 10.5 vecDropoff[1][0] = << -1147.14, -1253.07, 5.65 >> vecDropoff[1][1] = << -1161.97, -1216.69, 10.98 >> fDropoffWidth[1] = 12.0 // Silently add Barry as contact in case we've launched from debug menu ADD_CONTACT_TO_PHONEBOOK(CHAR_BARRY, FRANKLIN_BOOK, FALSE) // Has the delivery call happened? bDeliveryCallTriggered = FALSE SET_GPS_DISABLED_ZONE(<< -1132.88, -1262.01, 0.0 >>, << -1102.43, -1196.58, 15.0 >>) TOGGLE_CAR_MOD_SHOPS_UNAVAILABLE(TRUE) ENDPROC //************************************************************************************************************************************************* // // Mission stage procs // //************************************************************************************************************************************************* /// PURPOSE: /// MISSION STAGE PROC /// Initial get into car step, check whether the player has arrived with a tow truck PROC STAGE_ENTER_STASH_CAR() SWITCH sProgress CASE SP_SETUP IF HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) // See if player is wise to what's up and has brought their own ride IF IS_PLAYER_IN_TOWTRUCK() CPRINTLN(DEBUG_MISSION, "Player has started mission in towtruck/cargobob") CHECK_VEHGEN_CREATION() // Franklin's comment IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", "BAR3C_C2", CONV_PRIORITY_MEDIUM) // Have they hooked? IF IS_STASH_CAR_HOOKED() // Yes - deliver INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(BA3C_DELIVERY_TIME) MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP ELSE // No - start towing MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) mStage = MS_STAGE_TOW_VEHICLE sProgress = SP_SETUP ENDIF ENDIF ELSE // Blip vehicle and advise player to enter it biGotoBlip = CREATE_VEHICLE_BLIP(stStashCar.vehicle) DISPLAY_MISSION_OBJECTIVE(MO_B3CENTV) // Get in the stash car sProgress = SP_RUNNING // Request audio bank now REQUEST_SCRIPT_AUDIO_BANK("BARRY3C_IGNITION_FAIL") ENDIF ENDIF BREAK CASE SP_RUNNING // Check for normal progression - player gets in car IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) // Player in stash car sProgress = SP_CLEANUP // Check for player getting back into a tow truck after mission launch ELIF IS_PLAYER_IN_TOWTRUCK() CHECK_VEHGEN_CREATION() // Franklin's comment IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", "BAR3C_C2", CONV_PRIORITY_MEDIUM) // Have they hooked? IF IS_STASH_CAR_HOOKED() // Yes - deliver INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(BA3C_DELIVERY_TIME) MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP ELSE // No - start towing MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) mStage = MS_STAGE_TOW_VEHICLE sProgress = SP_SETUP ENDIF ENDIF ENDIF BREAK CASE SP_CLEANUP CLEAR_PRINTS() SAFE_REMOVE_BLIP(biGotoBlip) mStage = MS_STAGE_START_STASH_CAR sProgress = SP_SETUP BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Handles the car not staring sequence PROC STAGE_START_STASH_CAR() SWITCH sProgress CASE SP_SETUP // Fade in in case we're on a replay SAFE_FADE_SCREEN_IN_FROM_BLACK() SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON) CPRINTLN(DEBUG_MISSION, "Text loaded...") // Check for shady exactly-this-frame truck entry or other weirdness IF IS_PLAYER_IN_TOWTRUCK() CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SP_SETUP: Detected mission start from player hooking car, checking whether it's still attached...") INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(BA3C_DELIVERY_TIME) MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) SET_VEHICLE_CAN_LEAK_OIL(stStashCar.vehicle, FALSE) SET_VEHICLE_CAN_LEAK_PETROL(stStashCar.vehicle, FALSE) IF IS_STASH_CAR_HOOKED() // Player is in a truck and hooked up CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SP_SETUP: ...car still hooked, going to MS_STAGE_RETURN_VEHICLE.") sProgress = SP_SETUP mStage = MS_STAGE_RETURN_VEHICLE ELSE // Player hooked car but it's already loose! CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SP_SETUP: ...car already came unhooked, going to MS_STAGE_TOW_VEHICLE.") sProgress = SP_SETUP mStage = MS_STAGE_TOW_VEHICLE ENDIF ELSE // Normal flow, player is currently in stash car CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SP_SETUP: Mission start from player entering stash car, going to SP_RUNNING") SET_VEHICLE_CAN_LEAK_OIL(stStashCar.vehicle, FALSE) SET_VEHICLE_CAN_LEAK_PETROL(stStashCar.vehicle, FALSE) bPlayerWantsOut = FALSE sceProgress = SCE_ASSETS sProgress = SP_RUNNING ENDIF BREAK CASE SP_RUNNING IF NOT bPlayerWantsOut AND (sceProgress <> SCE_ASSETS) // Ignore exit attempts while we're still loading assets AND (iIgnitionAttempts > 0 AND iIgnitionAttempts < NUM_IGNITION_ATTEMPTS) // Ignore exit attempts before they've tried engine once, and after the final attempt AND IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_EXIT) CPRINTLN(DEBUG_MISSION, "Player wants out!") bPlayerWantsOut = TRUE ENDIF SWITCH sceProgress CASE SCE_ASSETS // Check sounds and assets loaded... IF REQUEST_SCRIPT_AUDIO_BANK("BARRY3C_IGNITION_FAIL") AND HAS_ANIM_DICT_LOADED(sIgnitionAnims) // Don't go on before player is in driver seat IF GET_PED_IN_VEHICLE_SEAT(stStashCar.vehicle) = PLAYER_PED_ID() CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SCE_ASSETS: Got assets, starting cutscene...") IF NOT bStashStuckCheckActive ADD_VEHICLE_UPSIDEDOWN_CHECK(stStashCar.vehicle) bStashStuckCheckActive = TRUE ENDIF // Set up timer and go on to next step iIgnitionAttempts = 0 iIgnitionSoundID = GET_SOUND_ID() sceProgress = SCE_TRIGGER_ANIM ENDIF ENDIF BREAK CASE SCE_TRIGGER_ANIM IF GET_PED_IN_VEHICLE_SEAT(stStashCar.vehicle) = PLAYER_PED_ID() AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SCE_ASSETS: Triggering anim...") IF iIgnitionAttempts = NUM_IGNITION_ATTEMPTS-1 // Special long attempt then go to annoyance reaction OPEN_SEQUENCE_TASK(seqCarStart) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_enter", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 2000, AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_loop", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 8000, AF_LOOPING|AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_exit", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 766, AF_NOT_INTERRUPTABLE) CLOSE_SEQUENCE_TASK(seqCarStart) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seqCarStart) CLEAR_SEQUENCE_TASK(seqCarStart) iCarEventsTimer = GET_GAME_TIMER() + 2000 sceProgress = SCE_IGNITION_SOUND ELIF iIgnitionAttempts = NUM_IGNITION_ATTEMPTS-2 IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", "BAR3C_C1", CONV_PRIORITY_MEDIUM) OPEN_SEQUENCE_TASK(seqCarStart) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_enter", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 2000, AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_loop", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 1200+(iIgnitionAttempts*250), AF_LOOPING|AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_exit", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 766, AF_NOT_INTERRUPTABLE) CLOSE_SEQUENCE_TASK(seqCarStart) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seqCarStart) CLEAR_SEQUENCE_TASK(seqCarStart) iCarEventsTimer = GET_GAME_TIMER() + 2000 sceProgress = SCE_IGNITION_SOUND ENDIF ELSE OPEN_SEQUENCE_TASK(seqCarStart) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_enter", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 2000, AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_loop", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 1200+(iIgnitionAttempts*250), AF_LOOPING|AF_NOT_INTERRUPTABLE) TASK_PLAY_ANIM(NULL, sIgnitionAnims, "franklinfailingtostartcar_exit", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, 766, AF_NOT_INTERRUPTABLE) CLOSE_SEQUENCE_TASK(seqCarStart) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seqCarStart) CLEAR_SEQUENCE_TASK(seqCarStart) iCarEventsTimer = GET_GAME_TIMER() + 2000 sceProgress = SCE_IGNITION_SOUND ENDIF ENDIF BREAK CASE SCE_IGNITION_SOUND IF GET_GAME_TIMER() > iCarEventsTimer IF iIgnitionAttempts = NUM_IGNITION_ATTEMPTS PLAY_SOUND_FROM_ENTITY(iIgnitionSoundID, "IGNITION_FAIL", stStashCar.vehicle, "BARRY_03_SOUNDSET") SET_VARIABLE_ON_SOUND(iIgnitionSoundID, "HOLD TIME", 3.0) iCarEventsTimer = GET_GAME_TIMER() + 9100 ELSE PLAY_SOUND_FROM_ENTITY(iIgnitionSoundID, "IGNITION_FAIL", stStashCar.vehicle, "BARRY_03_SOUNDSET") SET_VARIABLE_ON_SOUND(iIgnitionSoundID, "HOLD TIME", (TO_FLOAT(1200+(iIgnitionAttempts*250))/1000.0)) iCarEventsTimer = GET_GAME_TIMER() + (iIgnitionAttempts*250) + 1200 + 766 ENDIF sceProgress = SCE_WAIT_TO_REPEAT ENDIF BREAK CASE SCE_WAIT_TO_REPEAT IF GET_GAME_TIMER() > iCarEventsTimer IF bPlayerWantsOut sceProgress = SCE_COMMENT ELSE iIgnitionAttempts++ IF iIgnitionAttempts = NUM_IGNITION_ATTEMPTS // We're done - annoyed gesture time TASK_PLAY_ANIM(PLAYER_PED_ID(), sIgnitionAnims, "franklinfailingtostartcar_slamwheel", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, 3300) iCarEventsTimer = GET_GAME_TIMER() + 330 sceProgress = SCE_ANNOYED_HORN ELSE sceProgress = SCE_TRIGGER_ANIM ENDIF ENDIF ENDIF BREAK CASE SCE_ANNOYED_HORN IF GET_GAME_TIMER() > iCarEventsTimer START_VEHICLE_HORN(stStashCar.vehicle, 500, GET_HASH_KEY("NORMAL")) iCarEventsTimer = GET_GAME_TIMER() + 2000 sceProgress = SCE_END ENDIF BREAK CASE SCE_COMMENT // Comment if player exits car manually IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SP_RUNNING: SCE_COMMENT: Player forcing exit, do shift it comment if not speaking") IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", "BAR3C_C2", CONV_PRIORITY_MEDIUM) iCarEventsTimer = GET_GAME_TIMER() sceProgress = SCE_EXIT_CAR ENDIF ELSE iCarEventsTimer = GET_GAME_TIMER() sceProgress = SCE_EXIT_CAR ENDIF ENDIF BREAK CASE SCE_EXIT_CAR IF GET_GAME_TIMER() > iCarEventsTimer CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SP_RUNNING: SCE_EXIT_CAR: Exit the car") CLEAR_PED_TASKS(PLAYER_PED_ID()) TASK_LEAVE_VEHICLE(PLAYER_PED_ID(), stStashCar.vehicle) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) sceProgress = SCE_END ENDIF BREAK CASE SCE_END CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_STASH_CAR: SP_RUNNING: SCE_END: Sequence over") iCarEventsTimer = GET_GAME_TIMER() SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) sProgress = SP_CLEANUP BREAK ENDSWITCH BREAK CASE SP_CLEANUP // Delay phone call IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND GET_GAME_TIMER() - iCarEventsTimer > 2500 sProgress = SP_SETUP mStage = MS_STAGE_CALL_BARRY ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Franklin calls Barry to see what to do about the car PROC STAGE_CALL_BARRY() SWITCH sProgress CASE SP_SETUP // Init the car startfail handler bPlayerInStashCar = FALSE bPlayerWantsOut = FALSE // Start phone call to Barry IF PLAYER_CALL_CHAR_CELLPHONE(mConversationStruct, CHAR_BARRY, "BAR3CAU", "BAR3C_NG", CONV_PRIORITY_VERY_HIGH) CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_SETUP: Phone call started") sProgress = SP_RUNNING ENDIF BREAK CASE SP_RUNNING TRUCK_SPAWNER() STASH_CAR_STARTFAIL_HANDLER() // Check for ninja truck acquisition IF IS_PLAYER_IN_TOWTRUCK() CHECK_VEHGEN_CREATION() IF IS_STASH_CAR_HOOKED() // Expire redundant objectives MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) // Get the vehicle to Barry's apartment. MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) // Hook the stash car IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 // Go to main driving stage CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_RUNNING: Player in truck with car hooked super fast, going to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP ELSE // Wanted! CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_RUNNING: Player in truck with car hooked super fast but is wanted, going to STAGE_LOSE_WANTED") mStage = MS_STAGE_LOSE_WANTED sProgress = SP_SETUP ENDIF ELSE //Go to tow stage CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_RUNNING: Player in truck, still needs to hook car, go to STAGE_TOW_VEHICLE") mStage = MS_STAGE_TOW_VEHICLE sProgress = SP_SETUP // Expire redundant objectives MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) // Get the vehicle to Barry's apartment. ENDIF ELIF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() sProgress = SP_CLEANUP CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_RUNNING: Phone call completed, going to SP_CLEANUP to show objective after a delay") ENDIF BREAK CASE SP_CLEANUP IF NOT IS_PLAYER_IN_TOWTRUCK() CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_CLEANUP: going on to find tow truck stage.") STASH_CAR_STARTFAIL_HANDLER() DISPLAY_MISSION_OBJECTIVE(MO_B3CNOGO) // Get the vehicle to Barry's apartment. SAFE_REMOVE_BLIP(biGotoBlip) biGotoBlip = CREATE_VEHICLE_BLIP(stStashCar.vehicle) bBarryCalledAboutTruck = FALSE iCallDelayTimer = GET_GAME_TIMER() sProgress = SP_SETUP mStage = MS_STAGE_FIND_TOWTRUCK ELSE //Go to tow stage CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_RUNNING: Player in truck, still needs to hook car, go to STAGE_TOW_VEHICLE") mStage = MS_STAGE_TOW_VEHICLE sProgress = SP_SETUP // Expire redundant objectives MISSION_OBJECTIVE_EXPIRE(MO_B3CNOGO) // Get the vehicle to Barry's apartment. ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Find a tow truck PROC STAGE_FIND_TOWTRUCK() SWITCH sProgress // Setup - stay here until player finds a towtruck CASE SP_SETUP TRUCK_SPAWNER() // Check for player in towtruck IF IS_PLAYER_IN_TOWTRUCK() // Let's start suppressing the towtruck model now SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, TRUE) CHECK_VEHGEN_CREATION() IF IS_STASH_CAR_HOOKED() CPRINTLN(DEBUG_MISSION, "STAGE_FIND_TOWTRUCK: SP_SETUP: Player already in towtruck and hooked, going to MS_STAGE_RETURN_VEHICLE") MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) SAFE_REMOVE_BLIP(biGotoBlip) bPlayerInTruckLastFrame = TRUE bBarryCalledAboutTruck = TRUE mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP ELSE CPRINTLN(DEBUG_MISSION, "STAGE_FIND_TOWTRUCK: SP_SETUP: Player got in towtruck, going to SP_RUNNING") DISPLAY_MISSION_OBJECTIVE(MO_B3CREVRS) SAFE_REMOVE_BLIP(biGotoBlip) biGotoBlip = CREATE_VEHICLE_BLIP(stStashCar.vehicle) bPlayerInTruckLastFrame = TRUE bBarryCalledAboutTruck = TRUE sProgress = SP_RUNNING ENDIF ELSE STASH_CAR_STARTFAIL_HANDLER() // Conversation triggering // See if we should be triggering Franklin's first comment IF NOT bFranklinPushMuttered AND GET_GAME_TIMER() - iCallDelayTimer > PUSH_MUTTER_DELAY IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", "BAR3C_MUTT", CONV_PRIORITY_MEDIUM) bFranklinPushMuttered = TRUE ENDIF // See if we should be triggering call from Barry ELIF NOT bBarryCalledAboutTruck AND GET_GAME_TIMER() - iCallDelayTimer > BARRY_CALL_DELAY IF NOT PLAYER_ABOUT_TO_GET_IN_TOWTRUCK() IF CHAR_CALL_PLAYER_CELLPHONE_FORCE_ANSWER(mConversationStruct, CHAR_BARRY, "BAR3CAU", "BAR3C_HC", CONV_PRIORITY_MEDIUM) bBarryCalledAboutTruck = TRUE ENDIF ENDIF // See if we should be triggering Franklin's second comment ELIF NOT bFranklinTruckMuttered AND GET_GAME_TIMER() - iCallDelayTimer > TRUCK_MUTTER_DELAY IF CREATE_CONVERSATION(mConversationStruct, "BAR3CAU", "BAR3C_TOW", CONV_PRIORITY_MEDIUM) bFranklinTruckMuttered = TRUE ENDIF ENDIF ENDIF BREAK // Running - wait for player to reach stash car area CASE SP_RUNNING IF bPlayerInTruckLastFrame // Player currently in truck // Check for player getting out of the truck IF NOT IS_PLAYER_IN_TOWTRUCK() DISPLAY_MISSION_OBJECTIVE(MO_B3CRTTT) // Get back in the towtruck SAFE_REMOVE_BLIP(biGotoBlip) biGotoBlip = CREATE_VEHICLE_BLIP(vehTowTruck) bPlayerInTruckLastFrame = FALSE // Are they near the stash car yet? ELIF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -417.58, -1723.81, 15.42 >>, << -473.60, -1705.96, 26.95 >>, 49.0) sProgress = SP_CLEANUP // Is player in truck with car hooked - fringe case from mucking about ELIF IS_STASH_CAR_HOOKED() CPRINTLN(DEBUG_MISSION, "Stash car hooked in STAGE_FIND_TOWTRUCK without going through angled area - Player may have moved car away from start point or be in cargobob") sProgress = SP_CLEANUP ENDIF // Player not in truck - Have they got back in? ELIF IS_PLAYER_IN_TOWTRUCK() CLEAR_MISSION_OBJECTIVE(MO_B3CRTTT) SAFE_REMOVE_BLIP(biGotoBlip) biGotoBlip = CREATE_VEHICLE_BLIP(stStashCar.vehicle) bPlayerInTruckLastFrame = TRUE ENDIF STASH_CAR_STARTFAIL_HANDLER() BREAK CASE SP_CLEANUP // Remove blip CLEAR_PRINTS() CLEAR_HELP(TRUE) // Set substage here in case it need to be overridden sProgress = SP_SETUP // Change states IF IS_PLAYER_IN_TOWTRUCK() // Player in truck - check towing status - VERY unlikely to happen here but best to check IF IS_STASH_CAR_HOOKED() // Car is attached - go to main driving stage INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(BA3C_DELIVERY_TIME) SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_START_TOW, "Start of towing stage") mStage = MS_STAGE_RETURN_VEHICLE ELSE // Go to intial towing stage mStage = MS_STAGE_TOW_VEHICLE ENDIF bPlayerInTruckLastFrame = TRUE ENDIF STASH_CAR_STARTFAIL_HANDLER() BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Get the tow truck attached to the stash car PROC STAGE_TOW_VEHICLE() STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_DRIVING) IF bPlayerInTruckLastFrame // Player is in the truck // Check whether player has got out of truck IF NOT IS_PLAYER_IN_TOWTRUCK() // Player not in truck CPRINTLN(DEBUG_MISSION, "STAGE_TOW_VEHICLE: SP_SETUP: Player not in tow truck") DISPLAY_MISSION_OBJECTIVE(MO_B3CRTTT) // Get back in the tow truck SAFE_REMOVE_BLIP(biGotoBlip) biGotoBlip = CREATE_VEHICLE_BLIP(vehTowTruck) ELSE // See if player has hooked car super fast IF IS_STASH_CAR_HOOKED() // Skip through to main driving stage CPRINTLN(DEBUG_MISSION, "STAGE_TOW_VEHICLE: SP_SETUP: Player in tow truck with car hooked, going to MS_STAGE_RETURN_VEHICLE") MISSION_OBJECTIVE_EXPIRE(MO_B3CREVRS) // Hook the stash car bObjectiveNeeded = FALSE INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(BA3C_DELIVERY_TIME) SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_START_TOW, "Start of towing stage") SAFE_REMOVE_BLIP(biGotoBlip) mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP ELSE // OK to go onto running step CPRINTLN(DEBUG_MISSION, "STAGE_TOW_VEHICLE: SP_SETUP: Player in tow truck, going to SP_RUNNING") IF GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3CREVRS) // Hook the stash car bObjectiveNeeded = FALSE ELSE bObjectiveNeeded = TRUE ENDIF IF NOT DOES_BLIP_EXIST(biGotoBlip) biGotoBlip = CREATE_VEHICLE_BLIP(stStashCar.vehicle) ENDIF sProgress = SP_RUNNING ENDIF ENDIF ELSE // Player is on foot // Check whether player is back in truck IF IS_PLAYER_IN_TOWTRUCK() IF NOT DOES_BLIP_EXIST(biGotoBlip) biGotoBlip = CREATE_VEHICLE_BLIP(stStashCar.vehicle) ENDIF bPlayerInTruckLastFrame = TRUE ENDIF ENDIF BREAK CASE SP_RUNNING // Display the current tow truck help message IF NOT bShowedRaiseLowerHelp AND IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -458.11, -1725.30, 17.67 >>, << -456.71, -1701.81, 22.0>>, 17.50) AND NOT IS_STASH_CAR_HOOKED() AND NOT TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() PRINT_HELP("B3CTTHB") // Raise/lower bShowedRaiseLowerHelp = TRUE ENDIF // Check if player has hooked car IF IS_STASH_CAR_HOOKED() // Stash car hooked - change state INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(BA3C_DELIVERY_TIME) SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_START_TOW, "Start of towing stage") sProgress = SP_CLEANUP bShouldPlayUnhookComment = TRUE // Check for player exiting towttruck ELIF NOT IS_PLAYER_IN_TOWTRUCK() // Set commment off, will be weird if player gets back in while car not attached bShouldPlayUnhookComment = FALSE // Player got out of truck, change states sProgress = SP_CLEANUP // As expected in this step - see if we need the hook objective ELIF bObjectiveNeeded IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3CREVRS) // Hook the stash car bObjectiveNeeded = FALSE ENDIF ENDIF BREAK CASE SP_CLEANUP // Remove blip SAFE_REMOVE_BLIP(biGotoBlip) CLEAR_PRINTS() CLEAR_HELP(TRUE) // Set substage here in case it need to be overridden sProgress = SP_SETUP // Change states IF IS_PLAYER_IN_TOWTRUCK() // Car is attached - go to main driving stage mStage = MS_STAGE_RETURN_VEHICLE ELSE // Player got out of truck mStage = MS_STAGE_GET_TRUCK_BACK ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Get vehicle to Barry if player has collected it PROC STAGE_RETURN_VEHICLE() VECTOR vTmpCar STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_SETUP") SAFE_REMOVE_BLIP(biGotoBlip) biGotoBlip = CREATE_COORD_BLIP(vecApartment) SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_DRIVING) // Set comment playing bool if all is well IF IS_STASH_CAR_HOOKED() bShouldPlayUnhookComment = TRUE ENDIF // Check the player's not wanted before displaying objective IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 // Check whether there are subtitles that might block the objective IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 DISPLAY_MISSION_OBJECTIVE(MO_B3CDELV) // Take the vehicle to Barry bObjectiveNeeded = FALSE ELSE bObjectiveNeeded = TRUE ENDIF ENDIF sProgress = SP_RUNNING BREAK CASE SP_RUNNING // Update Franklin complaint conversation in case it's ongoing FRANKLIN_UNHOOK_COMPLAINT() // Detect player getting out of tow truck IF NOT IS_PLAYER_IN_TOWTRUCK() // Player not in vehicle - change states sProgress = SP_CLEANUP // Detect vehicle becoming detatched ELIF NOT IS_STASH_CAR_HOOKED() // Stash car unhooked IF TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() IF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[1][0], vecDropoff[1][1], fDropoffWidth[1], FALSE, FALSE) CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_RUNNING: Car unhooked from cargobob, in delivery zone") IF NOT IS_ENTITY_IN_AIR(stStashCar.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_RUNNING: Car not in air") vTmpCar = GET_ENTITY_COORDS(stStashCar.vehicle) IF vTmpCar.z < 6.7 // Have to check this in case being hitched on the edge of a roof counts as on ground // Delivered. Probably with cargobob. CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_RUNNING: Car delivered") SAFE_REMOVE_BLIP(biGotoBlip) mStage = MS_STAGE_DELIVERY_PHONE_CALL sProgress = SP_SETUP ENDIF ENDIF ELSE // - change states sProgress = SP_CLEANUP ENDIF ELSE // - change states sProgress = SP_CLEANUP ENDIF // Check player isn't wanted ELIF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Player wanted - change states sProgress = SP_CLEANUP ELIF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[0][0], vecDropoff[0][1], fDropoffWidth[0], TRUE) // Go on to unhook stage and tell player to release vehicle sProgress = SP_CLEANUP ELIF bObjectiveNeeded IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() bObjectiveNeeded = FALSE DISPLAY_MISSION_OBJECTIVE(MO_B3CDELV) ENDIF ENDIF BREAK CASE SP_CLEANUP SAFE_REMOVE_BLIP(biGotoBlip) CLEAR_PRINTS() sProgress = SP_SETUP // Change stage IF NOT IS_PLAYER_IN_TOWTRUCK() // Get the truck back mStage = MS_STAGE_GET_TRUCK_BACK ELIF NOT IS_STASH_CAR_HOOKED() // Check whether we've delivered IF TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() AND IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[0][0], vecDropoff[0][1], fDropoffWidth[0], FALSE, FALSE) CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_RUNNING: Car unhooked, in the 2D area") IF NOT IS_ENTITY_IN_AIR(stStashCar.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_RUNNING: Car not in the air") vTmpCar = GET_ENTITY_COORDS(stStashCar.vehicle) IF vTmpCar.z < 6.7 // Have to check this in case being hitched on the edge of a roof counts as on ground // Delivered. Probably with cargobob. mStage = MS_STAGE_DELIVERY_PHONE_CALL ENDIF ELSE // Otherwise stay here until we're good sProgress = SP_CLEANUP ENDIF ELSE // Reattach car mStage = MS_STAGE_REATTACH_VEHICLE ENDIF ELIF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[0][0], vecDropoff[0][1], fDropoffWidth[0], FALSE) //IS_ENTITY_IN_RANGE_COORDS(vehTowTruck, vecApartment, 10) // Go on to car park drop-off stage mStage = MS_STAGE_UNHOOK_VEHICLE ELIF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Lose wanted mStage = MS_STAGE_LOSE_WANTED ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Tracks player getting back a tow truck if they abandon it en route to Barry PROC STAGE_GET_TRUCK_BACK() STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_GET_TRUCK_BACK: SP_SETUP") // Blip truck SAFE_REMOVE_BLIP(biGotoBlip) IF IS_ENTITY_ALIVE(vehTowTruck) biGotoBlip = CREATE_VEHICLE_BLIP(vehTowTruck) SET_BLIP_ROUTE(biGotoBlip, TRUE) IF GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() DISPLAY_MISSION_OBJECTIVE(MO_B3CRTCB) // Get back in the cargobob bObjectiveNeeded = FALSE ELSE DISPLAY_MISSION_OBJECTIVE(MO_B3CRTTT) // Get back in the tow truck bObjectiveNeeded = FALSE ENDIF ELSE bObjectiveNeeded = TRUE ENDIF sProgress = SP_RUNNING ELSE CPRINTLN(DEBUG_MISSION, "STAGE_GET_TRUCK_BACK: Dead truck, dropping to STAGE_REDELIVER") mStage = MS_STAGE_REDELIVER ENDIF BREAK CASE SP_RUNNING // Update Franklin complaint conversation in case it's ongoing FRANKLIN_UNHOOK_COMPLAINT() // Track player entering towtruck IF IS_PLAYER_IN_TOWTRUCK() // Player back in truck - change state sProgress = SP_CLEANUP // See if we need to drop to redeliver state due to dead truck ELIF bDeliveryCallTriggered AND NOT IS_ENTITY_ALIVE(vehTowTruck) CPRINTLN(DEBUG_MISSION, "STAGE_GET_TRUCK_BACK: Dead truck, dropping to STAGE_REDELIVER") SAFE_REMOVE_BLIP(biGotoBlip) CLEAR_PRINTS() mStage = MS_STAGE_REDELIVER sProgress = SP_SETUP // See if we need the objective ELIF bObjectiveNeeded IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF TOWTRUCK_IS_ACTUALLY_A_CARGOBOB() DISPLAY_MISSION_OBJECTIVE(MO_B3CRTCB) // Get back in the cargobob bObjectiveNeeded = FALSE ELSE DISPLAY_MISSION_OBJECTIVE(MO_B3CRTTT) // Get back in the tow truck bObjectiveNeeded = FALSE ENDIF ENDIF ENDIF BREAK CASE SP_CLEANUP CPRINTLN(DEBUG_MISSION, "STAGE_GET_TRUCK_BACK: SP_CLEANUP") SAFE_REMOVE_BLIP(biGotoBlip) CLEAR_PRINTS() // Is player in truck? IF IS_PLAYER_IN_TOWTRUCK() // Check for whether the stash car is attached to the truck IF IS_STASH_CAR_HOOKED() // Car hooked - Go to main driving stage unless wanted IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Wanted! mStage = MS_STAGE_LOSE_WANTED ELSE // Not wanted, check if they are in drop-off area IF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[0][0], vecDropoff[0][1], fDropoffWidth[0]) mStage = MS_STAGE_UNHOOK_VEHICLE ELSE mStage = MS_STAGE_RETURN_VEHICLE ENDIF ENDIF ELSE // Car not hooked - get it back mStage = MS_STAGE_REATTACH_VEHICLE ENDIF ENDIF sProgress = SP_SETUP BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Vehicle has become detatched before reaching destination PROC STAGE_REATTACH_VEHICLE() VECTOR vTmpCar STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: SP_SETUP") IF NOT bStashCarHasComeUnhooked CPRINTLN(DEBUG_MISSION, "Stash car just came unhooked! No stat check for you!") bStashCarHasComeUnhooked = TRUE ENDIF // Update blip and objective SAFE_REMOVE_BLIP(biGotoBlip) // Check that the tow truck is alive in cae we are in post-delivery state IF IS_ENTITY_ALIVE(vehTowTruck) biGotoBlip = CREATE_VEHICLE_BLIP(stStashCar.vehicle) SET_BLIP_ROUTE(biGotoBlip, TRUE) IF bStashCarHasBeenHooked DISPLAY_MISSION_OBJECTIVE(MO_B3CGBTB) // Reattach the stash car ENDIF // Initialise Franklin unhook conversation tracking IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND bShouldPlayUnhookComment AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_HEADLIGHT) // If key is still held down unhook was deliberate spFranklinUnhook = SP_SETUP ENDIF sProgress = SP_RUNNING ELSE // Dead truck CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: Dead truck, dropping to STAGE_REDELIVER") mStage = MS_STAGE_REDELIVER ENDIF BREAK CASE SP_RUNNING // Franklin complaint conversation FRANKLIN_UNHOOK_COMPLAINT() // See if we need to drop to redeliver state due to dead truck post delivery IF bDeliveryCallTriggered AND NOT IS_ENTITY_ALIVE(vehTowTruck) CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: Dead truck, dropping to STAGE_REDELIVER") SAFE_REMOVE_BLIP(biGotoBlip) CLEAR_PRINTS() mStage = MS_STAGE_REDELIVER sProgress = SP_SETUP // Detect player getting out of tow truck ELIF NOT IS_PLAYER_IN_TOWTRUCK() // Player not in truck - change state CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: Not in truck, going to cleanup") sProgress = SP_CLEANUP // Detect reattaching car ELIF IS_STASH_CAR_HOOKED() // Got car back - change states CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: In truck and hooked up, going to cleanup") sProgress = SP_CLEANUP bShouldPlayUnhookComment = TRUE // Detect cargobob/shunt delivery ELIF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[0][0], vecDropoff[0][1], fDropoffWidth[0], FALSE, FALSE) AND NOT IS_ENTITY_IN_AIR(stStashCar.vehicle) vTmpCar = GET_ENTITY_COORDS(stStashCar.vehicle) IF vTmpCar.z < 6.7 // Have to check this in case being hitched on the edge of a roof counts as on ground CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: Detatched truck is in delivery area - skipping directly to delivery call") mStage = MS_STAGE_DELIVERY_PHONE_CALL sProgress = SP_SETUP ENDIF ENDIF BREAK CASE SP_CLEANUP SAFE_REMOVE_BLIP(biGotoBlip) CLEAR_PRINTS() // Check player is in truck IF NOT IS_PLAYER_IN_TOWTRUCK() // Get the truck back CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: SP_CLEANUP: Going to STAGE_GET_TRUCK_BACK") mStage = MS_STAGE_GET_TRUCK_BACK ELSE // Player is in truck and must have car hitched CPRINTLN(DEBUG_MISSION, "STAGE_REATTACH_VEHICLE: SP_CLEANUP: Going to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE ENDIF sProgress = SP_SETUP BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Waits for player to unhook the car in the destination car park PROC STAGE_UNHOOK_VEHICLE() STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_SETUP") // remove blip SAFE_REMOVE_BLIP(biGotoBlip) // Show unhook help IF NOT bShowedDetachHelp iHelpTimer = GET_GAME_TIMER() ENDIF sProgress = SP_RUNNING BREAK CASE SP_RUNNING // Check if wanted IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Player wanted - change state CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_RUNNING: Player wanted, go to cleanup") sProgress = SP_CLEANUP // Check for player exiting towtruck prematurely ELIF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehTowtruck) // Player exited vehicle prematurely - change state CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_RUNNING: Player out of truck, go to cleanup") sProgress = SP_CLEANUP // Check if the towed car is attatched, and/or in the car park ELIF IS_STASH_CAR_HOOKED() // Still towing, do we need to update objectives? IF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[0][0], vecDropoff[0][1], fDropoffWidth[0]) // Show unhook objective SAFE_REMOVE_BLIP(biGotoBlip) // Show unhook help IF NOT bShowedDetachHelp IF GET_GAME_TIMER() - iHelpTimer > 1000 PRINT_HELP("B3CTTHA", DEFAULT_HELP_TEXT_TIME+5000) // Press button to release towed thing - Increased time B*1342412 bShowedDetachHelp = TRUE ENDIF ENDIF // Check whether player is dicking about removing vehicle again ELIF NOT IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[1][0], vecDropoff[1][1], fDropoffWidth[1]) CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_RUNNING: Car towed out of delivery area, go to redeliver stage") mStage = MS_STAGE_REDELIVER sProgress = SP_SETUP ENDIF ELSE // Vehicle is loose - need to check if we're complete or need to rehook CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_RUNNING: Vehicle loose, go to cleanup") sProgress = SP_CLEANUP ENDIF BREAK CASE SP_CLEANUP // Get rid of the unhook objective if it's still on CLEAR_PRINTS() CLEAR_HELP(TRUE) // Check if wanted IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Must lose cops to deliver mStage = MS_STAGE_LOSE_WANTED // Check for player exiting towtruck prematurely ELIF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehTowtruck) // Get back in truck mStage = MS_STAGE_GET_TRUCK_BACK // Check for towed car is attatched, and/or in the car park ELIF NOT IS_VEHICLE_ATTACHED_TO_TOW_TRUCK(vehTowtruck, stStashCar.vehicle) IF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[1][0], vecDropoff[1][1], fDropoffWidth[1]) // Car delivered CPRINTLN(DEBUG_MISSION, "Closing the timer stat.") INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_CLOSED() IF NOT bStashCarHasComeUnhooked CPRINTLN(DEBUG_MISSION, "Setting BA3C_STASH_UNHOOKED stat") INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(BA3C_STASH_UNHOOKED) #IF IS_DEBUG_BUILD ELSE CPRINTLN(DEBUG_MISSION, "Not setting BA3C_STASH_UNHOOKED stat") #ENDIF ENDIF // Make car unhookable NOBBLE_TOWING(TRUE) bPlayerInTruckLastFrame = TRUE // Check whether the phone call has been triggered yet IF bDeliveryCallTriggered CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_CLEANUP: Call was already triggered, going to STAGE_LEAVE") mStage = MS_STAGE_LEAVE ELSE CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_CLEANUP: Going to STAGE_DELIVERY_PHONE_CALL") iCallDelayTimer = GET_GAME_TIMER() + 5000 // B*1415971 // B*1530401 mStage = MS_STAGE_DELIVERY_PHONE_CALL ENDIF ELSE // Not in car park - reattach car CPRINTLN(DEBUG_MISSION, "STAGE_UNHOOK_VEHICLE: SP_CLEANUP: Car's out of delivery zone, going to MS_STAGE_REATTACH_VEHICLE") mStage = MS_STAGE_REATTACH_VEHICLE ENDIF ENDIF sProgress = SP_SETUP BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Franklin calls Barry to confirm delivery PROC STAGE_DELIVERY_PHONE_CALL() // Start phone call to Barry // Go directly to leave area IF GET_GAME_TIMER() > iCallDelayTimer IF PLAYER_CALL_CHAR_CELLPHONE(mConversationStruct, CHAR_BARRY, "BAR3CAU", "BAR3C_P1", CONV_PRIORITY_VERY_HIGH) CPRINTLN(DEBUG_MISSION, "STAGE_DELIVERY_PHONE_CALL: SP_SETUP: The call has started") SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_DELIVERY, "Delivered vehicle", TRUE) bDeliveryCallTriggered = TRUE mStage = MS_STAGE_LEAVE sProgress = SP_SETUP ENDIF ENDIF ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Player must leave the area where they have dropped off the stash car. PROC STAGE_LEAVE() STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE: SP_SETUP") SAFE_REMOVE_BLIP(biGotoBlip) // Leave the area IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3CLEAVE) AND (NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0) DISPLAY_MISSION_OBJECTIVE(MO_B3CLEAVE) // Leave the area. ENDIF sProgress = SP_RUNNING BREAK CASE SP_RUNNING // Check player isn't mucking about and dragging/shunting car off again IF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[1][0], vecDropoff[1][1], fDropoffWidth[1]) // Car position OK - see if ready to pass mission IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), stStashCar.vehicle, LEAVE_DISTANCE) AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() // Player clear of drop-off area now, phone call complete CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE: SP_RUNNING: Player clear of drop-off area now, phone call complete, going to cleanup") sProgress = SP_CLEANUP // Check in case we still need to display objective ELIF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3CLEAVE) AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3CLEAVE) // Leave the area. ENDIF ELSE // Player is messing about with car - go to another stage CLEAR_PRINTS() // Restore car's hookability NOBBLE_TOWING(FALSE) // Go to other stage IF IS_PLAYER_IN_TOWTRUCK() IF IS_STASH_CAR_HOOKED() CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE: Car out of position, player in truck with car attached, going to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE ELSE CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE: Car out of position, player in truck but car not attached, going to MS_STAGE_REATTACH_VEHICLE") mStage = MS_STAGE_REATTACH_VEHICLE ENDIF ELIF IS_ENTITY_ALIVE(vehTowTruck) CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE: Car out of position, towtruck OK but player not in it, going to STAGE_GET_TRUCK_BACK") mStage = MS_STAGE_GET_TRUCK_BACK ELSE CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE: Car out of position, towtruck dead, going to STAGE_REDELIVER") MISSION_OBJECTIVE_RESET(MO_B3CNOGO) // Find a way to move the stash car. mStage = MS_STAGE_REDELIVER ENDIF sProgress = SP_SETUP ENDIF BREAK CASE SP_CLEANUP CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE: SP_CLEANUP") SAFE_DELETE_OBJECT(oiStashBox) SAFE_DELETE_VEHICLE(stStashCar.vehicle) Script_Passed() BREAK ENDSWITCH ENDPROC /// PURPOSE: /// PROC STAGE_REDELIVER() STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_REDELIVER: SP_SETUP") IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3CNOGO) AND (NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0) DISPLAY_MISSION_OBJECTIVE(MO_B3CNOGO) // Find a way to move the stash car. ENDIF MISSION_OBJECTIVE_RESET(MO_B3CLEAVE) // Leave the area. sProgress = SP_RUNNING TRUCK_SPAWNER() BREAK CASE SP_RUNNING // Has player contrived the stash car back into the delivery zone? IF IS_ENTITY_IN_ANGLED_AREA(stStashCar.vehicle, vecDropoff[0][0], vecDropoff[0][1], fDropoffWidth[0]) CPRINTLN(DEBUG_MISSION, "STAGE_REDELIVER: SP_RUNNING: stash car back in the delivery zone, going to cleanup") sProgress = SP_CLEANUP ELSE // See if we still need the objective IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3CNOGO) AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3CNOGO) // Find a way to move the stash car. ENDIF // Check for tow truck action IF IS_PLAYER_IN_TOWTRUCK() IF IS_STASH_CAR_HOOKED() CPRINTLN(DEBUG_MISSION, "STAGE_REDELIVER: SP_RUNNING: Car hooked to truck, going to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE ELSE CPRINTLN(DEBUG_MISSION, "STAGE_REDELIVER: SP_RUNNING: Player in a tow truck, going to STAGE_REATTACH_VEHICLE") mStage = MS_STAGE_REATTACH_VEHICLE ENDIF sProgress = SP_SETUP ELSE TRUCK_SPAWNER() ENDIF ENDIF BREAK CASE SP_CLEANUP // Redelivered CPRINTLN(DEBUG_MISSION, "STAGE_REDELIVER: SP_CLEANUP") mStage = MS_STAGE_LEAVE sProgress = SP_SETUP BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Lose wanted level before you can deliver PROC STAGE_LOSE_WANTED() STASH_CAR_STARTFAIL_HANDLER() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_SETUP") SAFE_REMOVE_BLIP(biGotoBlip) DISPLAY_MISSION_OBJECTIVE(MO_B3CWAN1) // Lose the cops. sProgress = SP_RUNNING BREAK CASE SP_RUNNING // Update Franklin complaint conversation in case it's ongoing FRANKLIN_UNHOOK_COMPLAINT() // Has player lost wanted level IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_RUNNING: Cleared wanted level, going to cleanup") CLEAR_MISSION_OBJECTIVE(MO_B3CWAN1) sProgress = SP_CLEANUP // Detect player exiting tow truck ELIF NOT IS_PLAYER_IN_TOWTRUCK() // Player exited truck - change state CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_RUNNING: Player exited truck, going to cleanup") sProgress = SP_CLEANUP // Detect towed vehicle becoming detached ELIF NOT IS_STASH_CAR_HOOKED() // Truck is loose - change state CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_RUNNING: Towed vehicle not hooked, going to cleanup") sProgress = SP_CLEANUP ENDIF BREAK CASE SP_CLEANUP CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_CLEANUP") CLEAR_PRINTS() // Change state IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehTowTruck) CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_CLEANUP: Not in truck, going to STAGE_GET_TRUCK_BACK") mStage = MS_STAGE_GET_TRUCK_BACK ELSE // Player in truck, see if the stash car is hooked IF NOT IS_VEHICLE_ATTACHED_TO_TOW_TRUCK(vehTowTruck, stStashCar.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_CLEANUP: In truck, not hooked up, going to STAGE_REATTACH_VEHICLE") mStage = MS_STAGE_REATTACH_VEHICLE ELSE CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_CLEANUP: In truck and towing, going to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE ENDIF ENDIF sProgress = SP_SETUP BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Handles stupid stuff happening during our wait to fail the mission PROC STAGE_FAIL_FADE() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_FAIL_FADE: SP_SETUP") SAFE_REMOVE_BLIP(biGotoBlip) 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 sProgress = SP_RUNNING BREAK CASE SP_RUNNING IF GET_MISSION_FLOW_SAFE_TO_CLEANUP() // finished fading out CPRINTLN(DEBUG_MISSION, "STAGE_FAIL_FADE: Cleanup") // Remove player from stash vehicle, although this is a very unlikely case. // Don't remove from tow truck - not really a problem letting them keep that. // Detach truck from car in case player is about to get to keep the truck, otherwise it stuffs up the tow rope. IF IS_ENTITY_ALIVE(stStashCar.vehicle) AND IS_ENTITY_ALIVE(vehTowTruck) AND IS_ENTITY_ATTACHED_TO_ENTITY(stStashCar.vehicle, vehTowTruck) CPRINTLN(DEBUG_MISSION, "Unhooking car in cleanup") DETACH_VEHICLE_FROM_ANY_TOW_TRUCK(stStashCar.vehicle) ENDIF // Not warping player - not that likely they failed in an unsafe location COLLECT_AREA_CLEANUP() Script_Cleanup() 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)) SKIP_CLEAR_ALL_MISSION_OBJECTIVES() Script_Passed() // Check for Fail ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)) SKIP_CLEAR_ALL_MISSION_OBJECTIVES() mStage = MS_STAGE_FAIL_FADE sProgress = SP_SETUP // Check for skip forward ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)) SKIP_FORWARD() ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)) SKIP_BACKWARD() ELIF LAUNCH_MISSION_STAGE_MENU(mSkipMenu, iNewStage) DO_Z_SKIP(iNewStage) ENDIF IF bDebugCheatCarLocation bDebugCheatCarLocation = FALSE IF mStage = MS_STAGE_CALL_BARRY OR mStage = MS_STAGE_FIND_TOWTRUCK OR mStage = MS_STAGE_TOW_VEHICLE CPRINTLN(DEBUG_MISSION, "CHEAT!!! Moved stash car!") SET_ENTITY_COORDS(stStashCar.vehicle, <<-456.9121, -1710.0674, 17.7283>>) SET_ENTITY_HEADING(stStashCar.vehicle, 272.5) SET_VEHICLE_ON_GROUND_PROPERLY(stStashCar.vehicle) ELSE CPRINTLN(DEBUG_MISSION, "TRIED TO CHEAT CAR COORDS IN INVALID MISSION STAGE!") 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 // Grab stash car IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.vehID[0]) CPRINTLN(DEBUG_MISSION, "Grabbing stash car from initial scene") IF NOT IS_ENTITY_DEAD(sRCLauncherDataLocal.vehID[0]) SET_VEHICLE_AUTOMATICALLY_ATTACHES(sRCLauncherDataLocal.vehID[0],TRUE) ASSIGN_VEHICLE_INDEX(stStashCar.vehicle, sRCLauncherDataLocal.vehID[0]) SET_ENTITY_LOAD_COLLISION_FLAG(stStashCar.vehicle, TRUE) SET_VEHICLE_AS_RESTRICTED(stStashCar.vehicle, RESTRICTION_STASHVEH) ENDIF ENDIF ASSIGN_OBJECT_INDEX(oiStashBox, sRCLauncherDataLocal.objID[0]) DATA_INIT() // Grab truck from initial scene - after the vehicle structs are set up IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.vehID[1]) CPRINTLN(DEBUG_MISSION, "Grabbing start area tow truck from initial scene") ASSIGN_VEHICLE_INDEX(stTruck[6].vehicle, sRCLauncherDataLocal.vehID[1]) 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 // Individual skip procs handle START_REPLAY_SETUP - some stages need to handle vehicle positioning so the tow truck can attach SWITCH iReplayStage CASE 0 SKIP_TO_START_CAR(TRUE) RC_END_Z_SKIP() BREAK CASE CP_START_TOW SKIP_START_TOWING_SECTION(TRUE) RC_END_Z_SKIP() BREAK CASE CP_DELIVERY SKIP_TRIGGER_DELIVERY(TRUE) RC_END_Z_SKIP() BREAK CASE CP_MISSION_COMPLETE SKIP_MISSION_COMPLETE(TRUE) RC_END_Z_SKIP() BREAK DEFAULT SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected") BREAK ENDSWITCH ELIF IS_REPEAT_PLAY_ACTIVE() CPRINTLN(DEBUG_MISSION, "Barry3C - repeat play") IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) SET_ENTITY_HEADING(PLAYER_PED_ID(), 113.9) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) ENDIF RC_END_Z_SKIP() ENDIF // Loop within here until the mission passes or fails WHILE(TRUE) REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_GRTD") UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene) IF mStage = MS_STAGE_FAIL_FADE STAGE_FAIL_FADE() ELSE IF NOT MISSION_FAIL_CHECKS() // Check debug completion/failure DEBUG_Check_Debug_Keys() HANDLE_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT(stateRestoreConversation, mConversationStruct, "BAR3CAU", tSavedConversationRoot, tSavedConversationLabel) SWITCH mStage CASE MS_STAGE_ENTER_STASH_CAR STAGE_ENTER_STASH_CAR() BREAK CASE MS_STAGE_START_STASH_CAR STAGE_START_STASH_CAR() BREAK CASE MS_STAGE_CALL_BARRY STAGE_CALL_BARRY() BREAK CASE MS_STAGE_FIND_TOWTRUCK STAGE_FIND_TOWTRUCK() BREAK CASE MS_STAGE_TOW_VEHICLE STAGE_TOW_VEHICLE() BREAK CASE MS_STAGE_RETURN_VEHICLE STAGE_RETURN_VEHICLE() BREAK CASE MS_STAGE_UNHOOK_VEHICLE STAGE_UNHOOK_VEHICLE() BREAK CASE MS_STAGE_DELIVERY_PHONE_CALL STAGE_DELIVERY_PHONE_CALL() BREAK CASE MS_STAGE_LEAVE STAGE_LEAVE() BREAK CASE MS_STAGE_LOSE_WANTED STAGE_LOSE_WANTED() BREAK CASE MS_STAGE_GET_TRUCK_BACK STAGE_GET_TRUCK_BACK() BREAK CASE MS_STAGE_REATTACH_VEHICLE STAGE_REATTACH_VEHICLE() BREAK CASE MS_STAGE_REDELIVER STAGE_REDELIVER() BREAK ENDSWITCH ENDIF ENDIF WAIT(0) ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT