-- dlc02.lua
-- SR2 mission script
-- 9/04/08

--[[ *** NOTES ***

]]

	-- DEBUG FLAGS --
	DEBUG_APC_WEAPONS = false
	DEBUG_SKIP_HIJACKING = false
	DEBUG_AIRPORT_JUMP = false
	DEBUG_DISABLE_ATTACK_HELIS = false

	-- KNOBS_TO_TURN --

			--[[ *** READ ME ***
			
            Mission paramaters likely to be tweaked are stored in the table below. A simple naming convention is used so that
            different values can be automatically used in coop and single-player games.

				Parameter values for single player missions can use any name, say "PARAMETER_1" for example. If you wish to have
				a different value for that parameter in coop, then prepend "COOP" to the parameter name. In this case, we get
				"COOP_PARAMETER_1".

				When a mission function needs to access "PARAMETER_1", the value is looked up as follows:

					*	Single player games will use the value stored in "PARAMETER_1".
				
					*	Coop games will use the value stored in "COOP_PARAMETER_1", if it exists. Otherwise it will use the
						default single player value stored in "PARAMETER_1".
			 ]]

			-- Mission parameters
			DLC02_PARAMETERS	= 
         {		
            -- single-player values
               ["FLATBED_HIJACK_HP_MULTIPLIER"]		= 0.5,	-- Factor applied to the flatbed's hp
               ["FLATBED_MAX_SPEED_INITIAL"]			= 50,		-- Flatbed's max speed at the start of its path.
               ["FLATBED_MAX_SPEED_DAMAGED"]			= 70,		-- Flatbed's max speed after it takes damage.
               ["FLATBED_OUT_OF_RANGE_SPEED_RATIO"] = .6,	-- Flatbed travels at this portion of max speed if players out of range.
               ["FLATBED_OUT_OF_RANGE_DIST_M"]		= 50,		-- Distance at which above ratio is applied.
               ["FLATBED_DISABLED_HEALTH_PERCENT"] = .3,		-- Flatbed stops for hijacking at this point
					["FLATBED_ATTACK_DIST_M"]				= 100,	-- Distance from flatbed at which escorts can attack a target.

               ["FLATBED_TURRET_HP_MULTIPLIER"] = 4.25,      -- Factor applied to the turret flatbed's hp
               ["FLATBED_TURRET_NOTORIETY"] = 3,            -- Notoriety during the flatbed turret sequence
               ["FLATBED_TURRET_DESIRED_POLICE_VEHICLES"] = 4, -- Desired # notoriety vehicles during chase.

               ["CHASE_HELI_HP_MULTIPLIER"]				 = 0.7,	-- Applied to the attack helicopter's max hit points.            

               ["CHASE_VEHICLE_HP_MULTIPLIER"]			= 1.5,	-- Applied to the APC's max hit points.
               ["APC_MAX_SPEED"]							   = 90,		-- Max speed of the APC

            -- coop values
               --["COOP_BODY1_PICKUP_MIN_NOTORIEYT"]	= 1,	-- Min Police notoriety after body 1 pickup
         }

