./m02.lua

  1. --[[ 
  2. 	m02.lua 
  3. 	SR3 Mission Script 
  4. 	DATE: 06/07/10 
  5. 	AUTHOR:	Matt.Gawalek 
  6. ]]-- 
  7.  
  8.  
  9. -- Debug flags -- 
  10.  
  11. -- Checkpoints -- 
  12. 	M02_checkpoints = { 
  13. 		start = MISSION_START_CHECKPOINT,			-- defined in ug_lib.lua 
  14. 		free_falling = "m02_checkpoint_free_fall", 
  15. 		final_dive = "m02_checkpoint_final_dive", 
  16. 		 
  17. 		debug_checkpoints = { 
  18. 			first_dive = "m02_debug_checkpoint_first_dive", 
  19. 			final_qte = "m02_debug_checkpoint_final_qte", 
  20. 		}, 
  21. 	} 
  22.  
  23. -- Tweakable Parameters -- 
  24. 	M02_tweak_values = { 
  25. 		goon_hitpoint_modifier = 0.6, 
  26. 		player_downward_dive_speed = 12.0,	-- this doesn't set the player's speed, just used for reference in the script 
  27. 		 
  28. 		plane_interior_camera_shake = "cargo_plane_interior", 
  29. 		 
  30. 		-- Weapon stuff 
  31. 		skydiving_pistol = "Pistol-Gang", 
  32. 		skydiving_smg = "SMG-Gang", 
  33. 		 
  34. 		-- Final inventory load-out after completing the mission 
  35. 		mission_success_inventory = { 
  36. 			{ 
  37. 				name = "Pistol-Gang", 
  38. 				reserve_ammo = 16, 
  39. 			}, 
  40. 			{ 
  41. 				name = "SMG-Gang", 
  42. 				reserve_ammo = 39, 
  43. 			}, 
  44. 		}, 
  45. 		 
  46. 		-- Cooldown for the min/max time between cloud "puff" effects 
  47. 		skydive_cloud_min_cooldown_time = 15,	-- seconds 
  48. 		skydive_cloud_max_cooldown_time = 25,	-- seconds 
  49. 		 
  50. 		-- Hitpoints for the cargo plane windshield 
  51. 		cargo_plane_windshield_hp = 60, 
  52. 		 
  53. 		-- Car whoosh start/end trigger distanced (end should be larger than start) 
  54. 		car_whoosh_start_dist = 10.0, 
  55. 		car_whoosh_end_dist = 50.0, 
  56. 		 
  57. 		music_trigger_shuandi_catch_time_01 = 13.12, 
  58. 		music_trigger_shuandi_catch_time_02 = 12.8, 
  59. 	} 
  60.  
  61. -- Groups -- 
  62. 	M02_groups = { 
  63. 		-- Script item props for the cargo plane interior 
  64. 		cargo_plane_props = { 
  65. 			name = "Group_cargo_plane_items 001", 
  66. 		}, 
  67.  
  68. 		-- Shaundi in the plane 
  69. 		homies_01 = { 
  70. 			name = "Group_homies 001", 
  71. 			chars = { "char_shaundi" }, 
  72. 			shaundi = "char_shaundi", 
  73. 		}, 
  74. 		 
  75. 		-- Shuandi skydiving 
  76. 		homies_skydive_01 = { 
  77. 			name = "Group_homies_skydive 001", 
  78. 			chars = { "char_shaundi_skydive 001" }, 
  79. 			shaundi = "char_shaundi_skydive 001", 
  80. 		}, 
  81.  
  82. 		-- Initial bad guys, in the room the player starts 
  83. 		cargo_plane_goons_01 = { 
  84. 			name = "Group_cargo_plane_goons 001", 
  85. 			chars = { "char_goon_cargo_plane_01_ 001", "char_goon_cargo_plane_01_ 002", "char_goon_cargo_plane_01_ 003" }, 
  86. 		}, 
  87. 		 
  88. 		-- Bad guys in the second room of the cargo plane 
  89. 		cargo_plane_goons_02 = { 
  90. 			name = "Group_cargo_plane_goons 002", 
  91. 			chars = { "char_goon_cargo_plane_02_ 001", "char_goon_cargo_plane_02_ 002" }, 
  92. 		}, 
  93. 		 
  94. 		-- Bad guys in the cargo section of the plane 
  95. 		cargo_plane_goons_03 = { 
  96. 			name = "Group_cargo_plane_goons 003", 
  97. 			chars = { "char_goon_cargo_plane_03_ 001", "char_goon_cargo_plane_03_ 002", "char_goon_cargo_plane_03_ 003", "char_goon_cargo_plane_03_ 004", "char_goon_cargo_plane_03_ 005",  
  98. 						"char_goon_cargo_plane_03_ 006", "char_goon_cargo_plane_03_ 007", "char_goon_cargo_plane_03_ 008", "char_goon_cargo_plane_03_ 009", "char_goon_cargo_plane_03_ 010",  
  99. 						"char_goon_cargo_plane_03_ 011", "char_goon_cargo_plane_03_ 012", "char_goon_cargo_plane_03_ 013", "char_goon_cargo_plane_03_ 014" }, 
  100. 			move_up_chars = { "char_goon_cargo_plane_03_ 001" }, 
  101. 		}, 
  102. 		 
  103. 		-- Vehicles in the cargo plane interior (not falling) 
  104. 		cargo_vehicles = { 
  105. 			name = "Group_cargo_vehicles 002", 
  106. 			vehicles = { "cargo_vehicle 001", "cargo_vehicle 002", "cargo_vehicle 003", "cargo_vehicle 004", "cargo_vehicle 005", "cargo_vehicle 006" }, 
  107. 			car_alarm_vehicle = "cargo_vehicle 005", 
  108. 		}, 
  109.  
  110. 		-- The cargo plane that attempts to ram the player 
  111. 		plane = { 
  112. 			name = "Group_cargo_plane 001", 
  113. 			chars = { "char_cargo_plane_pilot 001" }, 
  114. 			vehicle = "veh_cargo_plane 001", 
  115. 			windshield_component = "windshield", 
  116. 			 
  117. 			circling_path = "path_plane_circle 001", 
  118. 			ram_start_pos = "nav_plane_ram_start_pos 001", 
  119. 			plane_ram_path = "path_cargo_plane_ram 001", 
  120. 			path_idx = 1, 
  121. 		}, 
  122. 		 
  123. 		-- Vehicles that are falling 
  124. 		debris_vehicles = { 
  125. 			name = "Group_debris_vehicles 001", 
  126. 			vehicles = {  
  127. 				{ name = "debris_vehicle 001", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  128. 				{ name = "debris_vehicle 002", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  129. 				{ name = "debris_vehicle 003", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  130. 				{ name = "debris_vehicle 004", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  131. 				{ name = "debris_vehicle 005", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  132. 				{ name = "debris_vehicle 006", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  133. 				{ name = "debris_vehicle 007", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  134. 				{ name = "debris_vehicle 008", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  135. 				{ name = "debris_vehicle 009", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  136. 				{ name = "debris_vehicle 010", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  137. 				{ name = "debris_vehicle 011", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  138. 				{ name = "debris_vehicle 012", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  139. 			} 
  140. 		}, 
  141. 		 
  142. 		debris_vehicles_dive_01 = { 
  143. 			name = "Group_debris_vehicle_dive 001", 
  144. 			vehicles = { 
  145. 				{ name = "debris_vehicle_dive_01_ 001", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  146. 				{ name = "debris_vehicle_dive_01_ 002", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  147. 				{ name = "debris_vehicle_dive_01_ 003", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  148. 				{ name = "debris_vehicle_dive_01_ 004", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  149. 				{ name = "debris_vehicle_dive_01_ 005", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  150. 				{ name = "debris_vehicle_dive_01_ 006", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  151. 				{ name = "debris_vehicle_dive_01_ 007", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  152. 				{ name = "debris_vehicle_dive_01_ 008", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  153. 				{ name = "debris_vehicle_dive_01_ 009", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  154. 				{ name = "debris_vehicle_dive_01_ 010", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  155. 				{ name = "debris_vehicle_dive_01_ 011", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  156. 				{ name = "debris_vehicle_dive_01_ 012", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  157. 			}, 
  158. 		}, 
  159. 		 
  160. 		debris_vehicles_dive_02 = { 
  161. 			name = "Group_debris_vehicle_dive 002", 
  162. 			vehicles = { 
  163. 				{ name = "debris_vehicle_dive_02_ 001", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  164. 				{ name = "debris_vehicle_dive_02_ 002", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  165. 				{ name = "debris_vehicle_dive_02_ 003", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  166. 				{ name = "debris_vehicle_dive_02_ 004", whoosh_event = INVALID_MESSAGE_HANDLE, fire_handle = -1, exp_handle = -1 }, 
  167. 			}, 
  168. 		}, 
  169.  
  170. 		-- Initial group of enemies while skydiving (includes the guy that grabs the player in the first QTE) 
  171. 		sky_goons_01 = { 
  172. 			name = "Group_sky_goons 001", 
  173. 			chars = {  
  174. 				{ name = "char_goon_sky_01_ 002", dest_nav = "nav_char_goon_sky_01_ 002", forced_dive = false, delay_marker = false, streamers = false, vfx_handles = {} }, 
  175. 				{ name = "char_goon_sky_01_ 003", dest_nav = "nav_char_goon_sky_01_ 003", forced_dive = false, delay_marker = false, streamers = false, vfx_handles = {} }, 
  176. 				{ name = "char_goon_sky_01_ 004", dest_nav = "nav_char_goon_sky_01_ 004", forced_dive = false, delay_marker = false, streamers = false, vfx_handles = {} }, 
  177. 			}, 
  178. 			grapple_enemy = "char_goon_sky_01_ 001", 
  179. 		}, 
  180. 		 
  181. 		-- Secondary group that is spawned in coop so that the coop player has someone to grapple with in the first QTE 
  182. 		sky_goons_01_a = { 
  183. 			name = "Group_sky_goons_A 001", 
  184. 			chars = { "char_goon_sky_01A_ 001" }, 
  185. 			grapple_enemy = "char_goon_sky_01A_ 001", 
  186. 		}, 
  187.  
  188. 		-- First wave of reinforcements (spawns below the player) 
  189. 		sky_goons_02 = {  
  190. 			name = "Group_sky_goons 002", 
  191. 			chars = { 
  192. 				{ name = "char_goon_sky_02_ 001", dest_nav = "nav_char_goon_sky_02_ 001", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  193. 				{ name = "char_goon_sky_02_ 002", dest_nav = "nav_char_goon_sky_02_ 002", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  194. 			}, 
  195. 		}, 
  196. 		 
  197. 		-- Next wave of reinforcement (spawns above the player, once they flip down) 
  198. 		sky_goons_03 = { 
  199. 			name = "Group_sky_goons 003", 
  200. 			chars = {  
  201. 				{ name = "char_goon_sky_03_ 001", dest_nav = "nav_char_goon_sky_03_ 001", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  202. 				{ name = "char_goon_sky_03_ 002", dest_nav = "nav_char_goon_sky_03_ 002", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  203. 				{ name = "char_goon_sky_03_ 003", dest_nav = "nav_char_goon_sky_03_ 003", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  204. 				{ name = "char_goon_sky_03_ 004", dest_nav = "nav_char_goon_sky_03_ 004", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  205. 			}, 
  206. 		}, 
  207.  
  208. 		-- Group of guys that spawn immediatly after the player fly through the cargo plane 
  209. 		sky_goons_05 = { 
  210. 			name = "Group_sky_goons 005", 
  211. 			chars = { 
  212. 				{ name = "char_goon_sky_05_ 001", dest_nav = "nav_char_goon_sky_05_ 001", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  213. 				{ name = "char_goon_sky_05_ 002", dest_nav = "nav_char_goon_sky_05_ 002", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  214. 				{ name = "char_goon_sky_05_ 003", dest_nav = "nav_char_goon_sky_05_ 003", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  215. 				{ name = "char_goon_sky_05_ 004", dest_nav = "nav_char_goon_sky_05_ 004", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  216. 				{ name = "char_goon_sky_05_ 005", dest_nav = "nav_char_goon_sky_05_ 005", forced_dive = true, delay_marker = false, streamers = false, vfx_handles = {} }, 
  217. 				{ name = "char_goon_sky_05_ 006", dest_nav = "nav_char_goon_sky_05_ 006", forced_dive = false, delay_marker = false, streamers = false, vfx_handles = {} }, 
  218. 				{ name = "char_goon_sky_05_ 007", dest_nav = "nav_char_goon_sky_05_ 007", forced_dive = false, delay_marker = false, streamers = false, vfx_handles = {} }, 
  219. 			}, 
  220. 		}, 
  221. 		 
  222. 		-- Group for the guy that grabs the local player during the final QTE sequence 
  223. 		sky_goons_07 = { 
  224. 			name = "Group_sky_goons 007", 
  225. 			chars = { "char_goon_sky_07_ 001" }, 
  226. 			grapple_enemy = "char_goon_sky_07_ 001", 
  227. 		}, 
  228. 		 
  229. 		-- Secondar group for the guy the grabs the coop player (only spawns in coop) 
  230. 		sky_goons_07_A = { 
  231. 			name = "Group_sky_goons_A 007", 
  232. 			chars = { "char_goon_sky_07A_ 001" }, 
  233. 			grapple_enemy = "char_goon_sky_07A_ 001", 
  234. 		} 
  235. 	} 
  236.  
  237. -- Navpoints -- 
  238. 	M02_navpoints = { 
  239. 		-- Player start positions 
  240. 		player_start_chk_01 = { "nav_player_start_local_chk 001", "nav_player_start_remote_chk 001" }, 
  241. 		player_start_chk_02 = { "nav_player_start_local_chk 002", "nav_player_start_remote_chk 002" }, 
  242. 		player_start_chk_03 = { "nav_player_start_local_chk 003", "nav_player_start_remote_chk 003" }, 
  243. 		player_end = { "nav_player_local_end 001", "nav_player_remote_end 001" }, 
  244. 		 
  245. 		-- Turbulance direction navpoints 
  246. 		turbulance_direction_01 = "nav_turbulance_direction 001", 
  247. 		turbulance_direction_02 = "nav_turbulance_direction 002", 
  248. 	 
  249. 		-- Locations for the AI to approach while investigating the player at the start of the mission 
  250. 		ai_investigation_01 = "nav_plane_ai_investigation 001", 
  251. 		ai_investigation_02 = "nav_plane_ai_investigation 002", 
  252. 	 
  253. 		-- When the cargo bay doors are open, this is the direction humans get tossed if the enter the region 
  254. 		plane_rear_ejection_point = "nav_plane_ejection_point 001", 
  255. 		 
  256. 		-- Position of the debris emitters for the junk falling around the player 
  257. 		debris_emitter_pos_01 = "debris_emitter_pos 001",	-- default while the player is skydiving (debris goes up) 
  258. 		debris_emitter_pos_02 = "debris_emitter_pos 002",	-- special emitter while the player's chute is open (debris goes down) 
  259. 		 
  260. 		-- Shaundi's position during the free fall section 
  261. 		shaundi_skydive_pos = "nav_shandi_skydive_pos 001", 
  262. 		remote_player_catch_pos = "nav_remote_player_catch_pos", 
  263. 		 
  264. 		player_grapple_pos = { "nav_player_grapple_pos 001", "nav_player_grapple_pos 002" }, 
  265. 		 
  266. 		player_camera_focus = "nav_player_camera_focus 001", 
  267.  
  268. 		cargo_plane_fly_away_start = "nav_plane_fly_away_start 001", 
  269. 		cargo_plane_fly_away_end = "nav_plane_fly_away_end 001", 
  270. 	} 
  271.  
  272. -- Triggers -- 
  273. 	M02_triggers = { 
  274. 		-- Triggers for picking up the parachutes 
  275. 		turbulance_01 = "tgr_turbulance 001", 
  276. 		turbulance_02 = "tgr_turbulance 002", 
  277. 		--stop_gat_music = "tgr_cargo_plane_stop_music 001", 
  278. 		cargo_plane_parachute_01 = "tgr_cargo_plane_exit 001", 
  279. 		 
  280. 		gun_grapple = "tgr_gun_grapple 001", 
  281. 		stop_dive_debris = "tgr_dive_debris_flow_stop 001", 
  282. 		 
  283. 		clean_up_debris_above_shaundi = "tgr_cleanup_shaundi_debris 001", 
  284. 		cargo_plane_ram_trigger_01 = "tgr_cargo_plane_ram 001", 
  285. 		cargo_plane_ram_trigger_02 = "tgr_cargo_plane_ram 002", 
  286. 		 
  287. 		-- Trigger region to end the vertical dive sequences of the mission (should be centered on Shaundi's position) 
  288. 		final_dive_01 = "tgr_vertical_dive 001", 
  289. 	} 
  290. 	 
  291. -- Interiors -- 
  292. 	M02_interiors = { 
  293. 		cargo_plane = "int_cargo_plane 001", 
  294. 		--vfx = "int_vfx 001", 
  295. 	} 
  296.  
  297. -- Characters -- 
  298.  
  299. -- Conversations -- 
  300. 	M02_conversations = { 
  301. 		leave_gat_behind = { 
  302. 			name = "m02_convo_1", 
  303. 			load_direct = false, 
  304. 			queued = false, 
  305. 			started = false, 
  306. 			completed = false, 
  307. 			ended = false, 
  308. 		}, 
  309. 		gat_takes_control = { 
  310. 			name = "m02_johnny_message_1", 
  311. 			load_direct = false, 
  312. 			queued = false, 
  313. 			started = false, 
  314. 			completed = false, 
  315. 			ended = false, 
  316. 		}, 
  317. 		gat_turbulence = { 
  318. 			name = "m02_turbulence", 
  319. 			load_direct = true, 
  320. 			queued = false, 
  321. 			started = false, 
  322. 			completed = false, 
  323. 			ended = false, 
  324. 		}, 
  325. 		door_unlocked = { 
  326. 			name = "m02_cargo_doors", 
  327. 			load_direct = false, 
  328. 			queued = false, 
  329. 			started = false, 
  330. 			completed = false, 
  331. 			ended = false, 
  332. 		}, 
  333. 		gat_update = { 
  334. 			name = "m02_convo_4", 
  335. 			load_direct = true, 
  336. 			queued = false, 
  337. 			started = false, 
  338. 			completed = false, 
  339. 			ended = false, 
  340. 		}, 
  341. 		shaundi_catch_1 = { 
  342. 			name = "m02_pull_chute_1", 
  343. 			load_direct = false, 
  344. 			queued = false, 
  345. 			started = false, 
  346. 			completed = false, 
  347. 			ended = false, 
  348. 		}, 
  349. 		notice_cargo_plane = { 
  350. 			name = "m02_plane", 
  351. 			load_direct = false, 
  352. 			queued = false, 
  353. 			started = false, 
  354. 			completed = false, 
  355. 			ended = false, 
  356. 		}, 
  357. 		shaundi_catch_2 = { 
  358. 			name = "m02_pull_chute_2", 
  359. 			load_direct = false, 
  360. 			queued = false, 
  361. 			started = false, 
  362. 			completed = false, 
  363. 			ended = false, 
  364. 		}, 
  365. 	} 
  366. 	 
  367. 	M02_dialog_lines = { 
  368. 		shaundi_nags = { 
  369. 			"m02_get_moving_01", 
  370. 			"m02_get_moving_02", 
  371. 			"m02_get_moving_03", 
  372. 			"m02_get_moving_04", 
  373. 		}, 
  374. 		gat_warning = "m02 gat warning", 
  375. 		free_fall_start = "m02_free_fall_03", 
  376. 		sky_goons = "m02_falling_goons", 
  377. 		push_shaundi_away = "m02_shaundi_pushed_away", 
  378. 		shoot_plane_window = "m02_shoot_plane_window", 
  379. 		window_shot = "m02_window_shot", 
  380. 		flew_through_plane = "m02_flew_through_the_plane", 
  381. 		falling_shit = "m02_falling_shit", 
  382. 	} 
  383.  
  384. -- Vehicles -- 
  385.  
  386. -- Mesh Movers -- 
  387. 	M02_movers = { 
  388. 		cargo_plane_doors = { 
  389. 			lounge1_utility1 = { 
  390. 				name = "mvr_cargo_plane_door 005", 
  391. 				locked = true, 
  392. 				open = false, 
  393. 			}, 
  394. 			lounge2_utility1 = { 
  395. 				name = "mvr_cargo_plane_door 001", 
  396. 				locked = true, 
  397. 				open = false, 
  398. 			}, 
  399. 			seating1_utility2 = { 
  400. 				name = "mvr_cargo_plane_door 002", 
  401. 				locked = true, 
  402. 				open = false, 
  403. 			}, 
  404. 			seating1_utility3 = { 
  405. 				name = "mvr_cargo_plane_door 003", 
  406. 				locked = true, 
  407. 				open = false, 
  408. 			}, 
  409. 			cargo1_utility3 = { 
  410. 				name = "mvr_cargo_plane_door 004", 
  411. 				locked = true, 
  412. 				open = false, 
  413. 			}, 
  414. 			cargo_bay = { 
  415. 				name = "mvr_cargo_bay_door 001", 
  416. 				locked = true, 
  417. 				open = false, 
  418. 			}, 
  419. 		}, 
  420. 			 
  421. 		debris_box_list = {  
  422. 			"mvr_debris_box 001", "mvr_debris_box 002", "mvr_debris_box 003", "mvr_debris_box 004", "mvr_debris_box 005", 
  423. 			"mvr_debris_box 006", "mvr_debris_box 007", "mvr_debris_box 008", "mvr_debris_box 009", "mvr_debris_box 010", 
  424. 			"mvr_debris_box 011", "mvr_debris_box 012", "mvr_debris_box 013", "mvr_debris_box 014", "mvr_debris_box 015", 
  425. 			"mvr_debris_box 016", "mvr_debris_box 017", "mvr_debris_box 018", "mvr_debris_box 019", "mvr_debris_box 020", 
  426. 			"mvr_debris_box 021", "mvr_debris_box 022", "mvr_debris_box 023", "mvr_debris_box 024", "mvr_debris_box 025", 
  427. 			"mvr_debris_box 026", "mvr_debris_box 027", "mvr_debris_box 028", "mvr_debris_box 029", "mvr_debris_box 030", 
  428. 			"mvr_debris_box 031", "mvr_debris_box 032", 
  429. 			 
  430. 			"mvr_drug_stack 001", "mvr_drug_stack 002", "mvr_drug_stack 003", "mvr_drug_stack 004", 
  431. 			"mvr_money_stack 001", "mvr_money_stack 002", "mvr_money_stack 003", "mvr_money_stack 004", "mvr_money_stack 005", "mvr_money_stack 006", 
  432. 		}, 
  433. 						 
  434. 		debris_pallet_list = { 
  435. 			"mvr_debris_pallet 001", "mvr_debris_pallet 002", "mvr_debris_pallet 003", "mvr_debris_pallet 004", "mvr_debris_pallet 005", "mvr_debris_pallet 006", 
  436. 			"mvr_debris_pallet 007", "mvr_debris_pallet 008", "mvr_debris_pallet 009", "mvr_debris_pallet 010", "mvr_debris_pallet 011", "mvr_debris_pallet 012", 
  437. 		}, 
  438.  
  439. 		debris_dive_boxes = { 
  440. 			"mvr_drug_stack_dive_01_ 001", "mvr_drug_stack_dive_01_ 002", "mvr_drug_stack_dive_01_ 003", "mvr_drug_stack_dive_01_ 004", "mvr_drug_stack_dive_01_ 005", "mvr_drug_stack_dive_01_ 006", 
  441. 			"mvr_drug_stack_dive_01_ 007", "mvr_drug_stack_dive_01_ 008", "mvr_drug_stack_dive_01_ 009", "mvr_drug_stack_dive_01_ 010", "mvr_drug_stack_dive_01_ 011", "mvr_drug_stack_dive_01_ 012", 
  442. 			 
  443. 			"mvr_money_stack_dive_01_ 001", "mvr_money_stack_dive_01_ 002", "mvr_money_stack_dive_01_ 003", "mvr_money_stack_dive_01_ 004", "mvr_money_stack_dive_01_ 005", "mvr_money_stack_dive_01_ 006", 
  444. 			"mvr_money_stack_dive_01_ 007", "mvr_money_stack_dive_01_ 008", "mvr_money_stack_dive_01_ 009", "mvr_money_stack_dive_01_ 010", 
  445. 			 
  446. 			"mvr_debris_box_dive_01_ 001", "mvr_debris_box_dive_01_ 002", "mvr_debris_box_dive_01_ 003", "mvr_debris_box_dive_01_ 004", "mvr_debris_box_dive_01_ 005", "mvr_debris_box_dive_01_ 006",  
  447. 			"mvr_debris_box_dive_01_ 007", "mvr_debris_box_dive_01_ 008", "mvr_debris_box_dive_01_ 009", "mvr_debris_box_dive_01_ 010",	"mvr_debris_box_dive_01_ 011", "mvr_debris_box_dive_01_ 012", 
  448. 			"mvr_debris_box_dive_01_ 013", "mvr_debris_box_dive_01_ 014", "mvr_debris_box_dive_01_ 015", "mvr_debris_box_dive_01_ 016", 
  449. 		}, 
  450. 		 
  451. 		debris_dive_pallets = { 
  452. 			"mvr_pallet_dive_01_ 001", "mvr_pallet_dive_01_ 002", "mvr_pallet_dive_01_ 003", "mvr_pallet_dive_01_ 004", "mvr_pallet_dive_01_ 005", "mvr_pallet_dive_01_ 006", 
  453. 			"mvr_pallet_dive_01_ 007", "mvr_pallet_dive_01_ 008", "mvr_pallet_dive_01_ 009", "mvr_pallet_dive_01_ 010", "mvr_pallet_dive_01_ 011", "mvr_pallet_dive_01_ 012", 
  454. 			"mvr_pallet_dive_01_ 013", "mvr_pallet_dive_01_ 014", "mvr_pallet_dive_01_ 015", "mvr_pallet_dive_01_ 016", 
  455. 		}, 
  456. 		 
  457. 		debris_dive_boxes_02 = { 
  458. 			"mvr_drug_stack_dive_02_ 001", "mvr_drug_stack_dive_02_ 002", "mvr_drug_stack_dive_02_ 003", "mvr_drug_stack_dive_02_ 004", 
  459. 			 
  460. 			"mvr_money_stack_dive_02_ 001", "mvr_money_stack_dive_02_ 002", 
  461. 			 
  462. 			"mvr_debris_box_dive_02_ 001", "mvr_debris_box_dive_02_ 002", "mvr_debris_box_dive_02_ 003", "mvr_debris_box_dive_02_ 004", "mvr_debris_box_dive_02_ 005",  
  463. 		}, 
  464. 		 
  465. 		debris_dive_pallets_02 = { 
  466. 			"mvr_pallet_dive_02_ 001", "mvr_pallet_dive_02_ 002", "mvr_pallet_dive_02_ 003", "mvr_pallet_dive_02_ 004", "mvr_pallet_dive_02_ 005", "mvr_pallet_dive_02_ 006", 
  467. 		}, 
  468. 	}	 
  469.  
  470. 	M02_debris_flows = { 
  471. 		{ 
  472. 			vehicle_group = M02_groups.debris_vehicles, 
  473. 			boxes = M02_movers.debris_box_list, 
  474. 			pallets = M02_movers.debris_pallet_list, 
  475. 			handle = 0, 
  476. 		}, 
  477. 		{ 
  478. 			vehicle_group = M02_groups.debris_vehicles_dive_01, 
  479. 			boxes = M02_movers.debris_dive_boxes, 
  480. 			pallets = M02_movers.debris_dive_pallets, 
  481. 			handle = 0, 
  482. 		}, 
  483. 		{ 
  484. 			vehicle_group = M02_groups.debris_vehicles_dive_02, 
  485. 			boxes = M02_movers.debris_dive_boxes_02, 
  486. 			pallets = M02_movers.debris_dive_pallets_02, 
  487. 			handle = 0, 
  488. 		} 
  489. 	} 
  490.  
  491. -- Text -- 
  492. 	M02_strings = { 
  493. 		help_melee_punch = "HELP_TEXT_THROW_PUNCH", 
  494. 		help_melee_block = "HELP_TEXT_MELEE_BLOCK", 
  495. 		help_melee_charged_attack = "HELP_TEXT_CHARGED_MELEE_ATTACK", 
  496. 		help_melee_lock = "HELP_TEXT_MELEE_LOCK", 
  497. 	 
  498. 		help_skydive_move = "HELP_TEXT_SKYDIVE_MOVE_CONTROL", 
  499. 		help_skydive_steer = "HELP_TEXT_SKYDIVE_STEER_CONTROL", 
  500. 		help_skydive_flip = "HELP_TEXT_SKYDIVE_FLIP", 
  501. 	 
  502. 		objective_escape = "M02_OBJ_ESCAPE", 
  503. 		objective_kill_guards = "M02_OBJ_KILL_GUARDS", 
  504. 		objective_open_doors = "M02_OBJ_OPEN_DOORS", 
  505. 		objective_find_parachute = "M02_OBJ_FIND_PARACHUTE", 
  506. 		objective_kill_pursuers = "M02_OBJ_KILL_PURSUERS", 
  507. 		objective_catch_shaundi = "M02_OBJ_CATCH_SHAUNDI", 
  508. 		objective_shoot_plane = "M02_OBJ_SHOOT_PLANE", 
  509. 	 
  510. 		failure_shaundi_died = "m02_failure_shaundi_died", 
  511. 		failure_player_ejected = "m02_failure_player_ejected" 
  512. 	} 
  513.  
  514. -- Threads -- 
  515. 	M02_threads = { 
  516. 		process_convo = -1, 
  517. 		shaundi_nag_vo = -1, 
  518. 		cue_plane_music = -1, 
  519. 		cargo_door_open = -1, 
  520. 		cargo_bay_vo = -1, 
  521. 		cargo_plane_flying = -1, 
  522. 		cloud_generator = -1,	 
  523. 		object_whoosh = -1, 
  524. 		catach_shaundi_audio = -1, 
  525. 		cargo_plane_retreat = -1, 
  526. 		clear_area_around_shaundi = -1, 
  527. 		kill_fallen_players = -1, 
  528. 	} 
  529. 	 
  530. -- Audio Events -- 
  531. 	M02_audio_events = { 
  532. 		cargo_bay_door_end = INVALID_MESSAGE_HANDLE, 
  533. 		car_whoosh = { 
  534. 			switch_groups = { "Mission_Number", "Mission_02" }, 
  535. 			switches = { "Mission_02", "Mid_Air_Car_Whoosh" }, 
  536. 		}, 
  537. 	} 
  538. 	 
  539. -- Audio Emitters -- 
  540. 	M02_audio_emitters = { 
  541. 		plane_sounds = { "M02_Cargo_Rattle_Chains", "M02_Cargo_Rattles_ Large", "M02_Cargo_Rattles_ Small", "M02_DSP_Cabin_Reverb", 
  542. 							"M02_DSP_Cargo_Bay", "M02_Muffled_Gun_Battle", "M02_Plane_Cabin_Interior", "M02_Plane_Cargo_Interior", 
  543. 							"M02_TV_Static_01", "M02_TV_Static_02", "M02_TV_Static_03", "M02_TV_Static_04", "M02_TV_Static_05_Capsule_Test", 
  544. 							"M02_Wind_Through_Cargo_Door"}, 
  545. 		plane_music = "M02_Plane_Cabin_Music", 
  546. 		cargo_bay_door = "M02_Cargo_Door_Open", 
  547. 		 
  548. 		cargo_bay_looping = { 
  549. 			wind = "M02_Wind_Through_Cargo_Door", 
  550. 			paper = "M02_Paper_Flying_VFX", 
  551. 			alarm = "M02_Plane_Cargo_Alarm", 
  552. 		}, 
  553. 	} 
  554.  
  555. -- Cutscenes -- 
  556. 	M02_cutscenes = { 
  557. 		mission_intro = "02_in", 
  558. 		mission_outro = "02_out", 
  559. 		plane_flythrough = "mission2_plane_flythrough" 
  560. 	} 
  561.  
  562. -- Zscenes -- 
  563. 	M02_zscenes = { 
  564. 		bailout = "02_z01", 
  565. 		fly_through = "02_z02", 
  566. 	} 
  567.  
  568. -- Other -- 
  569. 	M02_flags = { 
  570. 		-- Flags for the cargo plane interior sequence of events 
  571. 		opened_cargo_plane_rear_doors = false, 
  572. 		 
  573. 		-- Flag for when the parachute is picked up by a player 
  574. 		reached_parachutes = false, 
  575. 		 
  576. 		-- Flag for when the first QTE sequence is finished 
  577. 		local_gun_grapple_started = false, 
  578. 		remote_gun_grapple_started = false,		 
  579. 		local_gun_grapple_finished = false, 
  580. 		remote_gun_grapple_finished = false, 
  581. 		 
  582. 		-- Flag for when the cargo plane has reached the end of the ram path 
  583. 		cargo_plane_reached_ram_dest_01 = false, 
  584. 		cargo_plane_reached_ram_dest_02 = false, 
  585. 		 
  586. 		-- Flag for when the final QTE sequence is finished 
  587. 		local_final_grapple_finished = false, 
  588. 		remote_final_grapple_finished = false, 
  589.  
  590. 		-- Flags for various section of the skydiving sequence of events 
  591. 		triggered_final_dive_01 = false, 
  592. 		pull_parachute_finished = false, 
  593. 	} 
  594. 	 
  595. 	M02_hud_states = { 
  596. 		hide_minimap = -1, 
  597. 		hide_hud = -1, 
  598. 	} 
  599. 	 
  600. 	M02_runtime = { 
  601. 		sky_goons_alive = 0, 
  602. 		shaundi_nag_idx = 1, 
  603.  
  604. 		convo_queue = { 
  605. 			playing  = { 
  606. 				thread_id = -1, 
  607. 				conv_handle = INVALID_CONVERSATION_HANDLE, 
  608. 				convo_table = nil, 
  609. 			}, 
  610. 			list = {}, 
  611. 			size = 0, 
  612. 		}, 
  613. 		 
  614. 		stop_streamers = false, 
  615. 		shaundi_caught_by = LOCAL_PLAYER, 
  616. 	} 
  617. 		 
  618. 	M02_personas = { 
  619. 		gat = { 
  620. 			name = "Gat", 
  621. 			persona_id = -1, 
  622. 		}, 
  623. 		phillipe = { 
  624. 			name = "Phillipe", 
  625. 			persona_id = -1, 
  626. 		}, 
  627. 		mstar_wm_01 = { 
  628. 			name = "Morningstar_WM_01", 
  629. 			persona_id = -1, 
  630. 		}, 
  631. 		mstar_wm_02 = { 
  632. 			name = "Morningstar_WM_02", 
  633. 			persona_id = -1, 
  634. 		}, 
  635. 		interrogation = { 
  636. 			name = "Interrogation", 
  637. 			persona_id = -1, 
  638. 		}, 
  639. 	} 
  640. 	 
  641. 	--VFX 
  642. 	M02_vfx = { 
  643. 		skydive_city = { 
  644. 			nav = "vfx_city_texture 001", 
  645. 			handle = -1, 
  646. 		}, 
  647. 		skydive_clouds_below = { 
  648. 			nav = "vfx_bottom_clouds 001", 
  649. 			handle = -1, 
  650. 		}, 
  651. 		skydive_player_clouds = { 
  652. 			nav = "vfx_clouds 001", 
  653. 			handles = { -1, -1 }, 
  654. 		}, 
  655. 		skydive_cloud_puff = { 
  656. 			nav = "vfx_random_clouds 001", 
  657. 			handle = -1, 
  658. 		}, 
  659. 		skydive_player_streamers = { 
  660. 			nav = "vfx_cloud_streamers 001", 
  661. 			attach_points = { "l-foot", "r-foot", "l-hand", "r-hand" }, 
  662. 		}, 
  663. 		skydive_player_slow_clouds = { 
  664. 			nav = "vfx_slow_clouds 001", 
  665. 			handles = { -1, -1 }, 
  666. 		}, 
  667. 		debris_fire = { 
  668. 			name = "vfx_debris_fire 001", 
  669. 			box_handles = { }, 
  670. 			dive_box_handles = { }, 
  671. 		}, 
  672. 		cargo_bay_wind = { 
  673. 			name = "vfx_cargo_bay_wind 001", 
  674. 			handle = -1, 
  675. 		}, 
  676. 		cargo_dust = { 
  677. 			navs = { "vfx_dust_drop 001", "vfx_dust_drop 002", "vfx_dust_drop 003", "vfx_dust_drop 004", "vfx_dust_drop 005", 
  678. 					"vfx_dust_drop 006", "vfx_dust_drop 007", "vfx_dust_drop 008", "vfx_dust_drop 009", "vfx_dust_drop 010" }, 
  679. 		}, 
  680. 		-- Not hooked up 
  681. 		vehicle_explosion = { 
  682. 			name = "GP_Mission02_CarExp" 
  683. 		}, 
  684. 	} 
  685. 	 
  686. local M02_CONVO_PLAY_LAST = 0 
  687. local M02_CONVO_PLAY_NEXT = 1 
  688. local M02_CONVO_PLAY_IMMEDIATE = 2 
  689.  
  690. -- ************************* 
  691. -- 
  692. -- Standard functions 
  693. -- 
  694. -- ************************* 
  695.  
  696. -- This is the primary entry point for the mission, and is responsible for starting up the mission 
  697. -- at the specified checkpoint. 
  698. -- CALLED FROM CODE 
  699. -- 
  700. -- m02_checkpoint:	The checkpoint the mission should begin at 
  701. -- is_restart:					TRUE if the mission is restarting, FALSE otherwise 
  702. -- 
  703. function m02_start(m02_checkpoint, is_restart) 
  704. 	mission_start_fade_out(0.0) 
  705. 	 
  706. 	city_zone_swap("m2", true) 
  707. 	city_zone_swap("int_m2", true) 
  708.  
  709. 	-- turn off grenade drops 
  710. 	npc_drop_grenades(false) 
  711. 	 
  712. 	-- Check if this mission starting from the beginning 
  713. 	local playing_cutscene = false 
  714. 	if (m02_checkpoint == M02_checkpoints.start) then 
  715. 		if (is_restart == false) then 
  716. 			-- First time playing mission, play the intro cutscene 
  717. 			if (M02_cutscenes.mission_intro ~= "") then 
  718. 				cutscene_play(M02_cutscenes.mission_intro, nil, M02_navpoints.player_start_chk_01, false) 
  719. 				playing_cutscene = true 
  720. 			end 
  721. 		end 
  722. 	end 
  723.  
  724. 	-- Handle mission initialization for the current checkpoint 
  725. 	m02_initialize(m02_checkpoint, playing_cutscene) 
  726.  
  727. 	-- Run the mission from the current checkpoint 
  728. 	m02_run(m02_checkpoint) 
  729. end 
  730.  
  731. -- This is the primary function responsible for cleaning up the entire mission 
  732. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  733. -- 
  734. function m02_cleanup() 
  735. 	-- This should not get called on checkpoint restarts 
  736. 	-- Stop the music and any mission audio 
  737. 	--audio_object_post_event("M02_Stop_All_Mission_Audio", nil, nil, LOCAL_PLAYER) 
  738. 	--audio_object_post_event("M02_Score_Stop", nil, nil, LOCAL_PLAYER) 
  739.  
  740. 	-- Exit the special camera mode 
  741. 	camera_script_disable() 
  742. 	 
  743. 	-- Kill the conversation thread 
  744. 	m02_helper_conversation_kill_all() 
  745. 	if (thread_check_done(M02_threads.process_convo) == false) then 
  746. 		thread_kill(M02_threads.process_convo) 
  747. 		M02_threads.process_convo = -1 
  748. 	end 
  749.  
  750. 	-- Call the individual clean-up functions for the first checkpoint 
  751. 	m02_cleanup_basic_melee_tutorial() 
  752. 	m02_cleanup_advanced_melee_tutorial() 
  753. 	m02_cleanup_guy_with_gun() 
  754. 	m02_cleanup_go_to_cargo_hold() 
  755. 	m02_cleanup_grab_parachute() 
  756. 	m02_cleanup_cargo_plane_ejection_scene() 
  757. 	 
  758. 	-- Call the individual clean-up functions for the second checkpoint 
  759. 	m02_cleanup_free_falling_initial_dive() 
  760. 	m02_cleanup_kill_sky_goons_01() 
  761. 	m02_cleanup_kill_sky_goons_02_03() 
  762. 	m02_cleanup_dive_to_shaundi() 
  763. 	m02_cleanup_catch_shaundi_first_time() 
  764. 	m02_cleanup_ram_player_with_plane() 
  765. 	m02_cleanup_fly_through_plane_scene() 
  766. 	 
  767. 	-- Call the individual clean-up functions for the third checkpoint 
  768. 	m02_cleanup_kill_sky_goons_05() 
  769. 	m02_cleanup_final_dive_qte() 
  770. 	m02_cleanup_final_dive() 
  771. 	m02_cleanup_catch_shaundi_again() 
  772.  
  773. 	-- Stop the players from skydiving 
  774. 	character_set_skydiving(LOCAL_PLAYER, false) 
  775. 	action_stop_custom(LOCAL_PLAYER) 
  776. 	player_parachute_wear_backpack(LOCAL_PLAYER, false) 
  777. 	character_set_never_fall(LOCAL_PLAYER, false) 
  778. 	character_parachute_detach(LOCAL_PLAYER) 
  779. 	character_set_damage_multiplier(LOCAL_PLAYER, 1.0) 
  780. 	character_set_never_catch_fire(LOCAL_PLAYER, false) 
  781.  
  782. 	if (coop_is_active() == true) then 
  783. 		character_set_skydiving(REMOTE_PLAYER, false) 
  784. 		action_stop_custom(REMOTE_PLAYER) 
  785. 		player_parachute_wear_backpack(REMOTE_PLAYER, false) 
  786. 		character_set_never_fall(REMOTE_PLAYER, false) 
  787. 		character_parachute_detach(REMOTE_PLAYER) 
  788. 		character_set_damage_multiplier(REMOTE_PLAYER, 1.0) 
  789. 		character_set_never_catch_fire(REMOTE_PLAYER, false) 
  790. 	end 
  791. 	 
  792. 	-- Remove all temporary weapons and re-enable the weapon radial 
  793. 	inv_weapon_remove_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_pistol) 
  794. 	inv_weapon_remove_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg) 
  795. 	inv_weapon_remove_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_pistol) 
  796. 	inv_weapon_remove_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg) 
  797. 	inv_weapon_disable_all_slots(false)	-- enable 
  798.  
  799. 	-- Make sure there aren't any QTEs or camera look-throughs active 
  800. 	qte_cleanup() 
  801. 	 
  802. 	-- Stop any debris flow 
  803. 	for i, debris_flow in pairs(M02_debris_flows) do 
  804. 		if (debris_flow.handle ~= 0) then 
  805. 			debris_flow_destroy(debris_flow.handle) 
  806. 			debris_flow.handle = 0 
  807. 		end 
  808. 	end 
  809. 	 
  810. 	-- Reset the wind 
  811. 	wind_override_clear() 
  812.  
  813. 	-- Clean-up the debris flow vehicles 
  814. 	for i, vehicle in pairs(M02_groups.debris_vehicles.vehicles) do 
  815. 		m02_helper_cleanup_debris_vehicle(vehicle) 
  816. 	end 
  817. 	for i, vehicle in pairs(M02_groups.debris_vehicles_dive_01.vehicles) do 
  818. 		m02_helper_cleanup_debris_vehicle(vehicle) 
  819. 	end 
  820. 	for i, vehicle in pairs(M02_groups.debris_vehicles_dive_02.vehicles) do 
  821. 		m02_helper_cleanup_debris_vehicle(vehicle) 
  822. 	end 
  823.  
  824. 	-- Clean-up all the VFX 
  825. 	m02_helper_destroy_global_effects() 
  826. 	 
  827. 	-- Clean-up any loaded groups 
  828. 	for i, group in pairs(M02_groups) do 
  829. 		if (group_is_loaded(group.name)) then 
  830. 			group_destroy(group.name) 
  831. 		end 
  832. 	end 
  833. 	 
  834. 	-- Clean-up any active threads 
  835. 	for i, thread in pairs(M02_threads) do 
  836. 		if (thread ~= -1) then 
  837. 			thread_kill(thread) 
  838. 			thread = -1 
  839. 		end 
  840. 	end 
  841. 	 
  842. 	-- Clean up any boxes that may be on fire 
  843. 	for i, handle in pairs(M02_vfx.debris_fire.box_handles) do 
  844. 		effect_stop(handle) 
  845. 	end 
  846. 	for i, handle in pairs(M02_vfx.debris_fire.dive_box_handles) do 
  847. 		effect_stop(handle) 
  848. 	end 
  849. 	 
  850. 	-- Reset notoriety 
  851. 	notoriety_force_no_spawn("Morningstar", false) 
  852. 	 
  853. 	-- Re-eanble automatic vehicle corpse clean-up 
  854. 	vehicle_forced_corpse_removal_enabled(true) 
  855. 	 
  856. 	-- Make sure non of the prop weapons still remain in the player's hands from the QTEs 
  857. 	character_remove_child_item_by_name(LOCAL_PLAYER, "SMG-Gang") 
  858. 	 
  859. 	-- Restore the HUD 
  860. 	for i, hud_state in pairs(M02_hud_states) do 
  861. 		if (hud_state ~= -1) then 
  862. 			hud_display_remove_state(hud_state) 
  863. 			hud_state = -1 
  864. 		end 
  865. 	end 
  866. 	 
  867. 	light_group_set_intensity("Script_Light_Group_pit<001>", 0.0) 
  868. 	light_group_detach_from_camera("Script_Light_Group_pit<001>") 
  869. 	 
  870. 	-- Turn peds, vehicles, and action nodes back on 
  871. 	spawning_pedestrians(true) 
  872. 	spawning_vehicles(true) 
  873. 	action_nodes_enable(true)	 
  874.  
  875. 	-- Disable the mission02 interiors 
  876. 	city_zone_swap("m2", false) 
  877. 	city_zone_swap("int_m2", false) 
  878. 	city_zone_swap("m2fx", false) 
  879. 	 
  880. 	mission_cleanup_maybe_reenable_player_controls() 
  881. 	 
  882. 	crib_weapon_add_enable() 
  883. 	 
  884. 	-- customization_item_wear disables some stores, so we need to revert that 
  885. 	customization_item_revert( ) 
  886. end 
  887.  
  888. -- Called when the mission has ended with success 
  889. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  890. -- 
  891. function m02_success() 
  892. 	-- Give the players their starting inventory for Stealport 
  893. 	inv_item_remove_all(LOCAL_PLAYER) 
  894. 	if (coop_is_active() == true) then 
  895. 		inv_item_remove_all(REMOTE_PLAYER) 
  896. 	end 
  897. 	for i, weapon in pairs(M02_tweak_values.mission_success_inventory) do 
  898. 		inv_item_add(weapon.name, weapon.reserve_ammo, LOCAL_PLAYER) 
  899. 		if (coop_is_active() == true) then 
  900. 			inv_item_add(weapon.name, weapon.reserve_ammo, REMOTE_PLAYER) 
  901. 		end 
  902. 	end 
  903. end 
  904.  
  905.  
  906. -- ************************* 
  907. -- 
  908. -- Local functions 
  909. -- 
  910. -- ************************* 
  911.  
  912. -- *************************************************** 
  913. -- m02_initialize Helper Functions 
  914. -- *************************************************** 
  915.  
  916. -- Initialize the mission for the specified checkpoint 
  917. -- 
  918. -- checkpoint:		Checkpoint to initialize the mission to 
  919. -- 
  920. function m02_initialize(checkpoint, playing_cutscene) 
  921. 	-- Set the mission author 
  922. 	set_mission_author("Matt.Gawalek") 
  923.  
  924. 	-- Common initialization 
  925. 	m02_initialize_common() 
  926.  
  927. 	-- Checkpoint specific initialization 
  928. 	m02_initialize_checkpoint(checkpoint, playing_cutscene) 
  929.  
  930. 	-- Start fading in 
  931. 	mission_start_fade_in() 
  932. end 
  933.  
  934. -- Handle any common initialization 
  935. -- 
  936. function m02_initialize_common() 
  937. 	-- Hide all the debris objects 
  938. 	m02_helper_hide_debris() 
  939. 	 
  940. 	-- No notoriety spawning 
  941. 	notoriety_force_no_spawn("Morningstar", true) 
  942. 	 
  943. 	-- special script camera for the airplane interior 
  944. 	camera_script_enable() 
  945. 	 
  946. 	-- Disable crib weapons 
  947. 	crib_weapon_add_disable()	 
  948. 	 
  949. 	-- Start the conversation thread 
  950. 	M02_threads.process_convo = thread_new("m02_thread_process_conversations") 
  951. 	 
  952. 	-- Set the cancel warp locations 
  953. 	mission_set_cancel_warp_location(M02_navpoints.player_end[1], M02_navpoints.player_end[2]) 
  954. 	 
  955. 	-- Reduce the amount of damage the player takes 
  956. 	character_set_damage_multiplier(LOCAL_PLAYER, 0.72) 
  957. 	if (coop_is_active() == true) then 
  958. 		character_set_damage_multiplier(REMOTE_PLAYER, 0.72) 
  959. 	end 
  960. 	 
  961. 	-- Turn off peds, vehicles, and action nodes 
  962. 	spawning_pedestrians(false) 
  963. 	spawning_vehicles(false) 
  964. 	action_nodes_enable(false)	 
  965. 	 
  966. 	-- Create all the debris flows we will use while skydiving 
  967. 	for i, debris_flow in pairs(M02_debris_flows) do 
  968. 		m02_helper_create_debris_flow(debris_flow, (i ~= 1)) 
  969. 	end 
  970. end 
  971.  
  972. -- Checkpoint specific initialization 
  973. -- 
  974. -- checkpoint:		The checkpoint to be initialized 
  975. function m02_initialize_checkpoint(checkpoint, playing_cutscene) 
  976. 	if (checkpoint == M02_checkpoints.start) then 
  977. 		m02_initialize_cargo_plane(playing_cutscene) 
  978. 		 
  979. 	elseif (checkpoint == M02_checkpoints.free_falling) then 
  980. 		m02_run_setup_free_falling_pre(true) 
  981. 		m02_run_setup_free_falling() 
  982.  
  983. 		-- Move the players into place 
  984. 		teleport_coop(M02_navpoints.player_start_chk_02[1], M02_navpoints.player_start_chk_02[2]) 
  985. 		delay(1.0) 
  986. 		 
  987. 		m02_run_setup_free_falling_post(checkpoint) 
  988. 		 
  989. 		if (coop_is_active() == true) then 
  990. 			delay(1.5) 
  991. 		end 
  992. 		 
  993. 		-- Start the music at the correct spot 
  994. 		audio_object_post_event("M02_Score_Checkpoint_01", nil, nil, LOCAL_PLAYER) 
  995. 		 
  996. 	elseif (checkpoint == M02_checkpoints.debug_checkpoints.first_dive) then 
  997. 		m02_run_setup_free_falling_pre(true) 
  998. 		m02_run_setup_free_falling() 
  999. 		 
  1000. 		-- Move the players into place 
  1001. 		teleport_coop(M02_navpoints.player_start_chk_02[1], M02_navpoints.player_start_chk_02[2]) 
  1002. 		 
  1003. 		m02_run_setup_free_falling_post(checkpoint) 
  1004. 	 
  1005. 		-- Teleport Shaundi down below 
  1006. 		teleport(M02_groups.homies_skydive_01.shaundi, M02_navpoints.shaundi_skydive_pos) 
  1007. 		delay(1.0) 
  1008. 		 
  1009. 		-- Give the player(s) the SMG, equip it, and disable all other inventory slots 
  1010. 		inv_weapon_remove_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg) 
  1011. 		inv_weapon_add_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  1012. 		if (coop_is_active() == true) then 
  1013. 			inv_weapon_remove_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg) 
  1014. 			inv_weapon_add_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  1015. 		end 
  1016. 		inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SMG) 
  1017. 		 
  1018. 		skydive_set_player_dive_fall_speed(-1.0) 
  1019. 		 
  1020. 		-- Start the global wind effects 
  1021. 		m02_helper_create_global_effects(true, true, true, false) 
  1022. 		 
  1023. 		-- Start the music at the correct spot 
  1024. 		audio_object_post_event("M02_Score_Checkpoint_01", nil, nil, LOCAL_PLAYER) 
  1025. 		 
  1026. 	elseif (checkpoint == M02_checkpoints.final_dive or checkpoint == M02_checkpoints.debug_checkpoints.final_qte) then 
  1027. 		-- Make sure they have the default parachute backpack 
  1028. 		customization_item_wear("basicparachute", "cm_pack_basicparachute.cmeshx", "Basic Parachute") 
  1029. 	 
  1030. 		-- Make sure the player(s) are skydiving in the normal state state 
  1031. 		character_set_skydiving(LOCAL_PLAYER, true) 
  1032. 		player_parachute_wear_backpack(LOCAL_PLAYER, true) 
  1033. 		if (coop_is_active() == true) then 
  1034. 			character_set_skydiving(REMOTE_PLAYER, true) 
  1035. 			player_parachute_wear_backpack(REMOTE_PLAYER, true) 
  1036. 		end	 
  1037. 	 
  1038. 		-- Move the players into place 
  1039. 		teleport_coop(M02_navpoints.player_start_chk_03[1], M02_navpoints.player_start_chk_03[2]) 
  1040. 		 
  1041. 		m02_helper_setup_skydiving_common() 
  1042. 		 
  1043. 		m02_run_setup_final_dive() 
  1044. 		 
  1045. 		skydive_set_player_dive_fall_speed(-1.0) 
  1046. 		 
  1047. 		if (coop_is_active() == true) then 
  1048. 			delay(1.5) 
  1049. 		end 
  1050. 		 
  1051. 		-- Start the music at the correct spot 
  1052. 		audio_object_post_event("M02_Score_Checkpoint_02", nil, nil, LOCAL_PLAYER) 
  1053. 	end 
  1054. end 
  1055.  
  1056.  
  1057. -- *************************************************** 
  1058. -- m02_run Helper Functions 
  1059. -- *************************************************** 
  1060.  
  1061. -- This is the primary function responsible for running the entire mission from start to finish. 
  1062. -- 
  1063. -- first_checkpoint:	The first checkpoint to begin running the mission at 
  1064. -- 
  1065. function m02_run(first_checkpoint) 
  1066. 	local current_checkpoint = first_checkpoint 
  1067. 	 
  1068. 	-- Run the mission from the beginning, in the cargo plane 
  1069. 	if (current_checkpoint == M02_checkpoints.start) then 
  1070. 		m02_run_basic_melee_tutorial() 
  1071. 		m02_run_advanced_melee_tutorial() 
  1072. 		m02_run_guy_with_gun() 
  1073. 		m02_run_go_to_cargo_hold() 
  1074. 		m02_run_grab_parachute() 
  1075. 		 
  1076. 		m02_run_cargo_plane_ejection_scene() 
  1077. 		m02_run_setup_free_falling() 
  1078. 		m02_run_setup_free_falling_post(M02_checkpoints.free_falling) 
  1079. 		 
  1080. 		delay(0.2)	-- add a short delay to allow the debris to fade in 
  1081. 		if (coop_is_active() == true) then 
  1082. 			delay(1.5) 
  1083. 		end 
  1084. 		mission_start_fade_in() 
  1085. 		 
  1086. 		-- Set the checkpoint 
  1087. 		current_checkpoint = M02_checkpoints.free_falling 
  1088. 		mission_set_checkpoint(M02_checkpoints.free_falling) 
  1089. 	end 
  1090. 	 
  1091. 	-- Run the mission starting once the player is skydiving 
  1092. 	if (current_checkpoint == M02_checkpoints.free_falling) then 
  1093. 		m02_run_free_failling_initial_dive() 
  1094. 		m02_run_kill_sky_goons_01() 
  1095. 		m02_run_kill_sky_goons_02_03() 
  1096. 		 
  1097. 		current_checkpoint = M02_checkpoints.debug_checkpoints.first_dive 
  1098. 	end 
  1099. 	 
  1100. 	-- Debug checkpoint for first dive 
  1101. 	if (current_checkpoint == M02_checkpoints.debug_checkpoints.first_dive)	then 
  1102. 		m02_run_dive_to_shaundi() 
  1103. 		m02_run_catch_shaundi_first_time() 
  1104. 		m02_run_ram_player_with_plane() 
  1105. 		m02_run_fly_through_plane_scene() 
  1106. 		 
  1107. 		m02_run_setup_final_dive() 
  1108. 		 
  1109. 		current_checkpoint = M02_checkpoints.final_dive 
  1110. 		mission_set_checkpoint(M02_checkpoints.final_dive) 
  1111. 	end 
  1112. 	 
  1113. 	-- Run the mission starting after the player has flown threw the cargo plane 
  1114. 	if (current_checkpoint == M02_checkpoints.final_dive) then 
  1115. 		m02_run_kill_sky_goons_05() 
  1116. 		 
  1117. 		current_checkpoint = M02_checkpoints.debug_checkpoints.final_qte 
  1118. 	end 
  1119. 	 
  1120. 	-- Debug checkpoint for final QTE 
  1121. 	if (current_checkpoint == M02_checkpoints.debug_checkpoints.final_qte) then 
  1122. 		m02_run_final_dive_qte() 
  1123. 		m02_run_final_dive() 
  1124. 		m02_run_catch_shaundi_again() 
  1125. 	end 
  1126. 	 
  1127. 	delay(6.0) 
  1128. 	 
  1129. 	--[[ 
  1130. 		Do some immediate clean-up 
  1131. 		--]] 
  1132. 	 
  1133. 	-- Start fading out now 
  1134. 	fade_out(1.0) 
  1135. 	fade_out_block() 
  1136. 	 
  1137. 	-- Stop the catch Shaundi sequence 
  1138. 	skydive_set_catching_shaundi(false, false) 
  1139. 	 
  1140. 	-- Reset the wind (do this before the player teleports to fix some effects still having upward wind) 
  1141. 	wind_override_clear() 
  1142. 	 
  1143. 	-- Clean-up the debris flow vehicles 
  1144. 	for i, vehicle in pairs(M02_groups.debris_vehicles.vehicles) do 
  1145. 		m02_helper_cleanup_debris_vehicle(vehicle) 
  1146. 	end 
  1147. 	for i, vehicle in pairs(M02_groups.debris_vehicles_dive_01.vehicles) do 
  1148. 		m02_helper_cleanup_debris_vehicle(vehicle) 
  1149. 	end 
  1150. 	for i, vehicle in pairs(M02_groups.debris_vehicles_dive_02.vehicles) do 
  1151. 		m02_helper_cleanup_debris_vehicle(vehicle) 
  1152. 	end 
  1153.  
  1154. 	-- Stop the music and any mission audio 
  1155. 	audio_object_post_event("M02_Stop_All_Mission_Audio", nil, nil, LOCAL_PLAYER) 
  1156. 	 
  1157. 	-- Make sure we hide the debris so they don't fall in the cutscene 
  1158. 	for i, debris_flow in pairs(M02_debris_flows) do 
  1159. 		if (debris_flow.handle ~= 0) then 
  1160. 			debris_flow_set_inactive(debris_flow.handle) 
  1161. 		end 
  1162. 	end 
  1163. 	 
  1164. 	-- Remove the player's parachute 
  1165. 	player_parachute_wear_backpack(LOCAL_PLAYER, false) 
  1166. 	character_parachute_detach(LOCAL_PLAYER) 
  1167. 	if (coop_is_active()) then 
  1168. 		player_parachute_wear_backpack(REMOTE_PLAYER, false) 
  1169. 		character_parachute_detach(REMOTE_PLAYER) 
  1170. 	end 
  1171. 	 
  1172. 	-- Clean-up the VFX 
  1173. 	m02_helper_destroy_global_effects() 
  1174. 	 
  1175. 	-- Clean up any boxes that may be on fire 
  1176. 	for i, handle in pairs(M02_vfx.debris_fire.box_handles) do 
  1177. 		effect_stop(handle) 
  1178. 	end 
  1179. 	for i, handle in pairs(M02_vfx.debris_fire.dive_box_handles) do 
  1180. 		effect_stop(handle) 
  1181. 	end 
  1182. 	 
  1183. 	-- Call mission success?? 
  1184. 	mission_end_success("m02", M02_cutscenes.mission_outro, M02_navpoints.player_end) 
  1185. end 
  1186.  
  1187. -- Setup the cargo plane interior for the first checkpoint 
  1188. function m02_initialize_cargo_plane(playing_cutscene) 
  1189. 	inv_item_remove_all(LOCAL_PLAYER) 
  1190. 	inv_item_remove_all(REMOTE_PLAYER) 
  1191. 	 
  1192. 	-- Set the ragdoll restore location, so characters don't get teleported out of the cargo plane 
  1193. 	character_ragdoll_set_last_resort_position(M02_navpoints.player_start_chk_01[1]) 
  1194. 	character_ragdoll_set_last_valid_position(LOCAL_PLAYER, M02_navpoints.player_start_chk_01[1], true) 
  1195. 	if (coop_is_active() == true) then 
  1196. 		character_ragdoll_set_last_valid_position(REMOTE_PLAYER, M02_navpoints.player_start_chk_01[2], true) 
  1197. 	end 
  1198. 	 
  1199. 	-- Set the player's starting animation state 
  1200. 	set_animation_state(LOCAL_PLAYER, "M02 Player Mission Start Idle") 
  1201. 	 
  1202. 	-- Create all the necessary groups 
  1203. 	group_create(M02_groups.cargo_plane_props.name) 
  1204. 	group_create(M02_groups.homies_01.name) 
  1205. 	group_create(M02_groups.cargo_plane_goons_01.name)	 
  1206. 	 
  1207. 	-- Move the players back to the mission starting location (if the cutscene wasn't played) 
  1208. 	if (playing_cutscene == false) then 
  1209. 		teleport_coop(M02_navpoints.player_start_chk_01[1], M02_navpoints.player_start_chk_01[2]) 
  1210. 	end 
  1211. 	 
  1212. 	group_create_check_done_loop(M02_groups.cargo_plane_props.name) 
  1213. 	group_create_check_done_loop(M02_groups.homies_01.name) 
  1214. 	group_create_check_done_loop(M02_groups.cargo_plane_goons_01.name)	 
  1215. 	 
  1216. 	-- Setup Shaundi 
  1217. 	party_add(M02_groups.homies_01.shaundi, LOCAL_PLAYER) 
  1218. 	set_never_turn_on_player(M02_groups.homies_01.shaundi, true) 
  1219. 	on_death("m02_cb_failure_shaundi_died", M02_groups.homies_01.shaundi) 
  1220.  
  1221. 	-- Setup the guys in the cargo hold 
  1222. 	set_force_combat_ready_team("Morningstar") 
  1223. 	 
  1224. 	-- Setup the doors to their initial states 
  1225. 	for i, door in pairs (M02_movers.cargo_plane_doors) do 
  1226. 		if (door.open == true) then 
  1227. 			door_open(door.name, false, false)	-- don't open reverse, don't animate 
  1228. 		else 
  1229. 			door_close(door.name, false) -- don't animate 
  1230. 		end 
  1231. 		 
  1232. 		door_lock(door.name, door.locked) 
  1233. 	end 
  1234. 	 
  1235. 	-- Turn on all the audio emitters 
  1236. 	for i, emitter in pairs(M02_audio_emitters.plane_sounds) do 
  1237. 		audio_ambient_emitter_start(emitter) 
  1238. 	end 
  1239. 	 
  1240. 	-- Start the camera shake for the cargo plane interior 
  1241. 	camera_shake_play_looping(M02_tweak_values.plane_interior_camera_shake) 
  1242. 	 
  1243. 	-- Set the global wind override (we want this in the cargo plane as well, since side-ways winds doesn't look that great for "turbulance") 
  1244. 	wind_override_set(0.0, 1.0, 0.0, 0.075) 
  1245. 	 
  1246. 	-- Load the audio personas for Gat and Phillipe (they don't have any characters in the world) 
  1247. 	M02_personas.gat.persona_id = audio_persona_load_2d(M02_personas.gat.name) 
  1248. 	M02_personas.phillipe.persona_id = audio_persona_load_2d(M02_personas.phillipe.name) 
  1249. 	M02_personas.mstar_wm_01.persona_id = audio_persona_load_2d(M02_personas.mstar_wm_01.name) 
  1250. 	M02_personas.mstar_wm_02.persona_id = audio_persona_load_2d(M02_personas.mstar_wm_02.name) 
  1251. 	M02_personas.interrogation.persona_id = audio_persona_load_2d(M02_personas.interrogation.name)	 
  1252. 	 
  1253. 	-- Prep the next z-scene 
  1254. 	zscene_prep(M02_zscenes.bailout) 
  1255. end 
  1256.  
  1257. -- Run the initial melee tutorial, which takes place in the first room of the cargo plane interior 
  1258. function m02_run_basic_melee_tutorial() 
  1259. 	-- Queue up the first conversations 
  1260. 	m02_helper_conversation_play(M02_conversations.leave_gat_behind, M02_CONVO_PLAY_LAST, 0.5) 
  1261. 	m02_helper_conversation_play(M02_conversations.gat_takes_control, M02_CONVO_PLAY_LAST, 1.0) 
  1262. 	 
  1263. 	-- Kick of some threads to process stuff 
  1264. 	M02_threads.shaundi_nag_vo = thread_new("m02_thread_process_shaundi_nag", 60.0, 40.0) 
  1265. 	M02_threads.cue_plane_music = thread_new("m02_thread_process_plane_music") 
  1266. 	 
  1267. 	-- Display the melee tutorial 
  1268. 	tutorial_start("combat", 0, true) 
  1269. 	 
  1270. 	-- Start creating the rest of the enemies 
  1271. 	group_create(M02_groups.cargo_plane_goons_02.name) 
  1272. 	group_create(M02_groups.cargo_plane_goons_03.name) 
  1273. 	group_create(M02_groups.cargo_vehicles.name) 
  1274. 	 
  1275. 	thread_new("m02_play_player_start_anim_thread") 
  1276. 	 
  1277. 	-- Wait a bit, so it the AI doesn't appear to react immediatly 
  1278. 	delay(0.3) 
  1279. 	 
  1280. 	-- Unleash the Shaundi! 
  1281. 	npc_leash_remove(M02_groups.homies_01.shaundi) 
  1282. 	 
  1283. 	-- Add a new objective to kill the guards 
  1284. 	objective_text(0, M02_strings.objective_kill_guards, nil, nil, SYNC_ALL, OI_ASSET_KILL) 
  1285. 	 
  1286. 	-- Setup the enemies 
  1287. 	for i, char in pairs(M02_groups.cargo_plane_goons_01.chars) do 
  1288. 		-- Remove the enemy leashes, and tell them not to flee 
  1289. 		npc_leash_remove(char) 
  1290. 		set_cant_flee_flag(char, true) 
  1291. 	end 
  1292. 	 
  1293. 	-- Wait until all the guys have been killed 
  1294. 	process_enemy_set(M02_groups.cargo_plane_goons_01.chars) 
  1295. 	 
  1296. 	-- Wait for the next group of enemies to be created 
  1297. 	group_create_check_done_loop(M02_groups.cargo_plane_goons_02.name) 
  1298. 	 
  1299. 	-- Call the clean-up for this section 
  1300. 	m02_cleanup_basic_melee_tutorial() 
  1301. end 
  1302.  
  1303. -- Thread to process the player's start animation, so it doesn't block the main function 
  1304. function m02_play_player_start_anim_thread() 
  1305. 	-- Play the player's start animation 
  1306. 	clear_animation_state(LOCAL_PLAYER) 
  1307. 	action_play(LOCAL_PLAYER, "M02 Player Mission Start")	 
  1308. end 
  1309.  
  1310. -- Function to process when to trigger the music in the cargo plane 
  1311. function m02_thread_process_plane_music() 
  1312. 	while(m02_helper_conversation_check_done(M02_conversations.gat_takes_control) == false) do 
  1313. 		thread_yield() 
  1314. 	end 
  1315. 	 
  1316. 	if (M02_conversations.gat_takes_control.completed == true) then 
  1317. 		audio_ambient_emitter_start(M02_audio_emitters.plane_music) 
  1318. 		 
  1319. 		--[[ 
  1320. 		trigger_enable(M02_triggers.stop_gat_music, true) 
  1321. 		on_trigger("m02_cb_stop_plane_music", M02_triggers.stop_gat_music) 
  1322. 		--]] 
  1323. 	end 
  1324. end 
  1325.  
  1326. --[[ 
  1327. function m02_cb_stop_plane_music() 
  1328. 	m02_helper_disable_trigger(M02_triggers.stop_gat_music) 
  1329. 	local event_id = audio_object_post_event("M02_Stop_Plane_Cabin_Music", nil, nil, M02_audio_emitters.plane_music) 
  1330. end 
  1331. --]] 
  1332.  
  1333. -- Clean-up function for the basic melee tutorial 
  1334. function m02_cleanup_basic_melee_tutorial() 
  1335. 	if (thread_check_done(M02_threads.shaundi_nag_vo) == false) then 
  1336. 		thread_kill(M02_threads.shaundi_nag_vo) 
  1337. 		M02_threads.shaundi_nag_vo = -1 
  1338. 	end 
  1339. end 
  1340.  
  1341. -- Run the advanced melee tutorial, which takes place int he second room of the cargo plan interior 
  1342. function m02_run_advanced_melee_tutorial() 
  1343. 	-- Update the obejctive to escape from the cargo plane 
  1344. 	objective_text(0, M02_strings.objective_escape, nil, nil, SYNC_ALL, OI_ASSET_DEFEND) 
  1345. 	 
  1346. 	M02_threads.shaundi_nag_vo = thread_new("m02_thread_process_shaundi_nag", 60.0, 40.0) 
  1347.  
  1348. 	delay(2.0) 
  1349. 	 
  1350. 	-- Unlock and open the door leading to the next room of the mission 
  1351. 	door_lock(M02_movers.cargo_plane_doors.seating1_utility2.name, false) 
  1352. 	door_open(M02_movers.cargo_plane_doors.seating1_utility2.name) 
  1353. 	 
  1354. 	-- Send in the first enemy to "investigate" 
  1355. 	npc_leash_remove(M02_groups.cargo_plane_goons_02.chars[1]) 
  1356. 	ai_add_enemy_target(M02_groups.cargo_plane_goons_02.chars[1], CLOSEST_PLAYER, ATTACK_ON_SIGHT) 
  1357. 	ai_do_scripted_move(M02_groups.cargo_plane_goons_02.chars[1], M02_navpoints.ai_investigation_01, true, true) 
  1358. 	set_cant_flee_flag(M02_groups.cargo_plane_goons_02.chars[1], true) 
  1359. 	marker_add(M02_groups.cargo_plane_goons_02.chars[1], MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL) 
  1360. 	 
  1361. 	-- Loop over all the guys in the first wave of goons, and make them attack the player 
  1362. 	for i, enemy in pairs(M02_groups.cargo_plane_goons_02.chars) do 
  1363. 		if (character_is_dead(enemy) == false) then 
  1364. 			npc_leash_remove(enemy) 
  1365. 			ai_add_enemy_target(enemy, CLOSEST_PLAYER, ATTACK_NOW) 
  1366. 			set_cant_flee_flag(enemy, true) 
  1367. 		end 
  1368. 	end 
  1369. 	 
  1370. 	-- Wait until all the guards have been killed 
  1371. 	objective_text(0, M02_strings.objective_kill_guards, nil, nil, SYNC_ALL, OI_ASSET_KILL) 
  1372. 	process_enemy_set(M02_groups.cargo_plane_goons_02.chars) 
  1373. 	 
  1374. 	-- Wait just a sec 
  1375. 	delay(1.0) 
  1376. 	 
  1377. 	-- Make sure the next group of guys has been created 
  1378. 	group_create_check_done_loop(M02_groups.cargo_plane_goons_03.name) 
  1379. 	for i, char in pairs (M02_groups.cargo_plane_goons_03.chars) do 
  1380. 		ai_do_scripted_take_cover(char) 
  1381. 		set_cant_flee_flag(char, true) 
  1382. 		set_ignore_ai_flag(char, false) 
  1383. 	end	 
  1384. 	 
  1385. 	-- Clean-up this section 
  1386. 	m02_cleanup_advanced_melee_tutorial() 
  1387. end 
  1388.  
  1389. -- Clean-up the advanced melee tutorial 
  1390. function m02_cleanup_advanced_melee_tutorial() 
  1391. 	if (thread_check_done(M02_threads.shaundi_nag_vo) == false) then 
  1392. 		thread_kill(M02_threads.shaundi_nag_vo) 
  1393. 		M02_threads.shaundi_nag_vo = -1 
  1394. 	end 
  1395. end 
  1396.  
  1397. -- Process Gat opening the rear cargo bay doors 
  1398. function m02_run_guy_with_gun() 
  1399. 	-- Update the objective 
  1400. 	objective_text(0, M02_strings.objective_escape, nil, nil, SYNC_ALL, OI_ASSET_DEFEND) 
  1401. 	 
  1402. 	M02_threads.shaundi_nag_vo = thread_new("m02_thread_process_shaundi_nag", 40.0, 30.0) 
  1403. 	 
  1404. 	-- Unlock and open the door leading between utility room 3 and the seating room 1 
  1405. 	door_lock(M02_movers.cargo_plane_doors.seating1_utility3.name, false) 
  1406. 	door_open(M02_movers.cargo_plane_doors.seating1_utility3.name, true)	-- open reversed so it goes away from the AI guy 
  1407. 	 
  1408. 	-- Move an enemy into the second room of the cargo plane 
  1409. 	npc_leash_remove(M02_groups.cargo_plane_goons_03.move_up_chars[1]) 
  1410. 	ai_add_enemy_target(M02_groups.cargo_plane_goons_03.move_up_chars[1], CLOSEST_PLAYER, ATTACK_NOW) 
  1411. 	ai_do_scripted_move(M02_groups.cargo_plane_goons_03.move_up_chars[1], M02_navpoints.ai_investigation_02, true, true) 
  1412. 	set_cant_flee_flag(M02_groups.cargo_plane_goons_03.move_up_chars[1], true) 
  1413. 	ai_set_action_delay(M02_groups.cargo_plane_goons_03.move_up_chars[1], "cover take def", 10000) 
  1414. 	ai_set_action_delay(M02_groups.cargo_plane_goons_03.move_up_chars[1], "cover take off", 10000) 
  1415. 	 
  1416. 	-- Update the objective 
  1417. 	objective_text(0, M02_strings.objective_kill_guards, nil, nil, SYNC_ALL, OI_ASSET_KILL) 
  1418. 	 
  1419. 	-- Enable the trigger region 
  1420. 	trigger_enable(M02_triggers.turbulance_01, true) 
  1421. 	on_trigger("m02_cb_triggered_turbulance_01", M02_triggers.turbulance_01) 
  1422. 	 
  1423. 	-- Wait until all the guards have been killed 
  1424. 	process_enemy_set(M02_groups.cargo_plane_goons_03.move_up_chars) 
  1425. 	 
  1426. 	-- Give Shaundi a gun 
  1427. 	inv_item_add(M02_tweak_values.skydiving_pistol, 1, M02_groups.homies_01.shaundi, true) 
  1428. 	 
  1429. 	-- Make sure all the vehicles in the cargo hold have been created 
  1430. 	group_create_check_done_loop(M02_groups.cargo_vehicles.name) 
  1431. 	for i, vehicle in pairs(M02_groups.cargo_vehicles.vehicles) do 
  1432. 		vehicle_car_alarm_enable(vehicle, true) 
  1433. 	end 
  1434. 	on_damage("m02_cb_trigger_car_alarm", M02_groups.cargo_vehicles.car_alarm_vehicle, 0.98) 
  1435. 	turn_vulnerable(M02_groups.cargo_vehicles.car_alarm_vehicle) 
  1436. 	vehicle_car_alarm_enable(M02_groups.cargo_vehicles.car_alarm_vehicle, false)	 
  1437. 	 
  1438. 	-- Clean-up this section 
  1439. 	m02_cleanup_guy_with_gun() 
  1440. end 
  1441.  
  1442. -- Callback for when a player enters the trigger region that causes the first turbulance event on the plane 
  1443. function m02_cb_triggered_turbulance_01() 
  1444. 	-- Disable the trigger 
  1445. 	m02_helper_disable_trigger(M02_triggers.turbulance_01) 
  1446.  
  1447. 	-- Wait until none of the player's are playing a combat mobe 
  1448. 	m02_helper_turbulance_wait_for_anims() 
  1449. 	 
  1450. 	-- Make sure the goon is still alive 
  1451. 	if (character_is_dead(M02_groups.cargo_plane_goons_03.move_up_chars[1]) == true) then 
  1452. 		return 
  1453. 	end 
  1454. 	 
  1455. 	-- Do the stumbles (can't call non-blocking becasue it will never give control back to the player (which is stupid) 
  1456. 	thread_new("m02_thread_do_play_stumble_animation", LOCAL_PLAYER, M02_navpoints.turbulance_direction_01, false) 
  1457. 	if (coop_is_active() == true) then 
  1458. 		thread_new("m02_thread_do_play_stumble_animation", REMOTE_PLAYER, M02_navpoints.turbulance_direction_01, false) 
  1459. 	end 
  1460. 	 
  1461. 	-- Play stumble on the morning star guy 
  1462. 	ai_clear_scripted_action(M02_groups.cargo_plane_goons_03.move_up_chars[1]) 
  1463. 	action_play_non_blocking(M02_groups.cargo_plane_goons_03.move_up_chars[1], "Plane Cabin Stumble") 
  1464. 	 
  1465. 	-- Play Shaundi's stumble 
  1466. 	if (m02_helper_human_can_play_anim(M02_groups.homies_01.shaundi) == true) then 
  1467. 		--character_release_human_shield(M02_groups.homies_01.shaundi) 
  1468. 		action_play_non_blocking(M02_groups.homies_01.shaundi, "Plane Cabin Stumble") 
  1469. 	end 
  1470.  
  1471. 	-- Play Gat's conversation 
  1472. 	m02_helper_conversation_play(M02_conversations.gat_turbulence, M02_CONVO_PLAY_NEXT, 0.5) 
  1473. 	 
  1474. 	-- Do common turbulance stuff 
  1475. 	m02_helper_turbulance_do_common() 
  1476. end 
  1477.  
  1478. -- Clean-up for opening up the rear cargo bay doors in the plane 
  1479. function m02_cleanup_guy_with_gun() 
  1480. 	if (thread_check_done(M02_threads.shaundi_nag_vo) == false) then 
  1481. 		thread_kill(M02_threads.shaundi_nag_vo) 
  1482. 		M02_threads.shaundi_nag_vo = -1 
  1483. 	end 
  1484. 	 
  1485. 	m02_helper_disable_trigger(M02_triggers.turbulance_01) 
  1486. end 
  1487.  
  1488. -- Run opening hte door to the cargo hold 
  1489. function m02_run_go_to_cargo_hold() 
  1490. 	-- Update the objective 
  1491. 	objective_text(0, M02_strings.objective_escape, nil, nil, SYNC_ALL, OI_ASSET_DEFEND) 
  1492. 	 
  1493. 	M02_threads.shaundi_nag_vo = thread_new("m02_thread_process_shaundi_nag", 40.0, 20.0) 
  1494. 	 
  1495. 	-- Unlock the door leading leading between utility room 3 and the cargo hold 
  1496. 	M02_flags.door_to_cargo_bay_opened = false 
  1497. 	on_door_opened("m02_door_to_cargo_bay_opened_cb", M02_movers.cargo_plane_doors.cargo1_utility3.name) 
  1498. 	door_lock(M02_movers.cargo_plane_doors.cargo1_utility3.name, false) 
  1499. 	 
  1500. 	-- Wait until the door has been opened 
  1501. 	while (M02_flags.door_to_cargo_bay_opened == false) do 
  1502. 		thread_yield() 
  1503. 	end 
  1504. 	 
  1505. 	-- Clean-up 
  1506. 	m02_cleanup_go_to_cargo_hold() 
  1507. end 
  1508.  
  1509. -- Cleanup for going to the cargo hold 
  1510. function m02_cleanup_go_to_cargo_hold() 
  1511. 	-- Remove the calback on the door 
  1512. 	on_door_opened("", M02_movers.cargo_plane_doors.cargo1_utility3.name) 
  1513. 	 
  1514. 	if (thread_check_done(M02_threads.shaundi_nag_vo) == false) then 
  1515. 		thread_kill(M02_threads.shaundi_nag_vo) 
  1516. 		M02_threads.shaundi_nag_vo = -1 
  1517. 	end 
  1518. 	 
  1519. 	--m02_helper_disable_trigger(M02_triggers.stop_gat_music) 
  1520. 	--audio_ambient_emitter_stop(M02_audio_emitters.plane_music) 
  1521. end 
  1522.  
  1523. -- Callback for when the cargo bay door is opened 
  1524. function m02_door_to_cargo_bay_opened_cb() 
  1525. 	M02_flags.door_to_cargo_bay_opened = true 
  1526. 	on_door_opened("", M02_movers.cargo_plane_doors.cargo1_utility3.name) 
  1527. end 
  1528.  
  1529. -- Wait for the player to reach the parachutes 
  1530. function m02_run_grab_parachute() 
  1531. 	-- Add an obejctive to find the parachute 
  1532. 	objective_text(0, M02_strings.objective_find_parachute, nil, nil, SYNC_ALL, OI_ASSET_LOCATION) 
  1533. 	 
  1534. 	M02_threads.shaundi_nag_vo = thread_new("m02_thread_process_shaundi_nag", 120.0, 35.0) 
  1535. 	 
  1536. 	-- Stop the music 
  1537. 	audio_object_post_event("M02_Stop_Plane_Cabin_Music", nil, nil, M02_audio_emitters.plane_music)	 
  1538. 	 
  1539. 	-- Time to preload the skydiving groups 
  1540. 	m02_run_setup_free_falling_pre() 
  1541. 	 
  1542. 	delay(1.0) 
  1543. 	 
  1544. 	-- Loop over all the guys in the goons in the cargo hold, and make them attack the player 
  1545. 	for i, char in pairs(M02_groups.cargo_plane_goons_03.chars) do 
  1546. 		if (character_is_dead(char) == false) then 
  1547. 			on_detection("m02_cb_plane_goon_detected_player", char) 
  1548. 			on_take_damage("m02_cb_plane_goon_damaged", char) 
  1549. 		end 
  1550. 	end 
  1551. 	 
  1552. 	M02_threads.cargo_door_open = thread_new("m02_thread_process_cargo_bay_door") 
  1553. 	M02_threads.cargo_bay_vo = thread_new("m02_thread_process_cargo_bay_vo_lines") 
  1554. 	 
  1555. 	-- Start the global wind effects 
  1556. 	m02_helper_create_global_effects(false, true, false, false) 
  1557. 	 
  1558. 	-- Enable the trigger regions for the turbulance 02 area 
  1559. 	trigger_enable(M02_triggers.turbulance_02, true) 
  1560. 	on_trigger("m02_cb_triggered_turbulance_02", M02_triggers.turbulance_02) 
  1561. 	 
  1562. 	-- Enable the trigger regions for the parchute pickup 
  1563. 	M02_flags.reached_parachutes = false 
  1564. 	trigger_enable(M02_triggers.cargo_plane_parachute_01, true) 
  1565. 	on_trigger("m02_cb_triggered_grab_parachute", M02_triggers.cargo_plane_parachute_01) 
  1566. 	marker_add_trigger(M02_triggers.cargo_plane_parachute_01, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  1567. 	 
  1568. 	-- Loop until the parachute has been reached by a player 
  1569. 	while(M02_flags.reached_parachutes == false) do 
  1570. 		thread_yield() 
  1571. 	end 
  1572. 	 
  1573. 	-- Post an audio event to fade out all the cargo plane sounds 
  1574. 	audio_object_post_event("M02_Zscene_01_Transition", nil, nil, LOCAL_PLAYER) 
  1575. 	delay(0.25) 
  1576. 	 
  1577. 	-- Set the player's last valid ragdoll position 
  1578. 	character_ragdoll_set_last_valid_position(LOCAL_PLAYER, M02_navpoints.player_start_chk_02[1], true) 
  1579. 	if (coop_is_active() == true) then 
  1580. 		character_ragdoll_set_last_valid_position(REMOTE_PLAYER, M02_navpoints.player_start_chk_02[2], true) 
  1581. 	end 
  1582. 	 
  1583. 	m02_cleanup_grab_parachute() 
  1584. end 
  1585.  
  1586. -- Callback for when a player enters the trigger region that causes the first turbulance event on the plane 
  1587. function m02_cb_triggered_turbulance_02() 
  1588. 	-- Disable the trigger 
  1589. 	m02_helper_disable_trigger(M02_triggers.turbulance_02) 
  1590. 	 
  1591. 	-- Wait until none of the player's are playing a combat mobe 
  1592. 	m02_helper_turbulance_wait_for_anims() 
  1593. 	 
  1594. 	-- Don't do this event if the player doesn't have the pistol equipped (we don't have animations for those states) 
  1595. 	if (inv_item_get_equipped_item(LOCAL_PLAYER) ~= M02_tweak_values.skydiving_pistol) then 
  1596. 		return 
  1597. 	end 
  1598. 	if (coop_is_active() == true) then 
  1599. 		if (inv_item_get_equipped_item(REMOTE_PLAYER) ~= M02_tweak_values.skydiving_pistol) then 
  1600. 			return 
  1601. 		end 
  1602. 	end	 
  1603. 	 
  1604. 	-- Do the player stumbles (can't call non-blocking becasue it will never give control back to the player (which is stupid) 
  1605. 	thread_new("m02_thread_do_play_stumble_animation", LOCAL_PLAYER, M02_navpoints.turbulance_direction_02, true) 
  1606. 	if (coop_is_active() == true) then 
  1607. 		thread_new("m02_thread_do_play_stumble_animation", REMOTE_PLAYER, M02_navpoints.turbulance_direction_02, true) 
  1608. 	end 
  1609. 	 
  1610. 	-- Do Shaundi's stumble 
  1611. 	if (m02_helper_human_can_play_anim(M02_groups.homies_01.shaundi) == true) then 
  1612. 		--character_release_human_shield(M02_groups.homies_01.shaundi) 
  1613. 		action_play_directional_stumble_do(M02_groups.homies_01.shaundi, M02_navpoints.turbulance_direction_02) 
  1614. 	end 
  1615. 	 
  1616. 	-- Play a stumble on all the enemies 
  1617. 	for i, char in pairs(M02_groups.cargo_plane_goons_03.chars) do 
  1618. 		if (m02_helper_human_can_play_anim(char) == true and inv_item_is_equipped(M02_tweak_values.skydiving_pistol, char)) then 
  1619. 			--character_release_human_shield(char) 
  1620. 			action_play_directional_stumble_do(char, M02_navpoints.turbulance_direction_02) 
  1621. 		end 
  1622. 	end 
  1623. 	 
  1624. 	-- Do common turbulance stuff 
  1625. 	m02_helper_turbulance_do_common() 
  1626. end 
  1627.  
  1628. -- Thread to process opening the cargo bay door 
  1629. function m02_thread_process_cargo_bay_door() 
  1630. 	-- Open the cargo bay door 
  1631. 	door_lock(M02_movers.cargo_plane_doors.cargo_bay.name, false) 
  1632. 	door_open(M02_movers.cargo_plane_doors.cargo_bay.name) 
  1633. 	 
  1634. 	-- Start the wind VFX 
  1635. 	M02_vfx.cargo_bay_wind.handle = effect_play(M02_vfx.cargo_bay_wind.name, true) 
  1636. 	 
  1637. 	-- Start all the looping cargo bay audio emitters 
  1638. 	for i, emitter in pairs(M02_audio_emitters.cargo_bay_looping) do 
  1639. 		audio_ambient_emitter_start(emitter) 
  1640. 	end 
  1641. 	 
  1642. 	-- Start the open audio event, and wait for the door to finish opening 
  1643. 	audio_ambient_emitter_start(M02_audio_emitters.cargo_bay_door) 
  1644. 	 
  1645. 	delay(30) 
  1646. 	 
  1647. 	M02_audio_events.cargo_bay_door_end = audio_object_post_event("M02_Cargo_Door_Open_Finished", nil, nil, M02_audio_emitters.cargo_bay_door) 
  1648. 	while(audio_is_playing(M02_audio_events.cargo_bay_door_end) == true) do 
  1649. 		thread_yield() 
  1650. 	end 
  1651. 	audio_ambient_emitter_stop(M02_audio_emitters.cargo_bay_door) 
  1652. end 
  1653.  
  1654. -- Thread to process the cargo bay VO lines 
  1655. function m02_thread_process_cargo_bay_vo_lines() 
  1656. 	m02_helper_conversation_play(M02_conversations.door_unlocked, M02_CONVO_PLAY_IMMEDIATE, 1.0) 
  1657. 	while(m02_helper_conversation_check_done(M02_conversations.door_unlocked) == false) do 
  1658. 		thread_yield() 
  1659. 	end 
  1660. 	 
  1661. 	delay(3.0) 
  1662. 	local audio_id = audio_play_persona_line_2d(M02_personas.gat.persona_id, M02_dialog_lines.gat_warning) 
  1663. 	while(audio_is_playing(audio_id) == true) do 
  1664. 		thread_yield() 
  1665. 	end 
  1666. 	 
  1667. 	delay(2.0) 
  1668. 	m02_helper_conversation_play(M02_conversations.gat_update, M02_CONVO_PLAY_LAST, 2.0) 
  1669. end 
  1670.  
  1671. -- Clean-up for grabbing the player parachutes (final clean-up for checkpoint 01 which included general clean-up for the cargo plane) 
  1672. function m02_cleanup_grab_parachute() 
  1673. 	m02_helper_conversation_kill_all() 
  1674. 	 
  1675. 	character_ragdoll_clear_last_resort_position() 
  1676. 	 
  1677. 	if (thread_check_done(M02_threads.shaundi_nag_vo) == false) then 
  1678. 		thread_kill(M02_threads.shaundi_nag_vo) 
  1679. 		M02_threads.shaundi_nag_vo = -1 
  1680. 	end 
  1681. 	if (thread_check_done(M02_threads.cue_plane_music) == false) then 
  1682. 		thread_kill(M02_threads.cue_plane_music) 
  1683. 		M02_threads.cue_plane_music = -1 
  1684. 	end 
  1685. 	 
  1686. 	-- Remove all the active triggers 
  1687. 	m02_helper_disable_trigger(M02_triggers.cargo_plane_parachute_01) 
  1688. 	m02_helper_disable_trigger(M02_triggers.turbulance_02) 
  1689. 	 
  1690. 	-- Clean-up Shaundi 
  1691. 	if (group_is_loaded(M02_groups.homies_01.name)) then 
  1692. 		party_dismiss(M02_groups.homies_01.shaundi) 
  1693. 	end 
  1694. 	on_death("", M02_groups.homies_01.shaundi) 
  1695. 	 
  1696. 	-- Clean-up all the groups we created for this section 
  1697. 	if (group_is_loaded(M02_groups.cargo_plane_props.name)) then 
  1698. 		group_destroy(M02_groups.cargo_plane_props.name) 
  1699. 	end	 
  1700. 	if (group_is_loaded(M02_groups.homies_01.name)) then 
  1701. 		group_destroy(M02_groups.homies_01.name) 
  1702. 	end 
  1703. 	if (group_is_loaded(M02_groups.cargo_plane_goons_01.name)) then 
  1704. 		group_destroy(M02_groups.cargo_plane_goons_01.name) 
  1705. 	end 
  1706. 	if (group_is_loaded(M02_groups.cargo_plane_goons_02.name)) then 
  1707. 		group_destroy(M02_groups.cargo_plane_goons_02.name) 
  1708. 	end 
  1709. 	if (group_is_loaded(M02_groups.cargo_plane_goons_03.name)) then 
  1710. 		group_destroy(M02_groups.cargo_plane_goons_03.name) 
  1711. 	end 
  1712. 	 
  1713. 	-- Setup the guys in the cargo hold 
  1714. 	for i, char in pairs (M02_groups.cargo_plane_goons_03.chars) do 
  1715. 		on_detection("", char) 
  1716. 		on_take_damage("", char) 
  1717. 	end 
  1718. 	 
  1719. 	-- Clean up any personas we loaded 
  1720. 	if (M02_personas.gat.persona_id ~= -1) then 
  1721. 		audio_persona_remove_2d(M02_personas.gat.persona_id) 
  1722. 		M02_personas.gat.persona_id = -1 
  1723. 	end 
  1724. 	if (M02_personas.phillipe.persona_id ~= -1) then 
  1725. 		audio_persona_remove_2d(M02_personas.phillipe.persona_id) 
  1726. 		M02_personas.phillipe.persona_id = -1 
  1727. 	end 
  1728. 	if (M02_personas.mstar_wm_01.persona_id ~= -1) then 
  1729. 		audio_persona_remove_2d(M02_personas.mstar_wm_01.persona_id) 
  1730. 		M02_personas.mstar_wm_01.persona_id = -1 
  1731. 	end 
  1732. 	if (M02_personas.mstar_wm_02.persona_id ~= -1) then 
  1733. 		audio_persona_remove_2d(M02_personas.mstar_wm_02.persona_id) 
  1734. 		M02_personas.mstar_wm_02.persona_id = -1 
  1735. 	end 
  1736. 	if (M02_personas.interrogation.persona_id ~= -1) then 
  1737. 		audio_persona_remove_2d(M02_personas.interrogation.persona_id) 
  1738. 		M02_personas.interrogation.persona_id = -1 
  1739. 	end 
  1740. 	 
  1741. 	on_damage("", M02_groups.cargo_vehicles.car_alarm_vehicle) 
  1742. 	 
  1743. 	-- Stop the camera shake 
  1744. 	camera_shake_stop() 
  1745. 	 
  1746. 	-- Reset the wind 
  1747. 	wind_override_clear() 
  1748. 	 
  1749. 	-- Clean up the audio and thread for the cargo bay doors 
  1750. 	audio_stop(M02_audio_events.cargo_bay_door_end) 
  1751. 	if (thread_check_done(M02_threads.cargo_door_open) == false) then 
  1752. 		thread_kill(M02_threads.cargo_door_open) 
  1753. 		M02_threads.cargo_door_open = -1 
  1754. 	end 
  1755. 	 
  1756. 	if (thread_check_done(M02_threads.cargo_bay_vo) == false) then 
  1757. 		thread_kill(M02_threads.cargo_bay_vo) 
  1758. 		M02_threads.cargo_bay_vo = -1 
  1759. 	end 
  1760. 	 
  1761. 	-- Remove the callback for the vehicle alarm 
  1762. 	on_take_damage("", M02_groups.cargo_vehicles.car_alarm_vehicle) 
  1763. end 
  1764.  
  1765. -- The Z-scene of the player(s) and Shaundi getting tossed out the back of the plane 
  1766. function m02_run_cargo_plane_ejection_scene() 
  1767. 	-- Kick off the music 
  1768. 	audio_object_post_event("M02_Score_Start", nil, nil, LOCAL_PLAYER) 
  1769.  
  1770. 	-- Play the Z-scene 
  1771. 	cutscene_play(M02_zscenes.bailout, nil, M02_navpoints.player_start_chk_02, false) 
  1772. 	 
  1773. 	-- Handle if the cutscene was skipped 
  1774. 	if (cutscene_was_skipped() == true) then 
  1775. 		audio_object_post_event("M02_Score_Skip_Z02_01", nil, nil, LOCAL_PLAYER) 
  1776. 	end 
  1777. 	 
  1778. 	-- Do clean-up 
  1779. 	m02_cleanup_cargo_plane_ejection_scene() 
  1780. end 
  1781.  
  1782. -- Clean-up for the Z-scene 
  1783. function m02_cleanup_cargo_plane_ejection_scene() 
  1784. 	-- Turn off all the audio emitters in the cargo plane 
  1785. 	for i, emitter in pairs(M02_audio_emitters.plane_sounds) do 
  1786. 		audio_ambient_emitter_stop(emitter) 
  1787. 	end 
  1788. 	 
  1789. 	-- Turn off all the looping cargo bay emitters 
  1790. 	for i, emitter in pairs(M02_audio_emitters.cargo_bay_looping) do 
  1791. 		audio_ambient_emitter_stop(emitter) 
  1792. 	end 
  1793. 	 
  1794. 	-- Make sure the music has stopped 
  1795. 	audio_ambient_emitter_stop(M02_audio_emitters.plane_music) 
  1796. 	 
  1797. 	-- Stop the cargo bay effect 
  1798. 	if (M02_vfx.cargo_bay_wind.handle ~= -1) then 
  1799. 		effect_stop(M02_vfx.cargo_bay_wind.handle) 
  1800. 		M02_vfx.cargo_bay_wind.handle = -1 
  1801. 	end 
  1802. end 
  1803.  
  1804. -- Pre initialize free falling (before the Z-scene) 
  1805. function m02_run_setup_free_falling_pre(immediate) 
  1806. 	group_create_hidden(M02_groups.homies_skydive_01.name) 
  1807. 	group_create_hidden(M02_groups.plane.name) 
  1808. 	group_create_hidden(M02_groups.sky_goons_01.name) 
  1809. 	group_create_hidden(M02_groups.sky_goons_01_a.name) 
  1810. 	 
  1811. 	if (immediate == true) then 
  1812. 		group_create_check_done_loop(M02_groups.homies_skydive_01.name) 
  1813. 		group_create_check_done_loop(M02_groups.plane.name) 
  1814. 		group_create_check_done_loop(M02_groups.sky_goons_01.name) 
  1815. 		group_create_check_done_loop(M02_groups.sky_goons_01_a.name) 
  1816. 	end 
  1817. 	 
  1818. 	-- Prevent both player's from falling, otherwise the client might enter the fall state in the time it takes to 
  1819. 	-- process the packets telling them to start skydiving after the z-scene. 
  1820. 	character_set_never_fall(LOCAL_PLAYER, true) 
  1821. 	if (coop_is_active() == true) then 
  1822. 		character_set_never_fall(REMOTE_PLAYER, true) 
  1823. 	end 
  1824. end 
  1825.  
  1826. -- Setup the player free falling (before the teleport) 
  1827. function m02_run_setup_free_falling() 
  1828. 	-- Make sure they have the default parachute backpack 
  1829. 	customization_item_wear("basicparachute", "cm_pack_basicparachute.cmeshx", "Basic Parachute") 
  1830.  
  1831. 	-- Have the player(s) start skydiving 
  1832. 	skydive_set_player_dive_fall_speed(0.0) 
  1833. 	character_set_skydiving(LOCAL_PLAYER, true) 
  1834. 	player_parachute_wear_backpack(LOCAL_PLAYER, true) 
  1835. 	if (coop_is_active()) then 
  1836. 		character_set_skydiving(REMOTE_PLAYER, true)	 
  1837. 		player_parachute_wear_backpack(REMOTE_PLAYER, true) 
  1838. 	end 
  1839. 	 
  1840. 	-- Give the players a pistol, equip it, and disable all other inventory slots 
  1841. 	inv_weapon_add_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg, 0, true, true, false)	-- Pistol has unlimited ammo and is equipped immediatly, and dual weidling 
  1842. 	inv_weapon_add_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg, 0, true, true, false)	-- Pistol has unlimited ammo and is equipped immediatly, and dual weidling 
  1843. 	inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SMG) 
  1844.  
  1845. 	-- Start the cargo plane pathfinding thread to process the circling 
  1846. 	group_show(M02_groups.plane.name) 
  1847. 	vehicle_max_speed(M02_groups.plane.vehicle, 120.0) 
  1848. 	set_min_hit_points(M02_groups.plane.vehicle, (get_max_hit_points(M02_groups.plane.vehicle) * 0.5)) 
  1849. 	M02_threads.cargo_plane_flying = thread_new("m02_thread_process_cargo_plane_circling") 
  1850. 	 
  1851. 	-- Disable automatic vehicle corpse clean-up (we don't want the debris vehicles getting deleted on us) 
  1852. 	vehicle_forced_corpse_removal_enabled(false) 
  1853. end 
  1854.  
  1855. -- Setup the player free falling (after the teleport) 
  1856. function m02_run_setup_free_falling_post(checkpoint_name) 
  1857. 	if (checkpoint_name == M02_checkpoints.free_falling) then 
  1858. 		-- Enable the trigger that kicks of the gun grapple 
  1859. 		trigger_enable(M02_triggers.gun_grapple, true) 
  1860. 		on_trigger("m02_cb_gun_grapple_triggered", M02_triggers.gun_grapple) 
  1861. 	end 
  1862.  
  1863. 	-- Do common skydiving setup 
  1864. 	m02_helper_setup_skydiving_common() 
  1865.  
  1866. 	-- Move into the non-combat dive 
  1867. 	character_set_skydiving_state(LOCAL_PLAYER, 6, true)	-- lock him in the "non combat dive" state 
  1868. 	if (coop_is_active()) then 
  1869. 		character_set_skydiving_state(REMOTE_PLAYER, 6, true)	-- lock him in the "non combat dive" state 
  1870. 	end 
  1871. 	 
  1872. 	-- Enable exterior rendering for both the interior volumes, so we can see the city 
  1873. 	for i, interior in pairs(M02_interiors) do 
  1874. 		interior_disable_exterior(interior, true) 
  1875. 	end 
  1876. 	 
  1877. 	-- Start some thund-dah 
  1878. 	audio_object_post_event("Mission", { "Mission_Number", "Mission_02" }, { "Mission_02", "Thunder_Rumble" }, LOCAL_PLAYER) 
  1879. 	 
  1880. 	-- And... some wind 
  1881. 	audio_object_post_event("M02_Back_To_FreeFall_Wind", nil, nil, LOCAL_PLAYER) 
  1882. 	 
  1883. 	-- Start the global wind effects 
  1884. 	m02_helper_create_global_effects(false, true, true, false) 
  1885. 	 
  1886. 	-- Attack some lights to the camera 
  1887. 	light_group_set_intensity("Script_Light_Group_pit<001>", 1.0) 
  1888. 	light_group_attach_to_camera("Script_Light_Group_pit<001>") 
  1889. 	 
  1890. 	-- Preload the plane flythrough zscene 
  1891. 	zscene_prep(M02_zscenes.fly_through) 
  1892. end 
  1893.  
  1894. -- Process the short tutorial on the skydiving controls 
  1895. function m02_run_free_failling_initial_dive() 
  1896. 	-- Add the objective text to catch Shaundi 
  1897. 	objective_text(0, M02_strings.objective_catch_shaundi, nil, nil, SYNC_ALL, OI_ASSET_LOCATION) 
  1898. 	marker_add(M02_groups.homies_skydive_01.shaundi, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_DEFAULT, SYNC_ALL) 
  1899. 	 
  1900. 	skydive_set_player_dive_fall_speed(-1.0) 
  1901. 	 
  1902. 	-- Kick off the first QTE 
  1903. 	M02_flags.local_gun_grapple_started = false 
  1904. 	M02_flags.remote_gun_grapple_started = false 
  1905. 	M02_flags.local_gun_grapple_finished = false 
  1906. 	M02_flags.remote_gun_grapple_finished = false	 
  1907. 	 
  1908. 	-- Set up the grapple enemies 
  1909. 	character_set_skydiving(M02_groups.sky_goons_01.grapple_enemy, true) 
  1910. 	character_set_skydiving_state(M02_groups.sky_goons_01.grapple_enemy, 1, true) 
  1911. 	character_show(M02_groups.sky_goons_01.grapple_enemy) 
  1912. 	human_skydive_create_npc_backpack(M02_groups.sky_goons_01.grapple_enemy) 
  1913. 	set_ignore_ai_flag(M02_groups.sky_goons_01.grapple_enemy, true) 
  1914. 	character_prevent_flinching(M02_groups.sky_goons_01.grapple_enemy, true) 
  1915. 	character_allow_ragdoll(M02_groups.sky_goons_01.grapple_enemy, false) 
  1916. 	turn_invulnerable(M02_groups.sky_goons_01.grapple_enemy) 
  1917. 	if (coop_is_active()) then 
  1918. 		character_set_skydiving(M02_groups.sky_goons_01_a.grapple_enemy, true) 
  1919. 		character_set_skydiving_state(M02_groups.sky_goons_01_a.grapple_enemy, 1, true) 
  1920. 		character_show(M02_groups.sky_goons_01_a.grapple_enemy) 
  1921. 		human_skydive_create_npc_backpack(M02_groups.sky_goons_01_a.grapple_enemy) 
  1922. 		set_ignore_ai_flag(M02_groups.sky_goons_01_a.grapple_enemy, true) 
  1923. 		character_prevent_flinching(M02_groups.sky_goons_01_a.grapple_enemy, true) 
  1924. 		character_allow_ragdoll(M02_groups.sky_goons_01_a.grapple_enemy, false) 
  1925. 		turn_invulnerable(M02_groups.sky_goons_01_a.grapple_enemy) 
  1926. 	end 
  1927. 	 
  1928. 	-- MLG 07/04: This line is cut 
  1929. 	--[[ 
  1930. 	delay(1.0) 
  1931. 	audio_play_persona_line(LOCAL_PLAYER, M02_dialog_lines.free_fall_start) 
  1932. 	--]] 
  1933. 	 
  1934. 	-- Wait until one player has finished the QTE(s) 
  1935. 	while (M02_flags.local_gun_grapple_finished == false and M02_flags.remote_gun_grapple_finished == false) do 
  1936. 		thread_yield() 
  1937. 	end 
  1938. 	 
  1939. 	m02_cleanup_free_falling_initial_dive() 
  1940. end 
  1941.  
  1942. -- Callback when the player reaches the gun grapple trigger region 
  1943. function m02_cb_gun_grapple_triggered(player_name, trigger_name) 
  1944. 	local grapple_enemy, callback_func, grapple_pos 
  1945. 	if (player_name == LOCAL_PLAYER) then 
  1946. 		if (M02_flags.local_gun_grapple_started == true) then 
  1947. 			return 
  1948. 		end 
  1949. 		M02_flags.local_gun_grapple_started = true 
  1950. 		 
  1951. 		grapple_enemy = M02_groups.sky_goons_01.grapple_enemy 
  1952. 		callback_func = "m02_cb_local_gun_grapple_finished" 
  1953. 		grapple_pos = M02_navpoints.player_grapple_pos[1]  
  1954. 	else 
  1955. 		if (M02_flags.remote_gun_grapple_started == true) then 
  1956. 			return 
  1957. 		end 
  1958. 		 
  1959. 		M02_flags.remote_gun_grapple_started = true 
  1960. 		grapple_enemy = M02_groups.sky_goons_01_a.grapple_enemy 
  1961. 		callback_func = "m02_cb_remote_gun_grapple_finished" 
  1962. 		grapple_pos = M02_navpoints.player_grapple_pos[2] 
  1963. 	end 
  1964. 	 
  1965. 	-- Remove the marker on Shaundi 
  1966. 	marker_remove(M02_groups.homies_skydive_01.shaundi)	 
  1967. 	 
  1968. 	-- Stop streamers 
  1969. 	M02_runtime.stop_streamers = true 
  1970.  
  1971. 	-- Move the grapple enemy into position 
  1972. 	teleport_to_object(grapple_enemy, player_name, false, false, 0.0, 5.0, 0.0) 
  1973. 	 
  1974. 	delay(1.0) 
  1975. 	qte_start_m02_skyqte_01(player_name, callback_func, grapple_enemy, grapple_pos) 
  1976. 	 
  1977. 	-- If this is the Local player, player a reaction line 
  1978. 	if (player_name == LOCAL_PLAYER) then 
  1979. 		delay(1.5) 
  1980. 		audio_play_persona_line(player_name, "M02_Air_Flight_01") 
  1981. 	end 
  1982. end 
  1983.  
  1984. -- Clean-up the free falling tutorial 
  1985. function m02_cleanup_free_falling_initial_dive() 
  1986. 	skydive_set_player_dive_fall_speed(-1.0) 
  1987. 	 
  1988. 	-- Remove the marker on Shaundi 
  1989. 	marker_remove(M02_groups.homies_skydive_01.shaundi)		 
  1990. end 
  1991.  
  1992. -- Setup the player to kill the guys from above 
  1993. function m02_run_kill_sky_goons_01() 
  1994. 	-- Update the objective text to kill all the pursuers 
  1995. 	objective_text(0, M02_strings.objective_kill_pursuers, nil, nil, SYNC_ALL, OI_ASSET_KILL) 
  1996. 	 
  1997. 	-- Pre-create the next groups of enemies 
  1998. 	group_create_hidden(M02_groups.sky_goons_02.name) 
  1999. 	group_create_hidden(M02_groups.sky_goons_03.name) 
  2000. 	 
  2001. 	-- Show the skydiving enemies 
  2002. 	M02_runtime.sky_goons_alive = 0 
  2003. 	skydive_set_elev_angles_deg(60, 85) --was 50, 75 
  2004. 	m02_helper_set_sky_goon_group(M02_groups.sky_goons_01, true) 
  2005. 	 
  2006. 	delay(2.5) 
  2007. 	audio_play_persona_line(LOCAL_PLAYER, M02_dialog_lines.sky_goons) 
  2008. 	 
  2009. 	-- Start the global wind effects 
  2010. 	m02_helper_create_global_effects(true, true, true, false) 
  2011. 	 
  2012. 	-- Wait until all the enemies have been killed 
  2013. 	while(M02_runtime.sky_goons_alive > 0) do 
  2014. 		thread_yield() 
  2015. 	end 
  2016. 	 
  2017. 	-- Wait until the QTE(s) has finished 
  2018. 	while (M02_flags.local_gun_grapple_finished == false or (coop_is_active() == true and M02_flags.remote_gun_grapple_finished == false)) do 
  2019. 		thread_yield() 
  2020. 	end 
  2021.  
  2022. 	-- Teleport Shaundi down below 
  2023. 	teleport(M02_groups.homies_skydive_01.shaundi, M02_navpoints.shaundi_skydive_pos) 
  2024. 	 
  2025. 	m02_cleanup_kill_sky_goons_01() 
  2026. end 
  2027.  
  2028. -- Clean-up killing sky goons 01 
  2029. function m02_cleanup_kill_sky_goons_01() 
  2030. 	m02_helper_cleanup_sky_goon_group(M02_groups.sky_goons_01) 
  2031. 	 
  2032. 	-- Remove all fun grapple trigger 
  2033. 	m02_helper_disable_trigger(M02_triggers.gun_grapple) 
  2034. end 
  2035.  
  2036. -- Setup the player to kill the guys from below 
  2037. function m02_run_kill_sky_goons_02_03() 
  2038. 	skydive_set_elev_angles_deg(-30, -5) -- was -50,-25 
  2039. 	 
  2040. 	-- Set all the enemeies skydiving 
  2041. 	M02_runtime.sky_goons_alive = 0 
  2042. 	group_show(M02_groups.sky_goons_02.name) 
  2043. 	m02_helper_set_sky_goon_group(M02_groups.sky_goons_02, true) 
  2044. 	 
  2045. 	-- Kill the human shield, and set the player(s) into the inverted skydiving state 
  2046. 	thread_new("m02_thread_process_grapple_enemy_release", LOCAL_PLAYER, M02_groups.sky_goons_01.grapple_enemy) 
  2047. 	 
  2048. 	if (coop_is_active()) then 
  2049. 		delay(0.5) 
  2050. 		thread_new("m02_thread_process_grapple_enemy_release", REMOTE_PLAYER, M02_groups.sky_goons_01_a.grapple_enemy) 
  2051. 	end 
  2052. 	 
  2053. 	-- Start streamers again 
  2054. 	M02_runtime.stop_streamers = false 
  2055. 	 
  2056. 	delay(5.0) 
  2057. 	 
  2058. 	-- Display tutorial message 
  2059. 	if game_is_active_input_gamepad() then 
  2060. 		tutorial_start("mis_02_skydive_flip", 0, true, false, true) 
  2061. 	else 
  2062. 		tutorial_start("mis_02_skydive_flip_pc", 0, true, false, true) 
  2063. 	end 
  2064. 	 
  2065. 	-- Wait until one of the players has flipped 
  2066. 	while(get_char_skydiving_state(LOCAL_PLAYER) ~= 0 and (coop_is_active() == false or get_char_skydiving_state(REMOTE_PLAYER) ~= 0)) do 
  2067. 		thread_yield() 
  2068. 	end 
  2069. 	 
  2070. 	-- Clear the tutorial message 
  2071. 	tutorial_stop("mis_02_skydive_flip") 
  2072. 	tutorial_stop("mis_02_skydive_flip_pc") 
  2073. 	 
  2074. 	-- Wait until at lesat one guy as been killed 
  2075. 	while(M02_runtime.sky_goons_alive == #(M02_groups.sky_goons_02.chars)) do 
  2076. 		thread_yield() 
  2077. 	end 
  2078. 	 
  2079. 	-- Set all the enemeies skydiving 
  2080. 	group_show(M02_groups.sky_goons_03.name) 
  2081. 	m02_helper_set_sky_goon_group(M02_groups.sky_goons_03, true) 
  2082. 	 
  2083. 	-- Wait until group 02 & 03 are all dead 
  2084. 	while(M02_runtime.sky_goons_alive > 0) do 
  2085. 		thread_yield() 
  2086. 	end 
  2087. 	 
  2088. 	delay(2.0) 
  2089. 	 
  2090. 	m02_cleanup_kill_sky_goons_02_03() 
  2091. end 
  2092.  
  2093. -- Thread to process the Upside down HS release animation 
  2094. function m02_thread_process_grapple_enemy_release(player, enemy) 
  2095. 	character_parachute_open(enemy, true, "Free Fall") 
  2096. 	set_animation_state(enemy, "Chute fall Dead") 
  2097. 	character_parachute_play_action(enemy, "freefall HS upside release B") 
  2098. 	action_play_synced_do(player, enemy, "FreeFalling_HS_UpsDwn_Release") 
  2099. 	human_gravity_enable(enemy, false) 
  2100.  
  2101. 	while(action_play_synced_is_finished(player, enemy) == false) do 
  2102. 		thread_yield() 
  2103. 	end 
  2104. 		 
  2105. 	character_set_skydiving(enemy, true) 
  2106. 	set_ignore_ai_flag(enemy, true) 
  2107.  
  2108. 	character_set_skydiving_state(player, 2, false) 
  2109. end 
  2110.  
  2111. -- Clean-up killing sky goons 02 & 03 
  2112. function m02_cleanup_kill_sky_goons_02_03() 
  2113. 	-- Clean-up all the enemies in group 02 & 03 
  2114. 	m02_helper_cleanup_sky_goon_group(M02_groups.sky_goons_02) 
  2115. 	m02_helper_cleanup_sky_goon_group(M02_groups.sky_goons_03) 
  2116. end 
  2117.  
  2118. -- Process the first vertical dive where the player(s) reach Shaundi 
  2119. function m02_run_dive_to_shaundi() 
  2120. 	-- Add the objective text to catch Shaundi 
  2121. 	objective_text(0, M02_strings.objective_catch_shaundi, nil, nil, SYNC_ALL, OI_ASSET_LOCATION) 
  2122. 	marker_add(M02_groups.homies_skydive_01.shaundi, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_DEFAULT, SYNC_ALL) 
  2123. 	 
  2124. 	-- Enable the trigger to create the second wave of debris 
  2125. 	trigger_enable(M02_triggers.stop_dive_debris, true) 
  2126. 	on_trigger("m02_cd_triggered_start_secondary_debris", M02_triggers.stop_dive_debris) 
  2127.  
  2128. 	-- Start the second flow 
  2129. 	debris_flow_set_active(M02_debris_flows[1].handle, M02_navpoints.debris_emitter_pos_01, 0.0, 25.0, 250.0, LOCAL_PLAYER, 1.0, true) 
  2130. 	debris_flow_set_active(M02_debris_flows[2].handle, M02_navpoints.debris_emitter_pos_01, 0.0, 20.0, 250.0, LOCAL_PLAYER, 1.0, true) 
  2131.  
  2132. 	-- Make sure the player's are skydiving in the vertical dive state 
  2133. 	character_set_skydiving_state(LOCAL_PLAYER, 1, true) 
  2134. 	on_take_damage("m02_player_damaged_while_diving_cb", LOCAL_PLAYER) 
  2135. 	if (coop_is_active()) then 
  2136. 		character_set_skydiving_state(REMOTE_PLAYER, 1, true) 
  2137. 		on_take_damage("m02_player_damaged_while_diving_cb", REMOTE_PLAYER) 
  2138. 	end 
  2139. 	 
  2140. 	-- Setup the first trigger region, and just wait until the player get's there 
  2141. 	M02_flags.triggered_final_dive_01 = false 
  2142. 	on_trigger("m02_cb_triggered_final_dive_01", M02_triggers.final_dive_01) 
  2143. 	trigger_enable(M02_triggers.final_dive_01, true) 
  2144. 	 
  2145. 	-- Kick off a thread to figure out when to trigger the music transition for cataching Shaundi 
  2146. 	M02_threads.catach_shaundi_audio = thread_new("m02_thread_process_catch_shaundi_music", "M02_Score_Transition_01", M02_tweak_values.music_trigger_shuandi_catch_time_01) 
  2147. 	 
  2148. 	-- Wait until the player reaches the trigger region by Shaundi 
  2149. 	while(M02_flags.triggered_final_dive_01 == false) do 
  2150. 		thread_yield() 
  2151. 	end 
  2152. 	 
  2153. 	m02_cleanup_dive_to_shaundi() 
  2154. end 
  2155.  
  2156. -- Clean-up the dive to Shaundi 
  2157. function m02_cleanup_dive_to_shaundi() 
  2158. 	-- Remove the marker from Shaundi 
  2159. 	marker_remove(M02_groups.homies_skydive_01.shaundi) 
  2160. 	 
  2161. 	trigger_enable(M02_triggers.stop_dive_debris, false) 
  2162. 	on_trigger("", M02_triggers.stop_dive_debris) 
  2163. 	 
  2164. 	on_take_damage("", LOCAL_PLAYER) 
  2165. 	if (coop_is_active()) then 
  2166. 		on_take_damage("", REMOTE_PLAYER) 
  2167. 	end	 
  2168. end 
  2169.  
  2170. -- Show the enemy the player grapples with 
  2171. function m02_run_catch_shaundi_first_time() 
  2172. 	objective_text_clear(0) 
  2173. 	 
  2174. 	M02_threads.clear_area_around_shaundi = thread_new("m02_thread_cleanup_area_around_shaundi") 
  2175. 	 
  2176. 	-- The player's should be invulnerable to any enemy fire during this sequence (their camera is locked ont he plane) 
  2177. 	turn_invulnerable(LOCAL_PLAYER) 
  2178. 	if (coop_is_active()) then 
  2179. 		turn_invulnerable(REMOTE_PLAYER) 
  2180. 	end 
  2181. 	 
  2182. 	-- Stop streamers 
  2183. 	M02_runtime.stop_streamers = true 
  2184. 	 
  2185. 	-- Kill the thead processing the plane circling, and teleport it to it's new ram path 
  2186. 	if (M02_threads.cargo_plane_flying ~= -1) then 
  2187. 		thread_kill(M02_threads.cargo_plane_flying) 
  2188. 	end 
  2189.  
  2190. 	-- Tell code to start the Shaundi catching sequence 
  2191. 	skydive_set_catching_shaundi(true, true) 
  2192. 	 
  2193. 	-- Wait for the animation to start in code 
  2194. 	while(action_play_synced_is_finished(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi, 1.0) == true) do 
  2195. 		thread_yield() 
  2196. 	end 
  2197.  
  2198. 	-- Hide the HUD 
  2199. 	m02_helper_hide_hud(true) 
  2200.  
  2201. 	while (action_play_synced_is_finished(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi, 0.08148) == false) do 
  2202. 		thread_yield() 
  2203. 	end 
  2204. 	 
  2205. 	-- Start the plane approach audio 
  2206. 	thread_new("m02_thread_process_plane_approach_audio") 
  2207. 	 
  2208. 	while (action_play_synced_is_finished(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi, 0.11) == false) do 
  2209. 		thread_yield() 
  2210. 	end 
  2211. 	 
  2212. 	-- Change the wind audio 
  2213. 	audio_object_post_event("M02_Parachute_Open_Wind_Change", nil, nil, LOCAL_PLAYER) 
  2214. 	 
  2215. 	-- Stop the cloud particle effects 
  2216. 	m02_helper_create_global_effects(true, true, false, true) 
  2217. 	 
  2218. 	-- Start a new downward debris flow (since the player now has their parachute open) 
  2219. 	-- NOTE: (MLG) This debris flow must cleanup objects behind the emitter, otherwise we're at risk of objects going 
  2220. 	--			outside the broadphase, which is bad. 
  2221. 	debris_flow_set_active(M02_debris_flows[1].handle, M02_navpoints.debris_emitter_pos_02, 20.0, 40.0, 375.0, LOCAL_PLAYER, 2.0, true, true) 
  2222. 	debris_flow_set_active(M02_debris_flows[2].handle, M02_navpoints.debris_emitter_pos_02, 20.0, 40.0, 375.0, LOCAL_PLAYER, 2.0, true, true) 
  2223. 	debris_flow_set_active(M02_debris_flows[3].handle, M02_navpoints.debris_emitter_pos_02, 20.0, 40.0, 375.0, LOCAL_PLAYER, 2.0, true, true) 
  2224.  
  2225.  
  2226. 	m02_cleanup_catch_shaundi_first_time() 
  2227. end 
  2228.  
  2229. -- Clean-up catching Shaundi and pulling opening the parachute 
  2230. function m02_cleanup_catch_shaundi_first_time() 
  2231. 	-- NOTHING TO DO 
  2232. end 
  2233.  
  2234. function m02_thread_process_plane_approach_audio() 
  2235. 	audio_object_post_event("Mission", { "Mission_Number", "Mission_02" }, { "Mission_02", "Plane_Approach" }, LOCAL_PLAYER) 
  2236. 	 
  2237. 	thread_yield() 
  2238. 	 
  2239. 	-- Wait until the plane has reached it's first destination 
  2240. 	while(vehicle_anim_finished(M02_groups.plane.vehicle, 0.763) == false) do 
  2241. 		thread_yield() 
  2242. 	end 
  2243. 	audio_object_post_event("M02_Score_Plane_Approach", nil, nil, LOCAL_PLAYER) 
  2244. end 
  2245.  
  2246. -- Ram the cargo plane into the player 
  2247. function m02_run_ram_player_with_plane() 
  2248. 	-- Wait for the animation to get to the point where Shaundi should screem  
  2249. 	while (action_play_synced_is_finished(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi, 0.93) == false) do 
  2250. 		thread_yield() 
  2251. 	end 
  2252. 	 
  2253. 	camera_restrict_set_limits(-3, 3, -3, 3) 
  2254. 	camera_restrict_target_object(M02_groups.plane.vehicle, 0, nil, -4.0, -48.0, 0.0) 
  2255. 	camera_restrict_set_active(true) 
  2256. 	 
  2257. 	-- Wait for the synced animation to stop 
  2258. 	while (action_play_synced_is_finished(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi, 0.96) == false) do 
  2259. 		thread_yield() 
  2260. 	end 
  2261. 	 
  2262. 	m02_helper_hide_hud(false) 
  2263. 	 
  2264. 	delay(1.0) 
  2265. 	 
  2266. 	-- Update the objective text, and add a marker on the plane 
  2267. 	marker_add(M02_groups.plane.vehicle, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL) 
  2268. 	objective_text(0, M02_strings.objective_shoot_plane, nil, nil, SYNC_ALL, OI_ASSET_KILL) 
  2269. 	 
  2270. 	-- Register a callback for the cargo plane, so we know when the player shoots the windshield 
  2271. 	on_take_damage("m02_cargo_plane_damaged_cb", M02_groups.plane.vehicle) 
  2272. 	 
  2273. 	-- Wait until the plane has reached it's first destination 
  2274. 	while(vehicle_anim_finished(M02_groups.plane.vehicle, 0.995) == false) do 
  2275. 		thread_yield() 
  2276. 	end 
  2277.  
  2278. 	-- Clear the Shaundi catching sequence in code 
  2279. 	skydive_set_catching_shaundi(false, false) 
  2280. 	 
  2281. 	-- Check for failure 
  2282. 	if (vehicle_component_is_shattered(M02_groups.plane.vehicle, M02_groups.plane.windshield_component) == false) then 
  2283. 		-- Play the failure animation 
  2284. 		action_play_do(LOCAL_PLAYER, "m02 shootqte end a") 
  2285. 		if (coop_is_active()) then 
  2286. 			action_play_do(REMOTE_PLAYER, "m02 shootqte end a") 
  2287. 		end 
  2288. 		 
  2289. 		-- Wait a bit, then kill the players 
  2290. 		if (coop_is_active()) then 
  2291. 			character_parachute_detach(REMOTE_PLAYER) 
  2292. 			character_kill(REMOTE_PLAYER, true) 
  2293. 		end 
  2294. 		character_parachute_detach(LOCAL_PLAYER) 
  2295. 		character_kill(LOCAL_PLAYER, true) 
  2296. 		 
  2297. 		-- Spin the mission script, until the mission ends due to the player's death 
  2298. 		while (true) do 
  2299. 			thread_yield() 
  2300. 		end 
  2301. 	end 
  2302. 	 
  2303. 	-- Put the player back into the normal skydiving state 
  2304. 	character_set_skydiving_state(LOCAL_PLAYER, 0, false) 
  2305. 	if (coop_is_active() == true) then 
  2306. 		character_set_skydiving_state(REMOTE_PLAYER, 0, false) 
  2307. 	end 
  2308. 	 
  2309. 	m02_cleanup_ram_player_with_plane() 
  2310. end 
  2311.  
  2312. -- Callback for when the cargo plane is damaged 
  2313. -- 
  2314. -- damaged_obj:		Object that was damaged (the cargo plane) 
  2315. -- attacker:		Human that caused the damage 
  2316. -- hitpoint_pct:	Remaining hitpoint percentage after the damage was applied 
  2317. function m02_cargo_plane_damaged_cb(damaged_obj, attacker, hitpoint_pct) 
  2318. 	if (attacker == LOCAL_PLAYER or attacker == REMOTE_PLAYER) then 
  2319. 		-- If we've gone over the windshield hitpoints, then detach the windshield (make it shatter 
  2320. 		if ((1.0 - hitpoint_pct) * get_max_hit_points(M02_groups.plane.vehicle) >=  M02_tweak_values.cargo_plane_windshield_hp) then 
  2321. 			vehicle_component_shatter_glass(M02_groups.plane.vehicle, M02_groups.plane.windshield_component) 
  2322. 			on_take_damage("", M02_groups.plane.vehicle) 
  2323. 		end 
  2324. 	end 
  2325. end 
  2326.  
  2327. -- Clean-up ramming the player with the cargo plane 
  2328. function m02_cleanup_ram_player_with_plane() 
  2329. 	m02_helper_disable_trigger(M02_triggers.final_dive_01) 
  2330. 	 
  2331. 	-- Remove the marker on the cargo plane, and remove the damage callback 
  2332. 	marker_remove(M02_groups.plane.vehicle) 
  2333. 	 
  2334. 	-- Remove the restricted camera 
  2335. 	camera_restrict_set_active(false) 
  2336. 	 
  2337. 	skydive_set_catching_shaundi(false, false) 
  2338. 	 
  2339. 	-- Make the player(s) vulnerable again 
  2340. 	turn_vulnerable(LOCAL_PLAYER) 
  2341. 	player_script_controlled_clear(LOCAL_PLAYER) 
  2342. 	character_parachute_detach(LOCAL_PLAYER) 
  2343. 	if (coop_is_active()) then 
  2344. 		turn_vulnerable(REMOTE_PLAYER) 
  2345. 		player_script_controlled_clear(REMOTE_PLAYER) 
  2346. 		character_parachute_detach(REMOTE_PLAYER) 
  2347. 	end 
  2348. 	 
  2349. 	-- Remove the on damage callback for the cargo plane 
  2350. 	on_take_damage("", M02_groups.plane.vehicle) 
  2351. 	 
  2352. 	if (group_is_loaded(M02_groups.homies_skydive_01.name) == true) then 
  2353. 		group_hide(M02_groups.homies_skydive_01.name) 
  2354. 	end 
  2355. 	 
  2356. 	thread_kill(M02_threads.clear_area_around_shaundi) 
  2357. end 
  2358.  
  2359. -- Play the Z-scene of the player(s) flying through the cargo plane 
  2360. function m02_run_fly_through_plane_scene() 
  2361. 	-- Post an event to duck all other audio effects 
  2362. 	audio_object_post_event("M02_Zscene_02_Stop_All_Audio", nil, nil, LOCAL_PLAYER) 
  2363. 	 
  2364. 	-- Start playing the cargo bay wind VFX 
  2365. 	M02_vfx.cargo_bay_wind.handle = effect_play(M02_vfx.cargo_bay_wind.name, true) 
  2366. 	 
  2367. 	thread_new("m02_thread_hide_stuff_for_plane_fly_through") 
  2368. 	 
  2369. 	-- Remove player(s) parachute backpack 
  2370. 	player_parachute_wear_backpack(LOCAL_PLAYER, false) 
  2371. 	if (coop_is_active() == true) then 
  2372. 		player_parachute_wear_backpack(REMOTE_PLAYER, false) 
  2373. 	end 
  2374. 	 
  2375. 	-- Play the bink (wait two frames, one for the effects to stop, and another for the effect objects to get destroyed) 
  2376. 	cutscene_play(M02_zscenes.fly_through, nil, M02_navpoints.player_start_chk_03) 
  2377. 	 
  2378. 	-- Handle if the cutscene was skipped 
  2379. 	if (cutscene_was_skipped() == true) then 
  2380. 		audio_object_post_event("M02_Score_Skip_Z02_02", nil, nil, LOCAL_PLAYER) 
  2381. 	end 
  2382. 	 
  2383. 	-- Turn back on the freefall wind 
  2384. 	audio_object_post_event("M02_Back_To_FreeFall_Wind", nil, nil, LOCAL_PLAYER) 
  2385. 	 
  2386. 	m02_cleanup_fly_through_plane_scene() 
  2387. end 
  2388.  
  2389. function m02_thread_hide_stuff_for_plane_fly_through() 
  2390. 	delay(0.1) 
  2391. 	 
  2392. 	-- Destroy the cargo plane 
  2393. 	group_destroy(M02_groups.plane.name) 
  2394.  
  2395. 	-- Stop any debris flow 
  2396. 	for i, debris_flow in pairs(M02_debris_flows) do 
  2397. 		if (debris_flow.handle ~= 0) then 
  2398. 			debris_flow_set_inactive(debris_flow.handle) 
  2399. 		end 
  2400. 	end 
  2401. end 
  2402.  
  2403. -- Cleanup for the free falling section of the mission 
  2404. function m02_cleanup_fly_through_plane_scene() 
  2405. 	if (M02_vfx.cargo_bay_wind.handle ~= -1) then 
  2406. 		effect_stop(M02_vfx.cargo_bay_wind.handle) 
  2407. 		M02_vfx.cargo_bay_wind.handle = -1 
  2408. 	end 
  2409.  
  2410. 	-- Clean-up some groups 
  2411. 	if (group_is_loaded(M02_groups.sky_goons_01.name)) then 
  2412. 		group_destroy(M02_groups.sky_goons_01.name) 
  2413. 	end 
  2414. 	if (group_is_loaded(M02_groups.sky_goons_01_a.name)) then 
  2415. 		group_destroy(M02_groups.sky_goons_01_a.name) 
  2416. 	end 
  2417. 	if (group_is_loaded(M02_groups.sky_goons_02.name)) then 
  2418. 		group_destroy(M02_groups.sky_goons_02.name) 
  2419. 	end 
  2420. 	if (group_is_loaded(M02_groups.sky_goons_03.name)) then 
  2421. 		group_destroy(M02_groups.sky_goons_03.name) 
  2422. 	end 
  2423. 	 
  2424. 	-- Kill any threads that might still be active 
  2425. 	if (M02_threads.cargo_plane_flying ~= -1) then 
  2426. 		thread_kill(M02_threads.cargo_plane_flying) 
  2427. 		M02_threads.cargo_plane_flying = -1 
  2428. 	end 
  2429. end 
  2430.  
  2431. -- Setup for the final dive checkpoint 
  2432. function m02_run_setup_final_dive() 
  2433. 	-- Make sure the player(s) are skydiving in the normal state state 
  2434. 	character_set_skydiving(LOCAL_PLAYER, true) 
  2435. 	character_set_skydiving_state(LOCAL_PLAYER, 0, false) 
  2436. 	player_parachute_wear_backpack(LOCAL_PLAYER, true) 
  2437. 	if (coop_is_active() == true) then 
  2438. 		character_set_skydiving(REMOTE_PLAYER, true) 
  2439. 		character_set_skydiving_state(REMOTE_PLAYER, 0, false) 
  2440. 		player_parachute_wear_backpack(REMOTE_PLAYER, true) 
  2441. 	end 
  2442.  
  2443. 	-- Give the players the SMG, equip it, and disable all other inventory slots 
  2444. 	inv_weapon_remove_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg) 
  2445. 	inv_weapon_add_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  2446. 	inv_weapon_remove_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg) 
  2447. 	inv_weapon_add_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  2448. 	inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SMG) 
  2449. 	 
  2450. 	-- Do common skydiving setup 
  2451. 	m02_helper_setup_skydiving_common()	 
  2452.  
  2453. 	-- Shaundi has already been created, just make sure she's in the correct position 
  2454. 	teleport(M02_groups.homies_skydive_01.shaundi, M02_navpoints.shaundi_skydive_pos) 
  2455. 	 
  2456. 	-- Set the boxes on fire 
  2457. 	for i, box in pairs(M02_movers.debris_box_list) do 
  2458. 		if (rand_int(1, 10) < 2) then 
  2459. 			M02_vfx.debris_fire.box_handles[i] = effect_play_on_script_object(M02_vfx.debris_fire.name, box, nil, true) 
  2460. 		end 
  2461. 	end 
  2462. 	 
  2463. 	-- Start the global VFX 
  2464. 	m02_helper_create_global_effects(false, true, true, false) 
  2465. 	 
  2466. 	-- Start some BIG thund-dah 
  2467. 	audio_object_post_event("M02_Thunder_BIG", nil, nil, LOCAL_PLAYER) 
  2468. 	 
  2469. 	skydive_set_elev_angles_deg(-30, -5) -- was -50,-25 
  2470. 	 
  2471. 	-- Setup the cargo plane 
  2472. 	if (group_is_loaded(M02_groups.plane.name) == false) then 
  2473. 		group_create(M02_groups.plane.name, true) 
  2474. 		vehicle_set_special_override_never_ghost(M02_groups.plane.vehicle, true) 
  2475. 		turn_invulnerable(M02_groups.plane.vehicle) 
  2476. 	end 
  2477.  
  2478. 	group_show(M02_groups.plane.name) 
  2479. 	vehicle_set_keyframed_physics(M02_groups.plane.vehicle, false) -- make sure the vehicle isn't still set as keyframed physics 
  2480. 	vehicle_max_speed(M02_groups.plane.vehicle, 500.0) 
  2481. 	vehicle_enter_teleport(M02_groups.plane.chars[1], M02_groups.plane.vehicle, 0, true) 
  2482. 	teleport_vehicle(M02_groups.plane.vehicle, M02_navpoints.cargo_plane_fly_away_start) 
  2483. 	set_min_hit_points(M02_groups.plane.vehicle, (get_max_hit_points(M02_groups.plane.vehicle) * 0.5)) 
  2484. 	M02_threads.cargo_plane_retreat = thread_new("m02_thread_process_cargo_plane_retreat") 
  2485. 	 
  2486. 	-- Enable exterior rendering for both the interior volumes, so we can see the city 
  2487. 	for i, interior in pairs(M02_interiors) do 
  2488. 		interior_disable_exterior(interior, false) 
  2489. 	end	 
  2490. end 
  2491.  
  2492. -- Wait for the player(s) to kill the enemies in group 05 
  2493. function m02_run_kill_sky_goons_05() 
  2494. 	-- Update the objective text to kill all the pursuers 
  2495. 	objective_text(0, M02_strings.objective_kill_pursuers, nil, nil, SYNC_ALL, OI_ASSET_KILL) 
  2496. 	 
  2497. 	-- Start streamers again 
  2498. 	M02_runtime.stop_streamers = false 
  2499. 	 
  2500. 	-- Create and setup the group of guys immediatly after the player is rammed by the cargo plane 
  2501. 	group_create_hidden(M02_groups.sky_goons_05.name, true) 
  2502. 	delay(0.5) 
  2503. 	 
  2504. 	-- Process the set of enemies 
  2505. 	M02_runtime.sky_goons_alive = 0 
  2506. 	group_show(M02_groups.sky_goons_05.name) 
  2507. 	m02_helper_set_sky_goon_group(M02_groups.sky_goons_05, true, 2.0) 
  2508. 	 
  2509. 	delay(2.5) 
  2510. 	audio_play_persona_line(LOCAL_PLAYER, M02_dialog_lines.flew_through_plane) 
  2511. 	 
  2512. 	while(M02_runtime.sky_goons_alive > 0) do 
  2513. 		thread_yield() 
  2514. 	end 
  2515. 	 
  2516. 	-- Clean-up 
  2517. 	m02_cleanup_kill_sky_goons_05() 
  2518. end 
  2519.  
  2520. -- Clean-up for killing sky goons 05 
  2521. function m02_cleanup_kill_sky_goons_05() 
  2522. 	m02_helper_cleanup_sky_goon_group(M02_groups.sky_goons_05) 
  2523. end 
  2524.  
  2525. -- Run the final QTE, just before the second (final) vertical dive 
  2526. function m02_run_final_dive_qte() 
  2527. 	-- Create the enemies, and set them skydiving 
  2528. 	group_create_hidden(M02_groups.sky_goons_07.name, true) 
  2529. 	for i, char in pairs (M02_groups.sky_goons_07.chars) do 
  2530. 		character_set_never_fall(char, true) 
  2531. 		character_set_skydiving(char, true) 
  2532. 	end 
  2533. 	 
  2534. 	if (coop_is_active() == true) then 
  2535. 		-- Setup the final QTE for the remote player 
  2536. 		group_create_hidden(M02_groups.sky_goons_07_A.name, true) 
  2537. 		for i, char in pairs (M02_groups.sky_goons_07_A.chars) do 
  2538. 			character_set_never_fall(char, true) 
  2539. 			character_set_skydiving(char, true) 
  2540. 		end 
  2541. 	end 
  2542. 	 
  2543. 	-- Add the objective text to catch Shaundi 
  2544. 	objective_text(0, M02_strings.objective_catch_shaundi, nil, nil, SYNC_ALL, OI_ASSET_LOCATION) 
  2545. 	marker_add(M02_groups.homies_skydive_01.shaundi, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_DEFAULT, SYNC_ALL) 
  2546. 	 
  2547. 	delay(1.5) 
  2548. 	 
  2549. 	-- Move into the non-combat dive 
  2550. 	character_set_skydiving_state(LOCAL_PLAYER, 6, true)	-- lock him in the "non combat dive" state 
  2551. 	if (coop_is_active() == true) then 
  2552. 		character_set_skydiving_state(REMOTE_PLAYER, 6, true)	-- lock him in the "non combat dive" state 
  2553. 	end 
  2554.  
  2555. 	-- Wait a bit so that the players have flipped over before showing the QTE enemies 
  2556. 	delay(2.0) 
  2557. 	group_show(M02_groups.sky_goons_07.name) 
  2558. 	if (coop_is_active() == true) then 
  2559. 		group_show(M02_groups.sky_goons_07_A.name) 
  2560. 	end 
  2561. 	 
  2562. 	-- Wait just a tad longer 
  2563. 	delay(1.0) 
  2564. 	 
  2565. 	-- Stop streamers 
  2566. 	M02_runtime.stop_streamers = true 
  2567. 	 
  2568. 	-- Setup for the final QTE 
  2569. 	M02_flags.local_final_grapple_finished = false 
  2570. 	M02_flags.remote_final_grapple_finished = false 
  2571. 	if (coop_is_active()) then 
  2572. 		 
  2573. 		M02_flags.remote_final_grapple_finished = false 
  2574. 		set_ignore_ai_flag(M02_groups.sky_goons_07_A.grapple_enemy, true) 
  2575. 		human_skydive_create_npc_backpack(M02_groups.sky_goons_07_A.grapple_enemy) 
  2576. 		teleport_to_object(M02_groups.sky_goons_07_A.grapple_enemy, REMOTE_PLAYER, false, false, 0.0, 5.0, 0.0) 
  2577.  
  2578. 		character_set_skydiving_state(REMOTE_PLAYER, 1, true, nil, true) 
  2579. 		qte_start(REMOTE_PLAYER, "Mission02_SKYQTE3", "m02_cb_remote_final_grapple_finished", M02_groups.sky_goons_07_A.grapple_enemy) 
  2580. 	end 
  2581. 	 
  2582. 	-- Setup the final QTE for the local player 
  2583. 	 
  2584. 	set_ignore_ai_flag(M02_groups.sky_goons_07.grapple_enemy, true) 
  2585. 	human_skydive_create_npc_backpack(M02_groups.sky_goons_07.grapple_enemy) 
  2586. 	teleport_to_object(M02_groups.sky_goons_07.grapple_enemy, LOCAL_PLAYER, false, false, 0.0, 5.0, 0.0) 
  2587. 	 
  2588. 	character_set_skydiving_state(LOCAL_PLAYER, 1, true, nil, true) 
  2589. 	qte_start(LOCAL_PLAYER, "Mission02_SKYQTE3", "m02_cb_local_final_grapple_finished", M02_groups.sky_goons_07.grapple_enemy) 
  2590.  
  2591. 	delay(1.0) 
  2592. 	audio_play_persona_line(LOCAL_PLAYER, "M02_Air_Flight_02") 
  2593. 	 
  2594. 	-- Wait until the QTE(s) have finished 
  2595. 	while(M02_flags.local_final_grapple_finished == false and M02_flags.remote_final_grapple_finished == false) do 
  2596. 		thread_yield() 
  2597. 	end 
  2598. 	 
  2599. 	-- Start streamers again 
  2600. 	M02_runtime.stop_streamers = false 
  2601. 	 
  2602. 	m02_cleanup_final_dive_qte() 
  2603. end 
  2604.  
  2605. -- Clean-up for the last QTE before the final dive 
  2606. function m02_cleanup_final_dive_qte() 
  2607. 	-- NOTHING TO DO HERE, AS OF NOW 
  2608. end 
  2609.  
  2610. -- Do the final dive to catch up to Shaundi 
  2611. function m02_run_final_dive() 
  2612. 	-- Kick off a thread to figure out when to trigger the music transition for cataching Shaundi 
  2613. 	M02_threads.catach_shaundi_audio = thread_new("m02_thread_process_catch_shaundi_music", "M02_Score_End", M02_tweak_values.music_trigger_shuandi_catch_time_02) 
  2614. 	 
  2615. 	-- Enable the trigger to create the second wave of debris 
  2616. 	trigger_enable(M02_triggers.stop_dive_debris, true) 
  2617. 	on_trigger("m02_cd_triggered_start_secondary_debris", M02_triggers.stop_dive_debris) 
  2618. 	 
  2619. 	-- Create the dive debris flow, and set some of the boxes ablaze 
  2620. 	debris_flow_set_active(M02_debris_flows[1].handle, M02_navpoints.debris_emitter_pos_01, 0.0, 25.0, 250.0, LOCAL_PLAYER, 1.0, true) 
  2621. 	debris_flow_set_active(M02_debris_flows[2].handle, M02_navpoints.debris_emitter_pos_01, 0.0, 20.0, 250.0, LOCAL_PLAYER, 1.0, true) 
  2622.  
  2623. 	-- Add fire to some of the boxes 
  2624. 	for i, box in pairs(M02_movers.debris_dive_boxes) do 
  2625. 		if (rand_int(1, 10) < 4) then 
  2626. 			M02_vfx.debris_fire.dive_box_handles[i] = effect_play_on_script_object(M02_vfx.debris_fire.name, box, nil, true) 
  2627. 		end 
  2628. 	end 
  2629. 	 
  2630. 	-- Force the player into a vertical dive 
  2631. 	character_set_skydiving_state(LOCAL_PLAYER, 1, true) 
  2632. 	on_take_damage("m02_player_damaged_while_diving_cb", LOCAL_PLAYER) 
  2633. 	if (coop_is_active()) then 
  2634. 		character_set_skydiving_state(REMOTE_PLAYER, 1, true) 
  2635. 		on_take_damage("m02_player_damaged_while_diving_cb", REMOTE_PLAYER) 
  2636. 	end 
  2637. 	 
  2638. 	-- Setup the first trigger region, and just wait until the player get there 
  2639. 	M02_flags.triggered_final_dive_01 = false 
  2640. 	on_trigger("m02_cb_triggered_final_dive_01", M02_triggers.final_dive_01) 
  2641. 	trigger_enable(M02_triggers.final_dive_01, true) 
  2642. 	 
  2643. 	delay(4.0) 
  2644. 	audio_play_persona_line(LOCAL_PLAYER, M02_dialog_lines.falling_shit) 
  2645. 	 
  2646. 	-- Hide the cargo plane 
  2647. 	vehicle_hide(M02_groups.plane.vehicle, true) 
  2648. 	 
  2649. 	while(M02_flags.triggered_final_dive_01 == false) do 
  2650. 		thread_yield() 
  2651. 	end 
  2652. 	 
  2653. 	m02_cleanup_final_dive() 
  2654. end 
  2655.  
  2656. -- Clean-up for the final dive (last clean-up function called for the third checkpoint, and general clean-up for this checkpoint happens here) 
  2657. function m02_cleanup_final_dive() 
  2658. 	-- Remove the marker from Shaundi 
  2659. 	marker_remove(M02_groups.homies_skydive_01.shaundi) 
  2660. 	 
  2661. 	-- Disable the final dive trigger 
  2662. 	trigger_enable(M02_triggers.stop_dive_debris, false) 
  2663. 	on_trigger("", M02_triggers.stop_dive_debris) 
  2664. 	 
  2665. 	on_take_damage("", LOCAL_PLAYER) 
  2666. 	if (coop_is_active()) then 
  2667. 		on_take_damage("", REMOTE_PLAYER) 
  2668. 	end	 
  2669. end 
  2670.  
  2671. -- Show the enemy the player grapples with 
  2672. function m02_run_catch_shaundi_again() 
  2673. 	objective_text_clear(0) 
  2674. 	 
  2675. 	M02_threads.clear_area_around_shaundi = thread_new("m02_thread_cleanup_area_around_shaundi") 
  2676. 	 
  2677. 	-- The player's should be invulnerable to any enemy fire during this sequence (their camera is locked ont he plane) 
  2678. 	turn_invulnerable(LOCAL_PLAYER) 
  2679. 	if (coop_is_active()) then 
  2680. 		turn_invulnerable(REMOTE_PLAYER) 
  2681. 	end	 
  2682. 	 
  2683. 	-- Stop streamers 
  2684. 	M02_runtime.stop_streamers = true 
  2685. 	character_set_skydiving_state(M02_runtime.shaundi_caught_by, 0, true) 
  2686. 		 
  2687. 	-- Tell code to start the Shaundi catching sequence 
  2688. 	skydive_set_catching_shaundi(true, false) 
  2689. 	 
  2690. 	-- Wait for the animation to start in code	 
  2691. 	while(action_play_synced_is_finished(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi, 1.0) == true) do 
  2692. 		thread_yield() 
  2693. 	end 
  2694. 	 
  2695. 	m02_helper_hide_hud(true) 
  2696. 	 
  2697. 	while (action_play_synced_is_finished(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi, 0.11) == false) do 
  2698. 		thread_yield() 
  2699. 	end 
  2700. 	 
  2701. 	-- Change the wind audio 
  2702. 	audio_object_post_event("M02_Parachute_Open_Wind_Change", nil, nil, LOCAL_PLAYER) 
  2703. 	 
  2704. 	delay(0.2) 
  2705. 	 
  2706. 	-- Start a new downward debris flow (since the player now has their parachute open) 
  2707. 	-- NOTE: (MLG) This debris flow must cleanup objects behind the emitter, otherwise we're at risk of objects going 
  2708. 	--			outside the broadphase, which is bad. 
  2709. 	debris_flow_set_active(M02_debris_flows[1].handle, M02_navpoints.debris_emitter_pos_02, 20.0, 40.0, 300.0, LOCAL_PLAYER, 2.0, true, true) 
  2710. 	debris_flow_set_active(M02_debris_flows[2].handle, M02_navpoints.debris_emitter_pos_02, 20.0, 40.0, 300.0, LOCAL_PLAYER, 2.0, true, true) 
  2711. 	debris_flow_set_active(M02_debris_flows[3].handle, M02_navpoints.debris_emitter_pos_02, 20.0, 40.0, 300.0, LOCAL_PLAYER, 2.0, true, true) 
  2712.  
  2713. 	m02_cleanup_catch_shaundi_again() 
  2714. end 
  2715.  
  2716. -- Clean-up catching Shaundi and pulling opening the parachute 
  2717. function m02_cleanup_catch_shaundi_again() 
  2718. 	thread_kill(M02_threads.clear_area_around_shaundi) 
  2719. end 
  2720.  
  2721.  
  2722.  
  2723. -- *************************************************** 
  2724. -- Miscellaneous m02 Helper Funcrtions 
  2725. -- *************************************************** 
  2726.  
  2727. -- Disable a trigger 
  2728. -- 
  2729. -- trigger_name:		Name of the trigger to be disabled 
  2730. function m02_helper_disable_trigger(trigger_name) 
  2731. 	on_trigger("", trigger_name) 
  2732. 	trigger_enable(trigger_name, false) 
  2733. 	marker_remove_trigger(trigger_name, SYNC_ALL) 
  2734. end 
  2735.  
  2736. function m02_helper_cleanup_sky_goon_group(group_table) 
  2737. 	for i, char in pairs(group_table.chars) do 
  2738. 		on_death("", char.name) 
  2739. 		marker_remove(char.name) 
  2740. 		for i, vfx_handle in pairs(char.vfx_handles) do 
  2741. 			effect_stop(vfx_handle) 
  2742. 		end 
  2743. 	end 
  2744. end 
  2745.  
  2746. -- Hide or unhide the hud 
  2747. -- 
  2748. -- hide:	TRUE to hide the HUD, FALSE to unhide it 
  2749. function m02_helper_hide_hud(hide) 
  2750. 	if (hide == true) then 
  2751. 		if (M02_hud_states.hide_hud == -1) then 
  2752. 			M02_hud_states.hide_hud = hud_display_create_state() 
  2753. 			hud_display_set_element(M02_hud_states.hide_hud, HUD_ALL_ELEM, HUD_FADE_HIDDEN) 
  2754. 			hud_display_commit_state(M02_hud_states.hide_hud) 
  2755. 		end 
  2756. 	else 
  2757. 		if (M02_hud_states.hide_hud ~= -1) then 
  2758. 			hud_display_remove_state(M02_hud_states.hide_hud) 
  2759. 			M02_hud_states.hide_hud = -1 
  2760. 		end 
  2761. 	end 
  2762. end 
  2763.  
  2764. -- Common setup for the skydiving sections 
  2765. function m02_helper_setup_skydiving_common(do_teleport) 
  2766. 	-- Clear the objective text 
  2767. 	objective_text_clear(0) 
  2768. 	 
  2769. 	-- Set the global wind override 
  2770. 	wind_override_set(0.0, 1.0, 0.0, 1.0) 
  2771. 	 
  2772. 	-- Start the first debris field flowing 
  2773. 	debris_flow_set_active(M02_debris_flows[1].handle, M02_navpoints.debris_emitter_pos_01, 10.0, 25.0, 400.0, LOCAL_PLAYER, 1.0, false, true)	 
  2774. 	 
  2775. 	-- Player's can never catch on fire while skydiving 
  2776. 	character_set_never_catch_fire(LOCAL_PLAYER, true) 
  2777. 	if (coop_is_active() == true) then 
  2778. 		character_set_never_catch_fire(REMOTE_PLAYER, true) 
  2779. 	end 
  2780. 	 
  2781. 	-- Create the new homie group, for Shaundi 
  2782. 	if (group_is_loaded(M02_groups.homies_skydive_01.name) == false) then 
  2783. 		group_create_hidden(M02_groups.homies_skydive_01.name, true) 
  2784. 		party_add(M02_groups.homies_skydive_01.shaundi, LOCAL_PLAYER) 
  2785. 		set_never_turn_on_player(M02_groups.homies_skydive_01.shaundi, true) 
  2786. 		follower_make_independent(M02_groups.homies_skydive_01.shaundi, true) 
  2787. 	end 
  2788. 	 
  2789. 	group_show(M02_groups.homies_skydive_01.name) 
  2790. 	character_set_skydiving(M02_groups.homies_skydive_01.shaundi, true) 
  2791. 	character_set_skydiving_state(M02_groups.homies_skydive_01.shaundi, 7, true) 
  2792. 	character_set_never_catch_fire(M02_groups.homies_skydive_01.shaundi, true) 
  2793. 	character_prevent_flinching(M02_groups.homies_skydive_01.shaundi, true) 
  2794. 	set_dont_attack_me_on_sight_flag(M02_groups.homies_skydive_01.shaundi, true) 
  2795. 	inv_item_remove_all(M02_groups.homies_skydive_01.shaundi) 
  2796. 	set_ignore_ai_flag(M02_groups.homies_skydive_01.shaundi, true) 
  2797. 	 
  2798. 	-- Start a thread to process the vehicle audio whooshes 
  2799. 	if (M02_threads.object_whoosh == -1) then 
  2800. 		M02_threads.object_whoosh = thread_new("m02_thread_process_skydive_object_whoosh") 
  2801. 	end 
  2802. 	 
  2803. 	-- Hide the minimap 
  2804. 	if (M02_hud_states.hide_minimap == -1) then 
  2805. 		M02_hud_states.hide_minimap = hud_display_create_state() 
  2806. 		hud_display_set_element(M02_hud_states.hide_minimap, HUD_ELEM_MINIMAP, HUD_FADE_HIDDEN) 
  2807. 		hud_display_commit_state(M02_hud_states.hide_minimap) 
  2808. 	end 
  2809. 	 
  2810. 	M02_threads.kill_fallen_players = thread_new("m02_thread_kill_players_that_fall_too_far") 
  2811. end 
  2812.  
  2813. function m02_helper_create_debris_flow(debris_flow_table, hidden) 
  2814. 	-- Create a new flow 
  2815. 	debris_flow_table.handle = debris_flow_create() 
  2816. 	 
  2817. 	-- Create the vehicle group 
  2818. 	if (group_is_loaded(debris_flow_table.vehicle_group.name) == false) then 
  2819. 		if (hidden == true) then 
  2820. 			group_create_hidden(debris_flow_table.vehicle_group.name, true) 
  2821. 		else 
  2822. 			group_create(debris_flow_table.vehicle_group.name, true) 
  2823. 		end 
  2824. 	end 
  2825. 	 
  2826. 	-- Add the vehicle debris to the flow 
  2827. 	local vehicle_min_speed = 10.0 
  2828. 	local vehicle_max_speed = 14.0 
  2829. 	local vehicle_max_ang_vel = 4.0 
  2830. 	for i, vehicle in pairs(debris_flow_table.vehicle_group.vehicles) do 
  2831. 		-- Setup the vehicle 
  2832. 		vehicle_disable_explosion_and_damage_vfx(vehicle.name, true) 
  2833. 		vehicle_skydiving_start(vehicle.name) 
  2834. 		on_damage("m02_cb_debris_vehicle_damaged", vehicle.name, 0.2) 
  2835. 		on_vehicle_destroyed("m02_cb_debris_vehicle_destroyed", vehicle.name) 
  2836. 		on_vehicle_debris_flow_recycled("m02_cb_debris_vehicle_recycled", vehicle.name) 
  2837. 		 
  2838. 		-- Add the vehicle to the debris flow 
  2839. 		debris_flow_add_object(debris_flow_table.handle, vehicle.name, vehicle_min_speed, vehicle_max_speed, vehicle_max_ang_vel, true, true) 
  2840. 		 
  2841. 		-- Turn the headlights on 
  2842. 		vehicle_lights_on(vehicle.name, true) 
  2843. 	end 
  2844. 	 
  2845. 	-- Set all the boxes floating 
  2846. 	local box_min_speed = 14.0 
  2847. 	local box_max_speed = 18.0 
  2848. 	local box_max_ang_vel = 3.0 
  2849. 	for i, box in pairs(debris_flow_table.boxes) do 
  2850. 		--mesh_mover_reset(box) 
  2851. 		debris_flow_add_object(debris_flow_table.handle, box, box_min_speed, box_max_speed, box_max_ang_vel, true, true) 
  2852. 	end 
  2853. 	for i, pallet in pairs(debris_flow_table.pallets) do 
  2854. 		--mesh_mover_reset(pallet) 
  2855. 		debris_flow_add_object(debris_flow_table.handle, pallet, box_min_speed, box_max_speed, box_max_ang_vel, true, true) 
  2856. 	end	 
  2857. 	 
  2858. 	-- Add Shaundi to the avoid object list 
  2859. 	debris_flow_add_avoid_object(debris_flow_table.handle, M02_groups.homies_skydive_01.shaundi) 
  2860. end 
  2861.  
  2862. function m02_cd_triggered_start_secondary_debris() 
  2863. 	m02_helper_disable_trigger(M02_triggers.stop_dive_debris) 
  2864. 	 
  2865. 	-- Reset all the movers in the 3rd flow 
  2866. 	for i, box in pairs(M02_debris_flows[3].boxes) do 
  2867. 		mesh_mover_reset(box) 
  2868. 	end 
  2869. 	for i, pallet in pairs(M02_debris_flows[3].pallets) do 
  2870. 		mesh_mover_reset(pallet) 
  2871. 	end 
  2872. 	 
  2873. 	debris_flow_set_active(M02_debris_flows[3].handle, M02_navpoints.debris_emitter_pos_01, 0.0, 15.0, 250.0, LOCAL_PLAYER, 1.0, true) 
  2874. end 
  2875.  
  2876. -- Function to create all of the global skydiving effects 
  2877. -- 
  2878. -- show_city:			TRUE to show the city texture, FALSE otherwise 
  2879. -- show_clouds:			TRUE to show the clouds above the city texture, FALSE otherwise 
  2880. -- show_player_vfx:		TRUE to show the VFX that attach to the players, false otherwise 
  2881. -- show_slow_clouds:	TRUE to show the slow clouds 
  2882. function m02_helper_create_global_effects(show_city, show_clouds, show_player_vfx, show_slow_clouds) 
  2883. 	-- Start the global wind effects 
  2884. 	if (M02_vfx.skydive_city.handle == -1) then 
  2885. 		if (show_city == true) then 
  2886. 			M02_vfx.skydive_city.handle = effect_play(M02_vfx.skydive_city.nav, true, SYNC_ALL) 
  2887. 		end 
  2888. 	else 
  2889. 		if (show_city == false) then 
  2890. 			effect_stop(M02_vfx.skydive_city.handle) 
  2891. 			M02_vfx.skydive_city.handle = -1 
  2892. 		end 
  2893. 	end 
  2894. 	if (M02_vfx.skydive_clouds_below.handle == -1) then 
  2895. 		if (show_clouds == true) then 
  2896. 			M02_vfx.skydive_clouds_below.handle = effect_play(M02_vfx.skydive_clouds_below.nav, true, SYNC_ALL) 
  2897. 		end 
  2898. 	else 
  2899. 		if (show_clouds == false) then 
  2900. 			effect_stop(M02_vfx.skydive_clouds_below.handle) 
  2901. 			M02_vfx.skydive_clouds_below.handle = -1 
  2902. 		end 
  2903. 	end 
  2904. 	 
  2905. 	-- Play debris effects on the players 
  2906. 	if (M02_vfx.skydive_player_clouds.handles[1] == -1) then 
  2907. 		if (show_player_vfx == true) then 
  2908. 			M02_vfx.skydive_player_clouds.handles[1] = effect_play_on_human(M02_vfx.skydive_player_clouds.nav, LOCAL_PLAYER, nil, true, SYNC_LOCAL) 
  2909. 		end 
  2910. 	else 
  2911. 		if (show_player_vfx == false) then 
  2912. 			effect_stop(M02_vfx.skydive_player_clouds.handles[1]) 
  2913. 			M02_vfx.skydive_player_clouds.handles[1] = -1 
  2914. 		end 
  2915. 	end 
  2916. 	if (coop_is_active() == true and M02_vfx.skydive_player_clouds.handles[2] == -1) then 
  2917. 		if (show_player_vfx == true) then 
  2918. 			M02_vfx.skydive_player_clouds.handles[2] = effect_play_on_human(M02_vfx.skydive_player_clouds.nav, REMOTE_PLAYER, nil, true, SYNC_REMOTE) 
  2919. 		end 
  2920. 	else 
  2921. 		if (show_player_vfx == false) then 
  2922. 			effect_stop(M02_vfx.skydive_player_clouds.handles[2]) 
  2923. 			M02_vfx.skydive_player_clouds.handles[2] = -1 
  2924. 		end 
  2925. 	end 
  2926. 	 
  2927. 	-- Play slow debris effects on the players 
  2928. 	if (M02_vfx.skydive_player_slow_clouds.handles[1] == -1) then 
  2929. 		if (show_slow_clouds == true) then 
  2930. 			M02_vfx.skydive_player_slow_clouds.handles[1] = effect_play_on_human(M02_vfx.skydive_player_slow_clouds.nav, LOCAL_PLAYER, nil, true, SYNC_LOCAL) 
  2931. 		end 
  2932. 	else 
  2933. 		if (show_slow_clouds == false) then 
  2934. 			effect_stop(M02_vfx.skydive_player_slow_clouds.handles[1]) 
  2935. 			M02_vfx.skydive_player_slow_clouds.handles[1] = -1 
  2936. 		end 
  2937. 	end 
  2938. 	if (coop_is_active() == true and M02_vfx.skydive_player_slow_clouds.handles[2] == -1) then 
  2939. 		if (show_slow_clouds == true) then 
  2940. 			M02_vfx.skydive_player_slow_clouds.handles[2] = effect_play_on_human(M02_vfx.skydive_player_slow_clouds.nav, REMOTE_PLAYER, nil, true, SYNC_REMOTE) 
  2941. 		end 
  2942. 	else 
  2943. 		if (show_slow_clouds == false) then 
  2944. 			effect_stop(M02_vfx.skydive_player_slow_clouds.handles[2]) 
  2945. 			M02_vfx.skydive_player_slow_clouds.handles[2] = -1 
  2946. 		end 
  2947. 	end 
  2948. 	 
  2949. 	-- Kickoff the thread to generate the random clouds 
  2950. 	if (M02_threads.cloud_generator == -1) then 
  2951. 		if (show_player_vfx == true) then 
  2952. 			M02_threads.cloud_generator = thread_new("m02_thread_generate_clouds") 
  2953. 		end 
  2954. 	else 
  2955. 		if (show_player_vfx == false) then 
  2956. 			thread_kill(M02_threads.cloud_generator) 
  2957. 			M02_threads.cloud_generator = -1 
  2958. 		end 
  2959. 	end 
  2960. end 
  2961.  
  2962. -- Function to destroy all of the global skydiving effects 
  2963. function m02_helper_destroy_global_effects() 
  2964. 	-- Stop the looping effects 
  2965. 	if (M02_vfx.skydive_city.handle ~= -1) then 
  2966. 		effect_stop(M02_vfx.skydive_city.handle) 
  2967. 		M02_vfx.skydive_city.handle = -1 
  2968. 	end 
  2969. 	if (M02_vfx.skydive_clouds_below.handle ~= -1) then 
  2970. 		effect_stop(M02_vfx.skydive_clouds_below.handle) 
  2971. 		M02_vfx.skydive_clouds_below.handle = -1 
  2972. 	end 
  2973. 	if (M02_vfx.skydive_cloud_puff.handle ~= -1) then 
  2974. 		effect_stop(M02_vfx.skydive_cloud_puff.handle) 
  2975. 		M02_vfx.skydive_cloud_puff.handle = -1 
  2976. 	end 
  2977. 	 
  2978. 	-- Stop debris effects on the players 
  2979. 	if (M02_vfx.skydive_player_clouds.handles[1] ~= -1) then 
  2980. 		effect_stop(M02_vfx.skydive_player_clouds.handles[1], SYNC_LOCAL) 
  2981. 	end 
  2982. 	if (coop_is_active() == true and M02_vfx.skydive_player_clouds.handles[2] ~= -1) then 
  2983. 		effect_stop(M02_vfx.skydive_player_clouds.handles[2], SYNC_REMOTE) 
  2984. 	end 
  2985. 	 
  2986. 	-- Stop the slow clouds 
  2987. 	if (M02_vfx.skydive_player_slow_clouds.handles[1] ~= -1) then 
  2988. 		effect_stop(M02_vfx.skydive_player_slow_clouds.handles[1], SYNC_LOCAL) 
  2989. 	end 
  2990. 	if (coop_is_active() == true and M02_vfx.skydive_player_slow_clouds.handles[2] ~= -1) then 
  2991. 		effect_stop(M02_vfx.skydive_player_slow_clouds.handles[2], SYNC_REMOTE) 
  2992. 	end	 
  2993. 	 
  2994. 	-- Kill the cloud generator thread 
  2995. 	if (M02_threads.cloud_generator ~= -1) then 
  2996. 		thread_kill(M02_threads.cloud_generator) 
  2997. 		M02_threads.cloud_generator = -1 
  2998. 	end 
  2999. end 
  3000.  
  3001. -- Helper to setup a group of enemy skydivers 
  3002. -- 
  3003. -- Group_table:		Lua table defining the group of enemy skydivers (see M02_groups::sky_goons_01 for formatting example) 
  3004. -- show_character:	TRUE if the character should be unhidden 
  3005. -- leash_dist:		(optional) Set the leash distance (defaults to 3.0) 
  3006. function m02_helper_set_sky_goon_group(Group_table, show_characters, leash_dist) 
  3007. 	if (leash_dist == nil) then 
  3008. 		leash_dist = 2.0 
  3009. 	end 
  3010.  
  3011. 	for i, char in pairs(Group_table.chars) do 
  3012. 		on_death("m02_cb_sky_goon_killed", char.name) 
  3013. 		M02_runtime.sky_goons_alive = M02_runtime.sky_goons_alive + 1 
  3014. 	 
  3015. 		character_set_skydiving(char.name, true) 
  3016. 		if (show_characters == true) then 
  3017. 			character_show(char.name) 
  3018. 		end 
  3019. 		 
  3020. 		-- Give them a parachute 
  3021. 		human_skydive_create_npc_backpack(char.name) 
  3022. 		 
  3023. 		set_max_hit_points(char.name, (get_current_hit_points(char.name) * M02_tweak_values.goon_hitpoint_modifier) ) 
  3024. 		ai_add_enemy_target(char.name, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true) 
  3025. 		 
  3026. 		-- Do we need to do a pathfind? 
  3027. 		if (char.dest_nav ~= nil) then 
  3028. 			npc_leash_to_nav(char.name, char.dest_nav, leash_dist) 
  3029. 			thread_new("m02_thread_process_sky_goon_move", char) 
  3030. 		end 
  3031. 		 
  3032. 		-- Do we add the marker now or later? 
  3033. 		if (char.delay_marker == false) then 
  3034. 			marker_add(char.name, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL) 
  3035. 		end 
  3036. 	end 
  3037. end 
  3038.  
  3039. -- Quick thread to process a single skydiving enemies pathfinding (so we can add a marker when it finished) 
  3040. -- 
  3041. -- char:	Human Lua table 
  3042. function m02_thread_process_sky_goon_move(char) 
  3043. 	if (char.streamers == true) then 
  3044. 		m02_helper_create_character_streamers(char.name, true, char.vfx_handles) 
  3045. 	end	 
  3046.  
  3047. 	-- Do the move to 
  3048. 	skydive_move_to_do(char.name, char.dest_nav, false, 0, true, char.forced_dive) 
  3049. 	while(skydive_move_to_check_done(char.name, char.dest_nav, false, 0) == false) do 
  3050. 		thread_yield() 
  3051. 	end 
  3052. 		 
  3053. 	if (char.show_marker == true) then 
  3054. 		if (character_is_dead(char.name) == false) then 
  3055. 			marker_add(char, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL) 
  3056. 		end 
  3057. 	end 
  3058. 	 
  3059. 	for i, vfx_handle in pairs(char.vfx_handles) do 
  3060. 		effect_stop(vfx_handle) 
  3061. 	end 
  3062. end 
  3063.  
  3064. -- Check if a particular conversation is done 
  3065. -- 
  3066. -- convo_table:		Conversation Lua table (see M02_conversations) 
  3067. function m02_helper_conversation_check_done(convo_table) 
  3068. 	if (convo_table.queued == false) then 
  3069. 		return true 
  3070. 	else 
  3071. 		return convo_table.ended 
  3072. 	end 
  3073. end 
  3074.  
  3075. -- Helper to play conversations, by adding them to the cue 
  3076. -- 
  3077. -- convo_table:		Conversation Lua table (see M02_conversations) 
  3078. -- priority:		Desired priority for the conversation 
  3079. -- delay:			Amonut of time to dalya after this conversation before playing the next conversation (in seconds) 
  3080. function m02_helper_conversation_play(convo_table, priority, delay) 
  3081. 	convo_table.queued = true 
  3082. 	convo_table.delay = delay 
  3083. 	 
  3084. 	if (priority == M02_CONVO_PLAY_LAST) then 
  3085. 		-- Insert this entry at the end of hte lsit 
  3086. 		M02_runtime.convo_queue.list[M02_runtime.convo_queue.size] = convo_table 
  3087. 		M02_runtime.convo_queue.size = M02_runtime.convo_queue.size + 1 
  3088. 	elseif (priority == M02_CONVO_PLAY_NEXT) then 
  3089. 		-- Shift the list to the right 
  3090. 		for i = M02_runtime.convo_queue.size - 1, 0, -1 do 
  3091. 			M02_runtime.convo_queue.list[i + 1] = M02_runtime.convo_queue.list[i] 
  3092. 		end 
  3093. 		M02_runtime.convo_queue.list[0] = convo_table 
  3094. 		M02_runtime.convo_queue.size = M02_runtime.convo_queue.size + 1 
  3095. 	elseif (priority == M02_CONVO_PLAY_IMMEDIATE) then 
  3096. 		-- Stop any actively playing conversations, and start this one immediatly 
  3097. 		m02_helper_conversation_cleanup_playing(true) 
  3098. 		M02_runtime.convo_queue.playing.thread_id = thread_new("m02_thread_play_convo", convo_table) 
  3099. 	end 
  3100. end 
  3101.  
  3102. -- Kill any active conversation, and clear out the conversation queue 
  3103. function m02_helper_conversation_kill_all() 
  3104. 	-- Stop any active conversation 
  3105. 	m02_helper_conversation_cleanup_playing(false) 
  3106. 	 
  3107. 	-- Clear out the queue 
  3108. 	for i = 0, M02_runtime.convo_queue.size - 1 do 
  3109. 		M02_runtime.convo_queue.list[i].ended = true 
  3110. 	end 
  3111. 	M02_runtime.convo_queue.size = 0 
  3112. end 
  3113.  
  3114. -- Cleanup any playing conversation 
  3115. function m02_helper_conversation_cleanup_playing(wait_for_end) 
  3116. 	-- Stop the thread processing a playing conversation 
  3117. 	if (M02_runtime.convo_queue.playing.thread_id ~= -1) then 
  3118. 		thread_kill(M02_runtime.convo_queue.playing.thread_id) 
  3119. 		M02_runtime.convo_queue.playing.thread_id = -1 
  3120. 	end 
  3121. 	 
  3122. 	-- Mark the playing conversation as ended 
  3123. 	if (M02_runtime.convo_queue.playing.convo_table ~= nil) then 
  3124. 		M02_runtime.convo_queue.playing.convo_table.ended = true 
  3125. 	end	 
  3126. 	 
  3127. 	-- Cleanup and conversation data for a playing conversation 
  3128. 	if (M02_runtime.convo_queue.playing.conv_handle ~= INVALID_CONVERSATION_HANDLE) then 
  3129. 		audio_conversation_end(M02_runtime.convo_queue.playing.conv_handle) 
  3130. 		if (wait_for_end == true) then 
  3131. 			audio_conversation_wait_for_end(M02_runtime.convo_queue.playing.conv_handle) 
  3132. 		end 
  3133. 		M02_runtime.convo_queue.playing.conv_handle = INVALID_CONVERSATION_HANDLE 
  3134. 	end 
  3135. end 
  3136.  
  3137. -- Thread to process playing a single converation 
  3138. function m02_thread_play_convo(convo_table) 
  3139. 	-- Add this conversatin to the playing conversation data 
  3140. 	M02_runtime.convo_queue.playing.convo_table = convo_table 
  3141. 	convo_table.started = true	-- it has now started 
  3142. 	 
  3143. 	-- Load the conversation data 
  3144. 	if (convo_table.load_direct == false) then 
  3145. 		M02_runtime.convo_queue.playing.conv_handle = audio_conversation_load(convo_table.name) 
  3146. 	else 
  3147. 		M02_runtime.convo_queue.playing.conv_handle = audio_conversation_load_direct(convo_table.name) 
  3148. 	end 
  3149. 	 
  3150. 	-- Play the conversation and wait for it to end 
  3151. 	audio_conversation_play(M02_runtime.convo_queue.playing.conv_handle) 
  3152. 	audio_conversation_wait_for_end(M02_runtime.convo_queue.playing.conv_handle) 
  3153. 	audio_conversation_end(M02_runtime.convo_queue.playing.conv_handle) 
  3154. 	 
  3155. 	convo_table.completed = true 
  3156.  
  3157. 	-- Delay the desired amount 
  3158. 	delay(convo_table.delay) 
  3159.  
  3160. 	-- Do some book-keeping 
  3161. 	M02_runtime.convo_queue.playing.conv_handle = INVALID_CONVERSATION_HANDLE 
  3162. 	convo_table.ended = true 
  3163. end 
  3164.  
  3165. -- Process the conversation queue (should be running the duration of the mission) 
  3166. function m02_thread_process_conversations() 
  3167. 	-- Loop forever 
  3168. 	while(true) do 
  3169. 		-- Wait until something is added to the queue 
  3170. 		while(M02_runtime.convo_queue.size == 0 or M02_runtime.convo_queue.playing.conv_handle ~= INVALID_CONVERSATION_HANDLE) do 
  3171. 			thread_yield() 
  3172. 		end 
  3173. 		 
  3174. 		-- Play the first conversation from the queue, and then remove it from the qeue 
  3175. 		M02_runtime.convo_queue.playing.thread_id = thread_new("m02_thread_play_convo", M02_runtime.convo_queue.list[0]) 
  3176. 		for i = 1, M02_runtime.convo_queue.size do 
  3177. 			M02_runtime.convo_queue.list[i - 1] = M02_runtime.convo_queue.list[i] 
  3178. 		end 
  3179. 		M02_runtime.convo_queue.size = M02_runtime.convo_queue.size - 1 
  3180. 		 
  3181. 		-- Wait for the active conversation thread to end 
  3182. 		while(thread_check_done(M02_runtime.convo_queue.playing.thread_id) == false) do 
  3183. 			thread_yield() 
  3184. 		end 
  3185. 	end 
  3186. end 
  3187.  
  3188. -- Helper to check if a human is ready to play a custom animation 
  3189. --  
  3190. -- char_name:	Name of the characer 
  3191. -- 
  3192. -- returns:		TRUE if the character is ready to play an animation, FALSE otherwise	 
  3193. function m02_helper_human_can_play_anim(char_name) 
  3194. 	-- Check if they're ready (checks that they aren't dead, ragdolled 
  3195. 	if (character_is_ready(char_name) == false) then 
  3196. 		return false 
  3197. 	end 
  3198. 	if (character_playing_combat_move(char_name) == true) then 
  3199. 		return false 
  3200. 	end 
  3201. 	if (character_is_jumping(char_name) == true) then 
  3202. 		return false 
  3203. 	end 
  3204. 	 
  3205. 	return true 
  3206. end 
  3207.  
  3208. -- Wait until both players are not playing a synced animation 
  3209. function m02_helper_turbulance_wait_for_anims() 
  3210. 	-- Wait until none of the player's are playing a combat mobe 
  3211. 	local playing_anim = true 
  3212. 	local add_small_delay = false 
  3213. 	while(playing_anim == true) do 
  3214. 		playing_anim = false 
  3215. 		if (m02_helper_human_can_play_anim(LOCAL_PLAYER) == false) then 
  3216. 			playing_anim = true 
  3217. 			add_small_delay = true 
  3218. 		elseif(coop_is_active() == true and (m02_helper_human_can_play_anim(REMOTE_PLAYER) == false)) then 
  3219. 			playing_anim = true 
  3220. 			add_small_delay = true 
  3221. 		end 
  3222. 		 
  3223. 		if (playing_anim == false and add_small_delay == true) then 
  3224. 			delay(0.7) 
  3225. 			playing_anim = true 
  3226. 			add_small_delay = false 
  3227. 		end 
  3228. 		 
  3229. 		thread_yield() 
  3230. 	end 
  3231. end 
  3232.  
  3233. -- Helper for common turbulance stuff 
  3234. function m02_helper_turbulance_do_common() 
  3235. 	-- Hide the HUD 
  3236. 	m02_helper_hide_hud(true) 
  3237. 	 
  3238. 	-- Trigger the turbulance VFX 
  3239. 	local idx = rand_int(1, #(M02_vfx.cargo_dust.navs)) 
  3240. 	for i, nav in pairs(M02_vfx.cargo_dust.navs) do 
  3241. 		effect_play(M02_vfx.cargo_dust.navs[idx]) 
  3242. 		delay(0.07) 
  3243.  
  3244. 		idx = idx + 1 
  3245. 		if (idx > #(M02_vfx.cargo_dust.navs)) then 
  3246. 			idx = 1 
  3247. 		end 
  3248. 	end 
  3249. 	 
  3250. 	-- Increase the wind 
  3251. 	wind_override_set(0.0, 1.0, 0.0, 1.0) 
  3252.  
  3253. 	-- Wait until the stumble has finished 
  3254. 	while(action_play_is_finished(LOCAL_PLAYER) == false) do 
  3255. 		thread_yield() 
  3256. 	end 
  3257. 	delay(0.1) 
  3258. 	 
  3259. 	-- Back to normal 
  3260. 	wind_override_set(0.0, 1.0, 0.0, 0.075) 
  3261. 	m02_helper_hide_hud(false) 
  3262. end 
  3263.  
  3264. -- Search for a debris vehicle Lua table, by vehicle name 
  3265. function m02_helper_find_debris_vehicle(vehicle_name) 
  3266. 	-- Find this vehicle in the debris vehicle lists 
  3267. 	for i, vehicle in pairs(M02_groups.debris_vehicles.vehicles) do 
  3268. 		if (vehicle.name == vehicle_name) then 
  3269. 			-- We found the vehicle 
  3270. 			return vehicle 
  3271. 		end 
  3272. 	end 
  3273. 	for i, vehicle in pairs(M02_groups.debris_vehicles_dive_01.vehicles) do 
  3274. 		if (vehicle.name == vehicle_name) then 
  3275. 			-- We found the vehicle 
  3276. 			return vehicle 
  3277. 		end 
  3278. 	end 
  3279. 	for i, vehicle in pairs(M02_groups.debris_vehicles_dive_02.vehicles) do 
  3280. 		if (vehicle.name == vehicle_name) then 
  3281. 			-- We found the vehicle 
  3282. 			return vehicle 
  3283. 		end 
  3284. 	end 
  3285. 	 
  3286. 	return nil 
  3287. end 
  3288.  
  3289. -- Helper to clean-up a debris vehicle 
  3290. -- 
  3291. -- vehicle_table:	Lua table defining the vehicle 
  3292. function m02_helper_cleanup_debris_vehicle(vehicle_table) 
  3293. 	-- Clean-up any audio events 
  3294. 	if (vehicle_table.whoosh_event ~= INVALID_MESSAGE_HANDLE) then 
  3295. 		audio_stop(vehicle_table.whoosh_event) 
  3296. 		vehicle_table.whoosh_event = INVALID_MESSAGE_HANDLE 
  3297. 	end 
  3298. 	 
  3299. 	-- Clean up any fire effects 
  3300. 	if (vehicle_table.fire_handle ~= -1) then 
  3301. 		effect_stop(vehicle_table.fire_handle) 
  3302. 		vehicle_table.fire_handle = -1 
  3303. 	end 
  3304. 	 
  3305. 	-- Clean up any explosion VFX 
  3306. 	if (vehicle_table.exp_handle ~= -1) then 
  3307. 		effect_stop(vehicle_table.exp_handle) 
  3308. 		vehicle_table.exp_handle = -1 
  3309. 	end 
  3310. 	 
  3311. 	-- Un-register any callbacks 
  3312. 	on_vehicle_destroyed("", vehicle_table.name) 
  3313. 	on_damage("", vehicle_table.name) 
  3314. 	on_vehicle_debris_flow_recycled("", vehicle_table.name) 
  3315. end 
  3316.  
  3317. -- Create some streamers 
  3318. -- 
  3319. -- character_name:	Name of the character 
  3320. function m02_helper_create_character_streamers(character_name, looping, vfx_handles) 
  3321. 	for i, attach_point in pairs (M02_vfx.skydive_player_streamers.attach_points) do 
  3322. 		local handle = effect_play_on_human(M02_vfx.skydive_player_streamers.nav, character_name, attach_point, looping, SYNC_LOCAL) 
  3323. 		if (vfx_handles ~= nil) then 
  3324. 			vfx_handles[i] = handle 
  3325. 		end 
  3326. 	end 
  3327. end 
  3328.  
  3329. -- Hide debris 
  3330. function m02_helper_hide_debris() 
  3331. 	--[[ 
  3332. 	-- Hide all the debris objects 
  3333. 	for i, box in pairs(M02_movers.debris_box_list) do 
  3334. 		mesh_mover_hide(box) 
  3335. 	end 
  3336. 	for i, pallet in pairs(M02_movers.debris_pallet_list) do 
  3337. 		mesh_mover_hide(pallet) 
  3338. 	end 
  3339. 	--]] 
  3340. 	for i, box in pairs(M02_movers.debris_dive_boxes) do 
  3341. 		mesh_mover_hide(box) 
  3342. 	end	 
  3343. 	for i, pallet in pairs(M02_movers.debris_dive_pallets) do 
  3344. 		mesh_mover_hide(pallet) 
  3345. 	end 
  3346. 	for i, box in pairs(M02_movers.debris_dive_boxes_02) do 
  3347. 		mesh_mover_hide(box) 
  3348. 	end 
  3349. 	for i, pallet in pairs(M02_movers.debris_dive_pallets_02) do 
  3350. 		mesh_mover_hide(pallet) 
  3351. 	end 
  3352.  
  3353. end 
  3354.  
  3355. -- ************************* 
  3356. -- 
  3357. -- Callback functions 
  3358. -- 
  3359. -- ************************* 
  3360.  
  3361. -- Callback for when Shaundi is killed 
  3362. function m02_cb_failure_shaundi_died() 
  3363. 	mission_end_failure("m02", M02_strings.failure_shaundi_died) 
  3364. end 
  3365.  
  3366. --[[ 
  3367. -- Callback when the player is damaged, to show the melee "block" tutorial 
  3368. function m02_cb_show_block_tutorial(player) 
  3369. 	message(M02_strings.help_melee_block, 5.0) 
  3370. 	 
  3371. 	on_take_damage("", LOCAL_PLAYER) 
  3372. 	if (coop_is_active()) then 
  3373. 		on_take_damage("", REMOTE_PLAYER) 
  3374. 	end 
  3375. end 
  3376. --]] 
  3377.  
  3378. --[[ 
  3379. -- Callback when the player damages an enemey, to show the melee "charged attack" tutorial 
  3380. function m02_cb_show_charged_attack_tutorial(enemy) 
  3381. 	message(M02_strings.help_melee_charged_attack) 
  3382. 	 
  3383. 	-- Remove the on damage callback from each of the enemies 
  3384. 	for i, char in pairs(M02_groups.cargo_plane_goons_01.chars) do 
  3385. 		on_damage("", char, 0.0) 
  3386. 	end 
  3387. end 
  3388. --]] 
  3389.  
  3390. --[[ 
  3391. -- Callback when a vehicle in the cargo plane gets damaged 
  3392. function m02_cb_cargo_vehicle_damaged(vehicle) 
  3393. 	local alarm_chance = rand_int(1, 10) 
  3394. 	if (alarm_chance <= 2) then 
  3395. 	end 
  3396. end 
  3397. --]] 
  3398.  
  3399. -- Callback when an enemy on the plane detects the player 
  3400. function m02_cb_plane_goon_detected_player(detector, player) 
  3401. 	-- Remove their leash 
  3402. 	npc_leash_remove(detector) 
  3403. 	 
  3404. 	-- Clear any callbacks 
  3405. 	on_detection("", detector) 
  3406. 	on_take_damage("", detector) 
  3407. end 
  3408.  
  3409. -- Callback when an enemy on the plane is damaged 
  3410. function m02_cb_plane_goon_damaged(victim) 
  3411. 	-- Remove their leash 
  3412. 	npc_leash_remove(victim) 
  3413. 	 
  3414. 	-- Clear any callbacks 
  3415. 	on_detection("", victim) 
  3416. 	on_take_damage("", victim) 
  3417. end 
  3418.  
  3419. -- Trigger for when the player enteres the parachtute location 
  3420. function m02_cb_triggered_grab_parachute(player_name, trigger_name) 
  3421. 	if(trigger_name == M02_triggers.cargo_plane_parachute_01) then 
  3422. 		--m02_helper_disable_trigger(trigger_name) 
  3423. 		M02_flags.reached_parachutes = true 
  3424. 	end 
  3425. end 
  3426.  
  3427. -- Callback for when the local gun grapple QTE has finished (QTE1) 
  3428. function m02_cb_local_gun_grapple_finished() 
  3429. 	-- Unequip the enemy 
  3430. 	--inv_item_remove_all(M02_groups.sky_goons_01.grapple_enemy) 
  3431. 	 
  3432. 	-- Lock the player into the inverted skydiving state 
  3433. 	character_set_skydiving_state(LOCAL_PLAYER, 3, true, M02_groups.sky_goons_01.grapple_enemy, true) 
  3434.  
  3435. 	character_set_skydiving(M02_groups.sky_goons_01.grapple_enemy, true) 
  3436. 	character_prevent_flinching(M02_groups.sky_goons_01.grapple_enemy, true) 
  3437. 	character_allow_ragdoll(M02_groups.sky_goons_01.grapple_enemy, false) 
  3438. 	 
  3439. 	M02_flags.local_gun_grapple_finished = true 
  3440. 	 
  3441. 		-- Give the player the SMG, equip it, and disable all other inventory slots 
  3442. 	inv_weapon_remove_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg) 
  3443. 	inv_weapon_add_temporary(LOCAL_PLAYER, M02_tweak_values.skydiving_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  3444. 	inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SMG, false, SYNC_LOCAL) 
  3445.  
  3446. end 
  3447.  
  3448. -- Callback for when the remote gun grapple QTE has finished (QTE2) 
  3449. function m02_cb_remote_gun_grapple_finished() 
  3450. 	-- Unequip the enemy 
  3451. 	--inv_item_remove_all(M02_groups.sky_goons_01_a.grapple_enemy) 
  3452. 	 
  3453. 	-- Lock the player into the inverted skydiving state 
  3454. 	character_set_skydiving_state(REMOTE_PLAYER, 3, true, M02_groups.sky_goons_01_a.grapple_enemy, true) 
  3455.  
  3456. 	character_set_skydiving(M02_groups.sky_goons_01_a.grapple_enemy, true) 
  3457. 	character_prevent_flinching(M02_groups.sky_goons_01_a.grapple_enemy, true) 
  3458. 	character_allow_ragdoll(M02_groups.sky_goons_01_a.grapple_enemy, false) 
  3459. 	 
  3460. 	M02_flags.remote_gun_grapple_finished = true 
  3461. 	 
  3462. 		-- Give the player the SMG, equip it, and disable all other inventory slots 
  3463. 	inv_weapon_remove_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg) 
  3464. 	inv_weapon_add_temporary(REMOTE_PLAYER, M02_tweak_values.skydiving_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  3465. 	inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SMG, false, SYNC_REMOTE) 
  3466.  
  3467. end 
  3468.  
  3469. --[[ 
  3470. -- Callback for when the cargo plane has entered the ramming destination trigger 
  3471. function m02_cb_cargo_plane_at_ram_dest_01(character_name, trigger_name) 
  3472. 	if(trigger_name == M02_triggers.cargo_plane_ram_trigger_01) then 
  3473. 		if (character_name == M02_groups.plane.chars[1]) then 
  3474. 			m02_helper_disable_trigger(trigger_name) 
  3475. 			 
  3476. 			M02_flags.cargo_plane_reached_ram_dest_01 = true 
  3477. 		end 
  3478. 	end 
  3479. end 
  3480.  
  3481. -- Callback for when the cargo plane has entered the ramming destination trigger 
  3482. function m02_cb_cargo_plane_at_ram_dest_02(character_name, trigger_name) 
  3483. 	if(trigger_name == M02_triggers.cargo_plane_ram_trigger_02) then 
  3484. 		if (character_name == M02_groups.plane.chars[1]) then 
  3485. 			m02_helper_disable_trigger(trigger_name) 
  3486. 			 
  3487. 			M02_flags.cargo_plane_reached_ram_dest_02 = true 
  3488. 		end 
  3489. 	end 
  3490. end 
  3491. --]] 
  3492.  
  3493. -- Callback for when a player is damage while diving to catch Shaundi 
  3494. function m02_player_damaged_while_diving_cb(player_name, attacker, damage_amt, from_exp) 
  3495. 	-- If this isn't from an explosion, then play the collision animation on the player (since this must have been from hitting debris) 
  3496. 	if (from_exp == false) then 
  3497. 		delay(0.1) 
  3498. 		if (action_play_is_finished(player_name)) then 
  3499. 			audio_object_post_event("object_impact", "object_type", "generic_medium_wood", player_name)	 
  3500. 			 
  3501. 			audio_play_persona_line(player_name, "voc_pain") 
  3502. 			action_play(player_name, "FreeFall Collision") 
  3503. 		end 
  3504. 	end 
  3505. end 
  3506.  
  3507. -- Callback for when the player reaches the trigger at the end of the first dive to Shaundi (he has caught Shaundi) 
  3508. function m02_cb_triggered_final_dive_01(player_name, trigger_name) 
  3509. 	-- Remove the trigger callback 
  3510. 	on_trigger("", M02_triggers.final_dive_01) 
  3511.  
  3512. 	-- Keep track of who triggered the Shaundi catch sequence 
  3513. 	M02_runtime.shaundi_caught_by = player_name 
  3514. 	M02_runtime.shaundi_other_player = LOCAL_PLAYER 
  3515. 	if (player_name == LOCAL_PLAYER) then 
  3516. 		M02_runtime.shaundi_other_player = REMOTE_PLAYER 
  3517. 	end 
  3518.  
  3519. 	M02_flags.triggered_final_dive_01 = true 
  3520. end 
  3521.  
  3522. -- Callback for when an enemy in Group 02 or Group 03 is killed 
  3523. function m02_cb_sky_goon_killed(enemy) 
  3524. 	marker_remove(enemy) 
  3525. 	on_death("",enemy) 
  3526.  
  3527. 	M02_runtime.sky_goons_alive = M02_runtime.sky_goons_alive - 1 
  3528. end 
  3529.  
  3530. -- Callback when the local player finishes the last grapple QTE (QTE3) 
  3531. function m02_cb_local_final_grapple_finished() 
  3532. 	-- Lock the player into the diving state again 
  3533. 	character_set_skydiving_state(LOCAL_PLAYER, 1, true, nil, true) 
  3534. 	character_kill(M02_groups.sky_goons_07.grapple_enemy) 
  3535. 	 
  3536. 	M02_flags.local_final_grapple_finished = true 
  3537. end 
  3538.  
  3539. -- Callback when the remote player finishes the last grapple QTE (QTE3) 
  3540. function m02_cb_remote_final_grapple_finished() 
  3541. 	-- Lock the player into the diving state again 
  3542. 	character_set_skydiving_state(REMOTE_PLAYER, 1, true, nil, true) 
  3543. 	character_kill(M02_groups.sky_goons_07_A.grapple_enemy) 
  3544. 	 
  3545. 	M02_flags.remote_final_grapple_finished = true 
  3546. end 
  3547.  
  3548. -- Callback when one of the debris vehicles gets damaged 
  3549. -- 
  3550. -- vehicle_name:	Name of the vehicle that was damaged 
  3551. function m02_cb_debris_vehicle_damaged(vehicle_name) 
  3552. 	-- Remove the on_damage callback 
  3553. 	on_damage("", vehicle_name) 
  3554. 	 
  3555. 	-- Find the vehicle, and turn it on fire 
  3556. 	local vehicle_table = m02_helper_find_debris_vehicle(vehicle_name) 
  3557. 	if (vehicle_table ~= nil) then 
  3558. 		if (vehicle_table.fire_handle == -1) then 
  3559. 			-- We found the vehicle, spawn some fire on it 
  3560. 			vehicle_table.fire_handle = effect_play_on_script_object(M02_vfx.debris_fire.name, vehicle_table.name, nil, true) 
  3561. 		end		 
  3562. 	end 
  3563. end 
  3564.  
  3565. -- Callback when one of the debris vehicles gets destroyed 
  3566. -- 
  3567. -- vehicle_name:	Name of the vehicle that was destroyed 
  3568. function m02_cb_debris_vehicle_destroyed(vehicle_name) 
  3569. 	-- Remove the callback and trigger an explosion 
  3570. 	on_vehicle_destroyed("", vehicle_name) 
  3571. 	 
  3572. 	-- Find the vehicle and turn it on fire 
  3573. 	local vehicle_table = m02_helper_find_debris_vehicle(vehicle_name) 
  3574. 	if (vehicle_table ~= nil) then 
  3575. 		if (vehicle_table.fire_handle == -1) then 
  3576. 			-- We found the vehicle, spawn some fire on it 
  3577. 			vehicle_table.fire_handle = effect_play_on_script_object(M02_vfx.debris_fire.name, vehicle_table.name, nil, true) 
  3578. 		end 
  3579. 		 
  3580. 		vehicle_table.exp_handle = explosion_create("Mission02 Car Exp", vehicle_table.name, nil, true, "vfx_car_explosion 001") 
  3581. 	end 
  3582. end 
  3583.  
  3584. -- Callback when one of the debris vehicles gets recycled by the debris flow 
  3585. -- 
  3586. -- vehicle_name:	Name of the vehicle that was recycled 
  3587. function m02_cb_debris_vehicle_recycled(vehicle_name) 
  3588. 	local vehicle_table = m02_helper_find_debris_vehicle(vehicle_name) 
  3589. 	if (vehicle_table ~= nil) then 
  3590. 		-- We found the vehicle, stop any fire effect and setup the vehicle again 
  3591. 		if (vehicle_table.fire_handle ~= -1) then 
  3592. 			effect_stop(vehicle_table.fire_handle) 
  3593. 			vehicle_table.fire_handle = -1 
  3594. 		end 
  3595. 		if (vehicle_table.exp_handle ~= -1) then 
  3596. 			effect_stop(vehicle_table.exp_handle) 
  3597. 			vehicle_table.exp_handle = -1 
  3598. 		end 
  3599. 		 
  3600. 		-- Turn of damage VFX and re-register for vehicle damaged and destroyed callbacks 
  3601. 		vehicle_disable_explosion_and_damage_vfx(vehicle_table.name, true) 
  3602. 		on_damage("m02_cb_debris_vehicle_damaged", vehicle_table.name, 0.2) 
  3603. 		on_vehicle_destroyed("m02_cb_debris_vehicle_destroyed", vehicle_table.name) 
  3604. 	end 
  3605. end 
  3606.  
  3607. -- Callback when a vehicle with a forced car alarm get's damaged 
  3608. function m02_cb_trigger_car_alarm(vehicle_name) 
  3609. 	on_damage("", vehicle_name) 
  3610. 	turn_invulnerable(M02_groups.cargo_vehicles.car_alarm_vehicle) 
  3611. 	audio_object_post_event("Vehicle_Alarm", "Vehicle_Model", "car_4dr_luxery06", vehicle_name) 
  3612. end 
  3613.  
  3614. -- ************************* 
  3615. -- 
  3616. -- Thread functions 
  3617. -- 
  3618. -- ************************* 
  3619.  
  3620. -- Function to process shaundi's nags to the player to get moving 
  3621. -- 
  3622. -- initial_delay:		Amount of time (in seconds) to delay before first nagging the player 
  3623. -- repeat_delay:		Amount fo time (in seconds) to delay between nags 
  3624. function m02_thread_process_shaundi_nag(initial_delay, repeat_delay) 
  3625. 	delay(initial_delay) 
  3626. 	 
  3627. 	-- Loop forever until the thread gets killed 
  3628. 	while(true) do 
  3629. 		audio_play_persona_line(M02_groups.homies_01.shaundi, M02_dialog_lines.shaundi_nags[M02_runtime.shaundi_nag_idx]) 
  3630. 		 
  3631. 		M02_runtime.shaundi_nag_idx = M02_runtime.shaundi_nag_idx + 1 
  3632. 		if (M02_runtime.shaundi_nag_idx > #(M02_dialog_lines.shaundi_nags)) then 
  3633. 			M02_runtime.shaundi_nag_idx = 1 
  3634. 		end 
  3635. 		 
  3636. 		delay(repeat_delay) 
  3637. 		thread_yield() 
  3638. 	end 
  3639. end 
  3640.  
  3641. -- Thread to process the circling path of the cargo plane, while it waits to ram the player 
  3642. function m02_thread_process_cargo_plane_circling() 
  3643. 	vehicle_set_special_override_never_ghost(M02_groups.plane.vehicle, true) 
  3644. 	turn_invulnerable(M02_groups.plane.vehicle) 
  3645. 	vehicle_enter_teleport(M02_groups.plane.chars[1], M02_groups.plane.vehicle, 0, true) 
  3646. 	 
  3647. 	helicopter_set_max_bank_angle(M02_groups.plane.vehicle, 15.0) 
  3648. 	while (true) do 
  3649. 		helicopter_fly_to_do(M02_groups.plane.vehicle, 120.0, true, "", true, M02_groups.plane.circling_path) 
  3650.  
  3651. 		-- Wait until the engine has started, so we can override the spin up value on the rotors 
  3652. 		while (vehicle_engine_check_running(M02_groups.plane.vehicle) == false) do 
  3653. 			thread_yield() 
  3654. 		end 
  3655. 		vehicle_engine_start(M02_groups.plane.vehicle, false) 
  3656.  
  3657. 		while (vehicle_pathfind_check_done(M02_groups.plane.vehicle) == 0) do 
  3658. 			thread_yield() 
  3659. 		end 
  3660. 		thread_yield() 
  3661. 	end 
  3662. end 
  3663.  
  3664. -- Thread to process randomly generated cloud VFX 
  3665. function m02_thread_generate_clouds() 
  3666. 	-- loop forever 
  3667. 	while(true) do 
  3668. 		delay(rand_int(M02_tweak_values.skydive_cloud_min_cooldown_time, M02_tweak_values.skydive_cloud_max_cooldown_time)) 
  3669. 		 
  3670. 		-- Make sure we clean up the old effect first 
  3671. 		if (M02_vfx.skydive_cloud_puff.handle ~= -1) then 
  3672. 			effect_stop(M02_vfx.skydive_cloud_puff.handle) 
  3673. 			thread_yield() 
  3674. 		end 
  3675. 		 
  3676. 		-- Play the cloud "puff" effect 
  3677. 		M02_vfx.skydive_cloud_puff.handle = effect_play_on_human(M02_vfx.skydive_cloud_puff.nav, LOCAL_PLAYER, nil, false) 
  3678. 		 
  3679. 		delay(1) 
  3680. 		if (M02_runtime.stop_streamers == false) then 
  3681. 			m02_helper_create_character_streamers(LOCAL_PLAYER, false) 
  3682. 		end 
  3683. 	end 
  3684. end 
  3685.  
  3686. function m02_helper_do_vehicle_group_whooses(vehicle_group_table) 
  3687. 	-- Loop over all the vehicles, and update their whooshes 
  3688. 	for i, vehicle in pairs(vehicle_group_table.vehicles) do 
  3689. 		if (vehicle_hidden(vehicle.name) == false) then 
  3690. 			local dist = get_dist(vehicle.name, LOCAL_PLAYER) 
  3691. 			if (vehicle.whoosh_event == INVALID_MESSAGE_HANDLE) then 
  3692. 				-- Check if we should turn on the whoosh 
  3693. 				if (dist < M02_tweak_values.car_whoosh_start_dist) then 
  3694. 					vehicle.whoosh_event = audio_object_post_event("Mission", M02_audio_events.car_whoosh.switch_groups, M02_audio_events.car_whoosh.switches, vehicle.name) 
  3695. 				end 
  3696. 			else 
  3697. 				-- Check if we should stop the whoosh 
  3698. 				if (dist > M02_tweak_values.car_whoosh_end_dist) then 
  3699. 					audio_stop(vehicle.whoosh_event) 
  3700. 					vehicle.whoosh_event = INVALID_MESSAGE_HANDLE 
  3701. 				end 
  3702. 			end 
  3703. 		end 
  3704. 	end 
  3705. end 
  3706.  
  3707. -- Thread to process the dynamic whoosh audio for nearby objects while skydiving 
  3708. function m02_thread_process_skydive_object_whoosh() 
  3709. 	-- Loop forever 
  3710. 	while(true) do 
  3711. 		m02_helper_do_vehicle_group_whooses(M02_groups.debris_vehicles) 
  3712. 		if (group_is_loaded(M02_groups.debris_vehicles_dive_01.name) == true) then 
  3713. 			m02_helper_do_vehicle_group_whooses(M02_groups.debris_vehicles_dive_01) 
  3714. 		end 
  3715. 		if (group_is_loaded(M02_groups.debris_vehicles_dive_02.name) == true) then 
  3716. 			m02_helper_do_vehicle_group_whooses(M02_groups.debris_vehicles_dive_02) 
  3717. 		end 
  3718. 		 
  3719. 		thread_yield() 
  3720. 	end 
  3721. end 
  3722.  
  3723. -- Thread to process player stumble animations (we can't just call the non-blocking version since some cleanup for the player happens in the complete check) 
  3724. -- 
  3725. -- player: 			Player to play the stumble animation for 
  3726. -- stumble_dir:		Navpoint indicating the direction to stumble 
  3727. -- use_directional:	TRUE if the player should play the direction stumble 
  3728. function m02_thread_do_play_stumble_animation(player, stumble_dir, use_directional) 
  3729. 	if (character_has_human_shield(player) == true) then 
  3730. 		return 
  3731. 	end 
  3732. 	 
  3733. 	character_clear_combat_move(player) 
  3734. 	if (use_directional == true and inv_item_get_equipped_item(player) == M02_tweak_values.skydiving_pistol) then 
  3735. 		action_play_directional_stumble(player, stumble_dir) 
  3736. 	else 
  3737. 		action_play(player, "Plane Cabin Stumble") 
  3738. 	end 
  3739. end 
  3740.  
  3741. -- Process the cargo plane retreat path 
  3742. function m02_thread_process_cargo_plane_retreat() 
  3743. 	-- Fly to the end of the path, then destroy the cargo plane group 
  3744. 	if (helicopter_fly_to_do(M02_groups.plane.vehicle, 150.0, true, "", true, M02_navpoints.cargo_plane_fly_away_end, 0.0, false, false, true)) then 
  3745. 		-- Wait until the engine has started, so we can override the spin up value on the rotors 
  3746. 		while (vehicle_engine_check_running(M02_groups.plane.vehicle) == false) do 
  3747. 			thread_yield() 
  3748. 		end 
  3749. 		vehicle_engine_start(M02_groups.plane.vehicle, false) 
  3750. 	 
  3751. 		vehicle_pathfind_check_done(M02_groups.plane.vehicle) 
  3752. 		while (vehicle_pathfind_check_done(M02_groups.plane.vehicle)) do 
  3753. 			thread_yield() 
  3754. 		end 
  3755. 	end 
  3756. 	group_destroy(M02_groups.plane.name) 
  3757. end 
  3758.  
  3759. -- Process when to transition the music for the Shaundi catch 
  3760. -- 
  3761. -- event_name:	Name of the audio event to play 
  3762. -- time_unti: The time until the player cataches Shaundi when the music transition should be triggered 
  3763. function m02_thread_process_catch_shaundi_music(event_name, time_until) 
  3764. 	while(true) do 
  3765. 		-- Wait until the player is 5.34s away from catching Shaundi 
  3766. 		local current_dist = get_dist(LOCAL_PLAYER, M02_groups.homies_skydive_01.shaundi) 
  3767. 		if ((current_dist / M02_tweak_values.player_downward_dive_speed) <= time_until) then 
  3768. 			audio_object_post_event(event_name, nil, nil, LOCAL_PLAYER) 
  3769. 			return 
  3770. 		end 
  3771. 		 
  3772. 		thread_yield() 
  3773. 	end 
  3774. end 
  3775. 	 
  3776. -- Thread to clear the area around Shaundi from debris 
  3777. -- 
  3778. function m02_thread_cleanup_area_around_shaundi() 
  3779. 	while(true) do 
  3780. 		for i, debris_flow in pairs(M02_debris_flows) do 
  3781. 			-- Handle all the debris dive debris 
  3782. 			if (group_is_loaded(debris_flow.vehicle_group.name) == true) then 
  3783. 				for i, vehicle in pairs(debris_flow.vehicle_group.vehicles) do 
  3784. 					if (object_is_in_trigger(M02_triggers.clean_up_debris_above_shaundi, vehicle.name) == true) then 
  3785. 						debris_flow_recycle_object(debris_flow.handle, vehicle.name) 
  3786. 					end 
  3787. 				end 
  3788. 			end 
  3789. 			 
  3790. 			for i, box in pairs(debris_flow.boxes) do 
  3791. 				if (object_is_in_trigger(M02_triggers.clean_up_debris_above_shaundi, box) == true) then 
  3792. 					debris_flow_recycle_object(debris_flow.handle, box) 
  3793. 				end 
  3794. 			end	 
  3795. 			for i, pallet in pairs(debris_flow.pallets) do 
  3796. 				if (object_is_in_trigger(M02_triggers.clean_up_debris_above_shaundi, pallet) == true) then 
  3797. 					debris_flow_recycle_object(debris_flow.handle, pallet) 
  3798. 				end 
  3799. 			end 
  3800. 		end 
  3801.  
  3802. 		thread_yield() 
  3803. 	end 
  3804. end	 
  3805.  
  3806. -- Thread to kill any players that end up below Shaundi (last ditch fail safe) 
  3807. -- 
  3808. function m02_thread_kill_players_that_fall_too_far() 
  3809. 	while(true) do 
  3810. 		local x, y, z = get_object_pos(LOCAL_PLAYER) 
  3811. 		if (y < 915.0) then 
  3812. 			character_kill(LOCAL_PLAYER, true) 
  3813. 		end 
  3814. 		 
  3815. 		if (coop_is_active() == true) then 
  3816. 			x, y, z = get_object_pos(REMOTE_PLAYER) 
  3817. 			if (y < 915.0) then 
  3818. 				character_kill(REMOTE_PLAYER, true) 
  3819. 			end 
  3820. 		end 
  3821. 	 
  3822. 		thread_yield() 
  3823. 	end 
  3824. end 
  3825.