./m05.lua

  1. --[[ 
  2. 	m05.lua 
  3. 	SR3 Mission Script 
  4. 	DATE: 04-09-2010 
  5. 	AUTHOR:	Albert McDaniel 
  6. ]]-- 
  7.  
  8.  
  9. -- Debug flags -- 
  10.  
  11. -- Groups -- 
  12. 	M05_groups = { 
  13. 		heli_host = { 
  14. 			name = "m05_grp_heli_host", 
  15. 			heli = "m05_heli_host", 
  16. 		}, 
  17.  
  18. 		heli_client = { 
  19. 			name = "m05_grp_heli_client", 
  20. 			heli = "m05_heli_client", 
  21. 		}, 
  22.  
  23. 		pierce = { 
  24. 			name = "m05_grp_pierce", 
  25. 			heli = "m05_heli_pierce", 
  26. 			pierce = "m05_pierce", 
  27. 		}, 
  28.  
  29. 		shaundi = { 
  30. 			name = "m05_grp_shaundi", 
  31. 			shaundi = "m05_shaundi", 
  32. 		}, 
  33.  
  34. 		saints = { 
  35. 			name = "m05_grp_saints", 
  36. 			npcs = { "m05_saint<001>", "m05_saint<002>", "m05_saint<003>", "m05_saint<004>"}, 
  37. 		}, 
  38.  
  39. 		party_1 = { 
  40. 			name = "m05_grp_party_1", 
  41. 			npcs = { "m05_partier_f<001>", "m05_partier_f<002>", "m05_partier_f<004>", "m05_partier_f<005>", 
  42. 						"m05_partier_f<006>", "m05_partier_f<007>", "m05_partier_f<008>", "m05_partier_f<009>", "m05_partier_f<010>", 
  43. 						"m05_partier_f<011>", "m05_partier_f<012>", "m05_partier_f<013>", "m05_partier_f<014>", "m05_partier_f<015>", 
  44. 						"m05_partier_f<016>", "m05_partier_f<017>", "m05_partier_f<018>", "m05_partier_f<019>", "m05_partier_f<020>", 
  45. 						"m05_partier_f<021>", "m05_partier_f<022>", "m05_partier_f<023>", "m05_partier_m<001>", "m05_partier_m<002>", 
  46. 						"m05_partier_m<003>", "m05_partier_m<004>", "m05_partier_m<005>", "m05_partier_m<006>", "m05_partier_m<007>", 
  47. 						"m05_partier_m<009>", "m05_partier_m<010>", "m05_partier_m<011>", "m05_partier_m<014>", }, 
  48. 			nodes = { "Smoker", "Dancer", "Dancer", "Dancer", 
  49. 						 "Drinker", "Drinker", "Dancer", "Drinker", "Dancer", 
  50. 						 "Dancer", "Smoker", "Drinker", "Drinker", "Dancer", 
  51. 						 "Drinker", "Smoker", "Dancer", "Dancer", "Smoker", 
  52. 						 "Smoker", "Dancer", "Dancer", "Smoker", "Dancer", 
  53. 						 "Drinker", "Drinker", "Drinker", "Drinker", "Dancer", 
  54. 						 "Drinker", "Dancer", "Dancer", "Dancer", }, 
  55. 			--nodes = { "p_smoke<001>", "p_dance<001>", "p_talk<001>", "p_dance<002>", 
  56. 			--			 "p_drink<002>", "p_drink<003>", "p_dance<003>", "p_drink<004>", "p_dance<004>", 
  57. 			--			 "p_dance<005>", "p_smoke<014>", "p_drink<006>", "p_bench<001>", "p_talk<002>", 
  58. 			--			 "p_drink<007>", "p_smoke<002>", "p_dance<006>", "p_dance<007>", "p_smoke<003>", 
  59. 			--			 "p_smoke<004>", "p_dance<008>", "p_dance<009>", "p_smoke<005>", "p_talk<001>", 
  60. 			--			 "p_talk<003>", "p_drink<008>", "p_drink<009>", "p_drink<010>", "p_dance<010>", 
  61. 			--			 "p_drink<011>", "p_talk<004>", "p_cell<001>", "p_talk<005>", 
  62. 			--			 "p_drink<012>", "p_talk<006>", }, 
  63. 		}, 
  64.  
  65. 		party_2 = { 
  66. 			name = "m05_grp_party_2", 
  67. 			npcs = { "m05_partier_f<025>", "m05_partier_f<027>", "m05_partier_f<028>", 
  68. 						"m05_partier_f<029>", "m05_partier_f<031>", "m05_partier_f<032>", "m05_partier_f<033>", 
  69. 						"m05_partier_f<034>", "m05_partier_f<035>", "m05_partier_m<015>", "m05_partier_m<016>", 
  70. 						"m05_partier_m<017>", "m05_partier_m<019>", "m05_partier_m<020>" }, 
  71. 			nodes = { "Dancer", "Smoker", "Dancer", 
  72. 						 "Dancer", "Smoker", "Dancer", "Dancer", 
  73. 						 "Drinker", "Drinker", "Smoker", "Dancer", 
  74. 						 "Dancer", "Smoker", "Dancer" }, 
  75. 		}, 
  76.  
  77. 		guards = { 
  78. 			name = "m05_grp_guards", 
  79. 			npcs = { "m05_guard<001>", "m05_guard<002>", "m05_guard<003>", "m05_guard<004>", "m05_guard<005>", 
  80. 						"m05_guard<006>", "m05_guard<007>", "m05_guard<008>", "m05_guard<009>", "m05_guard<010>", 
  81. 						"m05_guard<011>", "m05_guard<012>", "m05_guard<013>" }, 
  82. 			nodes = { "Drinker", "Drinker", "Smoker", "Drinker", "Drinker", 
  83. 						 "Drinker", "Smoker", "Smoker", "Smoker", "Drinker", 
  84. 						 "Drinker", "Drinker", "Smoker", }, 
  85. 		}, 
  86.  
  87. 		barricade = { 
  88. 			name = "m05_grp_barricade", 
  89. 			npcs = { "m05_barr<001>", "m05_barr<002>", "m05_barr<003>", "m05_barr<004>", "m05_barr<005>", 
  90. 						"m05_barr<006>", "m05_barr<007>", "m05_barr<008>", "m05_barr<009>" }, 
  91. 			script = { "m05_barr<007>", "m05_barr<003>", "m05_barr<005>", "m05_barr<004>", "m05_barr<009>", "m05_barr<001>" }, 
  92. 		}, 
  93.  
  94. 		backup_1 = { 
  95. 			name = "m05_grp_backup_1", 
  96. 			npcs = { "m05_ms_backup<001>", "m05_ms_backup<002>", "m05_ms_backup<003>" }, 
  97. 		}, 
  98.  
  99. 		drop_1 = { 
  100. 			name = "m05_grp_drop_1", 
  101. 			npcs = { "m05_drop<001>", "m05_drop<002>", "m05_drop<003>", "m05_drop<004>" }, 
  102. 		}, 
  103.  
  104. 		drop_2 = { 
  105. 			name = "m05_grp_drop_2", 
  106. 			npcs = { "m05_drop<005>", "m05_drop<006>", "m05_drop<007>", "m05_drop<008>" }, 
  107. 		}, 
  108.  
  109. 		targets = { 
  110. 			name = "m05_grp_targets", 
  111. 			npcs = { "m05_target<001>",}, 
  112. 			nodes = { "Drinker",}, 
  113. 			taunt = { false,}, 
  114. 		}, 
  115. 		 
  116. 		elevator = { 
  117. 			name = "m05_grp_elevator_enemies", 
  118. 			npcs = { 
  119. 				"m05_enemy_elevator<001>", "m05_enemy_elevator<002>", "m05_enemy_elevator<003>", "m05_enemy_elevator<004>", "m05_enemy_elevator<005>", 
  120. 			}, 
  121. 			destination = { 
  122. 				-- At the entrance of the basement 
  123. 				{"m05_nav_elev_enemies_01<001>", "m05_nav_elev_enemies_01<002>", "m05_nav_elev_enemies_01<003>", "m05_nav_elev_enemies_01<004>", "m05_nav_elev_enemies_01<005>"}, 
  124. 				 
  125. 				-- Near the elevator 
  126. 				{"m05_nav_elev_enemies_02<001>", "m05_nav_elev_enemies_02<002>", "m05_nav_elev_enemies_02<003>", "m05_nav_elev_enemies_02<004>", "m05_nav_elev_enemies_02<005>"}, 
  127. 				 
  128. 				-- Do the same again. 
  129. 				{"m05_nav_elev_enemies_02<001>", "m05_nav_elev_enemies_02<002>", "m05_nav_elev_enemies_02<003>", "m05_nav_elev_enemies_02<004>", "m05_nav_elev_enemies_02<005>"}, 
  130. 			}, 
  131. 		}, 
  132.  
  133. 		chase_host = { 
  134. 			name = "m05_grp_chase_host", 
  135. 			heli = "m05_heli_chase_host", 
  136. 			pilot = "m05_pilot_host", 
  137. 			target = "m05_target_chase_host" 
  138. 		}, 
  139.  
  140. 		warehouse = { 
  141. 			name = "m05_grp_warehouse", 
  142. 		}, 
  143.  
  144. 		rockets = { 
  145. 			name = "m05_grp_rockets", 
  146. 			npcs = { "m05_rocket<001>", "m05_rocket<002>", "m05_rocket<003>", "m05_rocket<004>", 
  147. 						"m05_rocket<005>", "m05_rocket<006>", "m05_rocket<007>", "m05_rocket<008>", 
  148. 						"m05_rocket<009>", "m05_rocket<010>", "m05_rocket<011>", "m05_rocket<012>", } 
  149. 		}, 
  150. 	} 
  151.  
  152. -- Navpoints -- 
  153. 	M05_nav = { 
  154. 		start_navs = {"m05_cp_start_host", "m05_cp_start_client"}, 
  155. 		cp_start_host = "m05_cp_start_host", 
  156. 		cp_start_client = "m05_cp_start_client", 
  157. 		cp_saints_host = "m05_cp_saints_host", 
  158. 		cp_saints_client = "m05_cp_saints_client", 
  159. 		cp_shaundi = "m05_cp_shaundi", 
  160. 		end_navs = {"m05_nav_end_local", "m05_nav_end_remote"}, 
  161. 		pierce = "m05_nav_pierce", 
  162. 		hover_host = "m05_nav_hover_host", 
  163. 		hover_client = "m05_nav_hover_client", 
  164. 		land_host = "m05_nav_land_host", 
  165. 		land_client = "m05_nav_land_client", 
  166. 		leap_host = "m05_nav_leap_host", 
  167. 		leap_client = "m05_nav_leap_client", 
  168. 		cancel_host = "m05_nav_cancel_host", 
  169. 		cancel_client = "m05_nav_cancel_client", 
  170. 		chase_outside = "m05_nav_chase_outside", 
  171. 		chase_end = "m05_nav_chase_end", 
  172.  
  173. 		guards = { "m05_nav_barr<001>", "m05_nav_barr<002>", "m05_nav_barr<003>", "m05_nav_barr<004>", "m05_nav_barr<005>", "m05_nav_barr<006>" }, 
  174.  
  175. 		backup = { "m05_nav_backup<001>", "m05_nav_backup<002>", "m05_nav_backup<003>", "m05_nav_backup<004>", "m05_nav_backup<005>" }, 
  176.  
  177. 		saints01 = { "m05_nav_saint<001>", "m05_nav_saint<002>", "m05_nav_saint<003>", "m05_nav_saint<004>" }, 
  178. 		saints02 = { "m05_nav_saint<005>", "m05_nav_saint<006>", "m05_nav_saint<007>", "m05_nav_saint<008>" }, 
  179. 		saints03 = { "m05_nav_saint<009>", "m05_nav_saint<010>", "m05_nav_saint<011>", "m05_nav_saint<012>" }, 
  180. 		saints04 = { "m05_nav_saint<013>", "m05_nav_saint<014>", "m05_nav_saint<015>", "m05_nav_saint<016>" }, 
  181.  
  182. 		rockets = { "m05_nav_rocket<001>", "m05_nav_rocket<002>", "m05_nav_rocket<003>", "m05_nav_rocket<004>", 
  183. 						"m05_nav_rocket<005>", "m05_nav_rocket<006>", "m05_nav_rocket<007>", "m05_nav_rocket<008>", 
  184. 						"m05_nav_rocket<009>", "m05_nav_rocket<010>", "m05_nav_rocket<011>", "m05_nav_rocket<012>", }, 
  185. 		flee = {"m05_party_flee_nav<001>", "m05_party_flee_nav<002>", "m05_party_flee_nav<003>"}, 
  186. 	} 
  187.  
  188. 	M05_paths = { 
  189. 		heli_host = { "m05_heli_path<001>", "m05_heli_path<002>" }, 
  190. 		heli_client = { "m05_heli_path<001>", "m05_heli_path<002>" }, 
  191. 		heli_drop_host = { "m05_sp_chase_host_01", "m05_sp_chase_host_02", }, 
  192. 		heli_drop_client = { "m05_sp_chase_client_01", "m05_sp_chase_client_02", }, 
  193. 	} 
  194.  
  195. -- Triggers -- 
  196. 	M05_triggers = { 
  197. 		kill = "m05_trigger_kill", 
  198. 		left = "m05_trigger_left", 
  199. 		pool = "m05_trigger_pool", 
  200. 		land = "m05_trigger_land", 
  201. 		downstairs = "m05_trigger_downstairs", 
  202. 		grenades = "m05_trigger_grenades", 
  203. 		saints = "m05_trigger_saints", 
  204. 		barricade = "m05_trigger_barricade", 
  205. 		chase = "m05_trigger_chase", 
  206. 		chase_end = "m05_trigger_chase_end", 
  207. 		warehouse = "m05_trigger_warehouse", 
  208. 		saints02 = "m05_trigger_saints02", 
  209. 		saints03 = "m05_trigger_saints03", 
  210. 		saints04 = "m05_trigger_saints04", 
  211. 		enemy_elevator = "m05_trig_enemy_elevator", 
  212. 		lt_pool = "m05_trigger_lt_kill", 
  213. 	} 
  214.  
  215. -- Spawn Regions -- 
  216. 	M05_regions = { 
  217. 		e_base = "m05_sr_elevator_base", 
  218. 		e_mid = "m05_sr_elevator_mid", 
  219. 		e_top = "m05_sr_elevator_top", 
  220. 		s_base = "m05_sr_stairs_base", 
  221. 		s_top = "m05_sr_stairs_top", 
  222. 	} 
  223.  
  224. -- Spawn Groups -- 
  225. 	M05_cspawn = { 
  226. 		enemy_1 = "m05_grp_cs_enemy_1", 
  227. 		enemy_2 = "m05_grp_cs_enemy_2", 
  228. 		enemy_3 = "m05_grp_cs_enemy_3", 
  229. 		saints_1 = "m05_grp_cs_saints_1", 
  230. 		saints_2 = "m05_grp_cs_saints_2", 
  231. 		saints_3 = "m05_grp_cs_saints_3", 
  232. 	} 
  233.  
  234. -- Movers -- 
  235. 	M05_movers = { 
  236. 		"Barrel_Mover<001>", "Barrel_Mover<002>", "Barrel_Mover<003>", "Barrel_Mover<004>", 
  237. 		"Barrel_Mover<005>", "Barrel_Mover<006>", "Barrel_Mover<007>", "Barrel_Mover<008>", 
  238. 		"Barrel_Mover<009>", 
  239. 	} 
  240.  
  241. 	M05_doors = { 
  242. 		bathroom = "m05_door_bathroom", 
  243. 		bedroom = "m05_door_bedroom", 
  244. 		bedroom2= "m05_door_bedroom<001>", 
  245. 		bedroom3= "m05_door_bedroom<002>", 
  246. 		greenhouse = "m05_door_greenhouse", 
  247. 		ne1 = "m05_door_ne1", 
  248. 		ne2 = "m05_door_ne2", 
  249. 		nw1 = "m05_door_nw1", 
  250. 		stairs_e = "m05_door_stairs_e", 
  251. 		openme = "m05_door_openme", 
  252. 		elevator = "m05_door_elevator", 
  253. 		chase = "m05_door_chase", 
  254. 		enemy_elevator = "m05_elevator_door_mid", 
  255. 	} 
  256.  
  257. -- persona lines -- 
  258. 	M05_lines = { 
  259. 		jump = "M05_Jump",-- 
  260. 		jump_waiting = "M05_Jump_Waiting",-- 
  261. 		why_jump = "M05_Why_Am_I_Jumping",-- 
  262. 		penthouse = "M05_React_To_Penthouse",-- 
  263. 		come_get_us = "M05_Come_Get_Us",-- 
  264. 		barrier = "M05_Barrier",-- 
  265. 		stored_items = "M05_Comment_On_Stored_Items",-- 
  266. 		heli_dropoff = "M05_Helicopter_Dropping_off_01",-- 
  267. 		warehouse = "M05_Warehouse",-- 
  268. 	 
  269. 	} 
  270. 	 
  271. 	 
  272. -- Conversations -- 
  273. 	M05_conv = { 
  274. 		land = { 
  275. 			name = "M05_Landed",-- 
  276. 			handle = INVALID_CONVERSATION_HANDLE, 
  277. 		}, 
  278.  
  279. 		int1 = { 
  280. 			name = "M05_Interrogation_Roof",-- 
  281. 			handle = INVALID_CONVERSATION_HANDLE, 
  282. 			persona = "Interrogation", 
  283. 		}, 
  284.  
  285. 		elevator = { 
  286. 			name = "M05_Elevator",-- 
  287. 			handle = INVALID_CONVERSATION_HANDLE 
  288. 		}, 
  289.  
  290. 		clear_out = { 
  291. 			name = "M05_Clean_Out_Penthouse",-- 
  292. 			handle = INVALID_CONVERSATION_HANDLE 
  293. 		}, 
  294.  
  295. 		explosive = { 
  296. 			name = "M05_Finding_Explosives",-- 
  297. 			handle = INVALID_CONVERSATION_HANDLE 
  298. 		}, 
  299.  
  300. 		escape = { 
  301. 			name = "M05_Heli_Escape",-- 
  302. 			handle = INVALID_CONVERSATION_HANDLE 
  303. 		}, 
  304.  
  305. 		early_chase = { 
  306. 			name = "M05_Early_Heli_Chase", 
  307. 			handle = INVALID_CONVERSATION_HANDLE 
  308. 		}, 
  309.  
  310. 		chase = { 
  311. 			name = "M05_Heli_Chase", 
  312. 			handle = INVALID_CONVERSATION_HANDLE 
  313. 		}, 
  314.  
  315. 		int2 = { 
  316. 			name = "M05_Warehouse_Interrogation",-- 
  317. 			handle = INVALID_CONVERSATION_HANDLE, 
  318. 			persona = "Interrogation", 
  319. 		}, 
  320. 		 
  321. 		shaundi_color = { 
  322. 			name = "M05_Tell_Shaundi_Color", 
  323. 			handle = INVALID_CONVERSATION_HANDLE, 
  324. 		}, 
  325. 	} 
  326.  
  327. 	M05_persona = { 
  328. 		shaundi = { 
  329. 			name = "Shaundi", 
  330. 			id = INVALID_PERSONA_HANDLE 
  331. 		}, 
  332. 	} 
  333.  
  334. -- Threads -- 
  335. 	M05_threads = { 
  336. 		nag = INVALID_THREAD_HANDLE, 
  337. 		chase_host = INVALID_THREAD_HANDLE, 
  338. 		heli_client_thread = INVALID_THREAD_HANDLE, 
  339. 		dist_host = INVALID_THREAD_HANDLE, 
  340. 		dist_client = INVALID_THREAD_HANDLE, 
  341. 		rockets = INVALID_THREAD_HANDLE, 
  342. 		elevator_spawn = INVALID_THREAD_HANDLE, 
  343. 		attack_line = INVALID_THREAD_HANDLE, 
  344. 	} 
  345.  
  346. -- Checkpoints -- 
  347. 	M05_checkpoints = { 
  348. 		start = MISSION_START_CHECKPOINT,			-- defined in ug_lib.lua 
  349. 		saints = "m05_cp_saints", 
  350. 		chase = "m05_cp_chase", 
  351. 	} 
  352.  
  353. -- Cutscenes -- 
  354. 	M05_CUTSCENE_MISSION_INTRO = "05_IN" 
  355. 	M05_CUTSCENE_MISSION_OUTRO = "05_out" 
  356.  
  357. -- Other -- 
  358. 	M05_in_coop = false 
  359. 	M05_jumped = false 
  360. 	M05_goal_reached = false 
  361. 	M05_barricade_breached = false 
  362. 	M05_heli_arrived = false 
  363. 	M05_elevator_spawn_num = 0 
  364. 	M05_elevator_spawn_num_min = 2 
  365. 	M05_elevator_spawn_num_max = 4 
  366. 	M05_attack_line_time = 10.0 
  367. 	M05_dont_kill_lt = false 
  368.  
  369. 	M05_land_call_completed = false 
  370. 	M05_color_call_completed = false 
  371. 	M05_succeeded = false 
  372. 	 
  373. 	M05_chase = { 
  374. 		local_player_ready = false, 
  375. 		remote_player_ready = false, 
  376. 		min_dist = 20, 
  377. 		max_dist = 225, 
  378. 		min_speed = 10, 
  379. 		max_speed = 100, 
  380. 		rocket_dist = 150, 
  381. 	} 
  382.  
  383. 	M05_anims = { "cheering a", "observe a", "observe b", "observe c", "ovserve E", } 
  384. 	 
  385.  
  386. -- ************************* 
  387. -- 
  388. -- Standard functions 
  389. -- 
  390. -- ************************* 
  391.  
  392. -- This is the primary entry point for the mission, and is responsible for starting up the mission 
  393. -- at the specified checkpoint. 
  394. -- CALLED FROM CODE 
  395. -- 
  396. -- m05_checkpoint:	The checkpoint the mission should begin at 
  397. -- is_restart:			TRUE if the mission is restarting, FALSE otherwise 
  398. -- 
  399. function m05_start(m05_cp, is_restart) 
  400. 	M05_in_coop = coop_is_active() 
  401. 	 
  402. 	-- Make sure the screen is completly faded out 
  403. 	mission_start_fade_out(0.0) 
  404. 	 
  405. 	spawning_vehicles( false ) 
  406. 	spawning_pedestrians( false ) 
  407. 	 
  408. 	crib_disable_interface( true ) 
  409. 	 
  410. 	-- do this before starting the cutscene so that the cutscene doesn't think it has to turn it back off 
  411. 	city_zone_swap( "m05", true ) 
  412.  
  413. 	-- Check if this mission starting from the beginning 
  414. 	if (m05_cp == M05_checkpoints.start) then 
  415. 		if (is_restart == false) then 
  416. 			-- First time playing mission 
  417.  
  418. 			-- Play an intro cutscene??? 
  419. 			if (M05_CUTSCENE_MISSION_INTRO ~= "") then 
  420. 				cutscene_play(M05_CUTSCENE_MISSION_INTRO, nil, M05_nav.start_navs, false) 
  421. 				--bink_play(M05_CUTSCENE_MISSION_INTRO) 
  422. 			end 
  423. 		end 
  424. 		fade_out(0) 
  425. 	end 
  426.  
  427. 	-- Handle mission initialization for the current checkpoint 
  428. 	m05_initialize(m05_cp) 
  429.  
  430. 	-- Run the mission from the current checkpoint 
  431. 	m05_run(m05_cp) 
  432. 	 
  433. end 
  434.  
  435. -- This is the primary function responsible for running the entire mission from start to finish. 
  436. -- 
  437. -- first_checkpoint:	The first checkpoint to begin running the mission at 
  438. -- 
  439. function m05_run(first_checkpoint) 
  440. 	local current_checkpoint = first_checkpoint 
  441.  
  442. 	-- For the entire mission, warp to the base of the tower on cancel 
  443. 	mission_set_cancel_warp_location(M05_nav.cancel_host, M05_nav.cancel_client) 
  444.  
  445. 	-- Set up failure if the player leaves the penthouse 
  446. 	trigger_enable(M05_triggers.left, true) 
  447. 	on_trigger_exit("m05_trigger_left", M05_triggers.left) 
  448.  
  449. 	-- Run the mission from the beginning 
  450. 	if current_checkpoint == M05_checkpoints.start then 
  451. 		-- Parachute in, find out how to let the Saints in, and do so 
  452. 		m05_parachute_in() 
  453. 		m05_get_info() 
  454. 		m05_let_saints_in() 
  455.  
  456. 		-- Set the next checkpoint 
  457. 		current_checkpoint = M05_checkpoints.saints 
  458. 		mission_set_checkpoint(M05_checkpoints.saints, true) 
  459. 	end 
  460.  
  461. 	if current_checkpoint == M05_checkpoints.saints then 
  462. 		-- Kill all remaining Morningstar 
  463. 		m05_clear_penthouse() 
  464.  
  465. 		-- Kill each lieutenant 
  466. 		--m05_kill_lieutenant_1() 
  467. 		--m05_kill_lieutenant_2() 
  468.  
  469. 		-- Set the next checkpoint 
  470. 		current_checkpoint = M05_checkpoints.chase 
  471. 		mission_set_checkpoint(M05_checkpoints.chase, true, true) 
  472. 	end 
  473.  
  474. 	if current_checkpoint == M05_checkpoints.chase then 
  475. 		-- Chase down the last lieutenant 
  476. 		m05_spawn_heli() 
  477. 		m05_get_on_heli() 
  478. 		m05_chase_heli() 
  479. 	end 
  480.  
  481. 	M05_succeeded = true 
  482. 	 
  483. 	mission_end_success("m05", M05_CUTSCENE_MISSION_OUTRO, M05_nav.end_navs) 
  484. end 
  485.  
  486. -- This is the primary function responsible for cleaning up the entire mission 
  487. -- CALLED FROM CODE 
  488. -- 
  489. function m05_cleanup() 
  490. 	-- Stop any conversations 
  491. 	cleanup_conversations(M05_conv) 
  492. 	 
  493. 	audio_remove_mission_cellphone(M05_conv.land.name) 
  494. 	audio_remove_mission_cellphone(M05_conv.early_chase.name) 
  495. 	audio_remove_mission_cellphone(M05_conv.chase.name) 
  496. 	audio_remove_mission_cellphone(M05_conv.shaundi_color.name) 
  497. 	 
  498. 	helicopters_set_jitter_override(1.0, 1.0) 
  499.  
  500. 	-- Unload personas 
  501. 	for i, pers in pairs(M05_persona) do 
  502. 		if (pers.id ~= INVALID_PERSONA_HANDLE) then 
  503. 			audio_persona_remove_2d(pers.id) 
  504. 			pers.id = INVALID_PERSONA_HANDLE 
  505. 		end 
  506. 	end 
  507.  
  508. 	-- Stop any threads 
  509. 	cleanup_threads(M05_threads) 
  510.  
  511. 	-- Clear any triggers 
  512. 	for i, trig in pairs(M05_triggers) do 
  513. 		m05_clear_trigger(trig) 
  514. 	end 
  515.  
  516. 	--clear guard callbacks 
  517. 	cleanup_callbacks( { M05_groups, M05_triggers, M05_movers } ) 
  518. 	 
  519. 	-- Clean up everything left at the penthouse 
  520. 	m05_cleanup_penthouse() 
  521. 	 
  522. 	if group_is_loaded(M05_groups.pierce.name) then 
  523. 		group_destroy(M05_groups.pierce.name) 
  524. 	end 
  525.  
  526. 	-- Clear the rest of the groups 
  527. 	if group_is_loaded(M05_groups.heli_host.name) then 
  528. 		on_vehicle_enter("", M05_groups.heli_host.heli) 
  529. 		marker_remove(M05_groups.heli_host.heli) 
  530. 		group_destroy(M05_groups.heli_host.name) 
  531. 	end 
  532. 	if group_is_loaded(M05_groups.heli_client.name) then 
  533. 		on_vehicle_enter("", M05_groups.heli_client.heli) 
  534. 		marker_remove(M05_groups.heli_client.heli) 
  535. 		group_destroy(M05_groups.heli_client.name) 
  536. 	end 
  537. 	if group_is_loaded(M05_groups.chase_host.name) then 
  538. 		marker_remove(M05_groups.chase_host.target) 
  539. 		group_destroy(M05_groups.chase_host.name) 
  540. 	end 
  541. 	if group_is_loaded(M05_groups.elevator.name) then 
  542. 		group_destroy(M05_groups.elevator.name) 
  543. 	end 
  544. 	if group_is_loaded(M05_groups.warehouse.name) then 
  545. 		group_destroy(M05_groups.warehouse.name) 
  546. 	end 
  547. 	if group_is_loaded(M05_groups.rockets.name) then 
  548. 		group_destroy(M05_groups.rockets.name) 
  549. 	end 
  550.  
  551. 	-- Clear any objective text 
  552. 	objective_text_clear(0) 
  553. 	hud_bar_off(0) 
  554. 	hud_bar_off(1) 
  555. 	hud_timer_stop(1) 
  556.  
  557. 	-- Restore player controls 
  558. 	player_human_shield_lock(LOCAL_PLAYER, false) 
  559. 	hud_prompt_clear(LOCAL_PLAYER) 
  560. 	on_taunt("", LOCAL_PLAYER) 
  561. 	character_allow_ragdoll(LOCAL_PLAYER, true) 
  562. 	if (M05_in_coop) then 
  563. 		player_human_shield_lock(REMOTE_PLAYER, false) 
  564. 		hud_prompt_clear(REMOTE_PLAYER) 
  565. 		on_taunt("", REMOTE_PLAYER) 
  566. 		character_allow_ragdoll(REMOTE_PLAYER, true) 
  567. 	end 
  568.  
  569. 	-- Remove costumes 
  570. --	customization_item_revert() 
  571. 	 
  572. 	-- crib access is now allowed 
  573. 	crib_disable_interface( false ) 
  574. 	 
  575. 	-- Re-enable base jumping 
  576. 	base_jumping_enable(true) 
  577. 	 
  578. 	-- Re-enable elevator triggers 
  579. 	trigger_type_enable( "warp", true) 
  580.  
  581. 	-- Restore notoriety spawns 
  582. 	notoriety_reset("morningstar") 
  583. 	notoriety_force_no_spawn("luchadores", false) 
  584. 	notoriety_force_no_spawn("deckers", false) 
  585. 	notoriety_force_no_spawn("morningstar", false) 
  586. 	notoriety_force_no_spawn("police", false) 
  587. 	notoriety_set_can_decay(true) 
  588. 	 
  589. 	city_zone_swap( "m05", false ) 
  590. 	 
  591. 	if M05_succeeded == true then 
  592. 		city_zone_swap( "hq", true ) 
  593. 	end 
  594. 	 
  595. 	-- something wonky with ped spawns 
  596. 	-- it's spawning street peds in hq 
  597. 	-- so just kill them all 
  598. 	world_despawn_all_pedestrians() 
  599. 	 
  600. 	spawning_vehicles( true ) 
  601. 	spawning_pedestrians( true ) 
  602. 	 
  603. 	crib_disable_interface( false ) 
  604. end 
  605.  
  606. -- Called when the mission has ended with success 
  607. -- CALLED FROM CODE 
  608. -- 
  609. function m05_success()	 
  610. 	--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]-- 
  611. end 
  612.  
  613. -- ************************* 
  614. -- 
  615. -- Local functions 
  616. -- 
  617. -- ************************* 
  618.  
  619. -- Initialize the mission for the specified checkpoint 
  620. -- 
  621. -- checkpoint:		Checkpoint to initialize the mission to 
  622. -- 
  623. function m05_initialize(checkpoint) 
  624. 	-- Set the mission author 
  625. 	set_mission_author("Albert McDaniel") 
  626.  
  627. 	-- Prevent notoriety spawns 
  628. 	notoriety_force_no_spawn("luchadores", true) 
  629. 	notoriety_force_no_spawn("deckers", true) 
  630. 	notoriety_force_no_spawn("morningstar", true) 
  631. 	notoriety_force_no_spawn("police", true) 
  632. 	notoriety_set_can_decay(false) 
  633. 	 
  634. 	-- Dress up players 
  635. 	-- customization_outfit_wear("Lets Pretend Male C") 
  636. 	 
  637. 	-- crib access is not allowed 
  638. 	crib_disable_interface( true ) 
  639. 	 
  640. 	-- Disable Base Juming 
  641. 	base_jumping_enable(false) 
  642. 	party_dismiss_all() 
  643. 	 
  644. 	-- Disable elevator triggers 
  645. 	trigger_type_enable( "warp", false) 
  646.  
  647. 	-- Set up the mission based on the checkpoint 
  648. 	if (checkpoint == M05_checkpoints.start) then 
  649. 		-- Spawn Pierce's helicopter 
  650. 		group_create(M05_groups.pierce.name, true) 
  651. 		vehicle_suppress_npc_exit(M05_groups.pierce.heli, true) 
  652. 		vehicle_enter_teleport(M05_groups.pierce.pierce, M05_groups.pierce.heli) 
  653. 		helicopter_fly_to_direct(M05_groups.pierce.heli, -1, M05_nav.pierce) 
  654. 		vehicle_set_keyframed_physics( M05_groups.pierce.heli, true ) 
  655. 		set_ignore_ai_flag(M05_groups.pierce.pierce, true) 
  656. 		set_dont_attack_me_on_sight_flag(M05_groups.pierce.pierce, true) 
  657. 		radio_block( M05_groups.pierce.heli ) 
  658.  
  659. 		-- Put the player(s) into the helicopter 
  660. 		vehicle_enter_teleport(LOCAL_PLAYER, M05_groups.pierce.heli, 5) 
  661. 		if (M05_in_coop == true) then 
  662. 			vehicle_enter_teleport(REMOTE_PLAYER, M05_groups.pierce.heli, 3) 
  663. 		end 
  664.  
  665. 		-- Prevent the players from re-entering the heli 
  666. 		set_unjackable_flag(M05_groups.pierce.heli, true) 
  667.  
  668. 		-- Spawn the penthouse 
  669. 		m05_spawn_penthouse(true, true) 
  670.  
  671. 		-- Play Morningstar music 
  672. 		audio_ambient_emitter_start("M05_Morningstar_Music<001>") 
  673. 		 
  674. 		for i, mover in pairs(M05_movers) do 
  675. 			mesh_mover_set_invulnerable(mover, true) 
  676. 		end 
  677. 	end 
  678.  
  679. 	if (checkpoint == M05_checkpoints.saints) then 
  680. 		-- Teleport the players (so the resources can stream in) 
  681. 		teleport_coop(M05_nav.cp_saints_host, M05_nav.cp_saints_client, true) 
  682.  
  683. 		-- Spawn the penthouse 
  684. 		m05_spawn_penthouse(true, false) 
  685. 		m05_spawn_saints(false, false) 
  686. 	end 
  687.  
  688. 	if (checkpoint == M05_checkpoints.chase) then 
  689. 		-- Teleport the players (so the resources can stream in) 
  690. 		teleport_coop(M05_nav.cp_start_host, M05_nav.cp_start_client, true) 
  691.  
  692. 		-- Spawn the penthouse 
  693. 		m05_spawn_penthouse(false, false) 
  694. 		m05_spawn_saints(true, false) 
  695.  
  696. 		-- Spawn the heli in the correct location 
  697. 		group_create(M05_groups.heli_host.name, true) 
  698. 		teleport_vehicle(M05_groups.heli_host.heli, M05_nav.land_host) 
  699. 		if (M05_in_coop) then 
  700. 			group_create(M05_groups.heli_client.name, true) 
  701. 			teleport_vehicle(M05_groups.heli_client.heli, M05_nav.land_client) 
  702. 		end 
  703. 	end 
  704.  
  705. 	-- Start fading in  
  706. 	mission_start_fade_in() 
  707. end 
  708.  
  709. function m05_setup_guard(npc) 
  710. 	on_attack_performed("m05_guard_attacked", npc) 
  711. end 
  712.  
  713. -- Set up and spawn everything in the penthouse 
  714. -- 
  715. -- party:		(bool) true if party guards should spawn 
  716. -- barricade:	(bool) true if barricade guards should spawn 
  717. -- 
  718. function m05_spawn_penthouse(party, barricade) 
  719. 	-- Set up the kill trigger for thrown NPCs 
  720. 	trigger_enable(M05_triggers.kill, true) 
  721. 	on_trigger_exit("m05_trigger_kill_zone", M05_triggers.kill) 
  722.  
  723. 	-- Open a bunch of doors for AI 
  724. 	door_open(M05_doors.bathroom) 
  725. 	door_open(M05_doors.bedroom) 
  726. 	door_open(M05_doors.bedroom2) 
  727. 	door_open(M05_doors.bedroom3) 
  728. 	door_open(M05_doors.greenhouse) 
  729. 	door_open(M05_doors.ne1, true) 
  730. 	door_open(M05_doors.ne2, true) 
  731. 	door_open(M05_doors.nw1, true) 
  732. 	door_open(M05_doors.openme, true) 
  733. 	door_open(M05_doors.stairs_e) 
  734. 	door_lock(M05_doors.elevator, true) 
  735. 	door_lock(M05_doors.enemy_elevator, true) 
  736.  
  737. 	-- Spawn party-goers 
  738. 	group_create(M05_groups.party_1.name, true) 
  739. 	--for i, npc in pairs(M05_groups.party_1.npcs) do 
  740. 	--	npc_use_closest_action_node_of_type(npc, M05_groups.party_1.nodes[i], 3) 
  741. 	--end 
  742.  
  743. 	-- Enable the spawn regions 
  744. 	spawn_region_enable(M05_regions.e_top, true) 
  745. 	spawn_region_enable(M05_regions.e_mid, true) 
  746. 	spawn_region_enable(M05_regions.s_top, true) 
  747. 	spawn_region_enable(M05_regions.s_base, true) 
  748.  
  749. 	-- Spawn the party guards 
  750. 	if (party) then 
  751. 		group_create(M05_groups.guards.name, true) 
  752. 		group_foreach_npc(M05_groups.guards.name, m05_setup_guard) 
  753. 	end 
  754.  
  755. 	-- Spawn or hide the barricade 
  756. 	if (barricade) then 
  757. 		-- Spawn additional temporary party-goers to fill out the area 
  758. 		group_create(M05_groups.party_2.name, true) 
  759. 		 
  760. 		-- Attach them to their action nodes. 
  761. 		--for i, npc in pairs(M05_groups.party_2.npcs) do 
  762. 		--	npc_use_closest_action_node_of_type(npc, M05_groups.party_2.nodes[i], 3) 
  763. 		--end 
  764.  
  765. 		-- Spawn the first objective target 
  766. 		m05_spawn_target(M05_groups.targets) 
  767.  
  768. 		-- Don't let the player grab the targets until they are actually targets, to prevent tossing them off the roof 
  769. 		for i, npc in pairs (M05_groups.targets.npcs) do 
  770. 			character_set_counter_on_grabbed_by_player(npc, true) 
  771. 			on_death( "m05_lt_died", npc ) 
  772. 		end 
  773. 		 
  774. 		-- set up kill zone for lt 
  775. 		trigger_enable(M05_triggers.lt_pool, true) 
  776. 		on_trigger_exit("m05_kill_lt", M05_triggers.lt_pool) 
  777. 		 
  778. 	else 
  779. 		-- The barricade is already cleared, so hide it 
  780. 		for i, mover in pairs(M05_movers) do 
  781. 			mesh_mover_hide(mover)  
  782. 		end 
  783.  
  784. 		-- Force initial notoriety 
  785. 		notoriety_set_min("morningstar", 2) 
  786. 	end 
  787. end 
  788.  
  789. function m05_lt_died() 
  790. 		if M05_dont_kill_lt  == false then 
  791. 			mission_end_failure( "m05", "m05_fail_lt_died" ) 
  792. 		end 
  793. end 
  794.  
  795. function m05_kill_lt( human_name, trigger_name ) 
  796. 	if human_name == M05_groups.targets.npcs[ 1 ] and M05_dont_kill_lt == false then 
  797. 		trigger_enable( trigger_name, false ) 
  798. 		on_trigger_exit( "", trigger_name ) 
  799. 		character_kill( human_name ) 
  800. 		 
  801. 		-- don't knock the lt around too much bro! 
  802. 		mission_end_failure( "m05", "m05_fail_lt_died" ) 
  803. 	end 
  804. end 
  805.  
  806. -- Sets up and spawns the Saints reinforcements 
  807. -- 
  808. -- restart:	(bool) true if starting from a checkpoint 
  809. -- open:		(bool) true to animate the door open 
  810. -- 
  811. function m05_spawn_saints(restart, open) 
  812. 	-- Spawn Shaundi 
  813. 	group_create(M05_groups.shaundi.name, true) 
  814. 	on_death("m05_failure_shaundi_died", M05_groups.shaundi.shaundi) 
  815.  
  816. 	-- Switch to the elevator spawn region 
  817. 	spawn_region_enable(M05_regions.s_base, false) 
  818. 	spawn_region_enable(M05_regions.e_base, true) 
  819.  
  820. 	-- Enable the spawn groups 
  821. 	continuous_spawn_start(M05_cspawn.saints_1) 
  822. 	continuous_spawn_start(M05_cspawn.saints_2) 
  823. 	continuous_spawn_start(M05_cspawn.saints_3) 
  824.  
  825. 	-- Open the door to let them out 
  826. 	door_open(M05_doors.elevator, false, open) 
  827.  
  828. 	-- Spawn additional Saints to fill out the area 
  829. 	group_create(M05_groups.saints.name, true) 
  830.  
  831. 	-- If at a checkpoint, teleport everyone; otherwise script move them 
  832. 	if (restart) then 
  833. 		-- Teleport Shaundi to the player and add her to the party 
  834. 		teleport(M05_groups.shaundi.shaundi, M05_nav.cp_shaundi, true) 
  835. 		party_add(M05_groups.shaundi.shaundi, LOCAL_PLAYER) 
  836.  
  837. 		-- Teleport the Saints upstairs 
  838. 		for i, saint in pairs(M05_groups.saints.npcs) do 
  839. 			teleport(saint, M05_nav.saints04[i], true) 
  840. 		end 
  841.  
  842. 		-- Play Saints music 
  843. 	   audio_ambient_emitter_stop("M05_Morningstar_Music<001>") 
  844. 		audio_ambient_emitter_start("M05_Saints_Music<002>") 
  845. 	else 
  846. 		-- Wait for the elevator doors to open 
  847. 		if open then 
  848. 			delay(1.5) 
  849. 		end 
  850.  
  851. 		-- Add Shandi to the party 
  852. 		party_add(M05_groups.shaundi.shaundi, LOCAL_PLAYER) 
  853.  
  854. 		-- Send the Saints running upstairs 
  855. 		for i, saint in pairs(M05_groups.saints.npcs) do 
  856. 			ai_do_scripted_move(saint, M05_nav.saints01[i]) 
  857. 			delay(.35) 
  858. 		end 
  859. 		 
  860. 		trigger_enable(M05_triggers.saints02, true) 
  861. 		on_trigger("m05_move_saints_up02", M05_triggers.saints02) 
  862. 		trigger_enable(M05_triggers.saints03, true) 
  863. 		on_trigger("m05_move_saints_up03", M05_triggers.saints03) 
  864. 		trigger_enable(M05_triggers.saints04, true) 
  865. 		on_trigger("m05_move_saints_up04", M05_triggers.saints04) 
  866. 	end 
  867. end 
  868.  
  869. function m05_move_saints_up02() 
  870. 	m05_clear_trigger(M05_triggers.saints02) 
  871. 	for i, saint in pairs(M05_groups.saints.npcs) do 
  872. 		if not character_is_dead(saint) then 
  873. 			ai_do_scripted_move(saint, M05_nav.saints02[i], true, true) 
  874. 			npc_leash_to_nav(saint, M05_nav.saints02[i], 0) 
  875. 		end 
  876. 	end 
  877. end 
  878.  
  879. function m05_move_saints_up03() 
  880. 	m05_clear_trigger(M05_triggers.saints03) 
  881. 	for i, saint in pairs(M05_groups.saints.npcs) do 
  882. 		if not character_is_dead(saint) then 
  883. 			npc_leash_remove(saint) 
  884. 			ai_do_scripted_move(saint, M05_nav.saints03[i], true, false) 
  885. 			npc_leash_to_nav(saint, M05_nav.saints03[i], 0) 
  886. 		end 
  887. 	end 
  888. end 
  889.  
  890. function m05_move_saints_up04() 
  891. 	m05_clear_trigger(M05_triggers.saints04) 
  892. 	for i, saint in pairs(M05_groups.saints.npcs) do 
  893. 		if not character_is_dead(saint) then 
  894. 			npc_leash_remove(saint) 
  895. 			ai_attack_region(saint, M05_nav.saints04[i], 8) 
  896. 		end 
  897. 	end 
  898.  
  899. 	-- Play Saints music 
  900. 	audio_ambient_emitter_stop("M05_Morningstar_Music<001>") 
  901. 	audio_ambient_emitter_start("M05_Saints_Music<002>") 
  902. end 
  903.  
  904. -- Spawn an invulnerable interrogation target 
  905. -- 
  906. -- target:	(table) group and name of the target to spawn 
  907. -- 
  908. function m05_spawn_target(target) 
  909. 	-- Create the target 
  910. 	group_create(target.name, true) 
  911.  
  912. 	-- Make him invulnerable and immovable until until taken hostage to force human shield 
  913. 	turn_invulnerable(target.npcs[1]) 
  914. 	character_prevent_explosion_fling(target.npcs[1], true) 
  915. 	character_allow_ragdoll(target.npcs[1], false) 
  916. 	character_set_only_player_grabs(target.npcs[1], true)	-- Only the player should grab 
  917. end 
  918.  
  919. -- Make a group of partygoers panic! 
  920. -- 
  921. -- npc_list: a list of the npcs that should panic 
  922. -- 
  923. function m05_partygoers_panic(npc_list) 
  924. 	-- Make them all run or cower 
  925. 	for i, npc in pairs(npc_list) do 
  926. 		if character_exists(npc) then 
  927. 			if rand_float(0.0, 1.0) < 0.25 then 
  928. 				local flee_idx = rand_int(1, #M05_nav.flee) 
  929. 				npc_leash_remove( npc ) 
  930. 				flee_to_navpoint(npc, M05_nav.flee[flee_idx], LOCAL_PLAYER, true) 
  931. 			else 
  932. 				cower(npc, LOCAL_PLAYER) 
  933. 			end 
  934. 		end 
  935. 	end 
  936. end 
  937.  
  938. -- Wait until a player interrogates the target 
  939. -- 
  940. -- target:	(string) name of the target to interrogate 
  941. -- conv:		(table) name and handle of the interrogation conversation 
  942. -- tutor:	(bool) true to show the tutorial 
  943. -- 
  944. function m05_interrogate(target, conv, tutor) 
  945. 	-- persona overriiiiiide. 
  946. 	if conv.persona ~= nil then 
  947. 		persona_override_persona_start(target, conv.persona) 
  948. 	end 
  949. 	 
  950. 	-- Change the objective to interrogation 
  951. 	objective_text_clear(0) 
  952. 	marker_remove(target, SYNC_ALL) 
  953.  
  954. 	objective_text(0, "M05_OBJ_INTERROGATE", "", "", SYNC_ALL, OI_ASSET_USE) 
  955. 	marker_add(target, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAG_STICKY + OI_FLAG_DISPLAY_DISTANCE, SYNC_ALL) 
  956.  
  957. 	-- Show the tutorial 
  958. 	if tutor then 
  959. 		tutorial_start("human_shield", 0, true) 
  960. 	end 
  961.  
  962. 	-- Wait until a player takes the target hostage 
  963. 	local hostage_taken = false 
  964. 	local char = LOCAL_PLAYER 
  965. 	while not hostage_taken do 
  966. 		if character_has_specific_human_shield(LOCAL_PLAYER, target) then 
  967. 			hostage_taken = true 
  968. 		elseif (M05_in_coop and character_has_specific_human_shield(REMOTE_PLAYER, target)) then 
  969. 			hostage_taken = true 
  970. 			char = REMOTE_PLAYER 
  971. 		end 
  972. 		thread_yield() 
  973. 	end 
  974.  
  975. 	-- Load the interrogation conversation 
  976. 	conv.handle = audio_conversation_load_player(conv.name, char) 
  977.  
  978. 	-- End the tutorial 
  979. 	if tutor then 
  980. 		tutorial_advance("human_shield") 
  981. 	end 
  982. 		 
  983. 	if target == M05_groups.chase_host.target then 
  984. 		hud_timer_stop(1) 
  985. 	end 
  986. 	 
  987. 	-- make player invulnerable 
  988. 	turn_invulnerable( char ) 
  989. 	 
  990. 	-- no ragdolling 
  991. 	character_allow_ragdoll( char, false ) 
  992. 	character_allow_ragdoll( target, false ) 
  993.  
  994. 	-- Block controls until the interrogation is complete 
  995. 	player_human_shield_lock(char, true) 
  996. 	delay(1) 
  997. 	-- play a synced interrogate animation 
  998. 	action_play_synced_state(char, target, "Gat Interrogation State") 
  999. 	action_play_synced(char, target, "Gat Interrogation Entry") 
  1000. 	 
  1001. 	-- TODO: Play the interrogation conversation 
  1002. 	audio_conversation_play(conv.handle) 
  1003. 	 
  1004. 	audio_conversation_wait_for_end(conv.handle) 
  1005. 	conv.handle = INVALID_CONVERSATION_HANDLE 
  1006. 	action_play_synced_state(char, target, "HS_Stand") 
  1007. 	action_play_synced(char, target, "Gat Interrogation Return") 
  1008. 	-- Restore control 
  1009. 	player_human_shield_lock(char, false) 
  1010. 	action_stop_synced_state(char, true) 
  1011. 	 
  1012. 	if conv.persona ~= nil then 
  1013. 		persona_override_persona_stop(target) 
  1014. 	end 
  1015.  
  1016. 	-- Clear invulnerability 
  1017. 	turn_vulnerable(target) 
  1018. 	turn_vulnerable(char) 
  1019. 	character_allow_ragdoll( char, true ) 
  1020. 	character_allow_ragdoll( target, true ) 
  1021. 	character_prevent_explosion_fling(target, false) 
  1022. 	character_allow_ragdoll(target, true) 
  1023.  
  1024. 	-- Clear objective 
  1025. 	marker_remove(target, SYNC_ALL) 
  1026. 	objective_text_clear(0) 
  1027. end 
  1028.  
  1029. -- Clean up everything in the penthouse 
  1030. function m05_cleanup_penthouse() 
  1031. 	-- Disable the kill and left triggers 
  1032. 	on_trigger_exit("", M05_triggers.kill) 
  1033. 	on_trigger_exit("", M05_triggers.left) 
  1034. 	trigger_enable(M05_triggers.kill, false) 
  1035. 	trigger_enable(M05_triggers.left, false) 
  1036.  
  1037. 	-- Stop the music 
  1038. 	audio_ambient_emitter_stop("M05_Morningstar_Music<001>") 
  1039. 	audio_ambient_emitter_stop("M05_Saints_Music<002>") 
  1040.  
  1041. 	-- Remove callbacks and markers and destroy groups 
  1042. 	if group_is_loaded(M05_groups.shaundi.name) then 
  1043. 		on_death("", M05_groups.shaundi.shaundi) 
  1044. 		group_destroy(M05_groups.shaundi.name) 
  1045. 	end 
  1046. 	if group_is_loaded(M05_groups.party_1.name) then 
  1047. 		group_destroy(M05_groups.party_1.name) 
  1048. 	end 
  1049. 	if group_is_loaded(M05_groups.party_2.name) then 
  1050. 		group_destroy(M05_groups.party_2.name) 
  1051. 	end 
  1052. 	if group_is_loaded(M05_groups.guards.name) then 
  1053. 		for i, guard in pairs(M05_groups.guards.npcs) do 
  1054. 			on_death("", guard) 
  1055. 			marker_remove(guard) 
  1056. 		end 
  1057. 		group_destroy(M05_groups.guards.name) 
  1058. 	end 
  1059. 	if group_is_loaded(M05_groups.barricade.name) then 
  1060. 		group_destroy(M05_groups.barricade.name) 
  1061. 	end 
  1062. 	if group_is_loaded(M05_groups.backup_1.name) then 
  1063. 		group_destroy(M05_groups.backup_1.name) 
  1064. 	end 
  1065.  
  1066. 	if group_is_loaded(M05_groups.drop_1.name) then 
  1067. 		for i, guard in pairs(M05_groups.drop_1.npcs) do 
  1068. 			on_vehicle_exit("", guard) 
  1069. 		end 
  1070. 		group_destroy(M05_groups.drop_1.name) 
  1071. 	end 
  1072. 	if group_is_loaded(M05_groups.drop_2.name) then 
  1073. 		for i, guard in pairs(M05_groups.drop_2.npcs) do 
  1074. 			on_vehicle_exit("", guard) 
  1075. 		end 
  1076. 		group_destroy(M05_groups.drop_2.name) 
  1077. 	end 
  1078. 	if group_is_loaded(M05_groups.saints.name) then 
  1079. 		group_destroy(M05_groups.saints.name) 
  1080. 	end 
  1081. 	if group_is_loaded(M05_groups.targets.name) then 
  1082. 		for i, npc in pairs(M05_groups.targets.npcs) do 
  1083. 			marker_remove(npc) 
  1084. 			on_death( "", npc ) 
  1085. 		end 
  1086. 		group_destroy(M05_groups.targets.name) 
  1087. 	end 
  1088.  
  1089. 	-- Clean up spawn regions and spawn groups 
  1090. 	for i, group in pairs(M05_cspawn) do 
  1091. 		continuous_spawn_stop(group, true) 
  1092. 	end 
  1093. 	for i, reg in pairs(M05_regions) do 
  1094. 		spawn_region_enable(reg, false) 
  1095. 	end 
  1096. end 
  1097.  
  1098. -- Disable trigger 
  1099. -- 
  1100. -- trigger:			(string) Name of the trigger 
  1101. -- 
  1102. function m05_clear_trigger(trigger) 
  1103. 	on_trigger("", trigger) 
  1104. 	trigger_enable(trigger, false) 
  1105. 	marker_remove_trigger(trigger, SYNC_ALL) 
  1106. end 
  1107.  
  1108.  
  1109. -- ************************* 
  1110. -- OBJECTIVE: Parachute In 
  1111. -- ************************* 
  1112.  
  1113. function m05_parachute_in() 
  1114. 	-- Prevent people from attacking until the players land 
  1115. 	notoriety_set_max("morningstar", 0) 
  1116. 	helicopters_set_jitter_override(0.01, 0.01) 
  1117. 	audio_object_post_event("Mission_05", "Mission_05", "M05_Power_Teaser", M05_groups.pierce.heli) 
  1118. 	-- Display the new objective 
  1119. 	objective_text(0, "M05_OBJ_PARACHUTE", "", "", SYNC_ALL, OI_ASSET_LOCATION) 
  1120. 	trigger_enable(M05_triggers.pool, true) 
  1121. 	marker_add_trigger(M05_triggers.pool, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  1122.  
  1123. 	-- Prompt the players to jump 
  1124. 	M05_jumped = false 
  1125. 	hud_prompt(LOCAL_PLAYER, "M05_JUMP", "m05_jump_local") 
  1126. 	player_supress_falling_scream( LOCAL_PLAYER ) 
  1127. 	if (M05_in_coop) then 
  1128. 		hud_prompt(REMOTE_PLAYER, "M05_JUMP", "m05_jump_remote") 
  1129. 		player_supress_falling_scream( REMOTE_PLAYER ) 
  1130. 	end 
  1131.  
  1132. 	-- Play intro line 
  1133. 	delay(2) 
  1134. 	audio_play_persona_line(M05_groups.pierce.pierce, M05_lines.jump) 
  1135.  
  1136. 	-- Set up a nag line 
  1137. 	M05_threads.nag = thread_new("m05_nag_thread") 
  1138.  
  1139. 	-- Wait for the player to jump 
  1140. 	while not M05_jumped do 
  1141. 		thread_yield() 
  1142. 	end 
  1143.  
  1144. 	-- Wait for the player to land 
  1145. 	M05_goal_reached = false 
  1146. 	trigger_enable(M05_triggers.land, true) 
  1147. 	on_trigger("m05_land_trigger_reached", M05_triggers.land) 
  1148. 	--play line 
  1149. 	delay(3) 
  1150. 	audio_play_persona_line(LOCAL_PLAYER, M05_lines.why_jump) 
  1151. 		 
  1152. 	while not M05_goal_reached do 
  1153. 		thread_yield() 
  1154. 	end 
  1155.  
  1156. 	objective_text_clear(0) 
  1157. 	marker_remove_trigger(M05_triggers.pool, SYNC_ALL) 
  1158. 	trigger_enable(M05_triggers.pool, false) 
  1159. 	notoriety_set_max("morningstar", 5) 
  1160.  
  1161. 	thread_kill(M05_threads.nag) 
  1162. 	M05_threads.nag = INVALID_THREAD_HANDLE 
  1163. 	 
  1164. 	helicopters_set_jitter_override(1.0, 1.0) 
  1165. end 
  1166.  
  1167. -- ************************* 
  1168. -- OBJECTIVE: Get Info 
  1169. -- ************************* 
  1170.  
  1171. function m05_get_info() 
  1172. 	-- Load then play the landing conversation 
  1173. 	M05_persona.shaundi.id = audio_persona_load_2d(M05_persona.shaundi.name) 
  1174. 	--M05_conv.land.handle = audio_conversation_load(M05_conv.land.name) 
  1175. 	 
  1176. 	delay(4) 
  1177. 	M05_land_call_completed = false 
  1178. 	audio_play_for_mission_cellphone(M05_conv.land.name, false, true, "", "m05_land_call_finished_cb") 
  1179.  
  1180. 	--audio_conversation_play(M05_conv.land.handle) 
  1181. 	--audio_conversation_wait_for_end(M05_conv.land.handle) 
  1182. 	--M05_conv.land.handle = INVALID_CONVERSATION_HANDLE 
  1183. 	while (M05_land_call_completed == false) do 
  1184. 		thread_yield() 
  1185. 	end 
  1186.  
  1187. 	-- Wait until a player interrogates the target 
  1188. 	M05_dont_kill_lt = true 
  1189. 	character_set_counter_on_grabbed_by_player(M05_groups.targets.npcs[1], false) 
  1190. 	m05_interrogate(M05_groups.targets.npcs[1], M05_conv.int1, true) 
  1191.  
  1192. 	-- it's ok to lose the lt now 
  1193. 	trigger_enable(M05_triggers.lt_pool, false) 
  1194. 	on_trigger_exit("", M05_triggers.lt_pool) 
  1195.  
  1196. 	-- Display the new objective 
  1197. 	objective_text(0, "M05_OBJ_KILL_LIEUTENANT", "", "", SYNC_ALL, OI_ASSET_KILL) 
  1198. 	marker_add(M05_groups.targets.npcs[1], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  1199.  
  1200. 	-- Display the throw Human Shield tutorial 
  1201. 	tutorial_start("throw_kill", 0, true) 
  1202. 	 
  1203. 	-- Run or hide. 
  1204. 	m05_partygoers_panic(M05_groups.party_1.npcs) 
  1205. 	m05_partygoers_panic(M05_groups.party_2.npcs) 
  1206.  
  1207. 	-- Wait until the lieutenant is thrown 
  1208. 	while (character_has_specific_human_shield(LOCAL_PLAYER, M05_groups.targets.npcs[1]) or (M05_in_coop and character_has_specific_human_shield(REMOTE_PLAYER, M05_groups.targets.npcs[1]))) do 
  1209. 		thread_yield() 
  1210. 	end 
  1211. 	tutorial_advance("throw_kill") 
  1212.  
  1213. 	-- Make sure the throw kills the lieutenant 
  1214. 	delay(2.5) 
  1215. 	marker_remove(M05_groups.targets.npcs[1], SYNC_ALL) 
  1216. 	if not character_is_dead(M05_groups.targets.npcs[1]) then 
  1217. 		character_kill(M05_groups.targets.npcs[1], true) 
  1218. 	end 
  1219.  
  1220. 	-- Release him and the partiers so we can spawn more guards 
  1221. 	release_to_world(M05_groups.targets.name) 
  1222. 	 
  1223. 	release_to_world(M05_groups.party_2.name) 
  1224. 	release_to_world(M05_groups.party_1.name) 
  1225.  
  1226. 	audio_play_persona_line(LOCAL_PLAYER, M05_lines.penthouse) 
  1227. 	 
  1228. 	objective_text_clear(0) 
  1229. end 
  1230.  
  1231. -- ************************* 
  1232. -- OBJECTIVE: Let the Saints in 
  1233. -- ************************* 
  1234.  
  1235. function m05_let_saints_in() 
  1236. 	-- Head to the basement to let your homies in 
  1237. 	objective_text(0, "M05_OBJ_BASEMENT", "", "", SYNC_ALL, OI_ASSET_LOCATION) 
  1238.  
  1239. 	-- Make the enemies hostile 
  1240. 	notoriety_set_min("morningstar", 2) 
  1241. 	--continuous_spawn_start(M05_cspawn.enemy_1) 
  1242. 	--continuous_spawn_start(M05_cspawn.enemy_2) 
  1243. 	--continuous_spawn_start(M05_cspawn.enemy_3) 
  1244.  
  1245. 	M05_goal_reached = false 
  1246. 	trigger_enable(M05_triggers.downstairs, true) 
  1247. 	marker_add_trigger(M05_triggers.downstairs, MINIMAP_ICON_LOCATION, "", OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  1248. 	on_trigger("m05_trigger_reached", M05_triggers.downstairs) 
  1249. 	while not M05_goal_reached do 
  1250. 		thread_yield() 
  1251. 	end 
  1252.  
  1253. 	objective_text_clear(0) 
  1254.  
  1255. 	-- Spawn the barricade guards 
  1256. 	group_create(M05_groups.barricade.name, true) 
  1257.  
  1258. 	-- Turn on the trigger to detect when the player enters the barricade room 
  1259. 	M05_barricade_breached = false 
  1260. 	trigger_enable(M05_triggers.barricade, true) 
  1261. 	on_trigger("m05_barricade_triggered", M05_triggers.barricade) 
  1262.  
  1263. 	--== WAYPOINT ==-- 
  1264.  
  1265. 	-- Display the new objective 
  1266. 	objective_text(0, "M05_OBJ_GRENADES", "", "", SYNC_ALL, OI_ASSET_USE) 
  1267.  
  1268. 	M05_goal_reached = false 
  1269. 	trigger_enable(M05_triggers.grenades, true) 
  1270. 	marker_add_trigger(M05_triggers.grenades, MINIMAP_ICON_USE, "", OI_ASSET_USE, OI_FLAGS_LOCATION, SYNC_ALL) 
  1271. 	on_trigger("m05_trigger_reached", M05_triggers.grenades) 
  1272.  
  1273. 	delay(3) 
  1274. 	audio_play_persona_line(LOCAL_PLAYER, M05_lines.barrier) 
  1275.  
  1276. 	-- Wait until the player picks up the grenades 
  1277. 	while M05_goal_reached  == false and M05_barricade_breached == false do 
  1278. 		thread_yield() 
  1279. 	end 
  1280.  
  1281. 	if game_is_active_input_gamepad() then 
  1282. 		tutorial_start("combat_grenades", 0, true) 
  1283. 	else 
  1284. 		tutorial_start("combat_grenades_pc", 0, true) 
  1285. 	end 
  1286.  
  1287. 	objective_text_clear(0) 
  1288.  
  1289. 	--== WAYPOINT ==-- 
  1290.  
  1291. 	-- Display the new objective 
  1292. 	objective_text(0, "M05_OBJ_BARRIER", "", "", SYNC_ALL, OI_ASSET_KILL) 
  1293. 	marker_add(M05_movers[1], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  1294.  
  1295. 	-- Make the barricade vulnerable 
  1296. 	for i, mover in pairs(M05_movers) do 
  1297. 		mesh_mover_set_invulnerable(mover, false) 
  1298. 	end 
  1299. 	 
  1300. 	-- Wait until the player kills a mover 
  1301. 	while m05_barricade_destroyed() == false and M05_barricade_breached == false do 
  1302. 		thread_yield() 
  1303. 	end 
  1304. 	 
  1305. 	explosion_create( "Barrel Exp", M05_movers[ 1 ], LOCAL_PLAYER ) 
  1306. 	marker_remove(M05_movers[1]) 
  1307. 	tutorial_advance("combat_grenades") 
  1308. 	tutorial_advance("combat_grenades_pc") 
  1309.  
  1310. 	objective_text_clear(0) 
  1311.  
  1312. 	--== WAYPOINT ==-- 
  1313.  
  1314. 	delay(2) 
  1315. 	audio_play_persona_line(LOCAL_PLAYER, M05_lines.stored_items) 
  1316. 	 
  1317. 	-- Display the new objective 
  1318. 	objective_text(0, "M05_OBJ_LET_IN_SAINTS", "", "", SYNC_ALL, OI_ASSET_USE) 
  1319.  
  1320. 	-- Wait until the player activates the elevator 
  1321. 	M05_goal_reached = false 
  1322. 	trigger_enable(M05_triggers.saints, true) 
  1323. 	marker_add_trigger(M05_triggers.saints, MINIMAP_ICON_USE, INGAME_EFFECT_CHECKPOINT, OI_ASSET_USE, OI_FLAGS_LOCATION, SYNC_ALL) 
  1324. 	on_trigger("m05_trigger_reached", M05_triggers.saints) 
  1325. 	while not M05_goal_reached do 
  1326. 		thread_yield() 
  1327. 	end 
  1328.  
  1329. 	objective_text_clear(0) 
  1330. 	objective_text(0, "M05_OBJ_WAIT_FOR_SAINTS", "", "", SYNC_ALL, OI_ASSET_DEFEND) 
  1331.  
  1332. 	-- Stop enemy continuous spawns 
  1333. 	continuous_spawn_stop(M05_cspawn.enemy_1) 
  1334. 	continuous_spawn_stop(M05_cspawn.enemy_2) 
  1335. 	--continuous_spawn_stop(M05_cspawn.enemy_3) 
  1336.  
  1337. 	-- Done with the barricade guards; release them to free up ped instances 
  1338. 	release_to_world(M05_groups.barricade.name) 
  1339.  
  1340. 	-- Spawn backup and have them rush downstairs 
  1341. 	group_create(M05_groups.backup_1.name, true) 
  1342. 	for i, npc in pairs(M05_groups.backup_1.npcs) do 
  1343. 		ai_do_scripted_move(npc, M05_nav.backup[i]) 
  1344. 	end 
  1345.  
  1346. 	-- Load and play the elevator conversation 
  1347. 	M05_conv.elevator.handle = audio_conversation_load(M05_conv.elevator.name) 
  1348. 	audio_conversation_play(M05_conv.elevator.handle) 
  1349.  
  1350. 	-- Play the elevator sound for 10 seconds 
  1351. 	local aid = audio_object_post_event("Misc_SFX", "Misc_SFX", "Elevator_Motor", M05_doors.elevator) 
  1352. 	delay(15) 
  1353. 	audio_stop(aid) 
  1354.  
  1355. 	audio_conversation_wait_for_end(M05_conv.elevator.handle) 
  1356. 	M05_conv.elevator.handle = INVALID_CONVERSATION_HANDLE 
  1357. 	if (M05_persona.shaundi.id ~= INVALID_PERSONA_HANDLE) then 
  1358. 		audio_persona_remove_2d(M05_persona.shaundi.id) 
  1359. 		M05_persona.shaundi.id = INVALID_PERSONA_HANDLE 
  1360. 	end 
  1361.  
  1362. 	-- Spawn the Saints and open the door 
  1363. 	delay(2) 
  1364. 	m05_spawn_saints(false, true) 
  1365.  
  1366. 	-- Done with the backup guards; release them to free up ped instances 
  1367. 	release_to_world(M05_groups.backup_1.name) 
  1368. end 
  1369.  
  1370. function m05_barricade_destroyed() 
  1371. 	for i, m in pairs( M05_movers ) do 
  1372. 		if mesh_mover_destroyed( m ) == true then 
  1373. 			return true 
  1374. 		end 
  1375. 	end 
  1376. 	 
  1377. 	return false 
  1378. end 
  1379.  
  1380. -- ************************* 
  1381. -- OBJECTIVE: Clear Penthouse 
  1382. -- ************************* 
  1383.  
  1384. function m05_release_group( group ) 
  1385. 	if group_is_loaded( group.name ) then 
  1386. 		for i, npc in pairs( group.npcs ) do 
  1387. 			if character_exists( npc )  then 
  1388. 				marker_remove( npc, SYNC_ALL ) 
  1389. 			end 
  1390. 		end 
  1391. 		 
  1392. 		release_to_world( group.name ) 
  1393. 	end 
  1394. end 
  1395.  
  1396. function m05_clear_penthouse() 
  1397. 	-- Kill all remaining Morningstar 
  1398. 	objective_text_clear(0) 
  1399. 	objective_text(0, "M05_OBJ_CLEAR_AREA", "", "", SYNC_ALL, OI_ASSET_KILL) 
  1400.  
  1401. 	-- Mark any left alive 
  1402. 	for i, guard in pairs(M05_groups.guards.npcs) do 
  1403. 		if (character_exists(guard) and not character_is_dead(guard)) then 
  1404. 			on_death("m05_enemy_killed", guard) 
  1405. 			marker_add(guard, MINIMAP_ICON_KILL, OI_ASSET_KILL) 
  1406. 		end 
  1407. 	end 
  1408. 	 
  1409. 	-- Start bringing guys in on the elevator. 
  1410. 	M05_threads.elevator_spawn = thread_new("m05_elevator_spawn_thread") 
  1411.  
  1412. 	-- Load and play the clear area conversation 
  1413. 	M05_conv.clear_out.handle = audio_conversation_load(M05_conv.clear_out.name) 
  1414. 	audio_conversation_play(M05_conv.clear_out.handle) 
  1415. 	audio_conversation_wait_for_end(M05_conv.clear_out.handle) 
  1416. 	M05_conv.clear_out.handle = INVALID_CONVERSATION_HANDLE 
  1417.  
  1418. 	-- Wait until only a few are left 
  1419. 	local num_targets = m05_get_num_remaining_targets() 
  1420. 	while (num_targets > 4) do 
  1421. 		thread_yield() 
  1422. 		num_targets = m05_get_num_remaining_targets() 
  1423. 	end 
  1424.  
  1425. 	-- Send the heli to land on the heli pad 
  1426. 	M05_threads.chase_host = thread_new("m05_land_thread", M05_groups.heli_host, M05_nav.land_host, M05_paths.heli_drop_host, M05_groups.drop_1, 0) 
  1427.  
  1428. 	-- Tell the player about them 
  1429. 	audio_play_persona_line(M05_groups.shaundi.shaundi, M05_lines.heli_dropoff) 
  1430. 	 
  1431. 		-- Repeat for co-op 
  1432. 	if (M05_in_coop) then 
  1433. 		M05_threads.heli_client_thread = thread_new("m05_land_thread", M05_groups.heli_client, M05_nav.land_client, M05_paths.heli_drop_client, M05_groups.drop_2, 10) 
  1434. 	end 
  1435. 	 
  1436. 	-- Wait until all are defeated 
  1437. 	while (m05_get_num_remaining_targets() > 0) or (M05_elevator_spawn_num < M05_elevator_spawn_num_min) do 
  1438. 		thread_yield() 
  1439. 	end 
  1440. 	 
  1441. 	-- Done with all guards; release them to free up ped instances 
  1442. 	m05_release_group( M05_groups.elevator ) 
  1443. 	m05_release_group( M05_groups.guards ) 
  1444. 	m05_release_group( M05_groups.drop_1 ) 
  1445. 	if (M05_in_coop) then 
  1446. 		m05_release_group( M05_groups.drop_2 ) 
  1447. 	end 
  1448.  
  1449. 	objective_text_clear(0) 
  1450.  
  1451. 	-- Load and play the explosive conversation 
  1452. 	M05_conv.explosive.handle = audio_conversation_load(M05_conv.explosive.name) 
  1453. 	audio_conversation_play(M05_conv.explosive.handle) 
  1454. 	audio_conversation_wait_for_end(M05_conv.explosive.handle) 
  1455. 	M05_conv.explosive.handle = INVALID_CONVERSATION_HANDLE 
  1456. 	 
  1457. 	-- Make sure all the markers get removed, then kill the thread. 
  1458. 	marker_remove_script_group(M05_groups.elevator.name) 
  1459. 	thread_kill(M05_threads.elevator_spawn) 
  1460. 	M05_threads.elevator_spawn = INVALID_THREAD_HANDLE 
  1461. end 
  1462.  
  1463. -- ************************* 
  1464. -- OBJECTIVE: Chase the final lieutenant 
  1465. -- ************************* 
  1466.  
  1467. -- Spawn the final lieutenant 
  1468. -- 
  1469. function m05_spawn_heli() 
  1470. 	-- Create the heli group 
  1471. 	group_create(M05_groups.chase_host.name, true) 
  1472.  
  1473. 	-- Set the target as immovable until until taken hostage to force human shield 
  1474. 	character_set_only_player_grabs(M05_groups.chase_host.target, true)	-- Only the player should grab 
  1475. 	character_prevent_explosion_fling(M05_groups.chase_host.target, true) 
  1476. 	character_allow_ragdoll(M05_groups.chase_host.target, false) 
  1477.  
  1478. 	-- Put everyone in the heli 
  1479. 	vehicle_enter_teleport(M05_groups.chase_host.pilot, M05_groups.chase_host.heli, 0, true) 
  1480. 	vehicle_enter_teleport(M05_groups.chase_host.target, M05_groups.chase_host.heli, 1, true) 
  1481.  
  1482. 	-- Set both the pilot and target as invulnerable and turn off their AI to prevent accidents 
  1483. 	vehicle_set_invulnerable(M05_groups.chase_host.heli) 
  1484. 	turn_invulnerable(M05_groups.chase_host.pilot) 
  1485. 	turn_invulnerable(M05_groups.chase_host.target) 
  1486. 	set_ignore_ai_flag(M05_groups.chase_host.pilot, true) 
  1487. 	set_ignore_ai_flag(M05_groups.chase_host.target, true) 
  1488. 	set_unjackable_flag(M05_groups.chase_host.heli, true) 
  1489.  
  1490. 	-- Tell the helicopter to take off (must do this immediately or it falls) 
  1491. 	thread_kill(M05_threads.chase_host) 
  1492. 	M05_threads.chase_host = thread_new("m05_fly_to_thread", M05_groups.chase_host.heli, M05_nav.hover_host) 
  1493.  
  1494. 	-- Disable the kill trigger, since we're leaving it 
  1495. 	on_trigger_exit("", M05_triggers.kill) 
  1496. 	trigger_enable(M05_triggers.kill, false) 
  1497.  
  1498. end 
  1499.  
  1500. -- Chase the final lieutenant 
  1501. -- 
  1502. function m05_get_on_heli() 
  1503. 	-- Direct the player to the helicopter 
  1504. 	M05_goal_reached = false 
  1505. 	trigger_enable(M05_triggers.chase, true) 
  1506. 	on_trigger("m05_trigger_reached", M05_triggers.chase) 
  1507.  
  1508. 	-- Display the new objective 
  1509. 	objective_text(0, "M05_OBJ_GET_TO_HELI", "", "", SYNC_ALL, OI_ASSET_USE) 
  1510.  
  1511. 	-- Start a thread to update the distance bar 
  1512. 	M05_threads.dist_host = thread_new("m05_chase_distance", M05_groups.chase_host.heli, SYNC_LOCAL) 
  1513. 	if (M05_in_coop) then 
  1514. 		M05_threads.dist_client = thread_new("m05_chase_distance", M05_groups.chase_host.heli, SYNC_REMOTE) 
  1515. 	end 
  1516.  
  1517. 	-- Unlock and mark the helis 
  1518. 	on_vehicle_enter("m05_heli_entered", M05_groups.heli_host.heli) 
  1519. 	set_unjackable_flag(M05_groups.heli_host.heli, false) 
  1520. 	vehicle_max_speed(M05_groups.heli_host.heli, -1) 
  1521. 	marker_add(M05_groups.heli_host.heli, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_LOCATION, SYNC_ALL) 
  1522. 	if group_is_loaded(M05_groups.heli_client.name) then 
  1523. 		on_vehicle_enter("m05_heli_entered", M05_groups.heli_client.heli) 
  1524. 		set_unjackable_flag(M05_groups.heli_client.heli, false) 
  1525. 		vehicle_max_speed(M05_groups.heli_client.heli, -1) 
  1526. 		marker_add(M05_groups.heli_client.heli, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_LOCATION, SYNC_ALL) 
  1527. 	end 
  1528.  
  1529. 	-- Load and play the helicopter escape conversation 
  1530. 	M05_conv.escape.handle = audio_conversation_load(M05_conv.escape.name) 
  1531. 	audio_conversation_play(M05_conv.escape.handle) 
  1532.  
  1533. 	-- Wait until the player gets to the helipad 
  1534. 	while not M05_goal_reached do 
  1535. 		thread_yield() 
  1536. 	end 
  1537.  
  1538. 	-- Leave Shaundi behind 
  1539. 	party_dismiss(M05_groups.shaundi.shaundi) 
  1540. 	on_death("", M05_groups.shaundi.shaundi) 
  1541. end 
  1542.  
  1543. -- Play the heli cutscene 
  1544. --function m05_setup_leap() 
  1545. --	-- Put the player(s) in the right spot 
  1546. --	teleport_coop(M05_nav.leap_host, M05_nav.leap_client, true) 
  1547. --end 
  1548.  
  1549. -- Start the leap-onto-heli QTE sequence 
  1550. -- 
  1551. --function m05_start_leap() 
  1552. --	-- Start the QTE 
  1553. --	M05_qte_complete = 0 
  1554. --	qte_start(LOCAL_PLAYER, "m05_leap", "m05_qte_completed") 
  1555. --	if (M05_in_coop == true) then 
  1556. --		M05_qte_complete = -1 
  1557. --		qte_start(REMOTE_PLAYER, "m05_leap", "m05_qte_completed_coop") 
  1558. --	end 
  1559. -- 
  1560. --	-- Loop until the QTE is complete (on both clients) 
  1561. --	while (M05_qte_complete < 1) do 
  1562. --		thread_yield() 
  1563. --	end 
  1564. --end 
  1565.  
  1566.  
  1567. function m05_thread_lt_flee_to_warehouse() 
  1568. 	-- Send the target up to the building and wait for streaming (force run, no shooting) 
  1569. 	ai_do_scripted_move(M05_groups.chase_host.target, M05_nav.chase_outside, true, false) 
  1570. 	npc_leash_to_nav(M05_groups.chase_host.target, M05_nav.chase_outside, 0) 
  1571. 	 
  1572. 	while not M05_goal_reached do 
  1573. 		thread_yield() 
  1574. 	end 
  1575.  
  1576. 	door_open(M05_doors.chase) 
  1577. 	 
  1578. 	-- Send the target into the building (force run, no shooting) 
  1579. 	npc_leash_remove(M05_groups.chase_host.target) 
  1580.  
  1581. 	repeat 
  1582. 		ai_clear_scripted_action( M05_groups.chase_host.target ) 
  1583. 		ai_do_scripted_move(M05_groups.chase_host.target, M05_nav.chase_end, true, false) 
  1584. 		 
  1585. 		while ai_scripted_action_is_processing(M05_groups.chase_host.target) do 
  1586. 			thread_yield() 
  1587. 		end 
  1588. 		 
  1589. 		thread_yield() 
  1590. 	until get_dist( M05_groups.chase_host.target, M05_nav.chase_end ) < 2 or character_is_dead( M05_groups.chase_host.target ) == true 
  1591. 	 
  1592. 	if character_is_dead( M05_groups.chase_host.target ) == false then 
  1593. 		npc_leash_to_nav(M05_groups.chase_host.target, M05_nav.chase_end, 3) 
  1594. 	end 
  1595. 	 
  1596. 	set_animation_state(M05_groups.chase_host.target, "cower stand") 
  1597.  
  1598. end 
  1599.  
  1600. -- Start the heli chase sequence 
  1601. -- 
  1602. function m05_chase_heli() 
  1603. 	-- Start the thread to send the heli to the final building 
  1604. 	M05_chase.local_player_ready = false 
  1605. 	M05_chase.remote_player_ready = false 
  1606. 	M05_heli_arrived = false 
  1607. 	 
  1608. 	spawning_vehicles( true ) 
  1609. 	spawning_pedestrians( true ) 
  1610.  
  1611. 	-- let it reach the hover navpoint first. 
  1612. 	while get_dist(M05_groups.chase_host.heli, M05_nav.hover_host) > 10 do 
  1613. 		thread_yield() 
  1614. 	end 
  1615. 	 
  1616. 	thread_kill(M05_threads.chase_host) 
  1617. 	M05_threads.chase_host = thread_new("m05_chase_thread", M05_groups.chase_host, M05_paths.heli_host, M05_nav.hover_host) 
  1618.  
  1619. 	-- Set up the rocket guys 
  1620. 	group_create(M05_groups.rockets.name, true) 
  1621. 	M05_threads.rockets = thread_new("m05_rockets_thread") 
  1622.  
  1623. 	-- Enable the destination trigger so we know when the crib is streamed in 
  1624. 	M05_goal_reached = false 
  1625. 	trigger_enable(M05_triggers.chase_end, true) 
  1626. 	on_trigger("m05_trigger_reached", M05_triggers.chase_end) 
  1627.  
  1628. 	-- Enable the warehouse trigger so we know when the player enters it 
  1629. 	trigger_enable(M05_triggers.warehouse, true) 
  1630. 	on_trigger("m05_warehouse_reached", M05_triggers.warehouse) 
  1631.  
  1632. 	delay(25) 
  1633. 	--play a conversation  
  1634. 	M05_persona.shaundi.id = audio_persona_load_2d(M05_persona.shaundi.name) 
  1635. 	audio_play_for_mission_cellphone(M05_conv.early_chase.name, false, true, "", "") 
  1636.  
  1637. 	-- Wait until the heli has arrived at its destination 
  1638. 	while not M05_heli_arrived do 
  1639. 		thread_yield() 
  1640. 	end 
  1641.  
  1642. 	-- Kill the distance update thread 
  1643. 	thread_kill(M05_threads.dist_host) 
  1644. 	M05_threads.dist_host = INVALID_THREAD_HANDLE 
  1645. 	if (M05_threads.dist_client ~= INVALID_THREAD_HANDLE) then 
  1646. 		thread_kill(M05_threads.dist_client) 
  1647. 		M05_threads.dist_client = INVALID_THREAD_HANDLE 
  1648. 	end 
  1649. 	hud_bar_off(0) 
  1650. 	hud_bar_off(1) 
  1651.  
  1652. 	-- Load and play the helicopter chase conversation 
  1653. 	--M05_conv.chase.handle = audio_conversation_load(M05_conv.chase.name) 
  1654. 	--audio_conversation_play(M05_conv.chase.handle) 
  1655. 	audio_play_for_mission_cellphone(M05_conv.chase.name, true, true, "", "") 
  1656.  
  1657. 	-- Set a fail timer 
  1658. 	hud_timer_set(1, 180000, "m05_fail_timer", SYNC_ALL) 
  1659. 	 
  1660. 	thread_kill(M05_threads.chase_host) 
  1661. 	M05_threads.chase_host = thread_new( "m05_thread_lt_flee_to_warehouse" ) 
  1662.  
  1663. 	while not M05_goal_reached do 
  1664. 		thread_yield() 
  1665. 	end 
  1666. 	 
  1667. 	trigger_enable(M05_triggers.chase_end, false) 
  1668. 	on_trigger("", M05_triggers.chase_end) 
  1669.  
  1670. 	-- Create the guards 
  1671. 	group_create(M05_groups.warehouse.name, false) 
  1672.  
  1673. 	-- Wait for the player to interrogate the target 
  1674. 	m05_interrogate(M05_groups.chase_host.target, M05_conv.int2, false) 
  1675. 	 
  1676. 	-- Display the new objective 
  1677. 	-- hud_timer_stop(1) 
  1678. 	objective_text(0, "M05_OBJ_KILL_LIEUTENANT", "", "", SYNC_ALL, OI_ASSET_KILL) 
  1679. 	marker_add(M05_groups.chase_host.target, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  1680.  
  1681. 	-- Display the execute Human Shield tutorial 
  1682. 	tutorial_start("quick_kill", 0, true) 
  1683.  
  1684. 	-- Wait until the lieutenant is dead 
  1685. 	while not character_is_dead(M05_groups.chase_host.target) do 
  1686. 		thread_yield() 
  1687. 	end 
  1688. 	 
  1689. 	thread_kill(M05_threads.chase_host) 
  1690. 	marker_remove(M05_groups.chase_host.target, SYNC_ALL) 
  1691. 	tutorial_advance("quick_kill") 
  1692. 	objective_text_clear(0) 
  1693. 	 
  1694. 	M05_color_call_completed = false 
  1695. 	audio_play_for_mission_cellphone(M05_conv.shaundi_color.name, false, true, "", "m05_color_call_finished_cb") 
  1696. 	 
  1697. 	while (M05_color_call_completed == false) do 
  1698. 		thread_yield() 
  1699. 	end 
  1700. 	 
  1701. 	delay(2) 
  1702. end 
  1703.  
  1704. -- ************************* 
  1705. -- 
  1706. -- Callback functions 
  1707. -- 
  1708. -- ************************* 
  1709.  
  1710. function m05_guard_attacked(name,weapon,attack) 
  1711. 	local line = "M05_Attack" 
  1712. 	 
  1713. 	if (not thread_check_done(M05_threads.attack_line)) then 
  1714. 		return 
  1715. 	end 
  1716. 	 
  1717. 	-- start timer 
  1718. 	M05_threads.attack_line = thread_new("delay", M05_attack_line_time) 
  1719.  
  1720. 	-- play line 
  1721. 	if not audio_play_persona_line(name, line) then 
  1722. 		-- line didn't play, kill our timer 
  1723. 		thread_kill(M05_threads.attack_line) 
  1724. 		M05_threads.attack_line = INVALID_THREAD_HANDLE 
  1725. 	end 
  1726.  
  1727. end 
  1728.  
  1729. -- Catch the local player jumping 
  1730. function m05_jump_local() 
  1731. 	hud_prompt_clear(LOCAL_PLAYER) 
  1732. 	vehicle_exit(LOCAL_PLAYER) 
  1733. 	M05_jumped = true 
  1734. end 
  1735.  
  1736. -- Catch the remote player jumping 
  1737. function m05_jump_remote() 
  1738. 	hud_prompt_clear(REMOTE_PLAYER) 
  1739. 	vehicle_exit(REMOTE_PLAYER) 
  1740. 	M05_jumped = true 
  1741. end 
  1742.  
  1743. -- Kill anyone who leaves the penthouse 
  1744. function m05_trigger_kill_zone(human_name, trigger_name) 
  1745. 	-- Don't kill players or characters in vehicles 
  1746. 	if (human_name ~= nil) and ((not character_is_player(human_name)) and (not character_is_in_vehicle(human_name))) then 
  1747. 		-- Override invulnerability 
  1748. 		character_kill(human_name, true) 
  1749. 	end 
  1750. end 
  1751.  
  1752. -- Trigger if a player leaves the penthouse 
  1753. function m05_trigger_left(human_name, trigger_name) 
  1754. 	if (character_is_player(human_name)) then 
  1755. 		-- If the player is in a script heli, they're allowed to leave 
  1756. 		local v_name = get_char_vehicle_name(human_name) 
  1757. 		if ((v_name == M05_groups.heli_host.heli) or (v_name == M05_groups.heli_client.heli)) then 
  1758. 			-- The player has left the penthouse, so it can now be cleaned up 
  1759. 			audio_conversation_wait_for_end(M05_conv.escape.handle) 
  1760. 			M05_conv.escape.handle = INVALID_CONVERSATION_HANDLE 
  1761. 			m05_cleanup_penthouse() 
  1762. 		else 
  1763. 			-- Not allowed to leave, yet, so fail 
  1764. 			mission_end_failure("m05", "m05_fail_left") 
  1765. 		end 
  1766. 	end 
  1767. end 
  1768.  
  1769. -- Catch when the player taunts and advance the mission accordingly 
  1770. function m05_taunted(char) 
  1771. 	-- Find which target was taunted, keeping count of the number taunted thus-far 
  1772. 	local num_taunted = 0 
  1773. 	local target = nil 
  1774. 	for i, npc in pairs(M05_groups.targets.npcs) do 
  1775. 		if (M05_groups.targets.taunt[i]) then 
  1776. 			-- This target has already been taunted 
  1777. 			num_taunted = num_taunted + 1 
  1778. 		else 
  1779. 			-- Check if the player is within the threshold distance of this target 
  1780. 			if (get_dist(char, npc) < 3) then 
  1781. 				-- This guy has now been taunted 
  1782. 				target = npc 
  1783. 				marker_remove(target) 
  1784. 				M05_groups.targets.taunt[i] = true 
  1785. 				num_taunted = num_taunted + 1 
  1786. 			end 
  1787. 		end 
  1788. 	end 
  1789.  
  1790. 	-- Once the 3rd guy is taunted, move on; until then return 
  1791. 	if (num_taunted < 3) then 
  1792. 		-- TODO: Play a response/prompt to move on? 
  1793. 		return 
  1794. 	end 
  1795.  
  1796. 	on_taunt("", LOCAL_PLAYER) 
  1797. 	if (M05_in_coop) then 
  1798. 		on_taunt("", REMOTE_PLAYER) 
  1799. 	end 
  1800.  
  1801. 	-- This guy knows something; remove other potential targets and wait until a player interrogates this one 
  1802. 	for i, npc in pairs (M05_groups.targets.npcs) do 
  1803. 		character_set_counter_on_grabbed_by_player(npc, false) 
  1804. 		marker_remove(npc) 
  1805. 	end 
  1806. 	m05_interrogate(target, M05_conv.int1, true) 
  1807. 	 
  1808. 	-- Allow the players to kill the interrogation targets now. 
  1809. 	for i, npc in pairs(M05_groups.targets.npcs) do 
  1810. 		on_death("", npc) 
  1811. 	end 
  1812.  
  1813. 	-- Display the new objective 
  1814. 	objective_text(0, "M05_OBJ_KILL_LIEUTENANT", "", "", SYNC_ALL, OI_ASSET_KILL) 
  1815. 	marker_add(target, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  1816.  
  1817. 	-- Display the throw Human Shield tutorial 
  1818. 	tutorial_start("throw_kill", 0, true) 
  1819.  
  1820. 	-- Wait until the target is thrown 
  1821. 	while (character_has_specific_human_shield(LOCAL_PLAYER, target) or (M05_in_coop and character_has_specific_human_shield(REMOTE_PLAYER, target))) do 
  1822. 		thread_yield() 
  1823. 	end 
  1824. 	tutorial_advance("throw_kill") 
  1825.  
  1826. 	-- Make sure the throw kills the lieutenant 
  1827. 	delay(2.5) 
  1828. 	marker_remove(target, SYNC_ALL) 
  1829. 	if not character_is_dead(target) then 
  1830. 		character_kill(target, true) 
  1831. 	end 
  1832.  
  1833. 	-- Allow the mission to advance 
  1834. 	M05_goal_reached = true 
  1835. end 
  1836.  
  1837. -- Reached the basement barricade 
  1838. function m05_barricade_triggered(char, trig) 
  1839. 	M05_barricade_breached = true 
  1840. 	m05_clear_trigger(trig) 
  1841. 	persona_override_persona_start(M05_groups.barricade.script[1], "Interrogation") 
  1842. 	audio_play_persona_line(M05_groups.barricade.script[1], M05_lines.come_get_us) 
  1843. 	for i, guard in pairs(M05_groups.barricade.script) do 
  1844. 		ai_do_scripted_move(guard, M05_nav.guards[i]) 
  1845. 		delay(.35) 
  1846. 	end 
  1847. 	delay(2) 
  1848. 	persona_override_persona_stop(M05_groups.barricade.script[1]) 
  1849. end 
  1850.  
  1851. --hit the land trigger 
  1852. function m05_land_trigger_reached(char, trig) 
  1853. 	--put party-goers in their action nodes 
  1854. 	for i, npc in pairs(M05_groups.party_1.npcs) do 
  1855. 		if not character_is_dead(npc) then 
  1856. 			npc_use_closest_action_node_of_type(npc, M05_groups.party_1.nodes[i], 3) 
  1857. 		end 
  1858. 	end 
  1859. 	for i, npc in pairs(M05_groups.party_2.npcs) do 
  1860. 		if not character_is_dead(npc) then 
  1861. 			npc_use_closest_action_node_of_type(npc, M05_groups.party_2.nodes[i], 3) 
  1862. 		end 
  1863. 	end 
  1864. 	for i, npc in pairs(M05_groups.guards.npcs) do 
  1865. 		if not character_is_dead(npc) then 
  1866. 			npc_use_closest_action_node_of_type(npc, M05_groups.guards.nodes[i], 3) 
  1867. 		end 
  1868. 	end 
  1869. 	 
  1870. 	npc_use_closest_action_node_of_type(M05_groups.targets.npcs[ 1 ], M05_groups.targets.nodes[ 1 ], 3) 
  1871. 	 
  1872. 	m05_clear_trigger(trig) 
  1873. 	M05_goal_reached = true 
  1874. end 
  1875.  
  1876. -- The next trigger has been activated 
  1877. function m05_trigger_reached(char, trig) 
  1878. 	m05_clear_trigger(trig) 
  1879. 	M05_goal_reached = true 
  1880. end 
  1881.  
  1882. -- The next door has been opened 
  1883. function m05_door_opened(door) 
  1884. 	marker_remove(door) 
  1885. 	on_door_opened("", door) 
  1886. 	M05_goal_reached = true 
  1887. end 
  1888.  
  1889. function m05_failure_shaundi_died() 
  1890. 	-- End the mission, Shaundi died 
  1891. 	mission_end_failure("m05", "m01_failure_shaundi_died") 
  1892. end 
  1893.  
  1894. function m05_fail_timer() 
  1895. 	-- End the mission, time ran out 
  1896. 	mission_end_failure("m05", "m05_fail_time") 
  1897. end 
  1898.  
  1899. -- When one of the guys you're supposed to taunt is killed. 
  1900. function m05_tauntee_killed(victim, attacker) 
  1901. 	on_death("", victim) 
  1902. 	marker_remove(victim) 
  1903. 	mission_end_failure("m05", "m12_failure_cover_blown") 
  1904. end 
  1905.  
  1906. -- Display the grenade tutorial 
  1907. function m05_enemy_killed(victim, attacker) 
  1908. 	on_death("", victim) 
  1909. 	marker_remove(victim) 
  1910. end 
  1911.  
  1912. -- Turn the pilot vulnerable upon exiting the heli 
  1913. function m05_pilot_exit(human, vehicle, index) 
  1914. 	on_vehicle_exit("", human) 
  1915. 	turn_vulnerable(human) 
  1916. end 
  1917.  
  1918. -- A player has entered a heli to start the chase sequence 
  1919. function m05_heli_entered(player, vehicle, seat) 
  1920. 	-- remove the marker for this heli for both players 
  1921. 	marker_remove(vehicle, SYNC_ALL) 
  1922.  
  1923. 	vehicle_set_vulnerable(vehicle) 
  1924. 	vehicle_prevent_explosion_fling(vehicle, false) 
  1925. 	 
  1926. 	-- if we haven't changed objectives yet, do it now 
  1927. 	if M05_chase.remote_player_ready == false and M05_chase.local_player_ready == false then 
  1928. 		objective_text(0, "M05_OBJ_CHASE_HELI", "", "", SYNC_ALL, OI_ASSET_LOCATION) 
  1929. 		marker_add(M05_groups.chase_host.target, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  1930. 	end 
  1931. 	 
  1932. 	-- remove the marker from the other heli for this player only 
  1933. 	if coop_is_active() then 
  1934. 		local other_heli = M05_groups.heli_client.heli 
  1935. 		if vehicle == other_heli then 
  1936. 			other_heli = M05_groups.heli_host.heli 
  1937. 		end 
  1938. 		 
  1939. 		local sync = SYNC_LOCAL 
  1940. 		if player == REMOTE_PLAYER then 
  1941. 			sync = SYNC_REMOTE 
  1942. 		end 
  1943. 		 
  1944. 		marker_remove( other_heli, sync ) 
  1945. 	end 
  1946.  
  1947. 	-- mark this player as ready to chase 
  1948. 	if (player == LOCAL_PLAYER) then 
  1949. 		M05_chase.local_player_ready = true 
  1950. 	elseif (player == REMOTE_PLAYER) then 
  1951. 		M05_chase.remote_player_ready = true 
  1952. 	end 
  1953. 	 
  1954. 	vehicle_max_speed( vehicle, -1 ) 
  1955. end 
  1956.  
  1957. -- The player entered the warehouse 
  1958. function m05_warehouse_reached(char, trig) 
  1959. 	m05_clear_trigger(trig) 
  1960. 	audio_conversation_wait_for_end(M05_conv.chase.handle) 
  1961. 	M05_conv.chase.handle = INVALID_CONVERSATION_HANDLE 
  1962. 	audio_play_persona_line(LOCAL_PLAYER, M05_lines.warehouse) 
  1963. end 
  1964.  
  1965. -- See how many targets remain in the "let in saints" objective. 
  1966. -- 
  1967. function m05_get_num_remaining_targets() 
  1968. 	local num_enemies = 0 
  1969. 	if group_is_loaded(M05_groups.elevator.name) then 
  1970. 		num_enemies = num_enemies + group_members_alive(M05_groups.elevator.name) 
  1971. 	end 
  1972. 	if group_is_loaded(M05_groups.guards.name) then 
  1973. 		num_enemies = num_enemies + group_members_alive(M05_groups.guards.name) 
  1974. 	end 
  1975. 	if group_is_loaded(M05_groups.drop_1.name) then 
  1976. 		num_enemies = num_enemies + group_members_alive(M05_groups.drop_1.name) 
  1977. 	end 
  1978. 	if group_is_loaded(M05_groups.drop_2.name) then 
  1979. 		num_enemies = num_enemies + group_members_alive(M05_groups.drop_2.name) 
  1980. 	end 
  1981. 	return num_enemies 
  1982. end 
  1983.  
  1984. function m05_land_call_finished_cb() 
  1985. 	M05_land_call_completed = true 
  1986. end 
  1987.  
  1988. function m05_color_call_finished_cb() 
  1989. 	M05_color_call_completed = true 
  1990. end 
  1991.  
  1992. -- ************************* 
  1993. -- 
  1994. -- Thread functions 
  1995. -- 
  1996. -- ************************* 
  1997.  
  1998. -- Spawn in new bad guys periodically until all bad guys are dead. 
  1999. -- 
  2000. function m05_elevator_spawn_thread() 
  2001. 	local done_spawning = false 
  2002. 	M05_elevator_spawn_num = 0 
  2003. 	 
  2004. 	while not done_spawning do 
  2005. 	 
  2006. 		group_create(M05_groups.elevator.name, true) 
  2007. 		while not group_is_loaded(M05_groups.elevator.name) do 
  2008. 			thread_yield() 
  2009. 		end 
  2010. 		 
  2011. 		for i, guard in pairs(M05_groups.elevator.npcs) do 
  2012. 			if (character_exists(guard) and not character_is_dead(guard)) then 
  2013. 				on_death("m05_enemy_killed", guard) 
  2014. 				marker_add(guard, MINIMAP_ICON_KILL, OI_ASSET_KILL) 
  2015. 				ai_set_personality(guard, "gang defensive") 
  2016. 			end 
  2017. 		end 
  2018. 		 
  2019. 		delay(2.0) 
  2020. 		 
  2021. 		door_open(M05_doors.enemy_elevator, false) 
  2022. 		 
  2023. 		delay(2.0) 
  2024. 		 
  2025. 		-- If we have a destination list, use that. 
  2026. 		local dest_list = M05_groups.elevator.destination[M05_elevator_spawn_num + 1] 
  2027. 		if dest_list ~= nil then 
  2028. 			for i, guard in pairs(M05_groups.elevator.npcs) do 
  2029. 				if (character_exists(guard) and not character_is_dead(guard)) then				 
  2030. 					local idx = (i % #dest_list) + 1 
  2031. 					local dest_nav = dest_list[idx] 
  2032. 					if (dest_nav ~= nil) then 
  2033. 						ai_do_scripted_move(guard, dest_nav, true, false) 
  2034. 					end 
  2035. 				end 
  2036. 			end 
  2037. 		end 
  2038. 		 
  2039. 		-- don't close the door until the elevator is empty. 
  2040. 		-- Need to find out if this will return dead humans... would be a problem if it does. 
  2041. 		while (get_num_humans_in_trigger(M05_triggers.enemy_elevator) > 0) do 
  2042. 			delay(1.0) 
  2043. 		end 
  2044. 		 
  2045. 		while true do		 
  2046. 			door_close(M05_doors.enemy_elevator) 
  2047. 			 
  2048. 			delay( 3 ) 
  2049. 			 
  2050. 			if get_num_humans_in_trigger(M05_triggers.enemy_elevator)  == 0 then 
  2051. 				break 
  2052. 			end 
  2053. 			 
  2054. 			door_open(M05_doors.enemy_elevator, false) 
  2055. 			delay( 3 ) 
  2056. 		end 
  2057. 		 
  2058. 		while group_is_loaded(M05_groups.elevator.name) and group_members_alive(M05_groups.elevator.name) > 0 do 
  2059. 			thread_yield() 
  2060. 		end 
  2061. 		 
  2062. 		-- Make sure all the markers get removed. 
  2063. 		marker_remove_script_group(M05_groups.elevator.name) 
  2064. 		 
  2065. 		delay(5.0) 
  2066. 		 
  2067. 		-- Release the (now dead) group so you can create it again. 
  2068. 		if group_is_loaded(M05_groups.elevator.name) then 
  2069. 			release_to_world(M05_groups.elevator.name) 
  2070. 		end 
  2071. 		 
  2072. 		-- Run no less than 3 times, no more than 5. 
  2073. 		M05_elevator_spawn_num = M05_elevator_spawn_num + 1 
  2074. 		if ((m05_get_num_remaining_targets() == 0 and M05_elevator_spawn_num >= M05_elevator_spawn_num_min) or M05_elevator_spawn_num >= M05_elevator_spawn_num_max) then 
  2075. 			done_spawning = true 
  2076. 		end 
  2077. 	end 
  2078. end 
  2079.  
  2080. -- Nag the player to get out of the heli 
  2081. function m05_nag_thread() 
  2082. 	-- Wait before nagging 
  2083. 	delay(20) 
  2084.  
  2085. 	-- If either player is in a vehicle, nag them 
  2086. 	if (character_is_in_vehicle(LOCAL_PLAYER) or (M05_in_coop and character_is_in_vehicle(REMOTE_PLAYER))) then 
  2087. 		audio_play_persona_line(M05_groups.pierce.pierce, M05_lines.jump_waiting) 
  2088. 	end 
  2089. end 
  2090.  
  2091. -- Fly a helicopter to a specified point 
  2092. -- 
  2093. -- heli:		(string) name of the helicotper to move 
  2094. -- nav:		(string) name of the navpoint to move to 
  2095. -- 
  2096. function m05_fly_to_thread(heli, nav) 
  2097. 	while true do 
  2098. 		helicopter_fly_to_direct(heli, -1, nav) 
  2099. 		thread_yield() 
  2100. 	end 
  2101. end 
  2102.  
  2103. -- Fly a helicopter to a specified point then land 
  2104. function m05_land_thread(heli_group, landing_nav, sp, npc_group, delay_time) 
  2105. 	local heli = heli_group.heli 
  2106. 	local npc_list = npc_group.npcs 
  2107. 	 
  2108. 	delay( delay_time ) 
  2109. 	 
  2110. 	-- Spawn the reinforcements in a heli 
  2111. 	group_create_hidden(heli_group.name, true) 
  2112. 	group_create_hidden(npc_group.name, true) 
  2113. 	vehicle_set_invulnerable(heli) 
  2114. 	vehicle_prevent_explosion_fling(heli, true) 
  2115. 	vehicle_enter_group_teleport(npc_list, heli) 
  2116. 	vehicle_suppress_npc_exit( heli, true ) 
  2117.  
  2118. 	-- Mark them as required kills 
  2119. 	for i, guard in pairs(npc_list) do 
  2120. 		on_death("m05_enemy_killed", guard) 
  2121. 		 
  2122. 		-- Make them come right at the player. 
  2123. 		set_always_sees_player_flag(guard, true) 
  2124. 		ai_set_personality(guard, "gang offensive") 
  2125. 		 
  2126. 		marker_add(guard, MINIMAP_ICON_KILL, OI_ASSET_KILL) 
  2127. 	end 
  2128.  
  2129. 	-- Make the heli unenterable by the player. 
  2130. 	set_unjackable_flag(heli, true) 
  2131. 	 
  2132. 	-- Make sure the pilot is invulnerable until the heli lands 
  2133. 	local pilot = vehicle_get_driver(heli) 
  2134. 	turn_invulnerable(pilot) 
  2135. 	on_vehicle_exit("m05_pilot_exit", pilot) 
  2136. 	 
  2137. 	group_show( heli_group.name ) 
  2138. 	group_show( npc_group.name ) 
  2139. 	 
  2140. 	vehicle_max_speed(heli, 30) 
  2141. 	set_ignore_ai_flag( pilot, true ) 
  2142. 	 
  2143. 	helicopter_fly_to_direct( heli, 30, sp[ 1 ] ) 
  2144.  
  2145. 	-- Land at the navpoint and drop off all NPCs 
  2146. 	helicopter_fly_to_do( heli, 5, true, "", false, sp[ 2 ] ) 
  2147. 		 
  2148. 	local emergency_exit = false 
  2149. 	local frames_close = 0 
  2150. 	-- Wait until either the chopper comes to a stop or hits the deck. 
  2151. 	while get_char_vehicle_is_in_air( pilot ) == true and not emergency_exit do 
  2152. 		thread_yield() 
  2153. 		-- emergency plan in case we don't 'land' (bug 41980) 
  2154. 		if get_dist(heli, landing_nav) < 2.0 then 
  2155. 			-- we are pretty close 
  2156. 			frames_close = frames_close + 1 
  2157. 			if frames_close > 60 then 
  2158. 				-- we have been close for like 2 seconds and we are still here?  Abort! (expected values are in the 3-5 range) 
  2159. 				emergency_exit = true 
  2160. 			end 
  2161. 		end 
  2162. 	end 
  2163. 	 
  2164. 	-- Stop the pathfind. 
  2165. 	helicopter_fly_to_stop( heli ) 
  2166. 	 
  2167. 	delay(1.5) 
  2168. 	 
  2169. 	set_ignore_ai_flag( pilot, false ) 
  2170. 	vehicle_suppress_npc_exit( heli, false ) 
  2171. 	vehicle_exit_group(npc_list, true) 
  2172. end 
  2173.  
  2174. -- Fly a helicopter along the specified path, then have the NPCs exit 
  2175. -- 
  2176. -- group:	(string) name of the helicotper group to use 
  2177. -- paths:	(table) table of paths to move along 
  2178. -- nav:		(string) navpoint to return to afterward 
  2179. -- 
  2180. function m05_chase_thread(group, paths, nav) 
  2181. 	-- Force the heli to follow the paths (slowly) 
  2182. 	vehicle_max_speed(group.heli, M05_chase.min_speed) 
  2183. 	for i, path in pairs(paths) do 
  2184. 		helicopter_fly_to_direct_dont_stop(group.heli, -1, path) 
  2185. 	end 
  2186.  
  2187. 	-- Once the path is complete, have the passengers exit (the pilot MUST stay in or the heli crashes) 
  2188. 	vehicle_exit(group.target) 
  2189.  
  2190. 	-- Reenable their AI 
  2191. 	vehicle_set_vulnerable(group.heli) 
  2192. 	turn_vulnerable(group.pilot) 
  2193. 	set_ignore_ai_flag(group.target, true) 
  2194. 	set_unjackable_flag(group.heli, false) 
  2195. 	 
  2196. 	delay(.75) 
  2197. 	vehicle_exit(group.pilot) 
  2198. 	set_ignore_ai_flag(group.pilot, false) 
  2199. 	 
  2200. 	-- Continue onward 
  2201. 	M05_heli_arrived = true 
  2202.  
  2203. end 
  2204.  
  2205. function m05_chase_distance(heli, sync) 
  2206. 	-- Turn on the distance meter 
  2207. 	local hud_index = 0 
  2208. 	if (sync == SYNC_REMOTE) then 
  2209. 		hud_index = 1 
  2210. 	end 
  2211. 	 
  2212. 	hud_bar_on(hud_index, "annoyance", "", M05_chase.max_dist - M05_chase.min_dist, sync) 
  2213.  
  2214. 	local my_dist = 9999 
  2215. 	local co_dist = 9999 
  2216. 	local closest = 9999 
  2217. 	local speed = M05_chase.min_speed 
  2218. 	while(true) do 
  2219. 		-- Get the current distances 
  2220. 		my_dist = get_dist(LOCAL_PLAYER, heli) 
  2221. 		if not M05_in_coop then 
  2222. 			closest = my_dist 
  2223. 		else 
  2224. 			co_dist = get_dist(REMOTE_PLAYER, heli) 
  2225. 			if (my_dist < co_dist) then 
  2226. 				closest = my_dist 
  2227. 			else 
  2228. 				closest = co_dist 
  2229. 			end 
  2230.  
  2231. 			if (sync == SYNC_REMOTE) then 
  2232. 				my_dist = co_dist 
  2233. 			end 
  2234. 		end 
  2235.  
  2236. 		-- Update the bar 
  2237. 		if (my_dist > M05_chase.max_dist) then 
  2238. 			hud_bar_set_value(hud_index, 0, sync) 
  2239. 		elseif (my_dist < M05_chase.min_dist) then 
  2240. 			-- They're close enough, so show a full bar 
  2241. 			hud_bar_set_value(hud_index, M05_chase.max_dist - M05_chase.min_dist, sync) 
  2242. 		else 
  2243. 			hud_bar_set_value(hud_index, M05_chase.max_dist - my_dist, sync) 
  2244. 		end 
  2245.  
  2246. 		-- Fail if all players strayed too far 
  2247. 		if (closest > M05_chase.max_dist) then 
  2248. 			mission_end_failure("m05", "m05_fail_chase") 
  2249. 		end 
  2250.  
  2251. 		-- Update the heli's speed based on the distance 
  2252. 		if M05_chase.local_player_ready or M05_chase.remote_player_ready then 
  2253. 			-- Calculate percent distance 
  2254. 			speed = 1 - (closest / M05_chase.max_dist) 
  2255.  
  2256. 			-- The closer the player, the faster the heli should fly 
  2257. 			speed = M05_chase.min_speed + ((M05_chase.max_speed - M05_chase.min_speed) * speed) 
  2258. 			vehicle_max_speed(heli, speed) 
  2259. 		end 
  2260.  
  2261. 		thread_yield() 
  2262. 	end 
  2263. end 
  2264.  
  2265. -- Fire off rockets when the player nears 
  2266. -- 
  2267. function m05_rockets_thread() 
  2268. 	while(true) do 
  2269. 		for i, npc in pairs(M05_groups.rockets.npcs) do 
  2270. 			if (get_dist_closest_player_to_object(npc) < M05_chase.rocket_dist) then 
  2271. 				force_fire(npc, M05_nav.rockets[i], true) 
  2272. 			end 
  2273. 			delay(0.5) 
  2274. 		end 
  2275. 	end 
  2276. end 
  2277.