-- Global constants (All caps == GLOBAL CONSTANT)
--	(In general, these shouldn't be modified in running code, except for maybe in the setup function )

	-- Coop mission?
		IN_COOP	= false

	-- GROUPS --
	
		GROUP_FLATBED_HIJACK =				"dlc02_$Gflatbed_hijack"
		GROUP_FLATBED_HIJACK_ESCORT =		"dlc02_$Gflatbed_escort"
		GROUP_FLATBED_TURRET =				"dlc02_$Gflatbed_turret"
		GROUP_COURTESY	=						"dlc02_$Gcourtesy"
		GROUP_TERA =							"dlc02_$Gtera"
		GROUP_EDF =								"dlc02_$Gapc"
		GROUP_HELI =							"dlc02_$Gattack_heli"

	-- TRIGGERS -- 

		-- List of all triggers, makes cleaning up more convenient
		TABLE_ALL_TRIGGERS				= { }		

	-- VEHICLES --

		-- The flatbed used for the hijacking
		VEH_FLATBED_HIJACK = "dlc02_$Vflatbed_hijack"

		-- The flatbed that the player stands on to defend
		VEH_FLATBED_TURRET = "dlc02_$Vflatbed_turret"

		-- The Attack Helicopter
		VEH_HELI = "dlc02_$Vheli"

	-- CHARACTERS --

		CHAR_TERA = "dlc02_$Ctera"

		CHAR_FLATBED_DRIVER = "dlc02_$Cflatbed_driver"
		CHAR_FLATBED_PASSENGER = "dlc02_$Cflatbed_passenger"

		CHAR_HELI_PILOT = "dlc02_$Cheli_pilot"

	-- CONVERSATIONS

	-- CHECKPOINTS --
		CHECKPOINT_START					= MISSION_START_CHECKPOINT		-- defined in ug_lib.lua
		CHECKPOINT_TURRET					= "dlc02_checkpoint_turret"

	-- NAVPOINTS

		-- Start locations
		NAVP_LOCAL_PLAYER_START		= "dlc02_$Nlocal_start"
		NAVP_REMOTE_PLAYER_START	= "dlc02_$Nremote_start"
		
		-- If the flatbed gets to the end of the scripted path, it takes an exit marked by this navpoint
		NAVP_FLATBED_STAGE_1_EXIT_RAMP = "dlc02_$Nexit_ramp"

		-- Navpoints that players/Pierce are teleported to before starting the turret portion of the mission
		NAVP_TURRET_STAGING_1 = "dlc02_$Nturret_staging_1"
		NAVP_TURRET_STAGING_2 = "dlc02_$Nturret_staging_2"
		NAVP_TURRET_STAGING_3 = "dlc02_$Nturret_staging_3"

		-- The first point that the APC drives to when entering the highway from the on ramp.
		NAVP_APC_GOAL = "dlc02_$Napc_goal"

		-- Locations at which attack helis can spawn
		ATTACK_HELI_SPAWN_LOCATIONS = 
		{
			"dlc02_$n046", "dlc02_$n047", "dlc02_$n048", "dlc02_$n049", "dlc02_$n050",
			"dlc02_$n051", "dlc02_$n052", "dlc02_$n053", "dlc02_$n054", "dlc02_$n055", 
			"dlc02_$n056", "dlc02_$n057", "dlc02_$n058", "dlc02_$n059", "dlc02_$n060",
			"dlc02_$n061", "dlc02_$n062", "dlc02_$n063", "dlc02_$n064", "dlc02_$n065",
			"dlc02_$n066", "dlc02_$n067", "dlc02_$n068", "dlc02_$n069", "dlc02_$n070",
			"dlc02_$n071", "dlc02_$n072", "dlc02_$n073", "dlc02_$n074", "dlc02_$n075",
			"dlc02_$n076", "dlc02_$n077", "dlc02_$n078", "dlc02_$n079", "dlc02_$n080",
			"dlc02_$n081"}

		-- Paths followed by the attack helis when chasing the turret flatbed.
		ATTACK_HELI_CHASE_PATHS = 
		{"dlc02_$Pheli_chase_1", "dlc02_$Pheli_chase_2", "dlc02_$Pheli_chase_3",
		"dlc02_$Pheli_chase_4", "dlc02_$Pheli_chase_5", "dlc02_$Pheli_chase_6",
		"dlc02_$Pheli_chase_7", "dlc02_$Pheli_chase_8", "dlc02_$Pheli_chase_9",
		"dlc02_$Pheli_chase_10", "dlc02_$Pheli_chase_11", "dlc02_$Pheli_chase_12",
		"dlc02_$Pheli_chase_13", "dlc02_$Pheli_chase_14", "dlc02_$Pheli_chase_15",
		"dlc02_$Pheli_chase_16", "dlc02_$Pheli_chase_17", "dlc02_$Pheli_chase_18"}

		-- Paths followed by the attack helis when beginning to chase the turret flatbed.
		ATTACK_HELI_APPROACH_PATHS = 
		{"dlc02_$Pheli_approach_1", "dlc02_$Pheli_approach_2", "dlc02_$Pheli_approach_3",
		"dlc02_$Pheli_approach_4", "dlc02_$Pheli_approach_5", "dlc02_$Pheli_approach_6",
		"dlc02_$Pheli_approach_7", "dlc02_$Pheli_approach_8", "dlc02_$Pheli_approach_9",
		"dlc02_$Pheli_approach_10", "dlc02_$Pheli_approach_11", "dlc02_$Pheli_approach_12",
		"dlc02_$Pheli_approach_13", "dlc02_$Pheli_approach_14", "dlc02_$Pheli_approach_15",
		"dlc02_$Pheli_approach_16", "dlc02_$Pheli_approach_17", "dlc02_$Pheli_approach_18"}

		-- Attack heli spawn navpoints
		ATTACK_HELI_SPAWN_POINTS =
		{"dlc02_$n124", "dlc02_$n130", "dlc02_$n141",
		"dlc02_$n153", "dlc02_$n338", "dlc02_$n333",
		"dlc02_$n326", "dlc02_$n320", "dlc02_$n314",
		"dlc02_$n309", "dlc02_$n304", "dlc02_$n298",
		"dlc02_$n293", "dlc02_$n287", "dlc02_$n283",
		"dlc02_$n277", "dlc02_$n273", "dlc02_$n268"}

		-- Success teleport destinations		
		NAVP_LOCAL_SUCCESS				= NAVP_LOCAL_PLAYER_START -- teleport nav for the end of the mission
		NAVP_REMOTE_SUCCESS				= NAVP_REMOTE_PLAYER_START -- teleport nav for the end of the mission

		-- The end of the hijack path.
		NAVP_HIJACK_DEST					= "dlc02_$n018"

	-- MOVERS

	-- HELPTEXT MESSAGES
		TEXT_HUD_TRUCK_HEALTH_LABEL	= "bh06_parcel_truck_health" -- Truck:

		TEXT_PROMPT_HIJACK_TRUCK		= "MSN_DLC02_PROMPT_HIJACK_TRUCK" -- Stop the truck without destroying it.
		TEXT_PROMPT_PROTECT_TRUCK		= "MSN_DLC02_PROMPT_PROTECT_TRUCK" -- Protect the truck
		TEXT_PROMPT_APC					= "MSN_DLC02_PROMPT_APC" -- Destroy the apc
		TEXT_PROMPT_GO_TO_TRUCK			= "MSN_DLC02_PROMPT_DRIVE_TO_TRUCK"
		TEXT_PROMPT_TRUCK_APPROACHING = "MSN_DLC02_PROMPT_TRUCK_APPROACHING"
		
		TEXT_FAIL_FLATBED_DESTROYED	= "MSN_DLC02_FAIL_FLATBED_DESTROYED" -- Flatbed truck destroyed
		TEXT_FAIL_FLATBED_ESCAPED		= "MSN_DLC02_FAIL_FLATBED_ESCAPED" -- Flatbed truck escaped
		TEXT_FAIL_TERA_DIED				= "MSN_DLC03_FAIL_TERA_DIED"		-- "Tera died."
		TEXT_FAIL_TERA_ABANDONED		= "MSN_DLC02_FAIL_TERA_ABANDONED" -- "Tera was abandoned."

	-- MISC CONSTANTS
		HELI_HEALTH_MULTIPLIER = .8
		PATH_FLATBED_HIJACK = 
		{	
			{	"dlc02_$n000", "dlc02_$n001", "dlc02_$n002", "dlc02_$n003", "dlc02_$n004"	},
			{	"dlc02_$n005", "dlc02_$n006", "dlc02_$n007", "dlc02_$n008", "dlc02_$n009"	},
			{	"dlc02_$n010", "dlc02_$n011", "dlc02_$n012", "dlc02_$n013", "dlc02_$n014"	},
			{	"dlc02_$n015", "dlc02_$n016", "dlc02_$n017", "dlc02_$n018"},
		}

		PATH_FLATBED_AIRPORT = 
		{	
			"dlc02_$path_flatbed_turret_1",
			"dlc02_$path_flatbed_turret_2",
			"dlc02_$path_flatbed_turret_3",
			"dlc02_$path_flatbed_turret_4",
			"dlc02_$path_flatbed_turret_5",
			"dlc02_$path_flatbed_turret_6",
		}

		PATH_FLATBED_AIRPORT_RUNWAY = 
		{	"dlc02_$n094", "dlc02_$n095", "dlc02_$n096", "dlc02_$n097" }


		FLATBED_ESCORT	=	
		{	
			["dlc02_$v000"]	=	{"dlc02_$c000", "dlc02_$c001"},
			["dlc02_$v001"]	=	{"dlc02_$c002", "dlc02_$c003"}
		}

		PLAYER_SYNC								=
		{
			[LOCAL_PLAYER]					= SYNC_LOCAL,
			[REMOTE_PLAYER]				= SYNC_REMOTE,
		}

		OTHER_PLAYER							=
		{
			[LOCAL_PLAYER]					= REMOTE_PLAYER,
			[REMOTE_PLAYER]				= LOCAL_PLAYER,
		}

		EDF_CHASES =
		{
			{	
				["vehicle"	]	=	"dlc02_$Vapc",
				["passengers"]	= {	"dlc02_$Capc_driver", "dlc02_$Capc_passenger"}, 
				["chase start"] = "dlc02_$Napc_goal",
				["spline start"] = true,
				["trigger"] = "dlc02_$Tedf_chase_1",
			},
			{	
				["vehicle"	]	=	"dlc02_$v004",
				["passengers"]	= {	"dlc02_$c005", "dlc02_$c006"}, 
				["jump speed"] = 50,
				["chase start"] = "dlc02_$n083",
				["trigger"] = "dlc02_$Tedf_chase_2",
			},
			{	
				["vehicle"	]	=	"dlc02_$v005",
				["passengers"]	= {	"dlc02_$c007", "dlc02_$c008"}, 
				["jump speed"] = 30,
				["chase start"] = "dlc02_$n093",
				["trigger"] = "dlc02_$Tedf_chase_3",
			},
		}

		
		TRUCK_SPOTTED_CONVERSATION =
		{
			-- There's the chemical truck!
			{ "TERA_DLC02_SPOTTRUCK", CHAR_TERA, 0.0 },
			-- Alright, let's take it.
			{ "PLAYER_DLC02_SPOTTRUCK", LOCAL_PLAYER, 0.0 },
		}

		-- Alright, get in the back and cover us�Ultor isn't going to like losing a shipment.
		TRUCK_STOPPED_LINE = "TERA_DLC02_TRUCKSTOPPED"
				
		SCOUT_CONVERSATION = 
		{
			-- The fuck is that thing?
			{ "PLAYER_DLC02_SEESCOUT", LOCAL_PLAYER, 0.0 },
			-- Jesus, they sent the Scout Protoype?  They're not messing around�
			{ "TERA_DLC02_SCOUTCONVO_01", CHAR_TERA, 0.0 },
			-- "Scout Protoype"? What the hell are you talkin' about?
			{ "PLAYER_DLC02_SCOUT_01", LOCAL_PLAYER, 0.0 },
			-- It's Eric Gryphon's pet project�he wanted an ATV to scout for prime mining locations.
			{ "TERA_DLC02_SCOUTCONVO_02", CHAR_TERA, 0.0 },
			-- Why does a mining vehicle need a goddamn turret?
			{ "PLAYER_DLC02_SCOUT_02", LOCAL_PLAYER, 0.0 },
			-- You gotta blast through rock, makes sense to me�
			{ "TERA_DLC02_SCOUTCONVO_03", CHAR_TERA, 0.0 },
		   -- Where the hell are you people planning on mining?
			{ "PLAYER_DLC02_SCOUT_03", LOCAL_PLAYER, 0.0  },
			-- Trust me, you wouldn't believe me if I told you.
			{ "TERA_DLC02_SCOUTCONVO_04", CHAR_TERA, 0.0 },
		}
		
		TERA_AIRPORT_LINES = 
		{
			-- Let's stash this thing at the airport until we get a hold of Jane.
			"TERA_DLC02_STARTDRIVING",
			-- We're almost there�just buy us a little more time�
			"TERA_DLC02_ALMOSTTHERE",
		}

		TERA_CHATTER_LINES = 
		{
			-- They're every where!
			"TERA_DLC02_CHATTER_09",
			-- Don't these people ever give up?
			"TERA_DLC02_CHATTER_10",
		}
		
		TERA_TRUCK_DAMAGE = 
		{
			num_items = 4,
			
			-- You gotta keep these guys off of us!
			{ 0.75, "TERA_DLC02_TRUCK75" }, 
			-- What are you doing back there!
			{ 0.50, "TERA_DLC02_TRUCK50" },
			-- This is not good�
			{ 0.25, "TERA_DLC02_TRUCK25" },
			-- We're not going to make it!
			{ 0.10, "TERA_DLC02_TRUCK10" },		
		}
		
		Truck_damaged_during_hijack_lines = {
			num_items = 4,
			[1] = { threshold = 0.95, played = false, line_played = -1 },
			[2] = { threshold = 0.80, played = false, line_played = -1 },
			[3] = { threshold = 0.60, played = false, line_played = -1 },
			[4] = { threshold = 0.45, played = false, line_played = -1 },			
				
			text = { 
				num_lines = 8,
				
				-- We're gonna pull this off, I know it�
				[1] = "TERA_DLC02_CHATTER_02",
				-- Ultor's never gonna see this comin'�
				[2] =	"TERA_DLC02_CHATTER_03",
				-- You're doin' great!
				[3] = "TERA_DLC02_CHATTER_04",
	 			-- Keep it up!
				[4] = "TERA_DLC02_CHATTER_05",
				-- They don't have a chance!
				[5] = "TERA_DLC02_CHATTER_06",
				-- We're gonna expose these assholes�
				[6] = "TERA_DLC02_CHATTER_07",
				-- Don't stop shooting!
				[7] = "TERA_DLC02_CHATTER_08",
				-- Wooo!				
				[8] = "TERA_DLC02_CHATTER_01",
			}
		}
		
-- GLOBAL VARIABLES (First letter caps == Global Variable)

   -- MISC. GLOBAL VARIABLES
		Flatbed_disabled = false
		Flatbed_damaged = false
		Flatbed_was_damaged_early = false
		
		Flatbed_escort_disabled	= {}
		Flatbed_escort_damaged	= false
		Flatbed_escort_driver	= {}
		
		Player_saw_scout = false
		Scout_audio_played = false		
		
		Play_encouraging_line = false
		Play_bitching_line = false
		
		Num_escorts					= 0
		Temp_weapons_given = false
      Trigger_to_chase_index = {} -- Maps chase trigger -> chase index.

	-- THREADS
		Thread_attack_helis = INVALID_THREAD_HANDLE
		Thread_hijack_flatbed_pathfind = INVALID_THREAD_HANDLE
		Audio_thread_handle = INVALID_THREAD_HANDLE
		
-- Ignore This Stuff --
GROUP_MYSTERY						= "dlc02_$group_mystery"
V_UFO									= "dlc02_$v_ufo"
C_ALIEN								= "dlc02_$c_alien"
MYSTERY_PATH						= "dlc02_$path_ufo"
TRIG_MYSTERY						= "dlc02_$trig_mystery"


-----------------------------------------------------------------------------------
--																											--
-- The main function/thread. Called when the mission starts.							--
--																											--
-----------------------------------------------------------------------------------

function dlc02_start(dlc02_checkpoint, is_restart)

	if(DEBUG_AIRPORT_JUMP) then
		dlc02_debug_airport_jump()
	end

	if(DEBUG_APC_WEAPONS) then
      dlc02_debug_apc_weapons()
	end

	mission_start_fade_out()

	if (DEBUG_SKIP_HIJACKING) then
		group_create(GROUP_TERA, true)
		dlc02_checkpoint = CHECKPOINT_TURRET
	end

	if (dlc02_checkpoint == CHECKPOINT_START) then

		local start_groups = {GROUP_FLATBED_HIJACK, GROUP_FLATBED_HIJACK_ESCORT, GROUP_COURTESY, GROUP_TERA}
		if (coop_is_active()) then
			start_groups = {GROUP_FLATBED_HIJACK, GROUP_FLATBED_HIJACK_ESCORT, GROUP_COURTESY, GROUP_TERA}
		end

      -- Load the groups/teleport manually for a restart. Otherwise use the cutscene system.
		if (is_restart) then

			-- Load starting groups
			for i,group in pairs(start_groups) do
				group_create(group, true)
			end

			-- Teleport players to the start location
			teleport_coop(NAVP_LOCAL_PLAYER_START, NAVP_REMOTE_PLAYER_START)

		else

			-- Play the intro cutscene
			cutscene_play("DLC02-01", start_groups, {NAVP_LOCAL_PLAYER_START, NAVP_REMOTE_PLAYER_START}, false)
			for i,group in pairs(start_groups) do
				group_show(group)
			end

		end

	end

	dlc02_initialize(dlc02_checkpoint)

	if (dlc02_checkpoint == CHECKPOINT_START) then

      -- Players have to hijack the flatbed truck.
		dlc02_drive_down_downtown()

		-- Transition to the turret sequence.
		dlc02_transition_to_turret()

      -- Update the checkpoint
		dlc02_checkpoint = CHECKPOINT_TURRET
	end
	

	if (dlc02_checkpoint == CHECKPOINT_TURRET) then

      -- Player(s) must defend the flatbed in a turret sequence.
		dlc02_defend_flatbed()

	end

end

-----------------------------------------------------------------------------------
--																											--
-- Initialization routines																			--
--																											--
-----------------------------------------------------------------------------------


function dlc02_initialize(dlc02_checkpoint)

	dlc02_initialize_common()

	dlc02_initialize_checkpoint(dlc02_checkpoint)

	mission_start_fade_in()

end

-- Initialization code shared by all checkpoints.
function dlc02_initialize_common()

	-- Start trigger is hit...the activate button was hit
	set_mission_author("Phillip Alexander")

	if coop_is_active() then
		IN_COOP = true
	end

	-- Failure callbacks.
	on_death("dlc02_failure_tera_died", CHAR_TERA)
	on_dismiss("dlc02_failure_tera_abandoned", CHAR_TERA)

	-- Lock homies.
	homie_mission_lock("Tera_Patrick")
end

-- Initialization code specific to the checkpoint.
function dlc02_initialize_checkpoint(checkpoint)

	if (checkpoint == CHECKPOINT_START) then

		-- Put Pierce in the player's party
		party_add(CHAR_TERA,LOCAL_PLAYER)

		dlc02_setup_flatbed_hijack()
	end
	
	if (checkpoint == CHECKPOINT_TURRET) then

		-- Create the new vehicle and attach the trailer to the cab
		group_create(GROUP_FLATBED_TURRET, true)

		-- Place the correct people in the vehicle
		dlc02_setup_flatbed_turret_occupants()

		-- Prepare the car for the drive
		dlc02_setup_flatbed_for_turret()

	end

end

-----------------------------------------------------------------------------------
--																											--
-- Functions pertaining to getting to stage 1:												--
--																											--
-----------------------------------------------------------------------------------

-- MINIMAP_ICON_KILL
-- MINIMAP_ICON_PROTECT_ACQUIRE
-- MINIMAP_ICON_LOCATION
-- INGAME_EFFECT_KILL
-- INGAME_EFFECT_PROTECT_ACQUIRE
-- INGAME_EFFECT_LOCATION
-- INGAME_EFFECT_CUTSCENE
-- INGAME_EFFECT_VEHICLE_PROTECT_ACQUIRE
-- INGAME_EFFECT_VEHICLE_KILL
-- INGAME_EFFECT_VEHICLE_LOCATION
-- INGAME_EFFECT_VEHICLE_CUTSCENE

function dlc02_drive_down_downtown()
	marker_add_vehicle( VEH_FLATBED_HIJACK, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL )
	waypoint_add( VEH_FLATBED_HIJACK, SYNC_ALL )
	
	-- "Get to the truck"
	mission_help_table(TEXT_PROMPT_GO_TO_TRUCK)
	
	local were_close = false
	repeat
		if (get_dist(LOCAL_PLAYER, VEH_FLATBED_HIJACK) < 125) then
			were_close = true
		elseif (IN_COOP) and (get_dist(REMOTE_PLAYER, VEH_FLATBED_HIJACK) < 125) then
			were_close = true
		elseif Flatbed_was_damaged_early == true then
			were_close = true
		else
			delay(.25)
		end
	until were_close
	waypoint_remove(SYNC_ALL) 
	dlc02_hijack_flatbed()
end

-----------------------------------------------------------------------------------
--																											--
-- Functions pertaining to stage 1: Hijacking the flatbed truck.						--
--																											--
-----------------------------------------------------------------------------------

-- Setup for the flatbed hijacking
function dlc02_setup_flatbed_hijack()

	dlc02_setup_flatbed()
	dlc02_setup_escorts()

end

-- Setup the flatbed for hijacking sequence
function dlc02_setup_flatbed()

	-- Put the driver and passenger in the truck
	vehicle_enter_teleport(CHAR_FLATBED_DRIVER, VEH_FLATBED_HIJACK, 0)
	vehicle_enter_teleport(CHAR_FLATBED_PASSENGER, VEH_FLATBED_HIJACK, 1)

	-- Give the driver and passenger their specified weapons
	inv_item_remove_all(CHAR_FLATBED_DRIVER)
	inv_item_add("glock", 0, CHAR_FLATBED_DRIVER, true) 
	inv_item_remove_all(CHAR_FLATBED_PASSENGER)
	inv_item_add("twelve_gauge", 0, CHAR_FLATBED_PASSENGER, true) 

	-- Set max hit points for the Flatbed
	local flatbed_normal_hp = get_current_hit_points(VEH_FLATBED_HIJACK)
	local flatbed_hp_multiplier = dlc02_get_parameter_value("FLATBED_HIJACK_HP_MULTIPLIER")

	-- Set a few flags on the flatbed cab
	vehicle_prevent_explosion_fling(VEH_FLATBED_HIJACK,true)
	vehicle_set_allow_ram_ped(VEH_FLATBED_HIJACK,true)
	vehicle_infinite_mass(VEH_FLATBED_HIJACK, true)
	vehicle_suppress_npc_exit(VEH_FLATBED_HIJACK, true)
	set_unjackable_flag(VEH_FLATBED_HIJACK, true)	-- Cool. All the other ones are vehicle_function, but this one isn't.
		
	-- Set the fail condition for destroying the truck from the start. TDL #293435
	on_death("dlc02_flatbed_disabled", CHAR_FLATBED_DRIVER)
	on_take_damage("dlc02_prehijack_flatbed_damaged",VEH_FLATBED_HIJACK)
	on_vehicle_destroyed("dlc02_failure_flatbed_destroyed", VEH_FLATBED_HIJACK)

end

function dlc02_prehijack_flatbed_damaged(vehicle)
	Flatbed_was_damaged_early = true
end

-- Setup the flatbed's escorts for the hijacking sequence
function dlc02_setup_escorts()

	Flatbed_escort_damaged = false

	-- Put passenger into escort vehicles, setup callbacks
	for escort,passengers in pairs(FLATBED_ESCORT) do
		Num_escorts = Num_escorts + 1
		Flatbed_escort_disabled[escort] = false

		vehicle_suppress_npc_exit(escort, true)
		vehicle_set_allow_ram_ped(escort,true)
		vehicle_set_crazy(escort,true)
		vehicle_set_use_short_cuts(escort,true)
		vehicle_max_speed(escort, dlc02_get_parameter_value("FLATBED_MAX_SPEED_DAMAGED")+10)

		on_vehicle_destroyed("dlc02_escort_vehicle_disabled",escort)
		on_take_damage("dlc02_flatbed_escort_damaged", escort)
		on_death("dlc02_escort_driver_killed",passengers[1])

		for i,passenger in pairs(passengers) do
			vehicle_enter_teleport(passenger, escort, i-1)
			npc_combat_enable(passenger,true)
		end
		Flatbed_escort_driver[passengers[1]] = escort
	end

end

-- Called when a driver of one of the escort vehicles gets killed.
function dlc02_escort_driver_killed(driver)
	dlc02_escort_vehicle_disabled(Flatbed_escort_driver[driver])
end

-- Called when an escort vehicle has become disabled (destroyed or driver killed.)
function dlc02_escort_vehicle_disabled(vehicle)
	Num_escorts = Num_escorts - 1
	Flatbed_escort_disabled[vehicle] = true
end

function dlc02_hijack_flatbed()

	Audio_thread_handle = thread_new("dlc02_play_audio_conversation", TRUCK_SPOTTED_CONVERSATION)
	mission_help_table(TEXT_PROMPT_HIJACK_TRUCK)

	-- Turn on the health bar hud for the player that triggered the sequence.
	local van_disabled_health_percent = dlc02_get_parameter_value("VAN_DISABLED_PERCENT_HEALTH")
	local van_hit_points = dlc02_get_parameter_value("VAN_HIT_POINTS")

	damage_indicator_on(0, VEH_FLATBED_HIJACK, 0.0, TEXT_HUD_TRUCK_HEALTH_LABEL)

	-- Setup the van.
	-- marker_add_vehicle(VEH_FLATBED_HIJACK,MINIMAP_ICON_KILL,INGAME_EFFECT_VEHICLE_KILL,SYNC_ALL)
--	on_death("dlc02_flatbed_disabled", CHAR_FLATBED_DRIVER)
--	on_vehicle_destroyed("dlc02_failure_flatbed_destroyed", VEH_FLATBED_HIJACK)
	on_take_damage("dlc02_flatbed_damaged",VEH_FLATBED_HIJACK)

	-- Start up the thread for handling the escort vehicles
	local escort_thread = thread_new("dlc02_process_escort")

	-- Regulate the flatbed's speed
	local flatbed_speed_thread = thread_new("dlc02_flatbed_speed")

	-- Check the distance of the flatbed to warn the player if its getting close to its destination
	local dist = get_dist(VEH_FLATBED_HIJACK, NAVP_HIJACK_DEST)
	local flatbed_close_thread = thread_new("dlc02_flatbed_close", dist)	
	
	-- The Flatbed follows traffic splines to the North island
	for i, path_segment in pairs(PATH_FLATBED_HIJACK) do
		vehicle_turret_base_to(VEH_FLATBED_HIJACK, path_segment, false)
	end

	thread_kill(escort_thread)
	thread_kill(flatbed_speed_thread)
	thread_kill(flatbed_close_thread)

	-- Vehicle pathfinding may have ended because... 
	-- a) The vehicle reached its destination OR
	-- b) The vehicle was destroyed OR
	-- c) The vehicle's driver was killed OR
	-- d) THe vehicle's health dropped below a specified threshold

	delay(0.1)

	-- Find out how close the vehicle is to the destination.
	if (not vehicle_is_destroyed(VEH_FLATBED_HIJACK)) then
		dist = get_dist(VEH_FLATBED_HIJACK, NAVP_HIJACK_DEST)
	end

	-- If the truck reaches the end of its path without being disabled, then it takes the exit and the players lose
	if (	(not Flatbed_disabled) and 
			(not vehicle_is_destroyed(VEH_FLATBED_HIJACK)) and
			(dist < 25.0)
		) then

		-- TODO
		-- Get rid of the old callbacks

		-- Make sure that the player can't kill the driver or destroy the van during this sequence
		turn_invulnerable(CHAR_FLATBED_DRIVER,false)
		turn_invulnerable(VEH_FLATBED_HIJACK,false)

		-- You lose!
		dlc02_failure_flatbed_escaped()

		-- Truck keeps driving to the exit ramp
		if (not vehicle_is_destroyed(VEH_FLATBED_HIJACK)) then
			vehicle_turret_base_to(VEH_FLATBED_HIJACK, NAVP_FLATBED_STAGE_1_EXIT_RAMP, false)
		end

	elseif (not vehicle_is_destroyed(VEH_FLATBED_HIJACK)) then

		-- Make sure that the player can't destroy the truck		
		turn_invulnerable(VEH_FLATBED_HIJACK,false)

		-- Get rid of the old callbacks
		on_death("", CHAR_FLATBED_DRIVER)
		on_take_damage("",VEH_FLATBED_HIJACK)
		on_vehicle_destroyed("", VEH_FLATBED_HIJACK)

		-- Remove indicators
		damage_indicator_off(0)
		marker_remove_vehicle(VEH_FLATBED_HIJACK)

		-- Occupants can exit the flatbed now now.
		vehicle_suppress_npc_exit(VEH_FLATBED_HIJACK, false)

		vehicle_stop(VEH_FLATBED_HIJACK, true)
		local flatbed_speed = get_vehicle_speed(VEH_FLATBED_HIJACK)
		while(flatbed_speed > 2.0) do
			flatbed_speed = get_vehicle_speed(VEH_FLATBED_HIJACK)
			thread_yield()
		end

	end

