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

3665 lines
111 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 "clearmissionarea.sch"
USING "commands_audio.sch"
USING "commands_camera.sch"
USING "commands_pad.sch"
USING "commands_vehicle.sch"
USING "commands_path.sch"
USING "commands_ped.sch"
USING "commands_physics.sch"
USING "commands_script.sch"
USING "commands_task.sch"
USING "CompletionPercentage_public.sch"
USING "chase_hint_cam.sch" CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
using "dialogue_public.sch"
USING "flow_public_core_override.sch"
USING "flow_public_GAME.sch"
using "ped_component_public.sch"
USING "player_ped_public.sch"
USING "replay_public.sch"
USING "script_blips.sch"
USING "script_heist.sch"
USING "script_ped.sch"
USING "battlebuddy_public.sch"
USING "flow_special_event_checks.sch"
BOOL bJumpSkip = FALSE //flag for if current MISSION state should clean up and move to the next state
USING "prep_mission_common.sch"
USING "event_public.sch"
USING "commands_recording.sch"
#IF IS_DEBUG_BUILD
USING "select_mission_stage.sch"
USING "shared_debug.sch"
CONST_INT MAX_SKIP_MENU_LENGTH 2
INT i_debug_jump_stage
MissionStageMenuTextStruct s_skip_menu[MAX_SKIP_MENU_LENGTH]
#ENDIF
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// MISSION NAME : Template.sc
// AUTHOR : Ste Kerrigan
// DESCRIPTION :
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//----------------------
// CHECKPOINTS
//----------------------
//-----------------------
// CONSTANTS
//-----------------------
//POLY TEST CONST
CONST_INT MAX_POLY_TEST_VERTS 8 //poly test
//Ambient encounter speech
CONST_INT MAX_AMBIENT_CONV_LINES 8
CONST_INT DEFAULT_REACTION_LINE_DELAY 5000
/// --------------------------------------------------
/// ENUMS
/// -------------------------------------------
/// PURPOSE: Mission states
ENUM MISSION_STATE
MS_SET_UP = 0, //0
MS_STEAL, //1
MS_RETURN_WITH_THING, //2
MS_LEAVE_VEHICLE, //3
MS_LEAVE_AREA,
MS_FAILED //4
ENDENUM
/// PURPOSE:
/// Internal state machine states for mission state
ENUM STAGE_STATES
SS_INIT,
SS_ACTIVE,
SS_CLEANUP,
SS_SKIPPED
ENDENUM
/// PURPOSE: Mission requirements used for loading
/// and creating mission assets
ENUM MISSION_REQ
RQ_NONE,
RQ_TEXT,
RQ_STEAL_CAR,
RQ_TOW_GUY,
RQ_REPAIR_ANIM,
RQ_DRESSING_CAR,
RQ_CHASE_CAR
ENDENUM
/// PURPOSE: Fail reason enums for picking correct fail reason
ENUM FAILED_REASONS
FR_NONE,
FR_WRECKED_STEAL_CAR,
FR_ABAN_CAR,
FR_STUCK_CAR
ENDENUM
ENUM ABM_CONV_STATES
ACS_START_LINE,
ACS_WAIT_LINE_FIN,
ACS_PICK_NEXT_LINE,
ACS_FIN
ENDENUM
ENUM TOW_GUY_STATES
TGS_NULL, //0
TGS_REPAIRS, //1
TGS_REACT_PLAYER_IN_CAR, //2
TGS_REACT_PLAYER_IN_TOW, //3
TGS_GIVE_ABUSE, //4
TGS_RETURN_TO_REPAIRS, //5
TGS_ENTER_CAR, //6
TGS_ENTER_TOW, //7
TGS_ENTER_CHASE_CAR, //8
TGS_CHASE_VEH, //9
TGS_CHASE_VEH_ATTACK, //10
TGS_REACT_BUMP, //11
TGS_REACT_BEING_TOWED, //12
TGS_COWER, //13
TGS_FLEE, //14
TGS_ATTACK, //15
TGS_WANDER_IN_TOW, //16
TGS_QUESTION_PLAYER_PRESENTS, //17
TGS_WAIT_GET_DEAD, //18
TGS_PLAYER_RANG_BATTLE_BUD_NEAR, //19
TGS_PLAYER_RINGING_BATTLE_BUD_NEAR //20
ENDENUM
ENUM BATTLE_BUDDY_OVERRIDE_STATES
BBOS_WAITING,
BBOS_GO_TO_POSITION,
BBOS_GO_TO_POSITION_KNIFE,
BBOS_STEALTH_KO,
BBOS_STEALTH_KILL,
BBOS_DRIVING_TO_PLACE,
BBOS_END
ENDENUM
ENUM BATTLE_BUDDY_BEHAVIOUR
BBB_CONTROL,
BBB_KILL,
BBB_DRIVE
ENDENUM
///MISSION PED STATES
MISSION_STATE eMissionState = MS_SET_UP //track what MISSION stage we are at
STAGE_STATES eState = SS_INIT //Internal state tracking for mission stages
COP_MONITOR eCopMonitor = CM_MONITER
IN_STEAL_CAR_MONITOR eStealCarState = ISCM_NOT_IN_VEHICLE
TOW_GUY_STATES eTowGuyState = TGS_NULL
BATTLE_BUDDY_OVERRIDE_STATES eBattleBuddyState[MAX_BATTLE_BUDDIES]
BATTLE_BUDDY_BEHAVIOUR eBattleBuddyBehaviour[MAX_BATTLE_BUDDIES]
DYNAMIC_PHONE_STATE ePhoneCallState = DPS_CHOOSE_PHONE_CALL
//*****************************************************************************
// :STRUCTS:
//*****************************************************************************
/// PURPOSE: Holds data used to create a ped
/// Contains ped specific variables for the
/// perception system
STRUCT MYPED
PED_INDEX id
VECTOR vPos
FLOAT fDir
MODEL_NAMES Mod = DUMMY_MODEL_FOR_SCRIPT
AI_BLIP_STRUCT mAIBlip
INT iReactTimer = -1
INT iReactCount = 0
ENDSTRUCT
/// PURPOSE: Holds data for creating a
/// vehicle in an encounter
STRUCT MYVEHICLE
VEHICLE_INDEX id
VECTOR vPos
FLOAT fDir
MODEL_NAMES Mod = DUMMY_MODEL_FOR_SCRIPT
ENDSTRUCT
TEST_POLY mAreaCheck1 //Poly area 1
TEST_POLY mAreaCheck2 //Poly area 2
//****************************************************************************************************
// : MISSION FLOW VARIABLES :
//****************************************************************************************************
//mission flow
INT iMissionState = 0 //Used in skips and checkpoints
//Fail vars
STRING sFailReason = NULL //String to display when mission is failed
//GOD TEXT
STRING sGodText = "FBIPRB"
BOOL bObjectiveShown = FALSE //Has an objective been shown
TEXT_LABEL_15 sPhoneUpdateString
//BLIPs
BLIP_INDEX biBlip //Mission blip - mainly used for go to objectives
BLIP_INDEX biVehicleBlip
//ScriptCamera
CAMERA_INDEX camMain //Script camera used in place holder cutscenes
VECTOR vSafeVec = <<0,0,0>> //safe vector used when a proper position isnt needed
VECTOR vDropOffLoc = <<1374.8580, -2077.3743, 50.9981>>
///MISSION PED VARS SCRIPT AI
BOOL bPlayerInDressingCar = FALSE
BOOL bDamageSpeedStatTurnedOn = FALSE
BOOL bForceStop = FALSE
//CHASE
BOOL bRammedLastFrame
INT iRamTimer, iRammedCount
FLOAT fPlayerClosingSpeedLastFrame
//Timers
INT iAreaWarningTimer
INT iPlayerStoppedCloseTimer = -1
FLOAT fTowGuyAtDistance = 0
BOOL bCallTimer = FALSE
INT iCallTimerDelay = 0
FLOAT fHangingAroundTimer = 0
///==============| GOD TEXT BOOLS |============
BOOL bExpireReturnVehWanted = FALSE
BOOL bExpireReturnVeh = FALSE
BOOL bExpireLoseTowGuy = FALSE
BOOL bActivateLoseTowGuy = FALSE
BOOL bTurnedOffBaseAnims[MAX_BATTLE_BUDDIES]
BOOL bBuddySpeech = FALSE
///===============| models |===================
/// ===============| START VECTORS |==============
VECTOR vAnimOffset = <<0.2,2.45,0>>
/// ==============| START HEADINGS |===============
/// ==============| PED INDICES |================
MYPED mTowGuy
/// ==============| VEHICLE INDICES |===========
VEHICLE_INDEX viStealCar
VEHICLE_INDEX viAnyTowTruck
MYVEHICLE mDressingVeh
MYVEHICLE mChaseCar
MYVEHICLE mTowTruck
REL_GROUP_HASH HASH_ENEMY
//End mission vehicle
VEHICLE_INDEX viLastCar
BOOL bSpawnedEndMissionVeh = FALSE
SCENARIO_BLOCKING_INDEX sibBlocking
/// ===============| GROUPS |========================
/// ===============| DIALOGUE |======================
STRING sTextBlock = "FIBP2AU" //The Dialogue block for the mission
structPedsForConversation s_conversation_peds //conversation struct
//Used for tracking an interupted conversation
//TEXT_LABEL_23 sResumeRoot = "NONE"
//TEXT_LABEL_23 sResumeLine = "NONE"
/// PURPOSE:
/// Resets all variables used in flow
PROC RESET_ALL()
bExpireReturnVehWanted = FALSE
bExpireReturnVeh = FALSE
bPlayerInDressingCar = FALSE
bActivateLoseTowGuy = FALSE
bExpireLoseTowGuy = FALSE
bDamageSpeedStatTurnedOn = FALSE
iAreaWarningTimer = 0
iPlayerStoppedCloseTimer = -1
fTowGuyAtDistance = 0
mTowGuy.iReactTimer = -1
mTowGuy.iReactCount = 0
eTowGuyState = TGS_NULL
eCopMonitor = CM_MONITER
eStealCarState = ISCM_NOT_IN_VEHICLE
INT i
FOR i=0 TO (MAX_BATTLE_BUDDIES-1)
eBattleBuddyState[i] = BBOS_WAITING
eBattleBuddyBehaviour[i] = BBB_CONTROL
bTurnedOffBaseAnims[i] = FALSE
ENDFOR
ENDPROC
///
///
/// DEBUG ONLY MISSION STUFF ------------------------------------------------------------
///
///
#IF IS_DEBUG_BUILD
BOOL bShowDebugText = TRUE
WIDGET_GROUP_ID widgetGroup
BOOL bForceFail = FALSE
/// PURPOSE:
/// Prints a string to a TTY Channel
/// PARAMS:
/// s - The string to print
/// ddc - The debug channel to print to
PROC SK_PRINT(String s, DEBUG_CHANNELS ddc = DEBUG_MISSION)
IF bShowDebugText
CPRINTLN(ddc, s)
PRINTNL()
PRINTNL()
ENDIF
ENDPROC
/// PURPOSE:
/// Prints a string and an int to a TTY Channel
/// PARAMS:
/// s - The string to print
/// i - the int to print
/// ddc - the debug channel to print to
PROC SK_PRINT_INT(String s, INT i, DEBUG_CHANNELS ddc = DEBUG_MISSION)
IF bShowDebugText
CPRINTLN(ddc, s,i)
PRINTNL()
PRINTNL()
ENDIF
ENDPROC
/// PURPOSE:
/// Prints a string and a Float to a TTY Channel
/// PARAMS:
/// s - the string to print
/// f - the float to print
/// ddc - the debug channel
PROC SK_PRINT_FLOAT(String s, FLOAT f, DEBUG_CHANNELS ddc = DEBUG_MISSION)
IF bShowDebugText
CPRINTLN(ddc, s,f)
PRINTNL()
PRINTNL()
ENDIF
ENDPROC
/// PURPOSE:
/// Sets up a widget for this mission
PROC SETUP_FOR_RAGE_WIDGETS()
widgetGroup = START_WIDGET_GROUP("CURRENT Mission Widgets")
START_WIDGET_GROUP("Debug")
ADD_WIDGET_BOOL("Toggle Debug spew", bShowDebugText)
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Force Mission Fail")
ADD_WIDGET_BOOL("Force Fail", bForceFail)
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
ENDPROC
/// PURPOSE:
/// Deletes the mission widget
PROC CLEANUP_OBJECT_WIDGETS()
IF DOES_WIDGET_GROUP_EXIST(widgetGroup)
DELETE_WIDGET_GROUP(widgetGroup)
ENDIF
ENDPROC
/// PURPOSE:
/// Checks for any updates needed for the widgets
PROC UPDATE_RAG_WIDGETS()
IF bForceFail
eMissionState = MS_FAILED
eState = SS_INIT
bForceFail = FALSE
ENDIF
ENDPROC
/// PURPOSE:
/// Draws an angled area
/// PARAMS:
/// vec1 - first point of the area
/// vec2 - second point of the area
/// width - the width of the area
// PROC DRAW_DEBUG_LOCATE_SPECIAL(VECTOR vec1, VECTOR vec2, FLOAT width)
//
// VECTOR vBottom[2]
// VECTOR vTop[2]
//
// vBottom[0] = vec1
// vBottom[1] = vec2
//
// vTop[0] = vec1
// vTop[1] = vec2
//
// IF vec1.z > vec2.z
// vBottom[0].z = vec2.z
// vBottom[1].z = vec2.z
// vTop[0].z = vec1.z
// vTop[1].z = vec1.z
// ELSE
// vBottom[0].z = vec1.z
// vBottom[1].z = vec1.z
// vTop[0].z = vec2.z
// vTop[1].z = vec2.z
// ENDIF
//
// VECTOR fwd = NORMALISE_VECTOR(vBottom[1] - vBottom[0]) // normalize to get distance
// VECTOR side = <<-fwd.y, fwd.x, fwd.z>>
// VECTOR w = side * (width / 2.0)
//
// // Bottom points
// VECTOR c1 = vBottom[0] - w // base left
// VECTOR c2 = vBottom[0] + w // base right
// VECTOR c3 = vBottom[1] + w // top rt
// VECTOR c4 = vBottom[1] - w // top lt
//
// // Top points
// VECTOR d1 = vTop[0] - w // base left
// VECTOR d2 = vTop[0] + w // base right
// VECTOR d3 = vTop[1] + w // top rt
// VECTOR d4 = vTop[1] - w // top lt
//
// // Draw bottom lines
// DRAW_DEBUG_LINE(c1, c2, 128, 0, 128)
// DRAW_DEBUG_LINE(c2, c3, 128, 0, 128)
// DRAW_DEBUG_LINE(c3, c4, 128, 0, 128)
// DRAW_DEBUG_LINE(c4, c1, 128, 0, 128)
// // Draw top lines
// DRAW_DEBUG_LINE(d1, d2, 128, 0, 128)
// DRAW_DEBUG_LINE(d2, d3, 128, 0, 128)
// DRAW_DEBUG_LINE(d3, d4, 128, 0, 128)
// DRAW_DEBUG_LINE(d4, d1, 128, 0, 128)
// // Draw uprights
// DRAW_DEBUG_LINE(c1, d1, 128, 0, 128)
// DRAW_DEBUG_LINE(c2, d2, 128, 0, 128)
// DRAW_DEBUG_LINE(c3, d3, 128, 0, 128)
// DRAW_DEBUG_LINE(c4, d4, 128, 0, 128)
//
// ENDPROC
#ENDIF
///
///
/// GENERAL HELP FUNCTIONS
///
///
/// PURPOSE:
/// Set a peds position and heading safely ie check its ok then move it and set its heading
/// PARAMS:
/// index - The ped to move
/// pos - The position to move it to
/// dir - The Heading to set
PROC SET_PED_POS(PED_INDEX index, VECTOR pos, FLOAT dir)
IF IS_PED_UNINJURED(index)
CLEAR_PED_TASKS(index)
ENDIF
SAFE_TELEPORT_ENTITY(index, pos, dir)
ENDPROC
/// PURPOSE:
/// Requests a model and waits for it to load
/// PARAMS:
/// _modname - The name of the model to load
/// _debugstring - used to debug
/// i - used to debug
/// RETURNS:
/// TRUE when the model is loaded
FUNC BOOL REQUEST_AND_CHECK_MODEL(MODEL_NAMES _modname, STRING _debugstring, INT i = 0)
REQUEST_MODEL(_modname)
IF NOT Is_String_Null_Or_Empty(_debugstring)
AND i <> -1
#IF IS_DEBUG_BUILD
SK_PRINT_INT(_debugstring, i)
#ENDIF
ENDIF
IF HAS_MODEL_LOADED(_modname)
#IF IS_DEBUG_BUILD
SK_PRINT("MODEL LOADED")
#ENDIF
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Unloads a model - Sets it as no longer needed
/// PARAMS:
/// _modname - The model to unload
PROC UNLOAD_MODEL(MODEL_NAMES _modname, BOOL bCheckLoaded = TRUE)
IF bCheckLoaded
IF HAS_MODEL_LOADED(_modname)
SET_MODEL_AS_NO_LONGER_NEEDED(_modname)
ENDIF
ELSE
SET_MODEL_AS_NO_LONGER_NEEDED(_modname)
ENDIF
ENDPROC
/// PURPOSE:
/// Spawns a ped and returns true if it was succesful. Requests the model and unloads it
/// PARAMS:
/// pedindex - The PED_INDEX to write the newly create ped to
/// model - The model to load and use to create the ped
/// pos - The position the ped should be created
/// dir - The heading the ped should have when created
/// bUnloadAfterSpawn - If true we unload the model after spawning the ped
/// bFreeze - if true we freeze the ped after spawning
/// bTempEvents - if true we block temp events
/// bTargetable - if false we set the ped to not be targetted
/// RETURNS:
/// TRUE if the ped was created
FUNC BOOL SPAWN_PED(PED_INDEX &pedindex, MODEL_NAMES model, VECTOR pos, FLOAT dir, BOOL bUnloadAfterSpawn = TRUE, BOOL bFreeze = FALSE, BOOL bTempEvents = TRUE, BOOL bTargetable = TRUE)
IF NOT DOES_ENTITY_EXIST(pedindex)
IF REQUEST_AND_CHECK_MODEL(model,"Loading")
pedindex = CREATE_PED(PEDTYPE_MISSION, model, pos, dir)
//SET_PED_DEFAULT_COMPONENT_VARIATION(pedindex)
IF IS_PED_UNINJURED(pedindex)
#IF IS_DEBUG_BUILD SK_PRINT("PED CREATED !") #ENDIF
IF bFreeze
FREEZE_ENTITY_POSITION(pedindex, TRUE)
ENDIF
IF bTempEvents
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedindex, bTempEvents)
ENDIF
IF NOT bTargetable
SET_PED_CAN_BE_TARGETTED(pedindex, bTargetable)
ENDIF
IF bUnloadAfterSpawn
UNLOAD_MODEL(model)
ENDIF
RETURN TRUE
ENDIF
ENDIF
ELSE
IF IS_PED_UNINJURED(pedindex)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Spawns a vehicle and returns true if it was succesful - why does the is mission entity check return true
/// no matter what the out come of said check?
/// PARAMS:
/// vehicleindex - The VEHICLE_INDEX to write the newly create vehicle to
/// model - The model to load and use to create the vehicle
/// pos - The position the vehicle should be created
/// dir - The heading the vehicle should have when created
/// RETURNS:
/// TRUE if the vehicle was created
FUNC BOOL SPAWN_VEHICLE(VEHICLE_INDEX &vehicleindex, MODEL_NAMES model, VECTOR pos, FLOAT dir, BOOL bUnloadAfterSpawn = TRUE)
IF NOT DOES_ENTITY_EXIST(vehicleindex)
IF REQUEST_AND_CHECK_MODEL(model,"Loading")
vehicleindex = CREATE_VEHICLE(model, pos, dir)
IF DOES_ENTITY_EXIST(vehicleindex)
IF NOT IS_ENTITY_A_MISSION_ENTITY(vehicleindex)
SET_ENTITY_AS_MISSION_ENTITY(vehicleindex)
ENDIF
SET_VEHICLE_ON_GROUND_PROPERLY(vehicleindex)
IF bUnloadAfterSpawn
UNLOAD_MODEL(model)
ENDIF
RETURN TRUE
ENDIF
ENDIF
ELSE
IF IS_VEHICLE_OK(vehicleindex)
SET_ENTITY_COORDS(vehicleindex, pos)
SET_ENTITY_HEADING(vehicleindex, dir)
ENDIF
IF NOT IS_ENTITY_A_MISSION_ENTITY(vehicleindex)
SET_ENTITY_AS_MISSION_ENTITY(vehicleindex)
RETURN TRUE
ELSE
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Spawns a ped inside a vehicle
/// PARAMS:
/// pedindex - The index to write the newly created ped back to (ref)
/// Car - The vehicle to create the ped in
/// modelName - The model of the ped to create
/// seat - the seat to create the ped in
/// bUnloadAfterSpawn - should we unload the ped model after creation
/// RETURNS:
/// TRUE if the ped was spawned correctly
FUNC BOOL SPAWN_PED_IN_VEHICLE(PED_INDEX &pedindex, VEHICLE_INDEX Car, MODEL_NAMES modelName, VEHICLE_SEAT seat = VS_DRIVER, BOOL bUnloadAfterSpawn = TRUE)
IF IS_VEHICLE_OK(Car)
IF NOT DOES_ENTITY_EXIST(pedindex)
IF REQUEST_AND_CHECK_MODEL(modelName,"Loading")
pedindex = CREATE_PED_INSIDE_VEHICLE(Car, PEDTYPE_MISSION, modelName, seat)
IF DOES_ENTITY_EXIST(pedindex)
IF bUnloadAfterSpawn
UNLOAD_MODEL(modelName)
ENDIF
RETURN TRUE
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Spawns an object. And activates its physics
/// PARAMS:
/// objectindex - The OBJECT_INDEX to write the newly create object to
/// model - The model to load and use to create the object
/// pos - The position the object should be created
/// dir - The heading the object should have when created
/// RETURNS:
/// TRUE if the object was created
FUNC BOOL SPAWN_OBJECT(OBJECT_INDEX &objectindex, MODEL_NAMES model, VECTOR pos, FLOAT dir = 0.0, BOOL bUnloadAfterSpawn = TRUE)
IF NOT DOES_ENTITY_EXIST(objectindex)
IF REQUEST_AND_CHECK_MODEL(model,"Loading")
objectindex = CREATE_OBJECT(model, pos)
IF DOES_ENTITY_EXIST(objectindex)
SET_ENTITY_HEADING(objectindex, dir)
ACTIVATE_PHYSICS(objectindex)
IF bUnloadAfterSpawn
UNLOAD_MODEL(model)
ENDIF
RETURN TRUE
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
//PURPOSE:
/// PURPOSE:
/// Checkes to see if a ped is in a given vehicle, also does alive checks.
/// Returns TRUE if the given ped is in the given vehicle and they are all alive and well
/// PARAMS:
/// ped - Ped to check
/// veh - The vehicle to check they are in
/// RETURNS:
/// TRUE if the ped is in the vehicle and they are both alive and well
FUNC BOOL IS_SAFE_PED_IN_VEHICLE(PED_INDEX ped, VEHICLE_INDEX veh)
IF veh != NULL
IF IS_VEHICLE_OK(veh)
IF IS_PED_UNINJURED(ped)
IF IS_PED_IN_VEHICLE(ped,veh)
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Print a warning God text string and expires a bool when the warning has been shown
/// PARAMS:
/// WarnObj - the text key of the wanrning
/// expire - the bool to change
PROC PRINT_WARNING_OBJ(STRING WarnObj, BOOL &expire)
IF NOT expire
PRINT_NOW(WarnObj, DEFAULT_GOD_TEXT_TIME,0)
expire = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Gets the heading between to vectors
/// PARAMS:
/// V1 - First vector
/// V2 - Second vector
/// RETURNS:
/// FLOAT - the heading between the two
FUNC FLOAT GET_HEADING_BETWEEN_VECTORS(VECTOR V1, VECTOR V2)
RETURN GET_HEADING_FROM_VECTOR_2D(V2.x-V1.x,V2.y-V1.y)
ENDFUNC
///-----------------------------------------------------------------------------------
/// MISSION FUNCTIONS
///-----------------------------------------------------------------------------------
/// PURPOSE:
/// Checks that 2 entities are at the same height - within
/// 1.5m
/// PARAMS:
/// e1 - first entity
/// e2 - second entity
/// RETURNS:
/// TRUE if the entities are at the same height
FUNC BOOL ARE_ENTITYS_AT_SAME_HEIGHT(ENTITY_INDEX e1, ENTITY_INDEX e2)
VECTOR vE1 = GET_ENTITY_COORDS(e1)
VECTOR vE2 = GET_ENTITY_COORDS(e2)
FLOAT fDiff = ABSF(vE1.z - vE2.z) //want the absolute difference so it doesnt matter which entitys height was taken away first
IF fDiff <= 1.5
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks that the player is with in range of the hunter used when playing dialogue
/// PARAMS:
/// distance - The distance the player must be with in - defaults to 10.0
/// RETURNS:
/// TRUE if the player is with in the distance
FUNC BOOL IS_IN_CONV_DISTANCE(PED_INDEX ped, FLOAT distance = 10.0)
IF ped = NULL
RETURN TRUE
ENDIF
IF IS_PED_UNINJURED(PLAYER_PED_ID())
AND IS_PED_UNINJURED(ped)
// #IF IS_DEBUG_BUILD SK_PRINT_FLOAT(" DISTANCE BETWEEN CONVO === ", GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), ped, FALSE))#ENDIF
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), ped, FALSE) <= distance
AND ARE_ENTITYS_AT_SAME_HEIGHT(ped, PLAYER_PED_ID())
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks to see if the player has killed innocents then increaments the mission stat.
/// PARAMS:
/// bIsAfterOtherFail - Flag to see if the player has already failed the mission when this
/// returns true and changes the mission fail reason accordingly.
PROC CHECK_FOR_MURDER()
/*
PED_INDEX mPed
INT i = 0
IF Has_Ped_Been_Killed()
REPEAT Get_Number_Of_Ped_Killed_Events() i
IF DOES_ENTITY_EXIST(Get_Index_Of_Killed_Ped(i))
mPed = GET_PED_INDEX_FROM_ENTITY_INDEX(Get_Index_Of_Killed_Ped(i))
IF mPed <> PLAYER_PED_ID()
IF IS_ENTITY_A_PED(mPed)
IF NOT IS_ENTITY_A_MISSION_ENTITY(mPed)
AND IS_PED_HUMAN(mPed)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mPed, PLAYER_PED_ID())
//This stat has been removed
//INFORM_MISSION_STATS_OF_INCREMENT(FBI4P2_INNOCENTS_KILLED)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
*/
ENDPROC
PROC SET_STATS_WATCH_OFF()
INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(NULL, FBI4P2_MAX_SPEED)
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(NULL, FBI4P2_VEHICLE_DAMAGE)
ENDPROC
PROC MANAGE_PLAYER_VEHICLE_STATS()
IF NOT bDamageSpeedStatTurnedOn
IF IS_VEHICLE_OK(viStealCar)
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), viStealCar)
INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(viStealCar, FBI4P2_MAX_SPEED)
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(viStealCar, FBI4P2_VEHICLE_DAMAGE)
bDamageSpeedStatTurnedOn = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
PROC MONITER_STATS()
CHECK_FOR_MURDER()
MANAGE_PLAYER_VEHICLE_STATS()
ENDPROC
// -----------------------------------------------------------------------------------------------------------
// Script Fail
// -----------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Called when the player has failed
/// deletes blips and clears the screen of text and conversations are ended
/// PARAMS:
/// fail - An Enum of the fail reason used in a switch statment to pick the correct text to display
PROC MISSION_FAILED(FAILED_REASONS fail = FR_NONE)
CLEAR_PRINTS()
KILL_ANY_CONVERSATION()
SWITCH fail
CASE FR_NONE
BREAK
CASE FR_WRECKED_STEAL_CAR
sFailReason = "PRB_FWRECK"
BREAK
CASE FR_ABAN_CAR
sFailReason = "PRB_FFAR"
BREAK
CASE FR_STUCK_CAR
sFailReason = "PRB_FSTUCK"
BREAK
ENDSWITCH
eMissionState = MS_FAILED
eState = SS_INIT
ENDPROC
///-----------------------------------------------------------------------------------
/// STATE MACHINES
///-----------------------------------------------------------------------------------
PROC RETURN_TOW_GUY_REPAIRS()
IF IS_VEHICLE_OK(mDressingVeh.id)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_PLAY_ANIM)
IF NOT IS_ENTITY_IN_RANGE_COORDS(mTowGuy.id, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, vAnimOffset), 0.5)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
TASK_FOLLOW_NAV_MESH_TO_COORD(mTowGuy.id, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, vAnimOffset), PEDMOVEBLENDRATIO_WALK, 60000, 0.3, ENAV_STOP_EXACTLY, -GET_ENTITY_HEADING(mDressingVeh.id))
ENDIF
ELSE
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_ACHIEVE_HEADING)
TASK_ACHIEVE_HEADING(mTowGuy.id, -GET_ENTITY_HEADING(mDressingVeh.id) )
ENDIF
ENDIF
ENDIF
SET_PED_CAPSULE(mTowGuy.id, 0.1)
ENDIF
ENDPROC
PROC DO_SAFE_REACTION_LINE(STRING sConv, TOW_GUY_STATES state, enumSubtitlesState subs = DISPLAY_SUBTITLES)
IF eTowGuyState != state
AND NOT IS_MESSAGE_BEING_DISPLAYED()
TEXT_LABEL_23 sCheckConv = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF NOT ARE_STRINGS_EQUAL(sCheckConv, sConv)
AND NOT IS_PED_IN_WRITHE(mTowGuy.id)
AND NOT IS_PED_RAGDOLL(mTowGuy.id)
AND NOT IS_PED_BEING_STUNNED(mTowGuy.id)
AND NOT IS_PED_BEING_STEALTH_KILLED(mTowGuy.id)
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_peds, sTextBlock, sConv, CONV_PRIORITY_MEDIUM, subs)
#IF IS_DEBUG_BUILD SK_PRINT(sConv) #ENDIF
#IF IS_DEBUG_BUILD SK_PRINT("PLAYING THE ABOVE CONVO") #ENDIF
ENDIF
ENDIF
ENDPROC
PROC DO_SAFE_REPEAT_REACTION_LINE(STRING sConv, BOOL bIncreaseReact = FALSE, INT iDelay = DEFAULT_REACTION_LINE_DELAY)
IF (GET_GAME_TIMER() - iAreaWarningTimer) > iDelay
AND NOT IS_MESSAGE_BEING_DISPLAYED()
TEXT_LABEL_23 sCheckConv = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF NOT ARE_STRINGS_EQUAL(sCheckConv, sConv)
AND NOT IS_PED_IN_WRITHE(mTowGuy.id)
AND NOT IS_PED_RAGDOLL(mTowGuy.id)
AND NOT IS_PED_BEING_STUNNED(mTowGuy.id)
AND NOT IS_PED_BEING_STEALTH_KILLED(mTowGuy.id)
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_peds, sTextBlock, sConv, CONV_PRIORITY_MEDIUM)
IF bIncreaseReact
mTowGuy.iReactCount++
ENDIF
iAreaWarningTimer = GET_GAME_TIMER()
#IF IS_DEBUG_BUILD SK_PRINT(sConv) #ENDIF
#IF IS_DEBUG_BUILD SK_PRINT("PLAYING THE ABOVE CONVO") #ENDIF
ENDIF
ENDIF
ENDPROC
PROC DO_AMBIENT_CONTEXT_LINE(STRING line)
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE_NATIVE(mTowGuy.id, line, "S_M_M_TRUCKER_01_BLACK_FULL_02", "SPEECH_PARAMS_FORCE")
ENDPROC
PROC PICK_REACTION_LINE(TOW_GUY_STATES state)
SWITCH state
CASE TGS_REPAIRS
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
DO_SAFE_REPEAT_REACTION_LINE("FP2_RPAIR")
ENDIF
BREAK
CASE TGS_REACT_PLAYER_IN_TOW
DO_SAFE_REACTION_LINE("FP2_REACTTOW", state, DO_NOT_DISPLAY_SUBTITLES)
BREAK
CASE TGS_REACT_PLAYER_IN_CAR
DO_SAFE_REACTION_LINE("FP2_REACTCAR", state)
BREAK
CASE TGS_GIVE_ABUSE
IF eStealCarState = ISCM_IN_VEHICLE
DO_SAFE_REPEAT_REACTION_LINE("FP2_ABUSETOW", TRUE)
ELIF bPlayerInDressingCar
DO_SAFE_REPEAT_REACTION_LINE("FP2_REACTCAR", TRUE)
ENDIF
BREAK
CASE TGS_RETURN_TO_REPAIRS
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
DO_SAFE_REACTION_LINE("FP2_RETRPAIR", state)
ENDIF
BREAK
CASE TGS_ENTER_TOW
DO_SAFE_REACTION_LINE("FP2_ENTTOW", state)
BREAK
CASE TGS_ENTER_CAR
DO_SAFE_REACTION_LINE("FP2_ENTCAR", state)
BREAK
CASE TGS_CHASE_VEH
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
DO_SAFE_REPEAT_REACTION_LINE("FP2_VEHCHASE")
ENDIF
ENDIF
BREAK
CASE TGS_CHASE_VEH_ATTACK
BREAK
CASE TGS_FLEE
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
DO_SAFE_REPEAT_REACTION_LINE("FP2_FLEE")
ENDIF
BREAK
CASE TGS_COWER
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
IF GET_RANDOM_BOOL()
DO_AMBIENT_CONTEXT_LINE("GENERIC_FRIGHTENED_MED")
ELSE
DO_AMBIENT_CONTEXT_LINE("GENERIC_FRIGHTENED_HIGH")
ENDIF
ENDIF
BREAK
CASE TGS_ATTACK
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
DO_SAFE_REPEAT_REACTION_LINE("FP2_ATTACK")
ENDIF
BREAK
CASE TGS_REACT_BUMP
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
IF GET_RANDOM_BOOL()
DO_AMBIENT_CONTEXT_LINE("GENERIC_CURSE_MED")
ELSE
DO_AMBIENT_CONTEXT_LINE("GENERIC_CURSE_HIGH")
ENDIF
ENDIF
BREAK
CASE TGS_REACT_BEING_TOWED
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
DO_SAFE_REPEAT_REACTION_LINE("FP2_TOW")
ENDIF
BREAK
CASE TGS_QUESTION_PLAYER_PRESENTS
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
IF GET_RANDOM_BOOL()
DO_AMBIENT_CONTEXT_LINE("GENERIC_CURSE_MED")
ELSE
DO_AMBIENT_CONTEXT_LINE("GENERIC_CURSE_HIGH")
ENDIF
ENDIF
BREAK
CASE TGS_PLAYER_RANG_BATTLE_BUD_NEAR
IF IS_IN_CONV_DISTANCE(mTowGuy.id, 20)
DO_SAFE_REACTION_LINE("FP2_ENTCAR", state)
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC LEAVE_VEHICLE_ATTACK()
SEQUENCE_INDEX s
OPEN_SEQUENCE_TASK(s)
IF IS_PED_IN_ANY_VEHICLE(mTowGuy.id)
TASK_LEAVE_ANY_VEHICLE(NULL, 1000)
ENDIF
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, HASH_ENEMY, RELGROUPHASH_PLAYER)
TASK_COMBAT_PED(NULL, PLAYER_PED_ID())
CLOSE_SEQUENCE_TASK(s)
TASK_PERFORM_SEQUENCE(mTowGuy.id, s)
CLEAR_SEQUENCE_TASK(s)
ENDPROC
PROC PICK_TASK_REACTION(TOW_GUY_STATES state)
SWITCH state
CASE TGS_REPAIRS
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_PLAY_ANIM)
IF IS_VEHICLE_OK(mDressingVeh.id)
TASK_PLAY_ANIM(mTowGuy.id, "mini@repair", "fixing_a_ped", WALK_BLEND_IN, WALK_BLEND_OUT, -1, AF_LOOPING)
ENDIF
ENDIF
BREAK
CASE TGS_REACT_PLAYER_IN_TOW
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_ENTER_VEHICLE)
IF IS_VEHICLE_OK(mTowTruck.id)
TASK_ENTER_VEHICLE(mTowGuy.id, mTowTruck.id, 60000, VS_DRIVER, PEDMOVEBLENDRATIO_RUN, ECF_JUST_PULL_PED_OUT|ECF_JACK_ANYONE)
//TASK_FOLLOW_NAV_MESH_TO_COORD(mTowGuy.id, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mTowTruck.id, <<-1,0.5,0>>), PEDMOVEBLENDRATIO_RUN)
ENDIF
ENDIF
BREAK
CASE TGS_REACT_PLAYER_IN_CAR
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
IF IS_VEHICLE_OK(mTowTruck.id)
TASK_FOLLOW_NAV_MESH_TO_COORD(mTowGuy.id, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, <<-1,0.5,0>>), PEDMOVEBLENDRATIO_WALK, 30000, DEFAULT_NAVMESH_RADIUS, ENAV_DEFAULT, 141.2603)
ENDIF
ENDIF
BREAK
CASE TGS_RETURN_TO_REPAIRS
RETURN_TOW_GUY_REPAIRS()
BREAK
CASE TGS_ENTER_CAR
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_ENTER_VEHICLE)
IF IS_VEHICLE_OK(mDressingVeh.id)
IF NOT IS_PED_IN_ANY_VEHICLE(mTowGuy.id)
TASK_ENTER_VEHICLE(mTowGuy.id, mDressingVeh.id, 60000, VS_DRIVER, PEDMOVEBLENDRATIO_RUN)
ENDIF
ENDIF
ENDIF
BREAK
CASE TGS_ENTER_TOW
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_ENTER_VEHICLE)
IF IS_VEHICLE_OK(mTowTruck.id)
IF NOT IS_PED_IN_ANY_VEHICLE(mTowGuy.id)
TASK_ENTER_VEHICLE(mTowGuy.id, mTowTruck.id, 60000, VS_DRIVER, PEDMOVEBLENDRATIO_RUN)
ENDIF
ENDIF
ENDIF
BREAK
CASE TGS_ENTER_CHASE_CAR
IF IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_PERFORM_SEQUENCE)
OR (GET_SCRIPT_TASK_STATUS(mTowGuy.id, SCRIPT_TASK_PERFORM_SEQUENCE) = DORMANT_TASK)
CLEAR_PED_TASKS(mTowGuy.id)
ENDIF
IF IS_VEHICLE_OK(mChaseCar.id)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_ENTER_VEHICLE)
IF NOT IS_PED_IN_ANY_VEHICLE(mTowGuy.id)
TASK_ENTER_VEHICLE(mTowGuy.id, mChaseCar.id, 60000, VS_DRIVER, PEDMOVEBLENDRATIO_RUN)
ENDIF
ELSE
ENDIF
ENDIF
BREAK
CASE TGS_CHASE_VEH
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_VEHICLE_MISSION)
IF IS_VEHICLE_OK(mChaseCar.id)
IF IS_VEHICLE_OK(mDressingVeh.id)
AND IS_VEHICLE_OK(mTowTruck.id)
IF bPlayerInDressingCar
IF NOT IS_ENTITY_UPSIDEDOWN(mChaseCar.id)
TASK_VEHICLE_MISSION(mTowGuy.id, mChaseCar.id, mDressingVeh.id, MISSION_ESCORT_RIGHT, 30, DRIVINGMODE_AVOIDCARS_RECKLESS|DF_ChangeLanesAroundObstructions|DF_GoOffRoadWhenAvoiding|DF_UseStringPullingAtJunctions, 1, -1)
ELSE
LEAVE_VEHICLE_ATTACK()
state = TGS_CHASE_VEH_ATTACK
ENDIF
ELIF eStealCarState = ISCM_IN_VEHICLE
IF NOT IS_ENTITY_UPSIDEDOWN(mChaseCar.id)
TASK_VEHICLE_MISSION(mTowGuy.id, mChaseCar.id, mTowTruck.id, MISSION_ESCORT_RIGHT, 30, DRIVINGMODE_AVOIDCARS_RECKLESS|DF_ChangeLanesAroundObstructions|DF_GoOffRoadWhenAvoiding|DF_UseStringPullingAtJunctions, 1, -1)
ELSE
LEAVE_VEHICLE_ATTACK()
state = TGS_CHASE_VEH_ATTACK
ENDIF
ENDIF
ENDIF
ELSE
IF IS_VEHICLE_OK(mDressingVeh.id)
AND IS_VEHICLE_OK(mTowTruck.id)
IF bPlayerInDressingCar
IF NOT IS_ENTITY_UPSIDEDOWN(mTowTruck.id)
TASK_VEHICLE_MISSION(mTowGuy.id, mTowTruck.id, mDressingVeh.id, MISSION_ESCORT_RIGHT, 30, DRIVINGMODE_AVOIDCARS_RECKLESS|DF_ChangeLanesAroundObstructions|DF_GoOffRoadWhenAvoiding|DF_UseStringPullingAtJunctions, 1, -1)
ELSE
LEAVE_VEHICLE_ATTACK()
state = TGS_CHASE_VEH_ATTACK
ENDIF
ELIF eStealCarState = ISCM_IN_VEHICLE
IF NOT IS_ENTITY_UPSIDEDOWN(mDressingVeh.id)
TASK_VEHICLE_MISSION(mTowGuy.id, mDressingVeh.id, mTowTruck.id, MISSION_ESCORT_RIGHT, 30, DRIVINGMODE_AVOIDCARS_RECKLESS|DF_ChangeLanesAroundObstructions|DF_GoOffRoadWhenAvoiding|DF_UseStringPullingAtJunctions, 1, -1)
ELSE
LEAVE_VEHICLE_ATTACK()
state = TGS_CHASE_VEH_ATTACK
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE TGS_CHASE_VEH_ATTACK
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_PERFORM_SEQUENCE)
SEQUENCE_INDEX s
OPEN_SEQUENCE_TASK(s)
IF IS_PED_IN_ANY_VEHICLE(mTowGuy.id)
TASK_LEAVE_ANY_VEHICLE(NULL, 1000)
ENDIF
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, HASH_ENEMY, RELGROUPHASH_PLAYER)
TASK_COMBAT_PED(NULL, PLAYER_PED_ID())
CLOSE_SEQUENCE_TASK(s)
TASK_PERFORM_SEQUENCE(mTowGuy.id, s)
CLEAR_SEQUENCE_TASK(s)
ENDIF
BREAK
CASE TGS_REACT_BUMP
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY)
TASK_TURN_PED_TO_FACE_ENTITY(mTowGuy.id, PLAYER_PED_ID())
#IF IS_DEBUG_BUILD
SK_PRINT_INT("mTowGuy.iReactCount before increase ==== ", mTowGuy.iReactCount)
#ENDIF
ENDIF
BREAK
CASE TGS_REACT_BEING_TOWED
BREAK
CASE TGS_GIVE_ABUSE
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY)
TASK_TURN_PED_TO_FACE_ENTITY(mTowGuy.id, PLAYER_PED_ID())
SET_PED_CAPSULE(mTowGuy.id, 0)
#IF IS_DEBUG_BUILD
SK_PRINT_INT("mTowGuy.iReactCount before increase ==== ", mTowGuy.iReactCount)
#ENDIF
ENDIF
BREAK
CASE TGS_COWER
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_COWER)
CLEAR_PED_TASKS(mTowGuy.id)
TASK_COWER(mTowGuy.id)
ENDIF
BREAK
CASE TGS_FLEE
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_SMART_FLEE_PED)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_COWER)
CLEAR_PED_TASKS(mTowGuy.id)
ENDIF
TASK_SMART_FLEE_PED(mTowGuy.id, PLAYER_PED_ID(), 120, -1)
ENDIF
BREAK
CASE TGS_ATTACK
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_COMBAT)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, HASH_ENEMY, RELGROUPHASH_PLAYER)
TASK_COMBAT_PED(mTowGuy.id, PLAYER_PED_ID())
//TASK_PUT_PED_DIRECTLY_INTO_MELEE()
ENDIF
BREAK
CASE TGS_WANDER_IN_TOW
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_PERFORM_SEQUENCE)
IF IS_VEHICLE_OK(mTowTruck.id)
SEQUENCE_INDEX s
OPEN_SEQUENCE_TASK(s)
IF NOT IS_PED_IN_VEHICLE(mTowGuy.id, mTowTruck.id)
TASK_ENTER_VEHICLE(NULL, mTowTruck.id, 60000, VS_DRIVER, PEDMOVEBLENDRATIO_RUN)
ENDIF
TASK_VEHICLE_DRIVE_WANDER(NULL, mTowTruck.id, 30, DRIVINGMODE_AVOIDCARS)
CLOSE_SEQUENCE_TASK(s)
TASK_PERFORM_SEQUENCE(mTowGuy.id, s)
CLEAR_SEQUENCE_TASK(s)
INIT_HAS_PLAYER_RAMMED_ENEMY_ENOUGH(bRammedLastFrame, iRamTimer, iRammedCount, fPlayerClosingSpeedLastFrame)
ENDIF
ENDIF
BREAK
CASE TGS_QUESTION_PLAYER_PRESENTS
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY)
// TASK_TURN_PED_TO_FACE_ENTITY(mTowGuy.id, PLAYER_PED_ID())
ENDIF
BREAK
CASE TGS_PLAYER_RANG_BATTLE_BUD_NEAR
SET_PED_CAPSULE(mTowGuy.id, 0)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_COMBAT)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, HASH_ENEMY, RELGROUPHASH_PLAYER)
TASK_COMBAT_PED(mTowGuy.id, PLAYER_PED_ID())
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC DO_REACTION(TOW_GUY_STATES state)
PICK_REACTION_LINE(state)
PICK_TASK_REACTION(state)
mTowGuy.iReactTimer = GET_GAME_TIMER()
#IF IS_DEBUG_BUILD
IF eTowGuyState <> state
SK_PRINT_INT("CHANGING TOW GUY STATE TO ==== ", ENUM_TO_INT(state))
SK_PRINT_INT("mTowGuy.iReactCount before increase ==== ", mTowGuy.iReactCount)
ENDIF
#ENDIF
eTowGuyState = state
ENDPROC
PROC ACTIVATE_PEDS()
eTowGuyState = TGS_REPAIRS
ENDPROC
PROC PICK_FLEE_REACTION()
IF IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN|WF_INCLUDE_PROJECTILE)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mTowGuy.id, 10)
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_THREAT_TOW - eTowGuyState = TGS_FLEE") #ENDIF
DO_REACTION(TGS_FLEE)
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_THREAT_TOW - eTowGuyState = TGS_COWER") #ENDIF
DO_REACTION(TGS_COWER)
ENDIF
ELSE
IF eTowGuyState <> TGS_ATTACK
AND eTowGuyState <> TGS_CHASE_VEH
AND eTowGuyState <> TGS_CHASE_VEH_ATTACK
AND eTowGuyState <> TGS_ENTER_CAR
AND eTowGuyState <> TGS_ENTER_CHASE_CAR
AND eTowGuyState <> TGS_ENTER_TOW
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_THREAT_TOW - eTowGuyState = TGS_ATTACK") #ENDIF
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// IF eTowGuyState <> TGS_FLEE
/// AND eTowGuyState <> TGS_COWER
/// AND eTowGuyState <> TGS_ATTACK
/// AND eTowGuyState <> TGS_CHASE_VEH
/// AND eTowGuyState <> TGS_WANDER_IN_TOW
/// RETURNS:
/// FALSE if the tow guy is in any of the above states
FUNC BOOL CHECK_COMMON_REACTION_BLOCKERS()
IF eTowGuyState <> TGS_FLEE
AND eTowGuyState <> TGS_COWER
AND eTowGuyState <> TGS_ATTACK
AND eTowGuyState <> TGS_CHASE_VEH
AND eTowGuyState <> TGS_CHASE_VEH_ATTACK
AND eTowGuyState <> TGS_WANDER_IN_TOW
AND eTowGuyState <> TGS_REACT_BEING_TOWED
RETURN TRUE //we dont want to block the reactions
ENDIF
RETURN FALSE //we want to block the reations
ENDFUNC
/// PURPOSE:
/// IF eTowGuyState = TGS_GIVE_ABUSE
/// OR eTowGuyState = TGS_REACT_BUMP
/// RETURNS:
/// FALSE if the tow guy is in any of the states about
FUNC BOOL CHECK_RETURN_TO_REPAIRS_COMMON_BLOCKERS()
IF eTowGuyState = TGS_RETURN_TO_REPAIRS
OR eTowGuyState = TGS_REPAIRS
OR eTowGuyState = TGS_QUESTION_PLAYER_PRESENTS
OR NOT CHECK_COMMON_REACTION_BLOCKERS()
OR eMissionState = MS_RETURN_WITH_THING
OR eTowGuyState = TGS_PLAYER_RINGING_BATTLE_BUD_NEAR
OR eTowGuyState = TGS_PLAYER_RANG_BATTLE_BUD_NEAR
RETURN FALSE //we want to block the reations
ENDIF
RETURN TRUE //we dont want to block the reactions
ENDFUNC
FUNC BOOL SHOULD_RETURN_TO_REPAIRS()
IF CHECK_RETURN_TO_REPAIRS_COMMON_BLOCKERS()
IF eStealCarState = ISCM_NOT_IN_VEHICLE
AND NOT bPlayerInDressingCar
IF (eTowGuyState = TGS_REACT_BUMP
AND IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 5))
RETURN FALSE
ENDIF
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_PLAYER_BEHIND_UNARMED_STEALTH()
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mTowGuy.id, <<0,-2,0>>), <<2,3,2>>)
AND NOT IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN|WF_INCLUDE_PROJECTILE)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC DO_FLEE_REACTIONS()
IF NOT IS_PED_IN_ANY_VEHICLE(mTowGuy.id, TRUE)
PICK_FLEE_REACTION()
ELSE
IF IS_VEHICLE_OK(mTowTruck.id)
IF IS_PED_IN_VEHICLE(mTowGuy.id, mTowTruck.id)
TASK_VEHICLE_MISSION_PED_TARGET(mTowGuy.id, mTowTruck.id, PLAYER_PED_ID(), MISSION_FLEE, 30, DRIVINGMODE_AVOIDCARS, 300, 2)
eTowGuyState = TGS_FLEE
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_THREAT_TOW - mStealCar eTowGuyState = TGS_FLEE") #ENDIF
EXIT
ENDIF
ENDIF
IF IS_VEHICLE_OK(mDressingVeh.id)
IF IS_PED_IN_VEHICLE(mTowGuy.id, mDressingVeh.id)
TASK_VEHICLE_MISSION_PED_TARGET(mTowGuy.id, mDressingVeh.id, PLAYER_PED_ID(), MISSION_FLEE, 30, DRIVINGMODE_AVOIDCARS, 300, 2)
eTowGuyState = TGS_FLEE
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_THREAT_TOW - mDressingVeh eTowGuyState = TGS_FLEE") #ENDIF
EXIT
ENDIF
ENDIF
IF IS_VEHICLE_OK(mChaseCar.id)
IF IS_PED_IN_VEHICLE(mTowGuy.id, mChaseCar.id)
TASK_VEHICLE_MISSION_PED_TARGET(mTowGuy.id, mChaseCar.id, PLAYER_PED_ID(), MISSION_FLEE, 30, DRIVINGMODE_AVOIDCARS, 300, 2)
eTowGuyState = TGS_FLEE
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_THREAT_TOW - mChaseCar eTowGuyState = TGS_FLEE") #ENDIF
ENDIF
ENDIF
ENDIF
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mTowGuy.id)
ENDPROC
PROC MONITOR_PLAYER_THREAT_TOW()
IF eTowGuyState <> TGS_FLEE
AND eTowGuyState <> TGS_COWER
IF IS_ANYONE_SHOOTING_NEAR_PED(mTowGuy.id)
DO_REACTION(TGS_FLEE)
EXIT
ENDIF
IF NOT IS_PLAYER_BEHIND_UNARMED_STEALTH()
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTowGuy.id, PLAYER_PED_ID())
IF IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mTowGuy.id, 30)
IF HAS_PLAYER_THREATENED_PED(mTowGuy.id, TRUE, 50, 150, FALSE, TRUE)
DO_FLEE_REACTIONS()
EXIT
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL HAS_PLAYER_BUMPED_PED(BOOL &bRagdoll)
IF IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 2)
OR IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_TOUCHING_ENTITY(mTowGuy.id, PLAYER_PED_ID())
IF IS_PED_RAGDOLL(mTowGuy.id)
bRagdoll = TRUE
ELSE
bRagdoll = FALSE
ENDIF
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC MONITOR_PLAYER_BUMP()
IF CHECK_COMMON_REACTION_BLOCKERS()
AND eStealCarState = ISCM_NOT_IN_VEHICLE
AND eTowGuyState <> TGS_ENTER_CAR
AND eTowGuyState <> TGS_ENTER_TOW
AND eTowGuyState <> TGS_ENTER_CHASE_CAR
IF eTowGuyState <> TGS_REACT_BUMP
BOOL bRagdoll
IF HAS_PLAYER_BUMPED_PED(bRagdoll)
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF bRagdoll
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_BUMP - DO_REACTION(TGS_ATTACK)") #ENDIF
DO_REACTION(TGS_ATTACK)
ELSE
DO_REACTION(TGS_REACT_BUMP)
ENDIF
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_PLAYER_BUMP IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) - DO_REACTION(TGS_ATTACK)") #ENDIF
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
ELSE
IF SHOULD_RETURN_TO_REPAIRS()
DO_REACTION(TGS_RETURN_TO_REPAIRS)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC MONITOR_TOW_PAYO()
IF IS_VEHICLE_OK(mTowTruck.id)
IF CHECK_COMMON_REACTION_BLOCKERS()
AND eTowGuyState <> TGS_ENTER_CAR
AND eTowGuyState <> TGS_REACT_BUMP
AND eTowGuyState <> TGS_ENTER_CHASE_CAR
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mTowTruck.id)
DO_REACTION(TGS_REACT_PLAYER_IN_TOW)
EXIT
ENDIF
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_IN_RANGE_ENTITY(mTowTruck.id, PLAYER_PED_ID(), 6)
IF IS_ENTITY_TOUCHING_ENTITY(mTowTruck.id, PLAYER_PED_ID())
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
ELSE
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTowTruck.id, PLAYER_PED_ID())
IF NOT IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN)
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF IS_VEHICLE_OK(mDressingVeh.id)
IF CHECK_COMMON_REACTION_BLOCKERS()
AND eTowGuyState <> TGS_ENTER_TOW
AND eTowGuyState <> TGS_ENTER_CHASE_CAR
IF eTowGuyState <> TGS_REACT_PLAYER_IN_CAR
IF eTowGuyState <> TGS_GIVE_ABUSE
IF bPlayerInDressingCar
//player in Truck
DO_REACTION(TGS_REACT_PLAYER_IN_CAR)
EXIT
ENDIF
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_IN_RANGE_ENTITY(mDressingVeh.id, PLAYER_PED_ID(), 6)
IF IS_ENTITY_TOUCHING_ENTITY(mDressingVeh.id, PLAYER_PED_ID())
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
ELIF IS_PED_ON_SPECIFIC_VEHICLE(PLAYER_PED_ID(), mDressingVeh.id)
DO_REACTION(TGS_ATTACK)
ELSE
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mDressingVeh.id, PLAYER_PED_ID())
IF NOT IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN)
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF SHOULD_RETURN_TO_REPAIRS()
IF IS_ENTITY_IN_RANGE_COORDS(mDressingVeh.id, mDressingVeh.vPos, 2)
DO_REACTION(TGS_RETURN_TO_REPAIRS)
ENDIF
ENDIF
ELSE
IF CHECK_COMMON_REACTION_BLOCKERS()
AND eTowGuyState <> TGS_ENTER_TOW
AND eTowGuyState <> TGS_ENTER_CAR
AND eTowGuyState <> TGS_ENTER_CHASE_CAR
AND eTowGuyState <> TGS_REACT_BUMP
AND eTowGuyState <> TGS_WANDER_IN_TOW
AND eTowGuyState <> TGS_ENTER_TOW
DO_REACTION(TGS_WANDER_IN_TOW)
ENDIF
ENDIF
ENDPROC
PROC MONITOR_CHASE_PERCEPTION()
IF eTowGuyState <> TGS_ENTER_CAR
AND eTowGuyState <> TGS_ENTER_TOW
AND eTowGuyState <> TGS_ENTER_CHASE_CAR
AND eTowGuyState <> TGS_CHASE_VEH
AND eTowGuyState <> TGS_CHASE_VEH_ATTACK
AND eTowGuyState <> TGS_FLEE
AND eTowGuyState <> TGS_COWER
IF bPlayerInDressingCar
OR eStealCarState = ISCM_IN_VEHICLE
// IF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 10)
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-419.04160, -2179.05054, 8.78829>>, <<-389.54364, -2179.14795, 20.31836>>, 25)
IF NOT IS_PED_SITTING_IN_ANY_VEHICLE(mTowGuy.id)
IF IS_VEHICLE_OK(mChaseCar.id)
#IF IS_DEBUG_BUILD SK_PRINT("MONITOR_CHASE_PERCEPTION()") #ENDIF
DO_REACTION(TGS_ENTER_CHASE_CAR)
ELSE
IF bPlayerInDressingCar
DO_REACTION(TGS_ENTER_TOW)
ELIF eStealCarState = ISCM_IN_VEHICLE
DO_REACTION(TGS_ENTER_CAR)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC MONITOR_PLAYER_TOWING_GUY()
IF eTowGuyState = TGS_CHASE_VEH
AND eTowGuyState <> TGS_REACT_BEING_TOWED
IF IS_PED_IN_ANY_VEHICLE(mTowGuy.id)
IF IS_PLAYER_TOWING_VEHICLE(GET_VEHICLE_PED_IS_IN(mTowGuy.id))
DO_REACTION(TGS_REACT_BEING_TOWED)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC MONITOR_PLAYER_HANGING_AROUND()
IF eTowGuyState <> TGS_QUESTION_PLAYER_PRESENTS
AND eTowGuyState <> TGS_FLEE
AND eTowGuyState <> TGS_COWER
AND eTowGuyState <> TGS_ATTACK
IF fHangingAroundTimer < 20
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-414.48990, -2181.96729, 11.93531>>, <<-414.17139, -2170.25171, 5.64993>>, 12.63)
fHangingAroundTimer += GET_FRAME_TIME()
ENDIF
ELSE
#IF IS_DEBUG_BUILD SK_PRINT_FLOAT("fHangingAroundTimer", fHangingAroundTimer) #ENDIF
DO_REACTION(TGS_QUESTION_PLAYER_PRESENTS)
fHangingAroundTimer = 0
ENDIF
ENDIF
ENDPROC
PROC MONITOR_PLAYER_RINGING_BUDDY()
IF eTowGuyState != TGS_PLAYER_RINGING_BATTLE_BUD_NEAR
IF IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mTowGuy.id, 15)
IF IS_PHONE_ONSCREEN()
AND IS_CONTACTS_LIST_ON_SCREEN()
AND IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF IS_CALLING_CONTACT_FOR_SECONDARY_FUNCTION(CHAR_MICHAEL)
OR IS_CALLING_CONTACT_FOR_SECONDARY_FUNCTION(CHAR_FRANKLIN)
OR IS_CALLING_CONTACT_FOR_SECONDARY_FUNCTION(CHAR_TREVOR)
#IF IS_DEBUG_BUILD SK_PRINT("Player ringing sceondary function on other player char") #ENDIF
eTowGuyState = TGS_PLAYER_RINGING_BATTLE_BUD_NEAR
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC TOW_GUYS_PRECEPTION()
MONITOR_PLAYER_RINGING_BUDDY()
MONITOR_PLAYER_HANGING_AROUND()
MONITOR_PLAYER_TOWING_GUY()
MONITOR_PLAYER_BUMP()
MONITOR_TOW_PAYO()
MONITOR_CHASE_PERCEPTION()
MONITOR_PLAYER_THREAT_TOW()
ENDPROC
FUNC BOOL CHECK_FOR_LAST_WARNING()
IF eTowGuyState <> TGS_ATTACK
AND eTowGuyState <> TGS_PLAYER_RINGING_BATTLE_BUD_NEAR
AND eTowGuyState <> TGS_FLEE
IF mTowGuy.iReactCount >= 3
#IF IS_DEBUG_BUILD SK_PRINT("CHECK_FOR_LAST_WARNING - eTowGuyState = TGS_ATTACK") #ENDIF
DO_REACTION(TGS_ATTACK)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_PLAYER_CLOSE_AND_SLOW()
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 20)
RETURN TRUE
ELIF GET_ENTITY_SPEED(PLAYER_PED_ID()) < 10
IF iPlayerStoppedCloseTimer = -1
#IF IS_DEBUG_BUILD SK_PRINT("") #ENDIF
iPlayerStoppedCloseTimer = GET_GAME_TIMER()
ELIF (GET_GAME_TIMER() - iPlayerStoppedCloseTimer ) > 6000
RETURN TRUE
ENDIF
ENDIF
ELSE
IF IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 10)
IF GET_ENTITY_SPEED(PLAYER_PED_ID()) < 10
IF iPlayerStoppedCloseTimer = -1
#IF IS_DEBUG_BUILD SK_PRINT("") #ENDIF
iPlayerStoppedCloseTimer = GET_GAME_TIMER()
ELIF (GET_GAME_TIMER() - iPlayerStoppedCloseTimer ) > 5500
RETURN TRUE
ENDIF
ENDIF
ELSE
iPlayerStoppedCloseTimer = -1
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC TOW_GUY_STATE()
// IF IS_VEHICLE_OK(mDressingVeh.id)
// SET_VEHICLE_DOOR_OPEN(mDressingVeh.id ,SC_DOOR_BONNET, FALSE, TRUE)
// ENDIF
IF IS_PED_UNINJURED(mTowGuy.id)
TOW_GUYS_PRECEPTION()
SWITCH eTowGuyState
CASE TGS_WAIT_GET_DEAD
BREAK
CASE TGS_REPAIRS
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(9000, 10000)
IF NOT CHECK_FOR_LAST_WARNING()
DO_REACTION(eTowGuyState)
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("TGS_REPAIRS - eTowGuyState = TGS_ATTACK") #ENDIF
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
SET_PED_CAPSULE(mTowGuy.id, 0.1)
BREAK
CASE TGS_REACT_PLAYER_IN_TOW
IF IS_VEHICLE_OK(mTowTruck.id)
IF IS_ENTITY_IN_RANGE_COORDS(mTowGuy.id, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mTowTruck.id, <<-1,0.5,0>>), 3)
#IF IS_DEBUG_BUILD SK_PRINT("TGS_REPAIRS - eTowGuyState = TGS_REACT_PLAYER_IN_TOW") #ENDIF
DO_REACTION(TGS_ATTACK)
EXIT
ENDIF
ENDIF
BREAK
CASE TGS_REACT_PLAYER_IN_CAR
IF IS_VEHICLE_OK(mDressingVeh.id)
IF IS_ENTITY_IN_RANGE_COORDS(mDressingVeh.id, mDressingVeh.vPos, 2)
IF IS_ENTITY_IN_RANGE_COORDS(mTowGuy.id, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, <<-1,0.5,0>>), 2)
DO_REACTION(TGS_GIVE_ABUSE)
EXIT
ENDIF
ELSE
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
BREAK
CASE TGS_GIVE_ABUSE
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
IF IS_ENTITY_IN_RANGE_COORDS(mDressingVeh.id, mDressingVeh.vPos, 2)
IF NOT CHECK_FOR_LAST_WARNING()
DO_REACTION(TGS_GIVE_ABUSE)
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("TGS_GIVE_ABUSE - eTowGuyState = TGS_REACT_PLAYER_IN_TOW") #ENDIF
DO_REACTION(TGS_ATTACK)
ENDIF
ELSE
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
BREAK
CASE TGS_ENTER_TOW
IF IS_VEHICLE_OK(mTowTruck.id)
AND NOT IS_ENTITY_UPSIDEDOWN(mTowTruck.id)
IF IS_PED_SITTING_IN_VEHICLE(mTowGuy.id, mTowTruck.id)
DO_REACTION(TGS_CHASE_VEH)
ENDIF
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
IF NOT IS_PED_SITTING_IN_VEHICLE(mTowGuy.id, mTowTruck.id)
DO_REACTION(TGS_ENTER_TOW)
ENDIF
ENDIF
ELSE
DO_REACTION(TGS_ATTACK)
ENDIF
BREAK
CASE TGS_ENTER_CAR
IF IS_VEHICLE_OK(mDressingVeh.id)
AND NOT IS_ENTITY_UPSIDEDOWN(mDressingVeh.id)
IF IS_PED_SITTING_IN_VEHICLE(mTowGuy.id, mDressingVeh.id)
DO_REACTION(TGS_CHASE_VEH)
ENDIF
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
IF NOT IS_PED_SITTING_IN_VEHICLE(mTowGuy.id, mDressingVeh.id)
DO_REACTION(TGS_ENTER_CAR)
ENDIF
ENDIF
ELSE
DO_REACTION(TGS_ATTACK)
ENDIF
BREAK
CASE TGS_ENTER_CHASE_CAR
IF IS_VEHICLE_OK(mChaseCar.id)
AND NOT IS_ENTITY_UPSIDEDOWN(mChaseCar.id)
IF IS_PED_SITTING_IN_VEHICLE(mTowGuy.id, mChaseCar.id)
#IF IS_DEBUG_BUILD SK_PRINT("TGS_ENTER_CHASE_CAR") #ENDIF
DO_REACTION(TGS_CHASE_VEH)
ENDIF
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
IF NOT IS_PED_SITTING_IN_VEHICLE(mTowGuy.id, mChaseCar.id)
DO_REACTION(TGS_ENTER_CHASE_CAR)
ENDIF
ENDIF
ELSE
DO_REACTION(TGS_ATTACK)
ENDIF
BREAK
CASE TGS_CHASE_VEH
IF IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 20)
AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
DO_REACTION(TGS_CHASE_VEH_ATTACK)
EXIT
ENDIF
IF IS_PLAYER_CLOSE_AND_SLOW()
DO_REACTION(TGS_CHASE_VEH_ATTACK)
ELSE
DO_REACTION(TGS_CHASE_VEH)
ENDIF
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_COMBAT)
IF NOT IS_PED_SITTING_IN_ANY_VEHICLE(mTowGuy.id)
IF IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 10)
DO_REACTION(TGS_CHASE_VEH_ATTACK)
ELSE
IF IS_VEHICLE_OK(mChaseCar.id)
#IF IS_DEBUG_BUILD SK_PRINT("TGS_CHASE_VEH") #ENDIF
DO_REACTION(TGS_ENTER_CHASE_CAR)
ELSE
IF bPlayerInDressingCar
DO_REACTION(TGS_ENTER_TOW)
ELIF eStealCarState = ISCM_IN_VEHICLE
DO_REACTION(TGS_ENTER_CAR)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Play dialogue if ped close enough
ENDIF
BREAK
CASE TGS_CHASE_VEH_ATTACK
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
IF NOT IS_PLAYER_CLOSE_AND_SLOW()
DO_REACTION(TGS_CHASE_VEH_ATTACK)
ELSE
IF IS_VEHICLE_OK(mChaseCar.id)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, mChaseCar.id, 15)
AND NOT IS_PED_ON_FOOT(PLAYER_PED_ID())
#IF IS_DEBUG_BUILD SK_PRINT("slow and close not in range") #ENDIF
DO_REACTION(TGS_ENTER_CHASE_CAR)
ENDIF
ELSE
IF bPlayerInDressingCar
IF IS_VEHICLE_OK(mTowTruck.id)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, mTowTruck.id, 10)
DO_REACTION(TGS_ENTER_TOW)
ENDIF
ENDIF
ELIF eStealCarState = ISCM_IN_VEHICLE
IF IS_VEHICLE_OK(mDressingVeh.id)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, mDressingVeh.id, 10)
DO_REACTION(TGS_ENTER_CAR)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE TGS_REACT_BUMP
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1000, 2000)
//REPEAT dialogue
IF NOT CHECK_FOR_LAST_WARNING()
DO_REACTION(TGS_REACT_BUMP)
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("TGS_REACT_BUMP - eTowGuyState = TGS_ATTACK") #ENDIF
DO_REACTION(TGS_ATTACK)
ENDIF
ENDIF
BREAK
CASE TGS_FLEE
IF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 118)
SAFE_RELEASE_PED(mTowGuy.id, TRUE, TRUE)
#IF IS_DEBUG_BUILD SK_PRINT("Releasing tow guy and vehicle Tow guy is fleeing") #ENDIF
SAFE_RELEASE_VEHICLE(mDressingVeh.id)
ENDIF
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
//REPEAT dialogue?
ENDIF
BREAK
CASE TGS_COWER
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(3000, 5000)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 10)
DO_REACTION(TGS_FLEE)
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTowGuy.id, PLAYER_PED_ID())
DO_REACTION(TGS_FLEE)
//REPEAT dialogue
ELSE
// IF IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), mTowGuy.id)
// OR IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), mTowGuy.id)
DO_REACTION(TGS_COWER)
// ELSE
// DO_REACTION(TGS_FLEE)
// ENDIF
ENDIF
ELSE
IF IS_PLAYER_SHOOTING_NEAR_PED(mTowGuy.id)
DO_REACTION(TGS_FLEE)
ENDIF
ENDIF
BREAK
CASE TGS_ATTACK
IF IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN|WF_INCLUDE_PROJECTILE)
IF CAN_PED_SEE_PED(mTowGuy.id, PLAYER_PED_ID())
PICK_FLEE_REACTION()
#IF IS_DEBUG_BUILD SK_PRINT("player is armed flee 1") #ENDIF
EXIT
ENDIF
ENDIF
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(7000, 10000)
//REPEAT dialogue
DO_REACTION(TGS_ATTACK)
ENDIF
BREAK
CASE TGS_RETURN_TO_REPAIRS
IF IS_VEHICLE_OK(mDressingVeh.id)
IF IS_ENTITY_IN_RANGE_COORDS(mTowGuy.id, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, vAnimOffset),2)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
AND NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_ACHIEVE_HEADING)
DO_REACTION(TGS_REPAIRS)
ENDIF
ENDIF
SET_PED_CAPSULE(mTowGuy.id, 0.1)
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
RETURN_TOW_GUY_REPAIRS()
ENDIF
ENDIF
BREAK
CASE TGS_REACT_BEING_TOWED
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(1500, 2500)
IF NOT IS_PLAYER_TOWING_VEHICLE(GET_VEHICLE_PED_IS_IN(mTowGuy.id))
DO_REACTION(TGS_CHASE_VEH)
ELSE
DO_REACTION(TGS_REACT_BEING_TOWED)
ENDIF
ENDIF
BREAK
CASE TGS_WANDER_IN_TOW
IF IS_VEHICLE_OK(mTowTruck.id)
IF IS_PED_IN_VEHICLE(mTowGuy.id, mTowTruck.id)
IF HAS_PLAYER_RAMMED_ENEMY_ENOUGH(mTowTruck.id, bRammedLastFrame, iRamTimer, iRammedCount, fPlayerClosingSpeedLastFrame, 3, 2)
SEQUENCE_INDEX s
OPEN_SEQUENCE_TASK(s)
IF IS_PED_IN_VEHICLE(mTowGuy.id, mTowTruck.id)
TASK_LEAVE_ANY_VEHICLE(NULL, 1000, ECF_JUMP_OUT)
ENDIF
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 120, -1)
CLOSE_SEQUENCE_TASK(s)
TASK_PERFORM_SEQUENCE(mTowGuy.id, s)
CLEAR_SEQUENCE_TASK(s)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
eTowGuyState = TGS_FLEE
ELSE
CONTROL_VEHICLE_CHASE_HINT_CAM_ANY_MEANS(localChaseHintCamStruct, mTowTruck.id )
ENDIF
ENDIF
ENDIF
BREAK
CASE TGS_QUESTION_PLAYER_PRESENTS
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(10000, 12000)
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-414.48990, -2181.96729, 11.93531>>, <<-414.17139, -2170.25171, 5.64993>>, 12.63)
DO_REACTION(TGS_RETURN_TO_REPAIRS)
ELSE
DO_REACTION(TGS_QUESTION_PLAYER_PRESENTS)
ENDIF
ENDIF
BREAK
CASE TGS_PLAYER_RINGING_BATTLE_BUD_NEAR
IF HAS_CELLPHONE_CALL_FINISHED()
#IF IS_DEBUG_BUILD SK_PRINT("buddy call Finished") #ENDIF
DO_REACTION(TGS_PLAYER_RANG_BATTLE_BUD_NEAR)
ELIF WAS_LAST_CELLPHONE_CALL_INTERRUPTED()
#IF IS_DEBUG_BUILD SK_PRINT("buddy call interrupted") #ENDIF
// DO_REACTION(TGS_PLAYER_RANG_BATTLE_BUD_NEAR)
DO_REACTION(TGS_REPAIRS)
ENDIF
BREAK
CASE TGS_PLAYER_RANG_BATTLE_BUD_NEAR
IF (GET_GAME_TIMER() - mTowGuy.iReactTimer) > GET_RANDOM_INT_IN_RANGE(7000, 10000)
//REPEAT dialogue
DO_REACTION(TGS_ATTACK)
ENDIF
BREAK
ENDSWITCH
ELSE
SAFE_RELEASE_PED(mTowGuy.id)
IF IS_VEHICLE_OK(mDressingVeh.id)
IF NOT IS_ENTITY_IN_RANGE_COORDS(mDressingVeh.id, mDressingVeh.vPos, 50)
OR NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mDressingVeh.id, 250)
SAFE_RELEASE_VEHICLE(mDressingVeh.id)
#IF IS_DEBUG_BUILD SK_PRINT("Releasing tow guy and vehicle Tow guy is dead") #ENDIF
ENDIF
ENDIF
SAFE_REMOVE_BLIP(mTowGuy.mAIBlip.BlipID)
SAFE_REMOVE_BLIP(mTowGuy.mAIBlip.VehicleBlipID)
IF bActivateLoseTowGuy
bActivateLoseTowGuy = FALSE
PRINT_NOW("PRB_TAKBACK", DEFAULT_GOD_TEXT_TIME, 0)
ENDIF
ENDIF
IF eTowGuyState <> TGS_FLEE
AND eTowGuyState <> TGS_COWER
UPDATE_AI_PED_BLIP(mTowGuy.id, mTowGuy.mAIBlip)
ELSE
CLEANUP_AI_PED_BLIP(mTowGuy.mAIBlip)
ENDIF
ENDPROC
/// PURPOSE:
/// Sets the mission check point
PROC SET_CHECKPOINT()
ENDPROC
/// PURPOSE:
/// Turn off the ambient services
PROC SERVICES_TOGGLE(BOOL bOn)
//Wanted
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, bOn)
ENABLE_DISPATCH_SERVICE(DT_POLICE_HELICOPTER, bOn)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, bOn)
ENABLE_DISPATCH_SERVICE(DT_SWAT_AUTOMOBILE, bOn)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, bOn)
IF bOn
SET_WANTED_LEVEL_MULTIPLIER(1.0)
SET_MAX_WANTED_LEVEL(5)
ELSE
SET_MAX_WANTED_LEVEL(0)
SET_WANTED_LEVEL_MULTIPLIER(0)
ENDIF
ENDPROC
/// PURPOSE:
/// Loads a scene around a point used to the player
/// seeing the map stream in when starting a replay or debug skipping
/// PARAMS:
/// pos - the position to stream the scene around at
/// rad - the radius of the scene to load
PROC LOAD_SCENE_SKIP(VECTOR pos, FLOAT rad)
NEW_LOAD_SCENE_START_SPHERE(pos, rad)
INT i_load_scene_timer = GET_GAME_TIMER()
WHILE (NOT IS_NEW_LOAD_SCENE_LOADED()) AND (GET_GAME_TIMER() - i_load_scene_timer < 12000)
WAIT(0)
ENDWHILE
NEW_LOAD_SCENE_STOP()
ENDPROC
/// PURPOSE:
/// Adds peds for dialogue based off the Mission state
PROC ADD_PEDS_FOR_DIALOGUE()
ADD_CURRENT_PLAYER_FOR_DIALOGUE(s_conversation_peds)
ADD_PED_FOR_DIALOGUE(s_conversation_peds, 3, mTowGuy.id, "FIBP2TowGuy", TRUE)
ENDPROC
FUNC BOOL IS_PLAYER_IN_CORRECT_MODEL_ON_START()
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_VEHICLE_MODEL(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), TOWTRUCK)
SET_ENTITY_AS_MISSION_ENTITY(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), TRUE, FALSE)
viStealCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_VEHICLE_OK(viStealCar)
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Sets up a stage requirment via a switch using an ENUM
/// Stage requirements include the hunter the saleform or the mission text etc.
/// PARAMS:
/// missionReq - The Enum of the required mission element e.g. RQ_TEXT
/// pos - The position the thing is spawned at - if no position is required the use vSafeVec
/// If spawning multiple things at once then have the postions already in the switch statement
/// as calling this func multiple times wont work as well with the other function that calls it
/// dir - This is the heading or direction you want the thing to face when spawned. Defaults to
/// 0.0
/// RETURNS:
/// TRUE when the thing required is created/loaded/setup or whatever.
///
FUNC BOOL SETUP_STAGE_REQUIREMENTS(MISSION_REQ missionReq,VECTOR pos, FLOAT dir=0.0)
SWITCH missionReq
CASE RQ_NONE
IF ARE_VECTORS_ALMOST_EQUAL(pos, vSafeVec)
AND dir = 0.0
RETURN TRUE
ENDIF
BREAK
CASE RQ_TEXT
REQUEST_ADDITIONAL_TEXT(sGodText, MISSION_TEXT_SLOT)
REQUEST_ADDITIONAL_TEXT(sTextBlock, MISSION_DIALOGUE_TEXT_SLOT)
IF HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
AND HAS_ADDITIONAL_TEXT_LOADED(MISSION_DIALOGUE_TEXT_SLOT)
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_TEXT")
#ENDIF
RETURN TRUE
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("TEXT FAILED")
#ENDIF
BREAK
CASE RQ_STEAL_CAR
IF IS_VEHICLE_OK(g_sTriggerSceneAssets.veh[0])
SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.veh[0], TRUE, TRUE)
mTowTruck.id = g_sTriggerSceneAssets.veh[0]
IF IS_VEHICLE_OK(mTowTruck.id)
#IF IS_DEBUG_BUILD
SK_PRINT("g_sTriggerSceneAssets - RQ_STEAL_CAR")
#ENDIF
SET_VEHICLE_AS_RESTRICTED(mTowTruck.id, 0)
SET_VEHICLE_HAS_STRONG_AXLES(mTowTruck.id, TRUE)
RETURN TRUE
ENDIF
ELSE
IF SPAWN_VEHICLE(mTowTruck.id, mTowTruck.Mod, mTowTruck.vPos, mTowTruck.fDir)
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_STEAL_CAR")
#ENDIF
SET_VEHICLE_AS_RESTRICTED(mTowTruck.id, 0)
SET_VEHICLE_HAS_STRONG_AXLES(mTowTruck.id, TRUE)
RETURN TRUE
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_STEAL_CAR FAILED")
#ENDIF
BREAK
CASE RQ_TOW_GUY
IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.ped[0])
IF NOT IS_PED_DEAD_OR_DYING(g_sTriggerSceneAssets.ped[0])
SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.ped[0], TRUE, TRUE)
mTowGuy.id = g_sTriggerSceneAssets.ped[0]
IF IS_PED_UNINJURED(mTowGuy.id)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mTowGuy.id, TRUE)
SET_PED_CAPSULE(mTowGuy.id, 0.1)
STOP_PED_SPEAKING(mTowGuy.id, TRUE)
SET_PED_PATH_MAY_ENTER_WATER(mTowGuy.id, FALSE)
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
ELSE
IF SPAWN_PED(mTowGuy.id, mTowGuy.Mod, mTowGuy.vPos, mTowGuy.fDir)
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_TOW_GUY")
#ENDIF
SET_PED_CAPSULE(mTowGuy.id, 0.1)
STOP_PED_SPEAKING(mTowGuy.id, TRUE)
SET_PED_DEFAULT_COMPONENT_VARIATION(mTowGuy.id)
SET_PED_PATH_MAY_ENTER_WATER(mTowGuy.id, FALSE)
RETURN TRUE
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_TOW_GUY FAILED")
#ENDIF
BREAK
CASE RQ_REPAIR_ANIM
REQUEST_ANIM_DICT("mini@repair")
REQUEST_ANIM_DICT("amb@code_human_cower@male@enter")
IF HAS_ANIM_DICT_LOADED("mini@repair")
AND HAS_ANIM_DICT_LOADED("amb@code_human_cower@male@enter")
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_REPAIR_ANIM")
#ENDIF
RETURN TRUE
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_REPAIR_ANIM FAILED")
#ENDIF
BREAK
CASE RQ_DRESSING_CAR
IF IS_VEHICLE_OK(g_sTriggerSceneAssets.veh[1])
SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.veh[1], TRUE, TRUE)
mDressingVeh.id = g_sTriggerSceneAssets.veh[1]
IF IS_VEHICLE_OK(mDressingVeh.id)
SET_VEHICLE_COLOUR_COMBINATION(mDressingVeh.id, 0)
RETURN TRUE
ENDIF
ELSE
IF SPAWN_VEHICLE(mDressingVeh.id, mDressingVeh.Mod, mDressingVeh.vPos, mDressingVeh.fDir)
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_DRESSING_CAR")
#ENDIF
SET_VEHICLE_COLOUR_COMBINATION(mDressingVeh.id, 0)
SET_VEHICLE_DOOR_OPEN(mDressingVeh.id ,SC_DOOR_BONNET, FALSE)//, TRUE), TRUE)
SET_VEHICLE_DOOR_OPEN(mDressingVeh.id ,SC_DOOR_FRONT_LEFT, TRUE)//, TRUE), TRUE)
SET_VEHICLE_ENGINE_HEALTH(mDressingVeh.id, 100)
RETURN TRUE
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_DRESSING_CAR FAILED")
#ENDIF
BREAK
CASE RQ_CHASE_CAR
IF IS_VEHICLE_OK(g_sTriggerSceneAssets.veh[2])
SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.veh[2], TRUE, TRUE)
mChaseCar.id = g_sTriggerSceneAssets.veh[2]
IF IS_VEHICLE_OK(mChaseCar.id)
SET_VEHICLE_DOORS_LOCKED(mChaseCar.id, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
RETURN TRUE
ENDIF
ELSE
IF SPAWN_VEHICLE(mChaseCar.id, mChaseCar.Mod, mChaseCar.vPos, mChaseCar.fDir)
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_CHASE_CAR")
#ENDIF
SET_VEHICLE_DOORS_LOCKED(mChaseCar.id, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
RETURN TRUE
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("RQ_CHASE_CAR FAILED")
#ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Used to setup a mission stage(or state if you call it that) Uses a switch statement to pick which
/// set of SETUP_STAGE_REQUIREMENTS() to call. It checks to see if all the stage requirements are
/// setup and then does any other setup needed. such as setting the players position or switching a
/// bool to true or false etc.
/// Handles setting up stuff needed after a Z or p skip first then the normal setup takes place
/// PARAMS:
/// eStage - The mission state/stage that needs setting up
/// bJumped - Wether or not the state/stage has been jumped to using Z or P skips
/// RETURNS:
/// TRUE if everything required for a stage is loaded properly
FUNC BOOL SETUP_MISSION_STAGE(MISSION_STATE eStage, BOOL bJumped = FALSE)
SWITCH eStage
CASE MS_SET_UP
IF bJumped //If we have jumped to this stage set up everything that might of been cleared buy the jump to funtions
bJumpSkip = FALSE // everything has been setup that is not key to this stage but is required to carry the mission on from this stage so reset the jump flag
RC_END_Z_SKIP()
ELSE
IF SETUP_STAGE_REQUIREMENTS(RQ_TEXT, vSafeVec)
IF NOT IS_REPLAY_IN_PROGRESS()
IF IS_PLAYER_IN_CORRECT_MODEL_ON_START()
MISSION_FLOW_RELEASE_TRIGGER_SCENE_ASSETS(SP_MISSION_FBI_4_PREP_2)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRASH, TRUE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, TRUE)
eMissionState = MS_RETURN_WITH_THING//tesst
RETURN TRUE
ELSE
IF SETUP_STAGE_REQUIREMENTS(RQ_STEAL_CAR, mTowTruck.vPos, mTowTruck.fDir)
AND SETUP_STAGE_REQUIREMENTS(RQ_DRESSING_CAR, mDressingVeh.vPos, mDressingVeh.fDir)
AND SETUP_STAGE_REQUIREMENTS(RQ_CHASE_CAR, mChaseCar.vPos, mChaseCar.fDir)
AND SETUP_STAGE_REQUIREMENTS(RQ_TOW_GUY, mTowGuy.vPos, mTowGuy.fDir)
AND SETUP_STAGE_REQUIREMENTS(RQ_REPAIR_ANIM, vSafeVec)
sibBlocking = ADD_SCENARIO_BLOCKING_AREA(<<-417.19797, -2155.88574, 8.36266>>, <<-383.49078, -2188.51147, 12.92130>>)
MISSION_FLOW_RELEASE_TRIGGER_SCENE_ASSETS(SP_MISSION_FBI_4_PREP_2)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRASH, TRUE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, TRUE)
IF IS_PED_UNINJURED(mTowGuy.id)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_PLAY_ANIM)
TASK_PLAY_ANIM_ADVANCED(mTowGuy.id, "mini@repair", "fixing_a_ped", GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, vAnimOffset), <<0,0,-GET_ENTITY_HEADING(mDressingVeh.id)>>, INSTANT_BLEND_IN, WALK_BLEND_OUT, -1, AF_LOOPING)
FORCE_PED_AI_AND_ANIMATION_UPDATE(mTowGuy.id)
ENDIF
ACTIVATE_PEDS()
ADD_PEDS_FOR_DIALOGUE()
SET_PED_CONFIG_FLAG(mTowGuy.id, PCF_ShouldFixIfNoCollision, FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(mTowGuy.id, HASH_ENEMY)
ENDIF
IF GET_BLIP_FROM_ENTITY(mTowTruck.id) != NULL
BLIP_INDEX blip
blip = GET_BLIP_FROM_ENTITY(mTowTruck.id)
SET_THIS_SCRIPT_CAN_REMOVE_BLIPS_CREATED_BY_ANY_SCRIPT(TRUE)
SAFE_REMOVE_BLIP(blip)
SET_THIS_SCRIPT_CAN_REMOVE_BLIPS_CREATED_BY_ANY_SCRIPT(FALSE)
ENDIF
ADD_SAFE_BLIP_TO_VEHICLE(biVehicleBlip, mTowTruck.id, TRUE)
PLAY_SOUND_FROM_ENTITY(-1, "Tow_truck_damage" , mDressingVeh.id, "FBI_04_HEAT_SOUNDS")
RETURN TRUE //all mission stage requirements set up return true and activate stage
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("MS_SET_UP, FAILED")
#ENDIF
BREAK
CASE MS_STEAL
IF bJumped //If we have jumped to this stage set up everything that might of been cleared buy the jump to funtions
IF SETUP_STAGE_REQUIREMENTS(RQ_STEAL_CAR, mTowTruck.vPos, mTowTruck.fDir)
AND SETUP_STAGE_REQUIREMENTS(RQ_DRESSING_CAR, mDressingVeh.vPos, mDressingVeh.fDir)
AND SETUP_STAGE_REQUIREMENTS(RQ_REPAIR_ANIM, vSafeVec)
AND SETUP_STAGE_REQUIREMENTS(RQ_CHASE_CAR, mChaseCar.vPos, mChaseCar.fDir)
AND SETUP_STAGE_REQUIREMENTS(RQ_TOW_GUY, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, vAnimOffset), -GET_ENTITY_HEADING(mDressingVeh.id))
CLEAR_AREA(mTowGuy.vPos, 100, TRUE)
RESET_ALL()
IF IS_PED_UNINJURED(mTowGuy.id)
SET_PED_CAPSULE(mTowGuy.id, 0.1)
IF NOT IsPedPerformingTask(mTowGuy.id, SCRIPT_TASK_PLAY_ANIM)
TASK_PLAY_ANIM_ADVANCED(mTowGuy.id, "mini@repair", "fixing_a_ped", GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mDressingVeh.id, vAnimOffset), <<0,0,-GET_ENTITY_HEADING(mDressingVeh.id)>>, INSTANT_BLEND_IN, WALK_BLEND_OUT, -1, AF_LOOPING)
FORCE_PED_AI_AND_ANIMATION_UPDATE(mTowGuy.id)
ACTIVATE_PEDS()
ADD_PEDS_FOR_DIALOGUE()
SET_PED_CONFIG_FLAG(mTowGuy.id, PCF_ShouldFixIfNoCollision, FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(mTowGuy.id, HASH_ENEMY)
ENDIF
ENDIF
IF NOT IS_REPLAY_IN_PROGRESS()
SET_PED_POS(PLAYER_PED_ID(), <<-396.3081, -2145.1758, 9.3193>>, 172.0072)
ENDIF
IF NOT IS_REPLAY_BEING_SET_UP()
sibBlocking = ADD_SCENARIO_BLOCKING_AREA(<<-417.19797, -2155.88574, 8.36266>>, <<-383.49078, -2188.51147, 12.92130>>)
PLAY_SOUND_FROM_ENTITY(-1, "Tow_truck_damage" , mDressingVeh.id, "FBI_04_HEAT_SOUNDS")
ADD_SAFE_BLIP_TO_VEHICLE(biVehicleBlip, mTowTruck.id, TRUE)
bJumpSkip = FALSE // everything has been setup that is not key to this stage but is required to carry the mission on from this stage so reset the jump flag
RC_END_Z_SKIP()
ELSE
END_REPLAY_SETUP()
ENDIF
ENDIF
ELSE
RETURN TRUE //all mission stage requirements set up return true and activate stage
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("MS_STEAL, FAILED")
#ENDIF
BREAK
CASE MS_RETURN_WITH_THING
IF bJumped //If we have jumped to this stage set up everything that might of been cleared buy the jump to funtions
IF SETUP_STAGE_REQUIREMENTS(RQ_STEAL_CAR, mTowTruck.vPos, mTowTruck.fDir)
RESET_ALL()
IF NOT IS_REPLAY_BEING_SET_UP()
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), mTowTruck.id)
ENDIF
IF NOT IS_REPLAY_BEING_SET_UP()
sibBlocking = ADD_SCENARIO_BLOCKING_AREA(<<-417.19797, -2155.88574, 8.36266>>, <<-383.49078, -2188.51147, 12.92130>>)
bJumpSkip = FALSE // everything has been setup that is not key to this stage but is required to carry the mission on from this stage so reset the jump flag
RC_END_Z_SKIP()
ELSE
END_REPLAY_SETUP(mTowTruck.id)
ENDIF
ENDIF
ELSE
RETURN TRUE //all mission stage requirements set up return true and activate stage
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("MS_RETURN_WITH_THING, FAILED")
#ENDIF
BREAK
CASE MS_LEAVE_VEHICLE
IF bJumped //If we have jumped to this stage set up everything that might of been cleared buy the jump to funtions
IF SETUP_STAGE_REQUIREMENTS(RQ_STEAL_CAR, vDropOffLoc, mTowTruck.fDir)
RESET_ALL()
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), mTowTruck.id)
IF NOT IS_REPLAY_BEING_SET_UP()
bJumpSkip = FALSE // everything has been setup that is not key to this stage but is required to carry the mission on from this stage so reset the jump flag
RC_END_Z_SKIP()
ELSE
END_REPLAY_SETUP()
ENDIF
ENDIF
ELSE
RETURN TRUE //all mission stage requirements set up return true and activate stage
ENDIF
#IF IS_DEBUG_BUILD
SK_PRINT("MS_RETURN_WITH_THING, FAILED")
#ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Sits in the NEXT_STAGE() function and moniters for assest that
/// should be unloaded based on the mission state
/// PARAMS:
/// state - the current state we should evaluate
PROC MONITER_UNLOAD_ASSETS(MISSION_STATE state)
SWITCH state
CASE MS_SET_UP
BREAK
ENDSWITCH
ENDPROC
// ===========================================================================================================
// Termination
// ===========================================================================================================
// -----------------------------------------------------------------------------------------------------------
// Script Cleanup
// -----------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Unloads all models
PROC UNLOAD_ALL_MODELS()
SET_MODEL_AS_NO_LONGER_NEEDED(mTowTruck.Mod)
ENDPROC
/// PURPOSE:
/// Unloads all waypoints
PROC UNLOAD_ALL_WAYPOINTS()
ENDPROC
/// PURPOSE:
/// Unloads all anims
PROC UNLOAD_ANIMS()
REMOVE_ANIM_DICT("mini@repair")
REMOVE_ANIM_DICT("amb@code_human_cower@male@react_cowering")
ENDPROC
/// PURPOSE:
/// Unload all vehicle recordings
PROC UNLOAD_ALL_CAR_RECS()
ENDPROC
/// PURPOSE:
/// Deletes any blips that are valid
PROC REMOVE_BLIPS()
SAFE_REMOVE_BLIP(biBlip)
SAFE_REMOVE_BLIP(biVehicleBlip)
ENDPROC
/// PURPOSE:
/// Standard delete all function used the wait for fail state
/// Safe deletes all peds, props and vehicles
PROC DELETE_ALL()
SAFE_DELETE_VEHICLE(mTowTruck.id)
SAFE_DELETE_VEHICLE(mDressingVeh.id)
SAFE_DELETE_VEHICLE(mChaseCar.id)
SAFE_DELETE_VEHICLE(viStealCar)
SAFE_DELETE_PED(mTowGuy.id)
ENDPROC
PROC RELEASE_ALL()
SAFE_RELEASE_VEHICLE(mTowTruck.id)
SAFE_RELEASE_VEHICLE(mDressingVeh.id)
SAFE_RELEASE_VEHICLE(mChaseCar.id)
SAFE_RELEASE_VEHICLE(viStealCar)
SAFE_RELEASE_PED(mTowGuy.id)
ENDPROC
/// PURPOSE:
/// Deletes all mission entities and any other clean up
/// This is used to clear the mission when P or Z skipping
PROC CLEANUP(BOOL bDelAll = TRUE)
IF bDelAll
#IF IS_DEBUG_BUILD SK_PRINT("CLEANUP = DEL ALL") #ENDIF
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("CLEANUP = RELEASE ") #ENDIF
ENDIF
WAIT_FOR_CUTSCENE_TO_STOP()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
REMOVE_BLIPS()
UNLOAD_ALL_MODELS()
UNLOAD_ALL_WAYPOINTS()
UNLOAD_ANIMS()
UNLOAD_ALL_CAR_RECS()
IF bDelAll
IF DOES_ENTITY_EXIST(viStealCar)
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), viStealCar)
VECTOR vPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) // get out of vehicle
SET_ENTITY_COORDS(PLAYER_PED_ID(), vPos)
ENDIF
ENDIF
ENDIF
ENDIF
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
CLEAR_PRINTS()
DELETE_ALL()
ELSE
RELEASE_ALL()
ENDIF
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
IF DOES_CAM_EXIST(camMain)
RENDER_SCRIPT_CAMS(FALSE,FALSE)
DESTROY_CAM(camMain)
ENDIF
ENDPROC
/// PURPOSE:
/// Cleans up mission entities, releases the entity to be cleaned up by population
/// and will give a suitable task to the peds before clean up
PROC Script_Cleanup()
// CLEAR_ADDITIONAL_TEXT(MISSION_DIALOGUE_TEXT_SLOT,TRUE)
SERVICES_TOGGLE(TRUE)
SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(TRUE)
SET_STATS_WATCH_OFF()
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRASH, FALSE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, FALSE)
RELEASE_SCRIPT_AUDIO_BANK()
UNREGISTER_SCRIPT_WITH_AUDIO()
RESET_ALL_BATTLEBUDDY_BEHAVIOUR_REQUESTS()
OPEN_MASK_SHOP_ON_OTHER_PREP()
REMOVE_SCENARIO_BLOCKING_AREA(sibBlocking)
CLEANUP(FALSE)
TERMINATE_THIS_THREAD()
ENDPROC
//***************************************
// :MISSION FLOW FUNC:
//***************************************
//PURPOSE: Advances or reverses the mission stage
PROC NEXT_STAGE( BOOL bReverse = FALSE)
MONITER_UNLOAD_ASSETS(eMissionState)
iMissionState = ENUM_TO_INT(eMissionState)
IF NOT bReverse
eMissionState = INT_TO_ENUM(MISSION_STATE, (iMissionState + 1))
ELSE
IF iMissionState > 0
eMissionState = INT_TO_ENUM(MISSION_STATE, (iMissionState - 1))
ENDIF
ENDIF
bObjectiveShown = FALSE
eState = SS_INIT
ENDPROC
// -----------------------------------------------------------------------------------------------------------
// Script Pass
// -----------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Pass function calls cleanup and termination
/// if the player debug passes this function warps him to the end
/// of the chasem, it will then complete
PROC Script_Passed()
CLEAR_PRINTS()
KILL_ANY_CONVERSATION()
Mission_Flow_Mission_Passed()
Script_Cleanup()
ENDPROC
// -----------------------------------------------------------------------------------------------------------
// Script Fail
// -----------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Waits for the screen to fade out then updates failed reason
PROC FAILED_WAIT_FOR_FADE()
SWITCH eState
CASE SS_INIT
CLEAR_PRINTS()
CLEAR_HELP()
REMOVE_BLIPS()
/* (not supported for story missions atm)
// set if we want to delay the fade
BOOL bDelayFade
bDelayFade = FALSE
IF NOT IS_STRING_NULL_OR_EMPTY(sFailReason)
bDelayFade = TRUE // delay the fade if we failed for one of these reasons
ENDIF
*/
IF NOT IS_STRING_NULL_OR_EMPTY(sFailReason)
MISSION_FLOW_MISSION_FAILED_WITH_REASON(sFailReason)
ELSE
MISSION_FLOW_MISSION_FAILED()
ENDIF
eState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
// 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)
//
DELETE_ALL()
Script_Cleanup()
ELSE
// not finished fading out
// you may want to handle dialogue etc here.
ENDIF
BREAK
ENDSWITCH
ENDPROC
//------------------------------------------------------------------------------------
// MISSION STATES
//------------------------------------------------------------------------------------
/// PURPOSE:
/// Jumps the mission to a specific stage
/// PARAMS:
/// stage - The state to jump to
PROC JUMP_TO_STAGE(MISSION_STATE stage)
RC_START_Z_SKIP()
bJumpSkip = TRUE //Tells the mission stage setup function that we have just jumped and special setup is required
eMissionState = stage
IF eMissionState = MS_SET_UP
#IF IS_DEBUG_BUILD SK_PRINT("eMission state = MSS_SETUP GOING TO INTRO ") #ENDIF
eMissionState = MS_SET_UP
ENDIF
// bLoadingFinCutscene = FALSE
bObjectiveShown = FALSE
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
eState = SS_INIT
CLEANUP() //delete everything
ENDPROC
/// PURPOSE:
/// Fills an new MYPED
/// PARAMS:
/// pos - position the ped is spawned at
/// dir - the heading it faces
/// mod - the model used to create it
/// RETURNS:
/// a newly initialised MYPED
FUNC MYPED FILL_PED(VECTOR pos, FLOAT dir, MODEL_NAMES mod)
MYPED mTempPed
mTempPed.vPos = pos
mTempPed.fDir = dir
mTempPed.Mod = mod
RETURN mTempPed
ENDFUNC
/// PURPOSE:
/// Fills a new MYVEHICLE
/// PARAMS:
/// pos - the position the vehicle is spawned at
/// dir - the heading it faces
/// mod - the model used to create it
/// RETURNS:
/// A newly initialised MYVEHICLE
FUNC MYVEHICLE FILL_VEHICLE(VECTOR pos, FLOAT dir, MODEL_NAMES mod)
MYVEHICLE mTempVeh
mTempVeh.vPos = pos
mTempVeh.fDir = dir
mTempVeh.Mod = mod
RETURN mTempVeh
ENDFUNC
/// PURPOSE:
/// Adds points to a poly
/// PARAMS:
/// polys - The points to be added to the poly
/// count - the number of points to be added to the poly
PROC POPULATE_POLY_CHECKS(VECTOR &polys[], INT count = MAX_POLY_TEST_VERTS)
OPEN_TEST_POLY(mAreaCheck1)
INT i
FOR i = 0 TO (count-1)
ADD_TEST_POLY_VERT(mAreaCheck1, polys[i])
ENDFOR
CLOSE_TEST_POLY(mAreaCheck1)
COPY_EXPANDED_POLY(mAreaCheck2, mAreaCheck1, 50)
ENDPROC
/// PURPOSE:
/// Creates a poly check area using a local array
PROC CREATE_POLY_CHECKS()
VECTOR polys[5]
polys[0] = <<-1138.6897, -1893.3854, 2.4530>>
polys[1] = <<-1067.8933, -1941.2078, 12.1445>>
polys[2] = <<-1062.3744, -2034.3960, 12.1273>>
polys[3] = <<-1178.8055, -2101.6802, 12.3805>>
polys[4] = <<-1250.2238, -2047.0428, 8.9687>>
POPULATE_POLY_CHECKS(polys, 5)
ENDPROC
PROC POPULATE_VEHICLES()
mTowTruck = FILL_VEHICLE(<<-413.2349, -2182.0857, 9.3184>>, 83.9445, TOWTRUCK)
mDressingVeh = FILL_VEHICLE(<<-412.3477, -2176.2617, 9.3184>>, 281.0786, PEYOTE)
mChaseCar = FILL_VEHICLE(<<-386.5059, -2168.7383, 9.3184>>, 87.2085, RUINER)
ENDPROC
PROC POPULATE_PEDS()
mTowGuy = FILL_PED(<<-409.72052, -2175.85815, 9.31836>>, 121.7754, S_M_M_Trucker_01)
ENDPROC
PROC CREATE_RELATIONSHIP_GROUP()
ADD_RELATIONSHIP_GROUP("ENEMY", HASH_ENEMY)
ENDPROC
/// PURPOSE:
/// Initialises all variables and structs
PROC POPULATE_STUFF()
POPULATE_VEHICLES()
POPULATE_PEDS()
CREATE_POLY_CHECKS()
CREATE_RELATIONSHIP_GROUP()
INT i
FOR i=0 TO (MAX_BATTLE_BUDDIES-1)
eBattleBuddyState[i] = BBOS_WAITING
eBattleBuddyBehaviour[i] = BBB_CONTROL
bTurnedOffBaseAnims[i] = FALSE
ENDFOR
ENDPROC
/// PURPOSE:
/// Sets the Game world time after a replay/shit skip
PROC SET_TIME_FOR_REPLAY()
IF g_bShitskipAccepted
ELSE
ENDIF
ENDPROC
///PURPOSE:
/// Initiate the mission and load the things needed
/// for the immediate gameplay
/// The skip menu is initialsed here
/// And if a replay is being done then we init and load assests for the check point
PROC INITMISSION()
SWITCH eState
CASE SS_INIT
//DO_SCREEN_FADE_OUT(0)
// #IF IS_DEBUG_BUILD
// SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE (TRUE)
// #ENDIF
#IF IS_DEBUG_BUILD SK_PRINT("INIT MISSION - THIS WILL LOOP") #ENDIF
IF SETUP_MISSION_STAGE(eMissionState)
#IF IS_DEBUG_BUILD
s_skip_menu[0].sTxtLabel = "MS_STEAL"
s_skip_menu[1].sTxtLabel = "MS_RETURN_WITH_THING"
// s_skip_menu[2].sTxtLabel = "MS_LEAVE_VEHICLE"
#ENDIF
//SERVICES_TOGGLE(FALSE)
SET_MAX_WANTED_LEVEL(2)
SET_WANTED_LEVEL_MULTIPLIER(0.5)
MARK_PREP_START_CAR_AS_VEH_GEN()
INIT_BATTLEBUDDY_BEHAVIOUR_FOR_MISSION(SP_MISSION_FBI_4_PREP_2)
IF IS_REPLAY_IN_PROGRESS()
CLEAR_AREA_OF_VEHICLES(<<-399.8117, -2172.9419, 9.3184>>, 50, FALSE, FALSE, TRUE, TRUE)
CLEAR_AREA_OF_PROJECTILES(<<-399.8117, -2172.9419, 9.3184>>, 50)
JUMP_TO_STAGE(MS_STEAL)
ELSE
IF IS_REPEAT_PLAY_ACTIVE()
SET_PED_POS(PLAYER_PED_ID(), <<-404.3334, -2147.6479, 9.3140>>, 182.5609)
GET_GAMEPLAY_CAM_RELATIVE_HEADING()
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
CLEAR_AREA_OF_VEHICLES(<<-399.8117, -2172.9419, 9.3184>>, 50, FALSE, FALSE, TRUE, TRUE)
WAIT_FOR_WORLD_TO_LOAD(<<-404.3334, -2147.6479, 9.3140>>)
SAFE_FADE_SCREEN_IN_FROM_BLACK()
ENDIF
IF eMissionState = MS_RETURN_WITH_THING
eState = SS_INIT
ELSE
eState = SS_CLEANUP
ENDIF
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
#IF IS_DEBUG_BUILD SK_PRINT("CLEANEDUP INIT MISSION") #ENDIF
NEXT_STAGE()
BREAK
ENDSWITCH
ENDPROC
PROC MONITOR_IN_CAR()
IF IS_VEHICLE_OK(mDressingVeh.id)
IF NOT bPlayerInDressingCar
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mDressingVeh.id)
bPlayerInDressingCar = TRUE
ENDIF
ELSE
IF NOT IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), mDressingVeh.id)
bPlayerInDressingCar = FALSE
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL DOES_BUDDY_NEED_TO_DRIVE_TRUCK(INT i, PED_INDEX hPed)
IF NOT IS_PLAYER_PED_SWITCH_IN_PROGRESS()
IF DOES_ENTITY_EXIST(viStealCar)
AND IS_VEHICLE_DRIVEABLE(viStealCar)
AND NOT IS_ENTITY_AT_COORD(viStealCar, vDropOffLoc, <<2,2,2>>)
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), viStealCar)
AND GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
AND GET_PED_IN_VEHICLE_SEAT(viStealCar, VS_DRIVER) != PLAYER_PED_ID()
IF IS_PED_IN_VEHICLE(hPed, viStealCar)
AND GET_PED_IN_VEHICLE_SEAT(viStealCar, VS_DRIVER) = hPed
#IF IS_DEBUG_BUILD SK_PRINT_INT("Override buddy for driving behaviour = ", i) #ENDIF
eBattleBuddyBehaviour[i] = BBB_DRIVE
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL BATTLE_BUDDIES_DRIVE(INT i, PED_INDEX ped)
SWITCH eBattleBuddyState[i]
CASE BBOS_WAITING
REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(-632.49805, -2424.90771, 1710.12317, -1791.78992)
IF ARE_NODES_LOADED_FOR_AREA(-632.49805, -2424.90771, 1710.12317, -1791.78992)
TASK_VEHICLE_MISSION_COORS_TARGET(ped, GET_VEHICLE_PED_IS_IN(ped), vDropOffLoc, MISSION_GOTO, 20.0, DRIVINGMODE_AVOIDCARS, 2.0, 10.0)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Buddy set to drive to the drop off location = ", i) #ENDIF
eBattleBuddyState[i] = BBOS_DRIVING_TO_PLACE
ENDIF
BREAK
CASE BBOS_DRIVING_TO_PLACE
IF NOT DOES_BUDDY_NEED_TO_DRIVE_TRUCK(i, ped)
OR IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDropOffLoc, 1.5)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Finishing drive to override = ", i) #ENDIF
eBattleBuddyState[i] = BBOS_END
ENDIF
BREAK
CASE BBOS_END
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL IS_OTHER_BUDDY_KILLING_TOWGUY(INT i)
IF i = ENUM_TO_INT(CHAR_MICHAEL)
IF eBattleBuddyBehaviour[ENUM_TO_INT(CHAR_FRANKLIN)] = BBB_KILL
OR eBattleBuddyBehaviour[ENUM_TO_INT(CHAR_TREVOR)] = BBB_KILL
RETURN TRUE
ENDIF
ELIF i = ENUM_TO_INT(CHAR_FRANKLIN)
IF eBattleBuddyBehaviour[ENUM_TO_INT(CHAR_MICHAEL)] = BBB_KILL
OR eBattleBuddyBehaviour[ENUM_TO_INT(CHAR_TREVOR)] = BBB_KILL
RETURN TRUE
ENDIF
ELIF i = ENUM_TO_INT(CHAR_TREVOR)
IF eBattleBuddyBehaviour[ENUM_TO_INT(CHAR_FRANKLIN)] = BBB_KILL
OR eBattleBuddyBehaviour[ENUM_TO_INT(CHAR_MICHAEL)] = BBB_KILL
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SHOULD_BUDDY_KILL_TOW_GUY(INT i, PED_INDEX ped)
IF NOT IS_PLAYER_PED_SWITCH_IN_PROGRESS()
IF IS_PED_UNINJURED(mTowGuy.id)
IF IS_ENTITY_IN_ANGLED_AREA(ped, <<-408.02856, -2175.47583, 5.31836>>, <<-394.64401, -2175.29712, 15.31835>>, 21.52)
AND NOT IS_OTHER_BUDDY_KILLING_TOWGUY(i)
AND NOT IS_PED_IN_MELEE_COMBAT(mTowGuy.id)
AND NOT IS_PED_IN_ANY_VEHICLE(ped)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Set buddy to stealth kill tow guy = ", i) #ENDIF
eBattleBuddyBehaviour[i] = BBB_KILL
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL BATTLE_BUDDY_KILLING_TOW_GUY(INT i, PED_INDEX ped)
VECTOR vPos
VECTOR vOffset = <<0,-1,0>>
IF IS_PED_UNINJURED(mTowGuy.id)
IF IS_PED_IN_MELEE_COMBAT(mTowGuy.id)
RETURN TRUE
ENDIF
SWITCH eBattleBuddyState[i]
CASE BBOS_WAITING
vPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mTowGuy.id, vOffset)
IF NOT IS_POSITION_OCCUPIED(vPos, 1.5, FALSE, FALSE, TRUE, FALSE, FALSE, mTowGuy.id)
IF NOT bBuddySpeech
STRING sConv
IF i = ENUM_TO_INT(CHAR_MICHAEL)
sConv = "FP2_MTAKEDOW"
ELIF i = ENUM_TO_INT(CHAR_FRANKLIN)
sConv = "FP2_FTAKEDOW"
ELIF i = ENUM_TO_INT(CHAR_TREVOR)
sConv = "FP2_TTAKEDOW"
ENDIF
bBuddySpeech = CREATE_CONVERSATION(s_conversation_peds, sTextBlock, sConv, CONV_PRIORITY_MEDIUM)
ELSE
TASK_FOLLOW_NAV_MESH_TO_COORD(ped, vPos, PEDMOVEBLENDRATIO_WALK, DEFAULT_TIME_BEFORE_WARP, DEFAULT_NAVMESH_RADIUS, ENAV_DEFAULT, 82.7989 )
SET_PED_STEALTH_MOVEMENT(ped, TRUE)
IF i = ENUM_TO_INT(CHAR_TREVOR)
GIVE_WEAPON_TO_PED(ped, WEAPONTYPE_KNIFE, -1, TRUE, TRUE)
eBattleBuddyState[i] = BBOS_GO_TO_POSITION_KNIFE
ELSE
GIVE_WEAPON_TO_PED(ped, WEAPONTYPE_UNARMED, -1, TRUE, TRUE)
eBattleBuddyState[i] = BBOS_GO_TO_POSITION
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
BREAK
CASE BBOS_GO_TO_POSITION
vPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mTowGuy.id, vOffset)
IF NOT IsPedPerformingTask(ped, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
AND IS_ENTITY_IN_RANGE_COORDS(ped, vPos, 3)
TASK_STEALTH_KILL(ped, mTowGuy.id, GET_HASH_KEY("AR_stealth_kill_a"), PEDMOVEBLENDRATIO_WALK)
CLEAR_PED_TASKS(mTowGuy.id)
eTowGuyState = TGS_WAIT_GET_DEAD
eBattleBuddyState[i] = BBOS_STEALTH_KILL
ENDIF
BREAK
CASE BBOS_GO_TO_POSITION_KNIFE
vPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mTowGuy.id, vOffset)
IF NOT IsPedPerformingTask(ped, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
AND IS_ENTITY_IN_RANGE_COORDS(ped, vPos, 1.5)
TASK_STEALTH_KILL(ped, mTowGuy.id, GET_HASH_KEY("AR_stealth_kill_knife"), PEDMOVEBLENDRATIO_WALK)
CLEAR_PED_TASKS(mTowGuy.id)
eTowGuyState = TGS_WAIT_GET_DEAD
eBattleBuddyState[i] = BBOS_STEALTH_KILL
ENDIF
BREAK
CASE BBOS_STEALTH_KO
BREAK
CASE BBOS_STEALTH_KILL
BREAK
ENDSWITCH
ELSE
IF NOT IsPedPerformingTask(ped, SCRIPT_TASK_STEALTH_KILL)
// SET_PED_STEALTH_MOVEMENT(ped, FALSE)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC MONITOR_BUDDY_PASSENGER(PED_INDEX hPed, INT i)
IF hPed != PLAYER_PED_ID()
IF NOT bTurnedOffBaseAnims[i]
IF IS_PED_IN_ANY_VEHICLE(hPed)
bTurnedOffBaseAnims[i] = TRUE
SET_PED_CAN_PLAY_AMBIENT_ANIMS(hPed, FALSE)
SET_PED_CAN_PLAY_AMBIENT_BASE_ANIMS(hPed, FALSE)
ENDIF
ELSE
IF NOT IS_PED_IN_ANY_VEHICLE(hPed)
bTurnedOffBaseAnims[i] = FALSE
SET_PED_CAN_PLAY_AMBIENT_ANIMS(hPed, TRUE)
SET_PED_CAN_PLAY_AMBIENT_BASE_ANIMS(hPed, TRUE)
ENDIF
ENDIF
ELSE
IF bTurnedOffBaseAnims[i]
bTurnedOffBaseAnims[i] = FALSE
SET_PED_CAN_PLAY_AMBIENT_ANIMS(hPed, TRUE)
SET_PED_CAN_PLAY_AMBIENT_BASE_ANIMS(hPed, TRUE)
ENDIF
ENDIF
ENDPROC
PROC MONITOR_BATTLE_BUDDIES()
// For each playable character...
enumCharacterList eChar
REPEAT MAX_BATTLE_BUDDIES eChar
PED_INDEX hBuddy = GET_BATTLEBUDDY_PED(eChar)
IF NOT IS_PED_INJURED(hBuddy)
SWITCH eBattleBuddyBehaviour[ENUM_TO_INT(eChar)]
CASE BBB_CONTROL
IF NOT IS_BATTLEBUDDY_OVERRIDDEN(hBuddy)
MONITOR_BUDDY_PASSENGER(hBuddy, ENUM_TO_INT(eChar))
// Does script need to take control of buddy and drive to dest?
IF IS_BATTLEBUDDY_AVAILABLE(hBuddy, FALSE)
IF SHOULD_BUDDY_KILL_TOW_GUY(ENUM_TO_INT(eChar), hBuddy)
OR DOES_BUDDY_NEED_TO_DRIVE_TRUCK(ENUM_TO_INT(eChar), hBuddy)
IF OVERRIDE_BATTLEBUDDY(hBuddy, FALSE)
SET_ENTITY_AS_MISSION_ENTITY(hBuddy, TRUE, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(hBuddy, TRUE)
CLEAR_PED_TASKS(hBuddy)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Buddy Overriden = ", ENUM_TO_INT(eChar)) #ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE BBB_KILL
MONITOR_BUDDY_PASSENGER(hBuddy, ENUM_TO_INT(eChar))
IF BATTLE_BUDDY_KILLING_TOW_GUY(ENUM_TO_INT(eChar), hBuddy)
// AND DOES_ENTITY_BELONG_TO_THIS_SCRIPT(hBuddy)
// Buddy drives truck to destination
#IF IS_DEBUG_BUILD SK_PRINT_INT("Reset battle buddy to controller - BBB_KILL = ", ENUM_TO_INT(eChar)) #ENDIF
eBattleBuddyState[ENUM_TO_INT(eChar)] = BBOS_WAITING
eBattleBuddyBehaviour[ENUM_TO_INT(eChar)] = BBB_CONTROL
RELEASE_BATTLEBUDDY(hBuddy)
ENDIF
BREAK
CASE BBB_DRIVE
MONITOR_BUDDY_PASSENGER(hBuddy, ENUM_TO_INT(eChar))
IF BATTLE_BUDDIES_DRIVE(ENUM_TO_INT(eChar), hBuddy)
// AND DOES_ENTITY_BELONG_TO_THIS_SCRIPT(hBuddy)
// Buddy drives truck to destination
#IF IS_DEBUG_BUILD SK_PRINT_INT("Reset battle buddy to controller - BBB_DRIVE = ", ENUM_TO_INT(eChar)) #ENDIF
eBattleBuddyState[ENUM_TO_INT(eChar)] = BBOS_WAITING
eBattleBuddyBehaviour[ENUM_TO_INT(eChar)] = BBB_CONTROL
RELEASE_BATTLEBUDDY(hBuddy)
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDREPEAT
ENDPROC
PROC STEAL()
MONITOR_IN_CAR()
MONITOR_IN_STEAL_CAR(viStealCar, viAnyTowTruck, eStealCarState, biVehicleBlip, biBlip, vDropOffLoc, mTowTruck.id)
TOW_GUY_STATE()
MONITOR_BATTLE_BUDDIES()
SWITCH eState
CASE SS_INIT
IF SETUP_MISSION_STAGE(eMissionState, bJumpSkip)
PRINT_OBJ("PRB_GOVAN", bObjectiveShown)
#IF IS_DEBUG_BUILD SK_PRINT("INIT STEAL_VAN") #ENDIF
eState = SS_ACTIVE
ENDIF
BREAK
CASE SS_ACTIVE
IF IS_VEHICLE_OK(viStealCar)
IF eStealCarState = ISCM_IN_VEHICLE
OR eStealCarState = ISCM_IN_ANY_VEHICLE
OR eStealCarState = ISCM_IS_TOWING_VEHICLE
REPLAY_RECORD_BACK_FOR_TIME(8.0, 8.0, REPLAY_IMPORTANCE_HIGHEST)
eState = SS_CLEANUP
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
#IF IS_DEBUG_BUILD SK_PRINT("CLEANEDUP STEAL_VAN") #ENDIF
SAFE_REMOVE_BLIP(biVehicleBlip)
NEXT_STAGE()
BREAK
CASE SS_SKIPPED
IF IS_VEHICLE_OK(mTowTruck.id)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), mTowTruck.id)
ENDIF
RC_END_Z_SKIP()
eState = SS_ACTIVE
BREAK
ENDSWITCH
ENDPROC
PROC RELEASE_BATTLE_BUDDIES()
// For each playable character...
enumCharacterList eChar
REPEAT MAX_BATTLE_BUDDIES eChar
PED_INDEX hBuddy = GET_BATTLEBUDDY_PED(eChar)
IF NOT IS_PED_INJURED(hBuddy)
IF IS_BATTLEBUDDY_OVERRIDDEN(hBuddy)
RELEASE_BATTLEBUDDY(hBuddy)
ENDIF
ENDIF
ENDREPEAT
ENDPROC
PROC MONITOR_TOW_GUY_DISTANCE_FOR_CLEANUP()
IF IS_PED_UNINJURED(mTowGuy.id)
AND eTowGuyState <> TGS_ATTACK
IF IS_ENTITY_IN_RANGE_COORDS(mTowGuy.id, vDropOffLoc, 200)
bActivateLoseTowGuy = TRUE
ENDIF
IF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 150)
AND NOT IS_ENTITY_ON_SCREEN(mTowGuy.id)
fTowGuyAtDistance += GET_FRAME_TIME()
IF fTowGuyAtDistance > 10
IF IS_ENTITY_ON_SCREEN(mTowGuy.id)
SAFE_RELEASE_PED(mTowGuy.id, FALSE, TRUE)
SAFE_RELEASE_VEHICLE(mDressingVeh.id)
#IF IS_DEBUG_BUILD SK_PRINT("Releasing tow guy and vehicle is OnScreen Greater than 10s away") #ENDIF
ELSE
SAFE_DELETE_PED(mTowGuy.id)
SAFE_DELETE_VEHICLE(mDressingVeh.id)
#IF IS_DEBUG_BUILD SK_PRINT("Deleting tow guy and vehicle not OnScreen Greater than 10s away") #ENDIF
ENDIF
EXIT
ELSE
#IF IS_DEBUG_BUILD SK_PRINT_FLOAT("fTowGuyAtDistance += GET_FRAME_TIME() ==== ", fTowGuyAtDistance) #ENDIF
ENDIF
ELIF NOT IS_ENTITY_IN_RANGE_ENTITY(mTowGuy.id, PLAYER_PED_ID(), 200)
IF IS_ENTITY_ON_SCREEN(mTowGuy.id)
SAFE_RELEASE_PED(mTowGuy.id, FALSE, TRUE)
SAFE_RELEASE_VEHICLE(mDressingVeh.id)
#IF IS_DEBUG_BUILD SK_PRINT("Releasing tow guy and vehicle is OnScreen Greater than 200m away") #ENDIF
ELSE
SAFE_DELETE_PED(mTowGuy.id)
SAFE_DELETE_VEHICLE(mDressingVeh.id)
#IF IS_DEBUG_BUILD SK_PRINT("Deleting tow guy and vehicle not OnScreen Greater than 200m away") #ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC MONITOR_END_MISSION_VEH()
IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDropOffLoc, 220)
IF NOT bSpawnedEndMissionVeh
AND NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDropOffLoc, 100)
bSpawnedEndMissionVeh = SPAWN_VEHICLE(viLastCar, SADLER, <<1370.9122, -2060.0549, 50.9983>>, 312.8686)
ENDIF
ELIF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDropOffLoc, 240)
IF bSpawnedEndMissionVeh
SAFE_RELEASE_VEHICLE(viLastCar)
bSpawnedEndMissionVeh = FALSE
ENDIF
ENDIF
ENDPROC
PROC RETURN_THING()
MONITOR_TOW_GUY_DISTANCE_FOR_CLEANUP()
MONITOR_IN_STEAL_CAR(viStealCar, viAnyTowTruck, eStealCarState, biVehicleBlip, biBlip, vDropOffLoc, mTowTruck.id, FALSE, 11.0)
MONITOR_END_MISSION_VEH()
TOW_GUY_STATE()
SWITCH eState
CASE SS_INIT
IF SETUP_MISSION_STAGE(eMissionState, bJumpSkip)
#IF IS_DEBUG_BUILD SK_PRINT("INIT TAKE_VAN_BACK") #ENDIF
ADD_BLIP_LOCATION(biBlip, vDropOffLoc)
SERVICES_TOGGLE(TRUE)
eState = SS_ACTIVE
ENDIF
BREAK
CASE SS_ACTIVE
MONITER_PLAYER_WANTED(biBlip, vDropOffLoc, eCopMonitor, eStealCarState, bObjectiveShown, bExpireReturnVehWanted)
MONITOR_BATTLE_BUDDIES()
IF NOT bActivateLoseTowGuy
IF RETURN_STOLEN_VEHICLE(viStealCar, vDropOffLoc, biBlip, eCopMonitor, eStealCarState, bObjectiveShown, bExpireReturnVeh, FALSE, FALSE, 11.0)
eState = SS_CLEANUP
ENDIF
ELSE
IF NOT bExpireLoseTowGuy
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF IS_PED_UNINJURED(mTowGuy.id)
IF IS_PLAYER_TOWING_VEHICLE(GET_VEHICLE_PED_IS_IN(mTowGuy.id))
ADD_SAFE_BLIP_TO_VEHICLE(mTowGuy.mAIBlip.VehicleBlipID, mTowTruck.id)
ENDIF
ENDIF
PRINT_NOW("PRB_LOSETOW", DEFAULT_GOD_TEXT_TIME, 0)
SAFE_REMOVE_BLIP(biBlip)
bExpireLoseTowGuy = TRUE
ENDIF
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
#IF IS_DEBUG_BUILD SK_PRINT("CLEANEDUP TAKE_VAN_BACK") #ENDIF
RELEASE_BATTLE_BUDDIES()
SAFE_REMOVE_BLIP(biBlip)
SAFE_REMOVE_BLIP(biVehicleBlip)
IF STOP_MY_VEHICLE()
IF IS_VEHICLE_OK(viStealCar)
NEXT_STAGE()
ENDIF
ENDIF
BREAK
CASE SS_SKIPPED
IF IS_VEHICLE_OK(viStealCar)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), viStealCar)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), viStealCar)
ELSE
SAFE_TELEPORT_ENTITY(viStealCar, vDropOffLoc, 146.5443)
RC_END_Z_SKIP()
eState = SS_ACTIVE
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC LEAVE_VEHICLE()
MONITOR_IN_STEAL_CAR(viStealCar, viAnyTowTruck, eStealCarState, biVehicleBlip, biBlip, vDropOffLoc, mTowTruck.id, FALSE, 11.0)
SWITCH eState
CASE SS_INIT
IF SETUP_MISSION_STAGE(eMissionState, bJumpSkip)
#IF IS_DEBUG_BUILD SK_PRINT("INIT LEAVE_RING_LESTER") #ENDIF
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
IF IS_VEHICLE_OK(viStealCar)
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), viStealCar)
PRINT_OBJ("PRB_LEVVEH", bObjectiveShown)
ENDIF
ENDIF
ENDIF
eState = SS_ACTIVE
ENDIF
BREAK
CASE SS_ACTIVE
MONITER_PLAYER_WANTED(biBlip, vDropOffLoc, eCopMonitor, eStealCarState, bObjectiveShown, bExpireReturnVehWanted)
IF LEAVE_VEHICLE_STEAL(viStealCar, vDropOffLoc, biBlip, eStealCarState, eCopMonitor, bForceStop, bExpireReturnVeh, iCallTimerDelay, bCallTimer, bObjectiveShown, 11.0)
IF NOT IS_FIB4_AVAILABLE_AFTER_PASSED()
IF UPDATE_PHONE_STATES(ePhoneCallState, sPhoneUpdateString, s_conversation_peds)
IF IS_ENTITY_ALIVE(GET_ENTITY_ATTACHED_TO_TOW_TRUCK(viStealCar))
DETACH_VEHICLE_FROM_ANY_TOW_TRUCK(GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_ATTACHED_TO_TOW_TRUCK(viStealCar)))
ENDIF
SET_STATS_WATCH_OFF()
Script_Passed()
ENDIF
ELSE
IF IS_ENTITY_ALIVE(GET_ENTITY_ATTACHED_TO_TOW_TRUCK(viStealCar))
DETACH_VEHICLE_FROM_ANY_TOW_TRUCK(GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_ATTACHED_TO_TOW_TRUCK(viStealCar)))
ENDIF
SET_STATS_WATCH_OFF()
REPLAY_RECORD_BACK_FOR_TIME(8.0, 8.0, REPLAY_IMPORTANCE_HIGHEST)
NEXT_STAGE()
ENDIF
ENDIF
BREAK
CASE SS_SKIPPED
IF IS_VEHICLE_OK(mTowTruck.id)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mTowTruck.id)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), mTowTruck.id)
ELSE
SAFE_TELEPORT_ENTITY(mTowTruck.id, vDropOffLoc, 126.0705)
RC_END_Z_SKIP()
eState = SS_ACTIVE
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
FUNC CC_CommID GET_CHAR_END_MISSION_CONV(enumCharacterList ePlayer)
IF ePlayer = CHAR_FRANKLIN
RETURN CALL_FIB4_P2_F_DONE
ENDIF
RETURN CALL_FIB4_P2_T_DONE
ENDFUNC
FUNC enumCharacterList GET_WHO_TO_PHONE(enumCharacterList ePlayer)
IF ePlayer = CHAR_FRANKLIN
RETURN CHAR_MIKE_TREV_CONF
ENDIF
RETURN CHAR_MIKE_FRANK_CONF
ENDFUNC
PROC LEAVE_AREA()
SWITCH eState
CASE SS_INIT
#IF IS_DEBUG_BUILD SK_PRINT("INIT LEAVE_AREA") #ENDIF
eState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDropOffLoc, 270)
eState = SS_CLEANUP
ELSE
IF NOT IS_THIS_PRINT_BEING_DISPLAYED("PRB_LEVAREA")
PRINT_NOW("PRB_LEVAREA", 60000, 0)
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
#IF IS_DEBUG_BUILD SK_PRINT("CLEANEDUP LEAVE_AREA") #ENDIF
enumCharacterList ePlayer
ePlayer = GET_CURRENT_PLAYER_PED_ENUM()
IF IS_THIS_PRINT_BEING_DISPLAYED("PRB_LEVAREA")
CLEAR_PRINTS()
ENDIF
IF ePlayer = CHAR_MICHAEL
IF UPDATE_PHONE_STATES(ePhoneCallState, sPhoneUpdateString, s_conversation_peds)
SET_STATS_WATCH_OFF()
Script_Passed()
ENDIF
ELSE
SET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_MISSION_FBI_4_UNLOCKED_FROM_PREP, TRUE)
REGISTER_BRANCHED_CALL_FROM_PLAYER_TO_CHARACTER(GET_CHAR_END_MISSION_CONV(ePlayer), CALL_FIB4_GO_TIME, CALL_FIB4_GO_TIME, FLOW_CHECK_FBI4_PREP3, CT_END_OF_MISSION, ePlayer, GET_WHO_TO_PHONE(ePlayer), 0, CC_END_OF_MISSION_QUEUE_TIME, CC_END_OF_MISSION_QUEUE_TIME)
SET_STATS_WATCH_OFF()
Script_Passed()
ENDIF
BREAK
CASE SS_SKIPPED
RC_END_Z_SKIP()
eState = SS_CLEANUP
BREAK
ENDSWITCH
ENDPROC
///DEBUG KEYS
#IF IS_DEBUG_BUILD
/// PURPOSE: Check for Forced Pass or Fail
PROC DEBUG_Check_Debug_Keys()
// Check for Pass
IF eState = SS_ACTIVE
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S))
KILL_ANY_CONVERSATION()
CLEAR_PRINTS()
WAIT_FOR_CUTSCENE_TO_STOP()
Script_Passed()
ENDIF
// Check for Fail
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F))
KILL_ANY_CONVERSATION()
CLEAR_PRINTS()
WAIT_FOR_CUTSCENE_TO_STOP()
MISSION_FAILED(FR_NONE)
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J))
KILL_ANY_CONVERSATION()
CLEAR_PRINTS()
WAIT_FOR_CUTSCENE_TO_STOP()
RC_START_Z_SKIP()
eState = SS_SKIPPED
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P))
AND eMissionState <> MS_SET_UP
//Work out which stage we want to reach based on the current stage
iMissionState = ENUM_TO_INT(eMissionState)
IF iMissionState > 0
MISSION_STATE e_stage = INT_TO_ENUM(MISSION_STATE, iMissionState - 1)
JUMP_TO_STAGE(e_stage)
ENDIF
ENDIF
IF LAUNCH_MISSION_STAGE_MENU(s_skip_menu, i_debug_jump_stage)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Z DEBUG Initial pick = ", i_debug_jump_stage) #ENDIF
i_debug_jump_stage++
SK_PRINT_INT("Z DEBUG ACTUAL STATE = ", i_debug_jump_stage)
MISSION_STATE e_stage = INT_TO_ENUM(MISSION_STATE, i_debug_jump_stage)
JUMP_TO_STAGE(e_stage)
ENDIF
ENDIF
ENDPROC
#ENDIF
PROC MONITER_STEAL_CAR()
INT iCountOutOfRange = 0
IF NOT IS_VEHICLE_OK(viStealCar)
IF NOT IS_VEHICLE_OK(viAnyTowTruck)
AND NOT IS_VEHICLE_OK(mTowTruck.id)
MISSION_FAILED(FR_WRECKED_STEAL_CAR)
EXIT
ENDIF
IF IS_VEHICLE_OK(mTowTruck.id)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mTowTruck.id, 500)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Player out of range of the Tow truck out of range count = ", iCountOutOfRange) #ENDIF
iCountOutOfRange++
ENDIF
ELSE
iCountOutOfRange++
#IF IS_DEBUG_BUILD SK_PRINT_INT("Tow truck doesnt exits out of range count = ", iCountOutOfRange) #ENDIF
ENDIF
IF IS_VEHICLE_OK(viAnyTowTruck)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), viAnyTowTruck, 500)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Player out of range of the the other Tow truck out of range count = ", iCountOutOfRange) #ENDIF
iCountOutOfRange++
ENDIF
ELSE
iCountOutOfRange++
// #IF IS_DEBUG_BUILD SK_PRINT_INT("other Tow truck doesnt exist out of range count = ", iCountOutOfRange) #ENDIF
ENDIF
IF iCountOutOfRange >= 2
IF eMissionState != MS_LEAVE_AREA // B*1902549 - don't fail for leaving the taxi in the correct place when you are in leave area state
MISSION_FAILED(FR_ABAN_CAR)
EXIT
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("blocking fail for aban trucks this frame because we are in leave area state") #ENDIF
ENDIF
ENDIF
ELSE
IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), viStealCar, 500)
iCountOutOfRange++
#IF IS_DEBUG_BUILD SK_PRINT_INT("Player out of range of the steal car out of range count = ", iCountOutOfRange) #ENDIF
ENDIF
IF IS_VEHICLE_OK(viAnyTowTruck)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), viAnyTowTruck, 500)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Player out of range of the the other Tow truck out of range count = ", iCountOutOfRange) #ENDIF
iCountOutOfRange++
ENDIF
ELSE
iCountOutOfRange++
// #IF IS_DEBUG_BUILD SK_PRINT_INT("other Tow truck doesnt exist out of range count = ", iCountOutOfRange) #ENDIF
ENDIF
IF IS_VEHICLE_OK(mTowTruck.id)
IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mTowTruck.id, 500)
#IF IS_DEBUG_BUILD SK_PRINT_INT("Player out of range of the Tow truck out of range count = ", iCountOutOfRange) #ENDIF
iCountOutOfRange++
ENDIF
ELSE
iCountOutOfRange++
#IF IS_DEBUG_BUILD SK_PRINT_INT("Tow truck doesnt exits out of range count = ", iCountOutOfRange) #ENDIF
ENDIF
IF iCountOutOfRange >= 3
IF eMissionState != MS_LEAVE_AREA // B*1902549 - don't fail for leaving the taxi in the correct place when you are in leave area state
MISSION_FAILED(FR_ABAN_CAR)
EXIT
ELSE
#IF IS_DEBUG_BUILD SK_PRINT("blocking fail for aban trucks this frame because we are in leave area state") #ENDIF
ENDIF
ENDIF
iCountOutOfRange = 0
IF IS_CAR_STUCK(viStealCar)
iCountOutOfRange++
ENDIF
IF IS_VEHICLE_OK(viAnyTowTruck)
IF IS_CAR_STUCK(viAnyTowTruck)
#IF IS_DEBUG_BUILD SK_PRINT_INT("vehicle stuck viAnyTowTruck", iCountOutOfRange) #ENDIF
iCountOutOfRange++
ENDIF
ELSE
iCountOutOfRange++
ENDIF
IF IS_VEHICLE_OK(mTowTruck.id)
IF IS_CAR_STUCK(mTowTruck.id)
#IF IS_DEBUG_BUILD SK_PRINT_INT("vehicle stuck mTowTruck" , iCountOutOfRange) #ENDIF
iCountOutOfRange++
ENDIF
ELSE
iCountOutOfRange++
ENDIF
IF iCountOutOfRange >= 3
#IF IS_DEBUG_BUILD SK_PRINT_INT("vehicle stuck All ", iCountOutOfRange) #ENDIF
MISSION_FAILED(FR_STUCK_CAR)
EXIT
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Holds functions that moniter for the player failing
PROC CHECK_FOR_FAIL()
IF NOT bJumpSkip
AND eMissionState <> MS_FAILED
IF eMissionState > MS_SET_UP
MONITER_STEAL_CAR()
ENDIF
ENDIF
ENDPROC
SCRIPT
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))
PRINTSTRING("FORCE CLEAN UP") PRINTNL()
sFailReason = NULL
Mission_Flow_Mission_Force_Cleanup()
Script_Cleanup()
ENDIF
#IF IS_DEBUG_BUILD
SETUP_FOR_RAGE_WIDGETS()
#ENDIF
POPULATE_STUFF()
REGISTER_SCRIPT_WITH_AUDIO()
IF IS_REPLAY_IN_PROGRESS()
START_REPLAY_SETUP(<<-404.3334, -2147.6479, 9.3140>>, 182.5609)
ENDIF
CLOSE_MASK_SHOP_ON_OTHER_PREP()
// Loop within here until the mission passes or fails
WHILE(TRUE)
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("M_ToT")
IF IS_PED_UNINJURED(PLAYER_PED_ID())
CHECK_FOR_FAIL()
MONITER_STATS()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
SWITCH eMissionState
CASE MS_SET_UP
INITMISSION()
BREAK
CASE MS_STEAL
STEAL()
BREAK
CASE MS_RETURN_WITH_THING
RETURN_THING()
BREAK
CASE MS_LEAVE_VEHICLE
LEAVE_VEHICLE()
BREAK
CASE MS_LEAVE_AREA
LEAVE_AREA()
BREAK
CASE MS_FAILED
FAILED_WAIT_FOR_FADE()
BREAK
ENDSWITCH
IF eMissionState <> MS_FAILED
IF eMissionState >= MS_SET_UP
AND NOT bJumpSkip
ENDIF
#IF IS_DEBUG_BUILD
// Check debug completion/failure
DEBUG_Check_Debug_Keys()
UPDATE_RAG_WIDGETS()
#ENDIF
ENDIF
ENDIF
WAIT(0)
ENDWHILE
// Script should never reach here. Always terminate with cleanup function.
ENDSCRIPT