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