end

-- Should be called when the flatbed truck is disabled.
function dlc02_flatbed_disabled()

   -- This function should only process once
	if (Flatbed_disabled) then
		return
	end

	Flatbed_disabled = true

   -- Stop the truck
	vehicle_stop(VEH_FLATBED_HIJACK)

   -- Have the driver exit the truck and flee
	if (not character_is_dead(CHAR_FLATBED_DRIVER)) then
		vehicle_exit(CHAR_FLATBED_DRIVER)
		flee(CHAR_FLATBED_DRIVER)
	end
end

-- Determine if an attacker is a player ally.
function dlc02_flatbed_attacker_is_ally(attacker)

	if ((attacker == LOCAL_PLAYER) or (attacker == REMOTE_PLAYER) or 
		((attacker ~= nil) and character_exists(attacker) and npc_is_in_party(attacker))) then

		return true
	end

	return false

end


-- Called when the flatbed is damaged.
function dlc02_flatbed_damaged(flatbed, attacker, damage_percent)

   -- Convenience variable, percent health at which the flabed is considered to be disabled.
	local disabled_health_percent = dlc02_get_parameter_value("FLATBED_DISABLED_HEALTH_PERCENT")

	-- The first time that the truck gets damaged, it goes into crazy mode.
	if (not Flatbed_damaged) then

		-- Make sure the damage was done by a player or Tera.
		if (dlc02_flatbed_attacker_is_ally(attacker)) then
			vehicle_set_crazy(VEH_FLATBED_HIJACK, true)
			Flatbed_damaged = true
		end
	end

	-- Disable the flatbed if it has taken enough damage
	if (damage_percent <= disabled_health_percent) then
		dlc02_flatbed_disabled()
		return
	end
		
	if thread_check_done(Audio_thread_handle) == true then
		for i = 1, Truck_damaged_during_hijack_lines.num_items do
			if (Truck_damaged_during_hijack_lines[i].played == false and damage_percent < Truck_damaged_during_hijack_lines[i].threshold) then
				Audio_thread_handle = thread_new("dlc02_play_truck_damaged_line", i)
				return
			end
			
			if damage_percent > Truck_damaged_during_hijack_lines[i].threshold then
				return
			end
		end
	end
	
end

function dlc02_play_truck_damaged_line(index)
	-- Randomly play one of the 8 lines 
	local line_to_play = rand_int(1, Truck_damaged_during_hijack_lines.text.num_lines)
	local check = true
	
	-- No Repeats
	while (check == true) do
		check = false
		for i = 1, index do
			if line_to_play == Truck_damaged_during_hijack_lines[i].line_played then
				check = true
				line_to_play = rand_int(1, Truck_damaged_during_hijack_lines.text.num_lines)
				break
			end
		end
	end
	
	Truck_damaged_during_hijack_lines[index].played = true
	Truck_damaged_during_hijack_lines[index].line_played = line_to_play
	Audio_thread_handle = thread_new("dlc02_play_audio_line", Truck_damaged_during_hijack_lines.text[line_to_play], CHAR_TERA)
end

-- Called when a flatbed escort is damaged.
function dlc02_flatbed_escort_damaged(escort, attacker, damage_percent)

	-- Make sure the damage was done by a player or Tera.
	if (dlc02_flatbed_attacker_is_ally(attacker)) then
		Flatbed_escort_damaged = true
	end

end

-- Escort vehicles follow the Shaundi-knappers until a player approaches too close.
-- At this point, one of the vans will start chasing the player and not stop.
function dlc02_process_escort()

   -- Have the escort vehicles chase the flatbed driver
	for escort,passengers in pairs(FLATBED_ESCORT) do
		vehicle_chase(escort, CHAR_FLATBED_DRIVER, false, false, true, false)	
	end
   
   -- Allow cops to shoot from vehicles
   set_cops_shooting_from_vehicles(true)

   -- Convenience variables
	local attack_dist = dlc02_get_parameter_value("FLATBED_ATTACK_DIST_M")
	local player_attackers = {}	-- maps from player -> the escort currently attacking the player

	-- Called to make an escort attack the player if one isn't already doing so.
	local function escort_attack(player)

		-- See which escort is currently attacking the player
		local current_attacker = player_attackers[player]

		-- Need a new attacker if 1) No current attacker or 2) Current attacker is disabled
		local need_attacker = false
		if( current_attacker == nil) then
			need_attacker = true	
		elseif (Flatbed_escort_disabled[current_attacker]) then
			need_attacker = true
		end

      -- If a new attacker is needed, find one
		if (need_attacker) then

			-- Find the nearest available escort
			local closest = 0
			local new_attacker = ""
			for escort,disabled in pairs(Flatbed_escort_disabled) do

            -- Disabled escorts and those attacking other players are not available.
            if (	(not disabled) and 
						(player_attackers[OTHER_PLAYER[player]] ~= escort) ) then

               -- Get the distance from this escort to the player
					local dist = get_dist(escort,player)

               -- Save the escort if it is the best that we've found so far.
               if( (new_attacker == "") or (dist < closest)) then
						new_attacker = escort
						closest = dist
					end							
				end
			end

         -- If we've found a viable escort and it is close enough to attack the player, have
         -- it do so.
			if ((new_attacker ~= "") and (closest < attack_dist)) then

            -- Remember that this vehicle is attacking the player
				player_attackers[player] = new_attacker

				-- Stop chasing the knapper mobile and start chasing the player
				vehicle_chase(new_attacker, player, false, true, true, false)
			end

		end
	end

   -- As long as escorts remain, have them attack players who are too close to the flatbed.
	while(Num_escorts > 0) do

		-- If the escorts are damaged or the flatbed is damaged, attack.
		if (Flatbed_damaged or Flatbed_escort_damaged) then

			-- Have an escort attack the local playe if he is too close to the flatbed.
			local local_dist = get_dist(LOCAL_PLAYER,VEH_FLATBED_HIJACK)
			if(local_dist < attack_dist) then
				escort_attack(LOCAL_PLAYER)
			end

			-- Have an escort attack the remote player if he is too close to the flatbed.
			if(IN_COOP) then
				local remote_dist = get_dist(REMOTE_PLAYER,VEH_FLATBED_HIJACK)
				if(remote_dist < attack_dist) then
					escort_attack(REMOTE_PLAYER)
				end
			end

		end

      -- Yield
		thread_yield()

	end

end

-- Regulate the flatbed's speed.
--
-- A base speed is determined based on whether the truck has been damaged yet or not.
-- If the players are too far from the van, then adjust the base speed downward so they can catch up.
-- At first we only adjust max speed. After the truck is damaged we start overriding the speed as well...
-- this makes it act a bit more reckless. We can't just throw it in chase mode as it needs to follow a path.
function dlc02_flatbed_speed()

   -- Convenience variables
	local speed_initial = dlc02_get_parameter_value("FLATBED_MAX_SPEED_INITIAL")
	local speed_damaged = dlc02_get_parameter_value("FLATBED_MAX_SPEED_DAMAGED")
	local range_ratio   = dlc02_get_parameter_value("FLATBED_OUT_OF_RANGE_SPEED_RATIO")
	local range_dist_m  = dlc02_get_parameter_value("FLATBED_OUT_OF_RANGE_DIST_M")

	local overriding_speed = false	-- Have we started overriding the van's speed yet?
	local current_speed = 0				-- The speed that we've set for the van, probably not the speed at which it is moving.

   -- Regulate the flatbed's speed until it is disabled or destroyed
	while( not (Flatbed_disabled or vehicle_is_destroyed(VEH_FLATBED_HIJACK)) ) do

		-- Get the base speed for the flatbed
		local new_speed = speed_initial
		if(Flatbed_damaged) then
			new_speed = speed_damaged
		end

		-- Decrease the speed if the players are too far from the van
		local dist,player = get_dist_closest_player_to_object(VEH_FLATBED_HIJACK)
		if (dist > range_dist_m) then
			new_speed = new_speed * range_ratio
		end

		-- Update the van's max speed if it has changed.
		local speed_changed = (new_speed ~= current_speed)
		if (speed_changed) then
			vehicle_max_speed(VEH_FLATBED_HIJACK, new_speed)
			current_speed = new_speed
		end
		
		-- Override the vehicle's speed if
		-- 1) (speed changed and van has been damaged) AND/OR
		-- 2) van was just damaged - we need to make sure that the speed is overriden even if the
		-- new speed hasn't changed.
		local start_override = (Flatbed_damaged ~= overriding_speed)
		if ( (speed_changed and Flatbed_damaged) or start_override ) then
			vehicle_speed_override(VEH_FLATBED_HIJACK, new_speed)			
			overriding_speed = true			
		end

		thread_yield()
	end

	-- After vehicle is disabled, set its speed to 0 and exit.
	if ( not vehicle_is_destroyed(VEH_FLATBED_HIJACK) ) then
		vehicle_speed_override(VEH_FLATBED_HIJACK, 0)
		vehicle_stop(VEH_FLATBED_HIJACK,true)
	end
end

-- Nag the player if the truck gets close to its destination
function dlc02_flatbed_close(total_distance)
	local distance = 0.0
	while not vehicle_is_destroyed(VEH_FLATBED_HIJACK) do
		distance = get_dist(VEH_FLATBED_HIJACK, NAVP_HIJACK_DEST)
		if distance / total_distance < 0.25 then
			mission_help_table_nag(TEXT_PROMPT_TRUCK_APPROACHING)
			return
		end
		
		thread_yield()
	end
end

-----------------------------------------------------------------------------------
--																											--
-- Functions used when transitioning from stage 1 to stage 2.     					--
--																											--
-----------------------------------------------------------------------------------

-- Transition from hijacking to the turret portion of the mission.
function dlc02_transition_to_turret()

	-- Don't do anything while either player is dead
	while( character_is_dead(LOCAL_PLAYER) or (IN_COOP and character_is_dead(REMOTE_PLAYER)) or character_is_dead(CHAR_TERA) ) do
		thread_yield()
	end

	-- Tera can be called again
	homie_mission_unlock("Tera_Patrick")

	-- Play the truck stopped
	audio_play_for_character(TRUCK_STOPPED_LINE, CHAR_TERA, "voice", false, true)
	
	-- Fade out and disable player controls
	fade_out(1.0,{0,0,0}, SYNC_ALL)
	fade_out_block()

	player_controls_disable(LOCAL_PLAYER)
	if (IN_COOP) then
		player_controls_disable(REMOTE_PLAYER)
	end

	-- CHECKPOINT! (ignore vehicle seating)
	mission_set_checkpoint(CHECKPOINT_TURRET, true)

	-- Get rid of the hijack groups
	dlc02_cleanup_hijack_groups()

	-- Create the new flatbed
	group_create(GROUP_FLATBED_TURRET, true)

	-- Place the correct people in the vehicle
	dlc02_setup_flatbed_turret_occupants()

	-- Prepare the car for the drive
	dlc02_setup_flatbed_for_turret()

	-- Fade back into the game
	fade_in(1.0, SYNC_ALL)
	fade_in_block()

	-- Reenable player controls
	player_controls_enable(LOCAL_PLAYER)
	if (IN_COOP) then
		player_controls_enable(REMOTE_PLAYER)
	end

end

-- Destroy all of the hijack groups
function dlc02_cleanup_hijack_groups()

	-- Make sure that the players aren't in a vehicle
	character_evacuate_from_all_vehicles(LOCAL_PLAYER)
   character_evacuate_from_all_vehicles(CHAR_TERA)
	if IN_COOP then
		character_evacuate_from_all_vehicles(REMOTE_PLAYER)
		while(character_is_in_vehicle(REMOTE_PLAYER)) do
			thread_yield()
		end
	end

	-- Destroy the hijack groups
	if (vehicle_exists(VEH_FLATBED_HIJACK)) then
		vehicle_evacuate(VEH_FLATBED_HIJACK)
	end

	marker_remove_vehicle(VEH_FLATBED_HIJACK)

	group_hide(GROUP_FLATBED_HIJACK)
	group_destroy(GROUP_FLATBED_HIJACK)

	group_hide(GROUP_FLATBED_HIJACK_ESCORT)
	group_destroy(GROUP_FLATBED_HIJACK_ESCORT)

	-- Delay hack for some of this stuff to process on the client.
	delay(0.5)

end

-----------------------------------------------------------------------------------
--																											--
-- Functions pertaining to stage 2: Defending the flatbed truck.						--
--																											--
-----------------------------------------------------------------------------------

-- Place passengers in the flatbed truck
function dlc02_setup_flatbed_turret_occupants()

	-- Make sure that no random ped or vehicle spawns obstruct our vehicle
	spawning_pedestrians(false, true)
	spawning_vehicles(false)

   -- Make players invulnerable
   turn_invulnerable(LOCAL_PLAYER, false)
   if (IN_COOP) then
      turn_invulnerable(REMOTE_PLAYER, false)
   end
	turn_invulnerable(CHAR_TERA, false)
	
	-- Teleport players and Tera to a staging area, removing them from vehicles along the way.
	teleport_coop(NAVP_TURRET_STAGING_1, NAVP_TURRET_STAGING_2, true)
   teleport(CHAR_TERA, NAVP_TURRET_STAGING_3, true)

	-- Dismiss any extra followers and put Tera in the player's party
	party_dismiss_all() 
   party_add(CHAR_TERA,LOCAL_PLAYER)

   follower_make_independent(CHAR_TERA, true)
   
	-- Make sure that the flatbed is loaded
	while( not group_is_loaded(GROUP_FLATBED_TURRET)  ) do
		thread_yield()
	end

	-- Place characters in the flatbed
	set_unjackable_flag(VEH_FLATBED_TURRET, false)
   vehicle_enter_teleport(CHAR_TERA,VEH_FLATBED_TURRET,0)
	vehicle_enter_teleport(LOCAL_PLAYER,VEH_FLATBED_TURRET,2)
	if IN_COOP then
		vehicle_enter_teleport(REMOTE_PLAYER,VEH_FLATBED_TURRET,3)
	end

	-- Wait for characters to enter the vehicle
   dlc02_wait_for_vehicle_entry(CHAR_TERA, VEH_FLATBED_TURRET, 0)
	dlc02_wait_for_vehicle_entry(LOCAL_PLAYER, VEH_FLATBED_TURRET, 2)
	if IN_COOP then
		dlc02_wait_for_vehicle_entry(REMOTE_PLAYER, VEH_FLATBED_TURRET, 3)
		delay(1.0)
	end

	-- Dole out turret weapons
	dlc02_setup_turret_weapons()

	-- Reenable ped and vehicle spawning
	spawning_pedestrians(true, true)
	spawning_vehicles(true)	

end

-- Make sure that the players have the correct weapons for the turret portion of the mission.
function dlc02_setup_turret_weapons()

	-- Give the player(s) an assault rifle
	inv_weapon_add_temporary(LOCAL_PLAYER, "AR50_launcher", 1, true, true)
	inv_weapon_add_temporary(LOCAL_PLAYER, "grenade", 1, true)

   if (IN_COOP) then
   	inv_weapon_add_temporary(REMOTE_PLAYER, "AR50_launcher", 1, true, true)
   	inv_weapon_add_temporary(REMOTE_PLAYER, "grenade", 1, true)
   end

   Temp_weapons_given = true

	-- Only allow the rifle slot
	inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_RIFLE)

	-- Make sure that the weapons is equipped and the characters are combat ready
	thread_new("dlc02_keep_ar200_equipped")

end

-- Make sure that the ar200 stays equipped
function dlc02_keep_ar200_equipped()

   -- Equips the player with the ar50 and makes them combat ready.
	local function update_player(player)
		if (not inv_item_is_equipped("AR50_launcher", player)) and character_is_in_vehicle(player, VEH_FLATBED_TURRET) then
			inv_item_equip("AR50_launcher", player)
		end
		character_set_combat_ready(player, true, 1.0)
	end

   -- Keep updating equipped weapons
	while(1) do
		update_player(LOCAL_PLAYER)
      if (IN_COOP) then
         update_player(REMOTE_PLAYER)
      end
		delay(0.25)
	end
end

-- Prepare the flatbed truck for the turret portion of the mission.
function dlc02_setup_flatbed_for_turret()

	-- Modify the vehicle's hit points
	local flatbed_hp_multiplier = dlc02_get_parameter_value("FLATBED_TURRET_HP_MULTIPLIER")
	set_max_hit_points(VEH_FLATBED_TURRET, get_current_hit_points(VEH_FLATBED_TURRET) * flatbed_hp_multiplier)

	-- Make sure that the on_destroyed callback is still active
	on_vehicle_destroyed("dlc02_failure_flatbed_destroyed",VEH_FLATBED_TURRET)
	
	-- Watch the truck for its damage lines
	thread_new("dlc02_defend_flatbed_damaged")
		
	-- Prepare the cab for turreting
	vehicle_set_torque_multiplier(VEH_FLATBED_TURRET, 1.2)
	vehicle_prevent_explosion_fling(VEH_FLATBED_TURRET,true)
	vehicle_set_allow_ram_ped(VEH_FLATBED_TURRET,true)
	vehicle_set_crazy(VEH_FLATBED_TURRET,true)
	vehicle_infinite_mass(VEH_FLATBED_TURRET, true)
	vehicle_disable_flee(VEH_FLATBED_TURRET, true)
	vehicle_disable_chase(VEH_FLATBED_TURRET, true)
	vehicle_never_flatten_tires(VEH_FLATBED_TURRET, true)
	set_unjackable_flag(VEH_FLATBED_TURRET, true)
	vehicle_set_script_hard_goto(VEH_FLATBED_TURRET, true)
	vehicle_set_explosion_damage_multiplier(VEH_FLATBED_TURRET, 0.25)
	vehicle_suppress_flipping(VEH_FLATBED_TURRET, true)
	
	-- The driver can't exit the truck
	vehicle_suppress_npc_exit(VEH_FLATBED_TURRET,true)
	set_seatbelt_flag(CHAR_TERA,true)

	-- Player(s) can't exit the truck
	set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
	if (IN_COOP) then
		set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
	end

end

-- Players defend the flatbed while Tera drives.
function dlc02_defend_flatbed()

   -- Get rid of roadblocks.
	roadblocks_enable(false)

	-- Ignore this
	trigger_enable( TRIG_MYSTERY, true )
	on_trigger( "dlc02_mystery", TRIG_MYSTERY )

   -- Tell the players to protect the truck and show it's health.
	mission_help_table(TEXT_PROMPT_PROTECT_TRUCK)
	damage_indicator_on(0, VEH_FLATBED_TURRET, 0.0, TEXT_HUD_TRUCK_HEALTH_LABEL)
	on_take_damage("dlc02_flatbed_turret_damaged", VEH_FLATBED_TURRET)
	
	-- Play Tera's line about heading to the airport and spawn the thread to check for the 'almost there'
	audio_play_for_character(TERA_AIRPORT_LINES[1], CHAR_TERA, "voice", false, false)	
	thread_new("dlc02_defend_flatbed_almost_there")	
	
	-- Randomly play some player lines according to the action
	thread_new("dlc02_maybe_play_player_lines")
	
	-- Set the Police notoriety level
	local level = dlc02_get_parameter_value("FLATBED_TURRET_NOTORIETY")
	notoriety_set_min("Police", level) 
	notoriety_set_max("Police", level) 

	-- Set the desired # of Police vehicles
	local count = dlc02_get_parameter_value("FLATBED_TURRET_DESIRED_POLICE_VEHICLES")
	notoriety_set_desired_vehicle_count("Police", count)

	-- Setup the edf chase vehicles. Don't block, players will take a while to reach the first edf.
	thread_new("dlc02_setup_chases")

   -- Start the thread that will spawn the attack helicopters
	if (not DEBUG_DISABLE_ATTACK_HELIS) then
		Thread_attack_helis = thread_new("dlc02_attack_helis")
	end

	-- The Flatbed follows traffic splines to the Airport
	for i, path_segment in pairs(PATH_FLATBED_AIRPORT) do
		vehicle_turret_base_to(VEH_FLATBED_TURRET, path_segment, false)
	end

	-- The Flatbed follows navmesh to the Airport and stops at the end of the path
	vehicle_pathfind_to(VEH_FLATBED_TURRET, PATH_FLATBED_AIRPORT_RUNWAY, true, true)

	-- If the vehicle has arrived at the airport, trigger success
	local final_navp = "dlc02_$n097"
	if (	(not vehicle_is_destroyed(VEH_FLATBED_TURRET)) and
			(get_dist(VEH_FLATBED_TURRET, final_navp) < 80) ) then
		-- Players win!
		dlc02_complete()
	else
		-- Something bad happened, fail the mission
		dlc02_failure_flatbed_destroyed()
	end	
end

function dlc02_flatbed_turret_damaged()
	Play_bitching_line = true
end

function dlc02_maybe_play_player_lines()
	
	local Player_bitching_lines = 
	{
		-- We almost there yet?
		"PLAYER_DLC02_BITCHING_01",
		-- The hell are you doin'?
		"PLAYER_DLC02_BITCHING_02",
		-- These Ultor bitches ever give up?
		"PLAYER_DLC02_BITCHING_03",
		-- We gotta hurry!
		"PLAYER_DLC02_BITCHING_04",
		-- I don't know how long I can hold these guys off!
		"PLAYER_DLC02_BITCHING_05",
	}
	
	local Player_encouraging_lines =
	{
		-- Keep driving Tera!
		"PLAYER_DLC02_ENCOURAGE_01",
		-- We can do this!
		"PLAYER_DLC02_ENCOURAGE_02",
		-- Don't worry, I got you covered!
		"PLAYER_DLC02_ENCOURAGE_03",
		-- You're doing great Tera!
		"PLAYER_DLC02_ENCOURAGE_04",
		-- Damn girl, where you learn to drive?
		"PLAYER_DLC02_ENCOURAGE_05",
	}

	-- Don't play any lines for a bit
	delay(15)
	
	local line_played = false
	local encourage_index = 0
	local bitch_index = 0
	
	-- I know these are called last 3, but I decided since you can hear about 5 in one mission, might as well as just ranom the order of all 5
	local last_three_encourage_lines = { index = 0, [0] = -1, [1] = -1, [2] = -1, [3] = -1, [4] = -1, }
	local last_three_bitching_lines  = { index = 0, [0] = -1, [1] = -1, [2] = -1, [3] = -1, [4] = -1, }
	
	local function pick_random_line(last_three)
		local line = rand_int(1, 5)
		local check_done = true
		while check_done == true do
			check_done = false
			for i = 0, 4 do
				if last_three[i] == line_played then
					check_done = true
					line = rand_int(1,5)
				end
			end
		end
		
		last_three[last_three.index] = line
		last_three.index = last_three.index + 1
		
		-- Wrap around in the event the player is not very good at all.
		if last_three.index > 4 then
			last_three.index = 0
		end
		
		return line
	end
	
	local line_to_play = 0
	local health_ratio = 0
	while(true) do
		health_ratio = get_current_hit_points(VEH_FLATBED_TURRET)/get_max_hit_points(VEH_FLATBED_TURRET)

		if health_ratio < .9 and thread_check_done(Audio_thread_handle) == true then
			line_to_play = 0
			
			if Play_bitching_line == true then
				line_to_play = Player_bitching_lines[pick_random_line(last_three_bitching_lines)]
			elseif Play_encouraging_line == true then
				line_to_play = Player_encouraging_lines[pick_random_line(last_three_encourage_lines)]
			end			
			
			if line_to_play ~= 0 then
				audio_play_for_character(line_to_play, LOCAL_PLAYER, "voice", false, true)	
				line_to_play = 0
				delay(18)
				line_played = false
			end
		end
		
		-- don't play the next ones immediately
		Play_encouraging_line = false
		Play_bitching_line = false
		thread_yield()
	end
	
end

function dlc02_defend_flatbed_almost_there()

	-- Get the total distance to the dig site
	local total_dist = get_dist(VEH_FLATBED_TURRET, "dlc02_$n097")

	while true do
		local current_dist = get_dist(VEH_FLATBED_TURRET, "dlc02_$n097")

		-- If we're 90% of the way there, play the line
		if (not vehicle_is_destroyed(VEH_FLATBED_TURRET)) and (current_dist < total_dist*.10) then
			if thread_check_done(Audio_thread_handle) then
				Audio_thread_handle = thread_new("dlc02_play_airport_line")
				return
			end
		end

		thread_yield()
	end
end

function dlc02_play_airport_line()
	audio_play_for_character(TERA_AIRPORT_LINES[2], CHAR_TERA, "voice", false, true)	
end

function dlc02_defend_flatbed_damaged()
	local health_ratio = 1.0
	
	for i = 1, TERA_TRUCK_DAMAGE.num_items do
		while (health_ratio > TERA_TRUCK_DAMAGE[i][1]) do
			health_ratio = get_current_hit_points(VEH_FLATBED_TURRET)/get_max_hit_points(VEH_FLATBED_TURRET)
			thread_yield();
		end
		
		if thread_check_done(Audio_thread_handle) == true then
			Audio_thread_handle = thread_new("dlc02_play_audio_line", TERA_TRUCK_DAMAGE[i][2], CHAR_TERA)
		end
	end
end

-- Setup the edf chase vehicles and enable their triggers.
function dlc02_setup_chases()

   -- Create group
	group_create(GROUP_EDF, true)

   -- Loop over all chases
	for i, chase_info in pairs(EDF_CHASES) do

		-- Convenience variables
		local vehicle = chase_info["vehicle"]
		local driver = (chase_info["passengers"])[1]
		local passenger = (chase_info["passengers"])[2]

		-- Put the driver and passenger in the apc
		vehicle_enter_teleport(driver, vehicle, 0)
		vehicle_enter_teleport(passenger, vehicle, 1)

		-- Make the driver invulnerable
		turn_invulnerable(driver)
		
		-- Make the scouts unable to done blow up each other
		turn_invulnerable(vehicle, true)

		-- Set max hit points for the vehicle
		local normal_hp = get_current_hit_points(vehicle)
		local hp_multiplier = dlc02_get_parameter_value("CHASE_VEHICLE_HP_MULTIPLIER")
		set_max_hit_points(vehicle, normal_hp * hp_multiplier)

		-- Set a few flags on the vehicle
		vehicle_prevent_explosion_fling(vehicle,true)
		vehicle_set_allow_ram_ped(vehicle,true)
		vehicle_infinite_mass(vehicle, true)
		vehicle_suppress_npc_exit(vehicle, true)
		vehicle_suppress_flipping(vehicle, true)

		-- Enable the chase trigger
		local trigger = chase_info["trigger"]
		on_trigger("dlc02_chase_trigger_activated", trigger)
		trigger_enable(trigger, true)
		Trigger_to_chase_index[trigger] = i		

		if i == 1 then
			on_weapon_fired("dlc02_start_scout_conversation_from_callback", driver)
			on_weapon_fired("dlc02_start_scout_conversation_from_callback", passenger)
			on_vehicle_destroyed("dlc02_start_scout_conversation_from_callback", vehicle)
		end
		
	end

end

-- Called when and edf-chase trigger is activated
function dlc02_chase_trigger_activated(triggerer, trigger)

	-- Disable the trigger
	on_trigger("", trigger)
	trigger_enable(trigger, false)

	-- Have the vehicle chase
	thread_new("dlc02_vehicle_chase", Trigger_to_chase_index[trigger])

	if Player_saw_scout == false then
		Player_saw_scout = true
		thread_new("dlc02_start_scout_conversation")
	end
end

function dlc02_start_scout_conversation()
	-- Wait until a player can "see" a scout
	while (true) do
		if (get_dist_closest_player_to_object(EDF_CHASES[1]["vehicle"]) < 50 and Scout_audio_played == false) then
			Scout_audio_played = true		
			Audio_thread_handle = thread_new("dlc02_play_audio_conversation", SCOUT_CONVERSATION)			
		end
		
		if Scout_audio_played == true then
			return
		end
		
		thread_yield()
	end	
end

function dlc02_start_scout_conversation_from_callback()
	if Scout_audio_played == false then
		Scout_audio_played = true
		Audio_thread_handle = thread_new("dlc02_play_audio_conversation", SCOUT_CONVERSATION)			
	end
end

-- Have an edf scout begin chasing the players
function dlc02_vehicle_chase(chase_index)

   -- convenience variables
   local vehicle = EDF_CHASES[chase_index]["vehicle"]
   local jump_speed = EDF_CHASES[chase_index]["jump speed"]
   local chase_start = EDF_CHASES[chase_index]["chase start"]
   local spline_start = EDF_CHASES[chase_index]["spline start"]

	-- Override the speed, ignore repulsors if we're jumping
	if (jump_speed) then
		vehicle_speed_override(vehicle, jump_speed)
		vehicle_ignore_repulsors(vehicle, true)
	end
	
	-- Pathfind to the start of the chase (on navmesh, don't stop at path end)
	local use_navmesh = (spline_start ~= true)
	vehicle_pathfind_to(vehicle, chase_start, use_navmesh, false)

	-- Do the actual jump if there is one
	if (jump_speed) then

		-- Wait for take off
		while (not vehicle_in_air(vehicle)) do
			thread_yield()
		end

		-- Wait for landing
		while (vehicle_in_air(vehicle)) do
			thread_yield()
		end

		-- Cancel vehicle speed override, stop ignoring repulsors
		vehicle_speed_cancel(vehicle)
		vehicle_ignore_repulsors(vehicle, false)
	
	end

	-- Have the vehicle chase the player
	-- exit_on_stop = false, allow_ram = false, allow_lateral_chase = false, no_sirens = true
	vehicle_chase(vehicle, LOCAL_PLAYER, false, false, false, true)
end


-- Spawn attack helis to chase the flatbed truck.
function dlc02_attack_helis()

	-- Don't let guided missiles timeout.
--	rocket_guide_timers_disable(true)

	-- Spawn a thread to keep the attack helis firing missiles
	thread_new("dlc02_attack_helis_fire_missiles")

	-- Loop over the chase paths
	for i = 1, sizeof_table(ATTACK_HELI_CHASE_PATHS), 1 do

		-- Try to spawn a new attack heli if the current one is disabled
		if (dlc02_heli_is_disabled()) then

			-- Spawn the attack heli at the start of the approach path
			dlc02_spawn_new_attack_heli(ATTACK_HELI_SPAWN_POINTS[i])
			
			-- Play an encouraging line if you would, sir.
			Play_encouraging_line = true

			-- Have the attack heli follow the approach path
			if ( not dlc02_heli_is_disabled() ) then
				dlc02_fly_to_direct_dont_stop(VEH_HELI, 50.0, ATTACK_HELI_APPROACH_PATHS[i])
			end

		end

		-- Now have the attack heli follow the chase path
		if ( not dlc02_heli_is_disabled() ) then
			dlc02_fly_to_direct_follow_dont_stop(VEH_HELI, 80.0, VEH_FLATBED_TURRET, ATTACK_HELI_CHASE_PATHS[i])
		end
		
		-- Give a short delay to prevent a race condition between the heli finishing pathfinding and being considered
		-- disabled.
		delay(0.5)
	end

	-- Release the heli
	release_to_world(GROUP_HELI)

end

-- Is the attack heli disabled?
function dlc02_heli_is_disabled()
	if (not vehicle_exists(VEH_HELI)) then
		return true
	end
	if (vehicle_is_destroyed(VEH_HELI)) then
		return true
	end

	-- Check if it's on fire.
	local smoke, fire = vehicle_get_smoke_and_fire_state(VEH_HELI)
	if (fire == true) then
		return true
	end
	if (not character_exists(CHAR_HELI_PILOT)) then
		return true
	end
	if (character_is_dead(CHAR_HELI_PILOT)) then
		return true
	end
	if (get_dist_closest_player_to_object(VEH_HELI) > 1000) then
		return true
	end
	return false
end

-- Have the attack helis fire missiles repeatedly
function dlc02_attack_helis_fire_missiles()

	while (true) do

		if (not dlc02_heli_is_disabled()) then
			dlc02_maybe_shoot_missile()
		end

		thread_yield()
	end

end

-- Have the attack heli shoot a missile if it is in position to do so.
function dlc02_maybe_shoot_missile()

	-- We want it to look like the heli is attacking the local player, so they're used for distance and LOS checks.
	-- However, we'll actually be aiming and the vehicle's driver to account for lag.
	local target = CHAR_TERA

   -- Helis can only fire missiles at players when they are in the player's LOS, and near the player.
	if (get_dist(LOCAL_PLAYER, VEH_HELI) < 300) then
		if (los_check(LOCAL_PLAYER, CHAR_HELI_PILOT)) then

         -- Select random r-vec and f-vec offsets.
			local r_offset = 0 -- rand_float(8,15)
			local f_offset = 30 -- rand_float(47, 50)
			--f_offset = f_offset * -1
			
         -- Sometimes offset to the left rather than the right
--			if (rand_int(0,1) == 0) then
--				r_offset = r_offset * -1
--			end
			
			-- Reset the pilot's accuracy
			npc_weapon_spread(CHAR_HELI_PILOT, 1.0)

         -- Shoot the missile
			
			helicopter_shoot_vehicle(VEH_HELI, VEH_FLATBED_TURRET, f_offset, r_offset)

			-- Decrease the pilot's accuracy
			npc_weapon_spread(CHAR_HELI_PILOT, 3.0)

         -- Wait a while after firing a missile before firing again or spawning a new attack heli.
			delay(rand_float(5.0, 8.0))

		end
	end

end

-- Spawn a new heli if we can find a valid spawn location
function dlc02_spawn_new_attack_heli(spawn_navp)

	-- Can't respawn the heli group if it is still loaded.
	if (group_is_loaded(GROUP_HELI)) then
		release_to_world(GROUP_HELI)
		thread_yield()
	end

	-- Create the heli and teleport the driver inside
	group_create(GROUP_HELI, true)
	dlc02_wait_for_vehicle_entry(CHAR_HELI_PILOT, VEH_HELI, 0)

	-- Set the hei's max hit points
	local normal_hp = get_current_hit_points(VEH_HELI)
	local hp_multiplier = dlc02_get_parameter_value("CHASE_HELI_HP_MULTIPLIER")
	set_max_hit_points(VEH_HELI, normal_hp * hp_multiplier)

	-- Decrease the pilot's accuracy
	npc_weapon_spread(CHAR_HELI_PILOT, 3.0)

	-- Teleport the heli to the attack location
	teleport_vehicle(VEH_HELI, spawn_navp)
	delay(1.0)

	-- Don't let the heli use its missiles except when scripted to do so
	helicopter_set_missile_chance(VEH_HELI, 0.001)

	-- Reduce the heli health.
	set_max_hit_points(VEH_HELI, get_max_hit_points(VEH_HELI) * HELI_HEALTH_MULTIPLIER, true)


end

-----------------------------------------------------------------------------------
--																											--
-- Mission termination functions	                                                --
--																											--
-----------------------------------------------------------------------------------

-- Cleanup mission
function dlc02_cleanup()

	IN_COOP = coop_is_active()

   -- Make players invulnerable
   turn_vulnerable(LOCAL_PLAYER)
   if (IN_COOP) then
      turn_vulnerable(REMOTE_PLAYER)
   end

	-- Allow roadblocks
	roadblocks_enable(true)

	-- Remove desired # notoriety vehicles override
	notoriety_set_desired_vehicle_count("Police", -1)

	-- Take back turret weapons, reenable all weapon slots
	-- Remove the player(s) an assault rifle
	if (Temp_weapons_given) then
		inv_weapon_remove_temporary(LOCAL_PLAYER, "AR50_launcher")
		inv_weapon_remove_temporary(LOCAL_PLAYER, "grenade")

      if (IN_COOP) then
         inv_weapon_remove_temporary(REMOTE_PLAYER, "AR50_launcher")
         inv_weapon_remove_temporary(REMOTE_PLAYER, "grenade")
      end
     
	end

	-- Enable all weapon slots...
	inv_weapon_enable_or_disable_all_slots(true)

	-- Don't allow cops to shoot from vehicles
	set_cops_shooting_from_vehicles(false)

	-- Allow laser guided rockets to timeout again.
--	rocket_guide_timers_disable(false)

	-- Player(s) can not enter/exit vehicles
	set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
	if (IN_COOP) then
		set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
	end

	-- reset the mid mission phonecall system
	mid_mission_phonecall_reset()

	-- remove minimap icons and ingame effects
	mission_waypoint_remove(SYNC_ALL)

	-- disable all triggers, remove callbacks
	for i, trigger in pairs(TABLE_ALL_TRIGGERS) do
		on_trigger("",trigger)
		on_trigger_exit("", trigger)
		trigger_enable(trigger,false)
	end

	if vehicle_exists(VEH_FLATBED_TURRET) and not vehicle_is_destroyed(VEH_FLATBED_TURRET) then
		vehicle_evacuate(VEH_FLATBED_TURRET)
		group_destroy(GROUP_FLATBED_TURRET)
	end
end

function dlc02_success()
	-- Called when the mission has ended with success
end

function dlc02_complete()	

	-- End the mission with success
	mission_end_success("dlc02", "dlc02-02", {NAVP_LOCAL_SUCCESS, NAVP_REMOTE_SUCCESS})
end

-- Fail mission, the flatbed was destroyed
function dlc02_failure_flatbed_destroyed()
	mission_end_failure("dlc02", TEXT_FAIL_FLATBED_DESTROYED)
end

-- Fail mission, the flatbed escaped.
function dlc02_failure_flatbed_escaped()
	mission_end_failure("dlc02", TEXT_FAIL_FLATBED_ESCAPED)
end

-- Fail mission, Tera died.
function dlc02_failure_tera_died()
	mission_end_failure("dlc02", TEXT_FAIL_TERA_DIED)
end

-- Faile mission, Tera abandoned
function dlc02_failure_tera_abandoned()
	mission_end_failure("dlc02", TEXT_FAIL_TERA_ABANDONED)
end

-----------------------------------------------------------------------------------
--																											--
-- Utility functions		                                                			--
--																											--
-----------------------------------------------------------------------------------

-- Get the value of the mission parameter.
--
-- parameter	Mission parameter whose value the function should return
--	i				If the parameter is a table, then i indexes the entry that should be returned
--
-- Returns mission paramater value.
function dlc02_get_parameter_value(parameter, i)

	local return_val = nil

	-- Check for an overloaded value for coop missions.
	if (IN_COOP and return_val == nil) then
		if (i) then
			if (DLC02_PARAMETERS["COOP_" .. parameter] ~= nil) then
				return_val = DLC02_PARAMETERS["COOP_" .. parameter][i]
			end
		else
			return_val = DLC02_PARAMETERS["COOP_" .. parameter]
		end
	end

	-- Get the standard value
	if (return_val == nil) then
		if (i) then
			if (DLC02_PARAMETERS[parameter] ~= nil) then
				return_val = DLC02_PARAMETERS[parameter][i]
			end
		else
			return_val = DLC02_PARAMETERS[parameter]
		end
	end

	return return_val
end

-- Wait for a character to enter a vehicle. Blocks 
function dlc02_wait_for_vehicle_entry(character, vehicle, seat_index)

	local delay_length = 0.25
	if (character == REMOTE_PLAYER) then
		delay_length = 0.5
	end

	local teleport_attempts = 1
	while( (not character_is_in_vehicle(character, vehicle)) and (teleport_attempts < 5) ) do
		teleport_attempts = teleport_attempts + 1
		vehicle_enter_teleport(character, vehicle, seat_index)
		delay(delay_length)
	end

end

-- Check if a navpoint is in either players field of view.
function dlc02_navpoint_in_fov(navpoint)

	local navpoint_in_local_fov = navpoint_in_player_fov(navpoint, LOCAL_PLAYER)
	local navpoint_in_remote_fov = false
	if (IN_COOP) then
		navpoint_in_remote_fov = navpoint_in_player_fov(navpoint, REMOTE_PLAYER)
	end

	return (navpoint_in_local_fov or navpoint_in_remote_fov)

end

-- Internal use: generalized helicopter_fly_to function
--
-- name:		name of the helicopter
-- dest:		name of destination navpoint(s)
-- direct:		if true, move directly, ignoring heightmap
-- follow:		if non-empty, target vehicle to follow
-- continue_at_goal:	if true, continue forward at goal
-- path:		list of navpoints to use for path
--
function dlc02_helicopter_fly_to(name, speed, direct, follow, continue_at_goal, path)
	local num_args
	num_args = path.n

	local arg_type = type(path[1])
	
	if (arg_type == "table") then
		num_args = sizeof_table(path[1])
		if (helicopter_fly_to_do(name, speed, direct, follow, continue_at_goal, num_args, path[1])) then
			local check_done = vehicle_pathfind_check_done(name)
			
			while ( check_done == 0 and not vehicle_is_destroyed(name)) do
				thread_yield()
				check_done = vehicle_pathfind_check_done(name)
			end
			
			return check_done == 1
		else
			return false
		end
	elseif (arg_type == "string") then
		if (helicopter_fly_to_do(name, speed, direct, follow, continue_at_goal, num_args, path)) then
			local check_done = vehicle_pathfind_check_done(name)
			
			while ( check_done == 0 and not vehicle_is_destroyed(name) ) do
				thread_yield()
				check_done = vehicle_pathfind_check_done(name)
			end
			
			return check_done == 1
		else
			return false
		end
	end
end

-- Make a helicopter go to a series of navpoints (could just be 1) without stopping
-- ignores heightmap and uses points directly as control points for the path
-- WARNING BE CAREFUL USING THIS!!!! HELICOPTER WILL NOT AVOID ANYTHING!!!
-- 
-- name:		name of the helicopter
-- dest:		name of destination navpoint(s)
--
function dlc02_fly_to_direct_dont_stop(name, speed, ...)
	return dlc02_helicopter_fly_to(name, speed, true, "", true, arg)
end

-- Make a helicopter go to a series of navpoints (could just be 1) while following a target without stopping
-- ignores heightmap and uses points directly as control points for the path
-- WARNING BE CAREFUL USING THIS!!!! HELICOPTER WILL NOT AVOID ANYTHING!!!
-- 
-- name:		name of the helicopter
-- dest:		name of destination navpoint(s)
-- target:		name of target to follow
--
function dlc02_fly_to_direct_follow_dont_stop(name, speed, target, ...)
	return dlc02_helicopter_fly_to(name, speed, true, target, true, arg)
end


-- Play a conversation in its own thread. Used to check-done the thread and suppress other voice lines
function dlc02_play_audio_conversation(conversation)
	audio_play_conversation(conversation)
end

-- Play a single line in its own thread
function dlc02_play_audio_line(line, character)
	audio_play_for_character(line, character, "voice", false, true)	
end

-----------------------------------------------------------------------------------
--																											--
-- Debugging/Test functions                                 							--
--																											--
-----------------------------------------------------------------------------------

-- An APC spawned near the mission-start trigger attacks th player. Used to test
-- vehicle weapons.
function dlc02_debug_apc_weapons()

   -- Fade out
   mission_start_fade_out()

   -- Teleport players to the start location
   teleport_coop(NAVP_LOCAL_PLAYER_START, NAVP_REMOTE_PLAYER_START)

   -- Create the test group
   group_create("dlc02_$Gapc_test", true)

   -- Declare convenience variables
   local driver = "dlc02_$c004"
   local apc = "dlc02_$v006"

   -- Put the driver and passenger in the apc
   vehicle_enter_teleport(driver, apc, 0)

   -- Give the driver the specified weapon
   inv_item_equip("sp_apc01", driver)

   -- Don't let the driver leave the vehicle
   vehicle_suppress_npc_exit(apc, true)

   -- Make the apc slow
   vehicle_max_speed(apc, 10)

   -- Fade back in
   mission_start_fade_in()	

   -- Allow cops to shoot from vehicles
   set_cops_shooting_from_vehicles(false)

   -- Have the driver attack and the apc start chasing
   attack(driver)
   vehicle_chase(apc, LOCAL_PLAYER)

   -- Don't progress through the mission
   while(true) do
      thread_yield()
   end

end

-- Used to test the EDF chases vehicles which jump from the a building near the airport
-- onto the highway.
function dlc02_debug_airport_jump()

   -- Create the EDF group.
	group_create(GROUP_EDF, true)

   -- Teleport plpayers to near the EDF, wait for teleport to complete
	teleport_coop("dlc02_$n082", "dlc02_$n082")
	delay(5.0)

   -- Start the various chases
	for i, edf_chase in pairs(EDF_CHASES) do

		local vehicle = edf_chase["vehicle"]
		local driver = (edf_chase["passengers"])[1]
		local passenger = (edf_chase["passengers"])[2]

		local do_jump = ((edf_chase["jump speed"] ~= nil) and (edf_chase["chase start"] ~= nil))

		-- Put the driver and passenger in the apc
		vehicle_enter_teleport(driver, vehicle, 0)
		vehicle_enter_teleport(passenger, vehicle, 1)

		-- Make the driver invulnerable
		turn_invulnerable(driver)

		-- Have the vehicle chase
		thread_new("dlc02_vehicle_chase",i)
	end


   -- Don't progress through the mission
   while(true) do
      thread_yield()
   end

end

----------------------------------
-- Ignore Everything Below Here --
----------------------------------

function dlc02_mystery()
	group_create( GROUP_MYSTERY )
	delay(3)
	vehicle_enter_teleport( C_ALIEN, V_UFO, 0 )
	teleport_vehicle( V_UFO, "dlc02_$n104" )
	helicopter_fly_to_direct( V_UFO, 45, MYSTERY_PATH )
	group_destroy( GROUP_MYSTERY )
end
