./m18.lua

  1.  
  2. --[[ 
  3. 	m18.lua 
  4. 	SR3 Mission Script 
  5. 	DATE: 08/12/10 
  6. 	AUTHOR:	Matt.Gawalek 
  7. ]]-- 
  8.  
  9.  
  10. -- Debug flags -- 
  11.  
  12. -- Tweakable Parameters -- 
  13. 	M18_tweak_values = { 
  14. 		ambient_plane_camera_shake = "cargo_plane_interior", 
  15. 		ambient_plane_camera_shake_intensity = 0.5, 
  16. 	 
  17. 		escape_time_limit = 60000,	-- miliseconds 
  18. 		escape_initial_cam_shake_amount = 1.5, 
  19. 		escape_looping_cam_shake_amount = 0.2, 
  20. 		escape_drunk_amount = 0.8, 
  21. 		escape_high_amount = 0.0, 
  22. 		escape_box_impulse_delay = { 0.1, 0.3 }, 
  23. 		escape_box_impulse_amount = { 5, 75 }, 
  24. 		skydive_looping_cam_shake_amount = 1.0, 
  25. 		skydive_collision_cam_shake_amount = 1.6, 
  26. 		 
  27. 		enemy_tank_threat_level = 3,	-- how many skydiving guys a tank is equivalent to when determining when to spawn reinforcements 
  28. 		 
  29. 		-- Values to control when tank health warnings occur 
  30. 		debris_flow_min_speed_mult = 0.4, 
  31. 		debris_flow_time_to_max_speed = 5.0,	-- how long it takes for the debris flow to go full speed 
  32. 		 
  33. 		tank_streamers_tags = { "wingtip_vortex", "headlight_glare" }, 
  34. 		 
  35. 		-- Values to control how often random clouds appear 
  36. 		skydive_cloud_min_cooldown_time = 15.0, 
  37. 		skydive_cloud_max_cooldown_time = 25.0, 
  38. 		 
  39. 		-- Values to control the tank bail out and stealing the skydiving enemy tank 
  40. 		tank_impact_start_player_fall_speed = 9.0, 
  41. 		tank_impact_force_dive_dist = 100.0,	-- distance before tank impacts cargo plane, to force players into vertical dive (so they can see it) 
  42.  
  43. 		steal_tank_fall_speed = 9.0, 
  44. 		steal_tank_player_fall_speed = 12.0, 
  45. 		steal_tank_stop_dive_elev = 20.0,	-- distance above the steal tank the player should stop diving 
  46. 		steal_tank_ai_spread_mult = 0.01, 
  47. 		steal_tank_driver_refire_rates = { 3000, 2000, 1000 }, 
  48. 		steal_tank_gunner_refire_rates = { 1000, 750, 500 }, 
  49. 		steal_tank_success_radius = 35.0, 
  50. 		 
  51. 		-- SMG to give the player while skydiving 
  52. 		player_smg = "SMG-Storm", 
  53. 	} 
  54. 	 
  55. -- Debug switches for easy development 
  56. 	M18_debug_switches = { 
  57. 		skip_to_bail_out = true, 
  58. 	} 
  59.  
  60. -- Groups -- 
  61. 	M18_groups = { 
  62. 		-- Group for the tanks in the cargo plane 
  63. 		cargo_plane_tanks = { 
  64. 			name = "Group_cargo_plane_tanks 001", 
  65. 			tanks = { "veh_cargo_plane_tank 001", "veh_cargo_plane_tank 002", "veh_cargo_plane_tank 003", "veh_cargo_plane_tank 004", "veh_cargo_plane_tank 005", "veh_cargo_plane_tank 006" }, 
  66. 		}, 
  67. 		 
  68. 		-- Group for all the script objects in the cargo plane interior 
  69. 		cargo_plane_interior = { 
  70. 			name = "Group_cargo_plane_interior 001", 
  71. 			chars = { "char_stag_catwalk 001", "char_stag_catwalk 002", "char_stag_door_guard 001", "char_stag_door_guard 002", 
  72. 						"char_stag_grunt_01_ 001", "char_stag_grunt_01_ 002", "char_stag_grunt_02_ 001", "char_stag_grunt_02_ 002", 
  73. 						"char_stag_grunt_04_ 001", "char_stag_grunt_04_ 002", "char_stag_grunt_06_ 001" }, 
  74. 			 
  75. 			door_guards = { "char_stag_door_guard 001", "char_stag_door_guard 002" }, 
  76. 			sonic_guns = { "itm_sonic_gun 001", "itm_sonic_gun 002" }, 
  77. 			dead_guys = { "char_stag_grunt_dead 001" }, 
  78. 			 
  79. 			-- The "squads" for the grunts 
  80. 			grunt_squads = { 
  81. 				catwalk = { 
  82. 					grunts = { "char_stag_catwalk 001", "char_stag_catwalk 002"}, 
  83. 					anims = { "ATM User", "Browse Crouch" }, 
  84. 					on_detection = "m18_grunt_detection_defend_cb", 
  85. 				}, 
  86. 			 
  87. 				grunt_squad_01 = { 
  88. 					grunts = { "char_stag_grunt_01_ 001", "char_stag_grunt_01_ 002" }, 
  89. 					anims = { "Smoker A", "Bus Loiter B" }, 
  90. 					on_detection = "m18_grunt_detection_attack_immediate_cb", 
  91. 				}, 
  92. 				 
  93. 				grunt_squad_02 = { 
  94. 					grunts = { "char_stag_grunt_02_ 001", "char_stag_grunt_02_ 002" }, 
  95. 					anims = { "Bus Loiter B", "Smoker B" }, 
  96. 					on_detection = "m18_grunt_detection_defend_cb", 
  97. 				}, 
  98.  
  99. 				grunt_squad_04 = { 
  100. 					grunts = { "char_stag_grunt_04_ 001", "char_stag_grunt_04_ 002" }, 
  101. 					anims = { "Smoker B", "Smoker C" }, 
  102. 					on_detection = "m18_grunt_detection_defend_cb", 
  103. 				}, 
  104. 				 
  105. 				grunt_squad_06 = { 
  106. 					grunts = { "char_stag_grunt_06_ 001" }, 
  107. 					anims = { "Bus Loiter B", "Bench Sit Hunched", "Bench Sit", }, 
  108. 					on_detection = "m18_grunt_detection_defend_cb", 
  109. 				},	 
  110. 			}, 
  111. 		}, 
  112. 	 
  113. 		-- STAG 'reinforcements' 
  114. 		stag_reinf = { 
  115. 			name = "group_stag_reinf 001", 
  116. 			chars = { "char_stag_reinf 001", "char_stag_reinf 002", "char_stag_reinf 003", "char_stag_reinf 004" }, 
  117. 		}, 
  118. 			 
  119. 		-- The player's tank group 
  120. 		player_tank = { 
  121. 			name = "Group_player_tank 001", 
  122. 			vehicles = "veh_player_tank 001", 
  123. 			tank = "veh_player_tank 001", 
  124. 			fire_handle = -1, 
  125. 			exp_handle = -1, 
  126. 			contrail_handles = { }, 
  127. 		}, 
  128. 		 
  129. 		-- The first wave of enemies during the tank free fall section 
  130. 		stag_free_fall_01 = { 
  131. 			name = "Group_stag_falling 001", 
  132. 			skydive_chars = {  
  133. 				{ name = "char_stag_diver_01_ 001", nav = "nav_stag_diver_dest_01_ 001", forced_dive = false }, 
  134. 				{ name = "char_stag_diver_01_ 002", nav = "nav_stag_diver_dest_01_ 002", forced_dive = false }, 
  135. 				{ name = "char_stag_diver_01_ 003", nav = "nav_stag_diver_dest_01_ 003", forced_dive = false }, 
  136. 				{ name = "char_stag_diver_01_ 004", nav = "nav_stag_diver_dest_01_ 004", forced_dive = false }, 
  137. 				{ name = "char_stag_diver_01_ 005", nav = "nav_stag_diver_dest_01_ 005", forced_dive = false }, 
  138. 				{ name = "char_stag_diver_01_ 006", nav = "nav_stag_diver_dest_01_ 006", forced_dive = false }, 
  139. 				{ name = "char_stag_diver_01_ 007", nav = "nav_stag_diver_dest_01_ 007", forced_dive = false }, 
  140. 				{ name = "char_stag_diver_01_ 008", nav = "nav_stag_diver_dest_01_ 008", forced_dive = false }, 
  141. 			},			 
  142. 		}, 
  143. 		 
  144. 		-- The second wave of enemies during the tank free fall section 
  145. 		stag_free_fall_02 = { 
  146. 			name = "Group_stag_falling 002", 
  147. 			skydive_chars = {  
  148. 			 	{ name = "char_stag_diver_02_ 001", nav = "nav_stag_diver_dest_02_ 001", forced_dive = false }, 
  149. 			 	{ name = "char_stag_diver_02_ 002", nav = "nav_stag_diver_dest_02_ 002", forced_dive = false }, 
  150. 			 	{ name = "char_stag_diver_02_ 003", nav = "nav_stag_diver_dest_02_ 003", forced_dive = false }, 
  151. 				{ name = "char_stag_diver_02_ 004", nav = "nav_stag_diver_dest_02_ 004", forced_dive = false }, 
  152. 			 	{ name = "char_stag_diver_02_ 005", nav = "nav_stag_diver_dest_02_ 005", forced_dive = false }, 
  153. 			 	{ name = "char_stag_diver_02_ 006", nav = "nav_stag_diver_dest_02_ 006", forced_dive = false }, 
  154. 			}, 
  155. 			 
  156. 			-- Group the objects for each enemy tank together 
  157. 			tank_groups = { 
  158. 				tank_01 = { 
  159. 					tank = "veh_stag_tank_02_ 001", 
  160. 					chars = { "char_stag_tank_driver_02_ 001", "char_stag_tank_gunner_02_ 001" }, 
  161. 					orient = "nav_stag_tank_02_ 001", 
  162. 					dest = "nav_stag_tank_dest_02_ 001", 
  163. 					fire_handle = -1, 
  164. 					exp_handle = -1, 
  165. 					contrail_handles = { }, 
  166. 					thread_id = -1, 
  167. 				},				 
  168. 			},		 
  169. 		}, 
  170. 		 
  171. 		-- The third wave of enemies during the tank free fall section 
  172. 		stag_free_fall_03 = { 
  173. 			name = "Group_stag_falling 003", 
  174. 			skydive_chars = {  
  175. 				{ name = "char_stag_diver_03_ 001", nav = "nav_stag_diver_dest_03_ 001", forced_dive = false }, 
  176. 				{ name = "char_stag_diver_03_ 002", nav = "nav_stag_diver_dest_03_ 002", forced_dive = false }, 
  177. 				{ name = "char_stag_diver_03_ 003", nav = "nav_stag_diver_dest_03_ 003", forced_dive = false }, 
  178. 				{ name = "char_stag_diver_03_ 004", nav = "nav_stag_diver_dest_03_ 004", forced_dive = false }, 
  179. 				{ name = "char_stag_diver_03_ 005", nav = "nav_stag_diver_dest_03_ 005", forced_dive = false }, 
  180. 				{ name = "char_stag_diver_03_ 006", nav = "nav_stag_diver_dest_03_ 006", forced_dive = false }, 
  181. 				{ name = "char_stag_diver_03_ 007", nav = "nav_stag_diver_dest_03_ 007", forced_dive = false }, 
  182. 			}, 
  183. 		}, 
  184. 		 
  185. 		-- The fourth wave of enemies during the tank free fall section 
  186. 		stag_free_fall_04 = { 
  187. 			name = "Group_stag_falling 004", 
  188. 			-- skydive_chars = {  
  189. 			-- 	{ name = "char_stag_diver_04_ 001", nav = "nav_stag_diver_dest_04_ 001", forced_dive = false }, 
  190. 			-- 	{ name = "char_stag_diver_04_ 002", nav = "nav_stag_diver_dest_04_ 002", forced_dive = false }, 
  191. 			-- 	{ name = "char_stag_diver_04_ 003", nav = "nav_stag_diver_dest_04_ 003", forced_dive = false }, 
  192. 			-- 	{ name = "char_stag_diver_04_ 004", nav = "nav_stag_diver_dest_04_ 004", forced_dive = false }, 
  193. 			-- 	{ name = "char_stag_diver_04_ 005", nav = "nav_stag_diver_dest_04_ 005", forced_dive = false }, 
  194. 			-- 	{ name = "char_stag_diver_04_ 006", nav = "nav_stag_diver_dest_04_ 006", forced_dive = false }, 
  195. 			-- 	{ name = "char_stag_diver_04_ 007", nav = "nav_stag_diver_dest_04_ 007", forced_dive = false }, 
  196. 			-- }, 
  197. 			-- Group the objects for each enemy tank together 
  198. 			tank_groups = { 
  199. 				tank_01 = { 
  200. 					tank = "veh_stag_tank_04_ 001", 
  201. 					chars = { "char_stag_tank_driver_04_ 001", "char_stag_tank_gunner_04_ 001" }, 
  202. 					orient = "nav_stag_tank_04_ 001", 
  203. 					dest = "nav_stag_tank_dest_04_ 001", 
  204. 					fire_handle = -1, 
  205. 					exp_handle = -1, 
  206. 					contrail_handles = { }, 
  207. 					thread_id = -1, 
  208. 				}, 
  209. 				 
  210. 				tank_02 = { 
  211. 					tank = "veh_stag_tank_04_ 002", 
  212. 					chars = { "char_stag_tank_driver_04_ 002", "char_stag_tank_gunner_04_ 002" }, 
  213. 					orient = "nav_stag_tank_04_ 002", 
  214. 					dest = "nav_stag_tank_dest_04_ 002", 
  215. 					fire_handle = -1, 
  216. 					exp_handle = -1, 
  217. 					contrail_handles = { }, 
  218. 					thread_id = -1, 
  219. 				},				 
  220. 			}, 
  221. 		}, 
  222. 	 
  223. 		-- The fifth wave of enemies during the tank free fall section 
  224. 		stag_free_fall_05 = { 
  225. 			name = "Group_stag_falling 005", 
  226. 			-- Group the objects for each enemy tank together 
  227. 			tank_groups = { 
  228. 				tank_01 = { 
  229. 					tank = "veh_stag_tank_05_ 001", 
  230. 					chars = { "char_stag_tank_driver_05_ 001", "char_stag_tank_gunner_05_ 001" }, 
  231. 					orient = "nav_stag_tank_05_ 001", 
  232. 					dest = "nav_stag_tank_dest_05_ 001", 
  233. 					fire_handle = -1, 
  234. 					exp_handle = -1, 
  235. 					contrail_handles = { }, 
  236. 					thread_id = -1, 
  237. 				}, 
  238. 				 
  239. 				tank_02 = { 
  240. 					tank = "veh_stag_tank_05_ 002", 
  241. 					chars = { "char_stag_tank_driver_05_ 002", "char_stag_tank_gunner_05_ 002" }, 
  242. 					orient = "nav_stag_tank_05_ 002", 
  243. 					dest = "nav_stag_tank_dest_05_ 002", 
  244. 					fire_handle = -1, 
  245. 					exp_handle = -1, 
  246. 					contrail_handles = { }, 
  247. 					thread_id = -1, 
  248. 				},				 
  249. 			}, 
  250. 		}, 
  251. 		 
  252. 		-- The sixth wave of enemies during the tank free fall section 
  253. 		stag_free_fall_06 = { 
  254. 			name = "Group_stag_falling 006", 
  255. 			skydive_chars = {  
  256. 				{ name = "char_stag_diver_06_ 001", nav = "nav_stag_diver_dest_06_ 001", forced_dive = false }, 
  257. 				{ name = "char_stag_diver_06_ 002", nav = "nav_stag_diver_dest_06_ 002", forced_dive = false }, 
  258. 				{ name = "char_stag_diver_06_ 003", nav = "nav_stag_diver_dest_06_ 003", forced_dive = false }, 
  259. 				{ name = "char_stag_diver_06_ 004", nav = "nav_stag_diver_dest_06_ 004", forced_dive = false }, 
  260. 				{ name = "char_stag_diver_06_ 005", nav = "nav_stag_diver_dest_06_ 005", forced_dive = false }, 
  261. 				{ name = "char_stag_diver_06_ 006", nav = "nav_stag_diver_dest_06_ 006", forced_dive = false }, 
  262. 			}, 
  263. 		}, 
  264. 		 
  265. 		-- The seventh wave of enemies during the tank free fall section 
  266. 		stag_free_fall_07 = { 
  267. 			name = "Group_stag_falling 007", 
  268. 			skydive_chars = {  
  269. 				{ name = "char_stag_diver_07_ 001", nav = "nav_stag_diver_dest_07_ 001", forced_dive = false }, 
  270. 				{ name = "char_stag_diver_07_ 002", nav = "nav_stag_diver_dest_07_ 002", forced_dive = false }, 
  271. 				{ name = "char_stag_diver_07_ 003", nav = "nav_stag_diver_dest_07_ 003", forced_dive = false }, 
  272. 				{ name = "char_stag_diver_07_ 004", nav = "nav_stag_diver_dest_07_ 004", forced_dive = false }, 
  273. 			}, 
  274. 			tank_groups = { 
  275. 				tank_01 = { 
  276. 					tank = "veh_stag_tank_07_ 001", 
  277. 					chars = { "char_stag_tank_driver_07_ 001", "char_stag_tank_gunner_07_ 001" }, 
  278. 					orient = "nav_stag_tank_07_ 001", 
  279. 					dest = "nav_stag_tank_dest_07_ 001", 
  280. 					fire_handle = -1, 
  281. 					exp_handle = -1, 
  282. 					contrail_handles = { }, 
  283. 					thread_id = -1, 
  284. 				}, 
  285. 			}, 
  286. 		}, 
  287.  
  288. 		-- The first group of VTOLs that flyby the player's tank 
  289. 		stag_vtol_flyby_01 = { 
  290. 			name = "Group_stag_vtols 001", 
  291. 			 
  292. 			-- Group the objects for each enemy VTOL 
  293. 			vtol_groups = { 
  294. 				vtol_01 = { 
  295. 					vtol = "veh_stag_vtol_01_ 001", 
  296. 					chars = { "char_stag_vtol_pilot_01_ 001" }, 
  297. 					animation = "MAD18 Flyby A", 
  298. 					start_pos = "nav_stag_vtol_root_01_ 001", 
  299. 					speed_multiplier = 0.45, 
  300. 					delay = 0.0, 
  301. 					whoosh_trigger = 0.7, 
  302. 					thread_id = -1, 
  303. 				}, 
  304. 		 
  305. 				vtol_02 = { 
  306. 					vtol = "veh_stag_vtol_01_ 002", 
  307. 					chars = { "char_stag_vtol_pilot_01_ 002" }, 
  308. 					animation = "MAD18 Flyby B", 
  309. 					start_pos = "nav_stag_vtol_root_01_ 002", 
  310. 					speed_multiplier = 0.45, 
  311. 					delay = 0.5, 
  312. 					whoosh_trigger = 0.5, 
  313. 					thread_id = -1, 
  314. 				}, 
  315. 				 
  316. 				vtol_03 = { 
  317. 					vtol = "veh_stag_vtol_01_ 003", 
  318. 					chars = { "char_stag_vtol_pilot_01_ 003" }, 
  319. 					animation = "MAD18 Flyby C", 
  320. 					start_pos = "nav_stag_vtol_root_01_ 003", 
  321. 					speed_multiplier = 0.45, 
  322. 					delay = 1.0, 
  323. 					whoosh_trigger = 0.80, 
  324. 					thread_id = -1, 
  325. 				}, 
  326. 				 
  327. 				vtol_04 = { 
  328. 					vtol = "veh_stag_vtol_01_ 004", 
  329. 					chars = { "char_stag_vtol_pilot_01_ 004" }, 
  330. 					animation = "MAD18 Flyby D", 
  331. 					start_pos = "nav_stag_vtol_root_01_ 004", 
  332. 					speed_multiplier = 0.45, 
  333. 					delay = 2.0, 
  334. 					whoosh_trigger = 0.8, 
  335. 					thread_id = -1, 
  336. 				}, 
  337. 			}, 
  338. 				 
  339. 			-- Special VTOL group that collides with the player's tank 
  340. 			vtol_collide = { 
  341. 				vtol = "veh_stag_vtol_01_ 005", 
  342. 				chars = { "char_stag_vtol_pilot_01_ 005" }, 
  343. 				animation = "MAD18 Flyby B", 
  344. 				start_pos = "nav_stag_vtol_root_01_ 005", 
  345. 				speed_multiplier = 0.30, 
  346. 				delay = 2.5, 
  347. 				whoosh_trigger = 0.5, 
  348. 			}, 
  349. 			 
  350. 			restricted_camera = "nav_vtol_flyby_camera 001", 
  351. 		}, 
  352. 		 
  353. 		-- The second group of VTOLs that flyby the player's tank 
  354. 		stag_vtol_flyby_02 = { 
  355. 			name = "Group_stag_vtols 002", 
  356. 			 
  357. 			-- Group the objects for each enemy VTOL together 
  358. 			vtol_groups = { 
  359. 				vtol_01 = { 
  360. 					vtol = "veh_stag_vtol_02_ 001", 
  361. 					chars = { "char_stag_vtol_pilot_02_ 001" }, 
  362. 					animation = "MAD18 Flyby C", 
  363. 					start_pos = "nav_stag_vtol_root_02_ 001", 
  364. 					speed_multiplier = 0.45, 
  365. 					delay = 0.0, 
  366. 					whoosh_trigger = 0.77, 
  367. 					thread_id = -1, 
  368. 				}, 
  369. 				vtol_02 = { 
  370. 					vtol = "veh_stag_vtol_02_ 002", 
  371. 					chars = { "char_stag_vtol_pilot_02_ 002" }, 
  372. 					animation = "MAD18 Flyby C", 
  373. 					start_pos = "nav_stag_vtol_root_02_ 002", 
  374. 					speed_multiplier = 0.45, 
  375. 					delay = 1.0, 
  376. 					whoosh_trigger = 0.79, 
  377. 					thread_id = -1, 
  378. 				}, 
  379. 				vtol_03 = { 
  380. 					vtol = "veh_stag_vtol_02_ 003", 
  381. 					chars = { "char_stag_vtol_pilot_02_ 003" }, 
  382. 					animation = "MAD18 Flyby C", 
  383. 					start_pos = "nav_stag_vtol_root_02_ 003", 
  384. 					speed_multiplier = 0.45, 
  385. 					delay = 1.5, 
  386. 					whoosh_trigger = 0.80, 
  387. 					thread_id = -1, 
  388. 				}, 
  389. 				 
  390. 				vtol_04 = { 
  391. 					vtol = "veh_stag_vtol_02_ 004", 
  392. 					chars = { "char_stag_vtol_pilot_02_ 004" }, 
  393. 					animation = "MAD18 Flyby B", 
  394. 					start_pos = "nav_stag_vtol_root_02_ 004", 
  395. 					speed_multiplier = 0.45, 
  396. 					delay = 2.0, 
  397. 					whoosh_trigger = 0.46, 
  398. 					thread_id = -1, 
  399. 				}, 
  400. 				vtol_05 = { 
  401. 					vtol = "veh_stag_vtol_02_ 005", 
  402. 					chars = { "char_stag_vtol_pilot_02_ 005" }, 
  403. 					animation = "MAD18 Flyby B", 
  404. 					start_pos = "nav_stag_vtol_root_02_ 005", 
  405. 					speed_multiplier = 0.45, 
  406. 					delay = 2.5, 
  407. 					whoosh_trigger = 0.47, 
  408. 					thread_id = -1, 
  409. 				}, 
  410. 				vtol_06 = { 
  411. 					vtol = "veh_stag_vtol_02_ 006", 
  412. 					chars = { "char_stag_vtol_pilot_02_ 006" }, 
  413. 					animation = "MAD18 Flyby D", 
  414. 					start_pos = "nav_stag_vtol_root_02_ 006", 
  415. 					speed_multiplier = 0.45, 
  416. 					delay = 0.5, 
  417. 					whoosh_trigger = 0.76, 
  418. 					thread_id = -1, 
  419. 				}, 
  420. 				vtol_07 = { 
  421. 					vtol = "veh_stag_vtol_02_ 007", 
  422. 					chars = { "char_stag_vtol_pilot_02_ 007" }, 
  423. 					animation = "MAD18 Flyby D", 
  424. 					start_pos = "nav_stag_vtol_root_02_ 007", 
  425. 					speed_multiplier = 0.45, 
  426. 					delay = 3.0, 
  427. 					whoosh_trigger = 0.78, 
  428. 					thread_id = -1, 
  429. 				}, 
  430. 			}, 
  431. 			 
  432. 			vtol_collide = { 
  433. 				vtol = "veh_stag_vtol_02_ 008", 
  434. 				chars = { "char_stag_vtol_pilot_02_ 008" }, 
  435. 				animation = "MAD18 Flyby A", 
  436. 				start_pos = "nav_stag_vtol_root_02_ 008", 
  437. 				speed_multiplier = 0.33, 
  438. 				delay = 3.5, 
  439. 				whoosh_trigger = 0.68, 
  440. 				thread_id = -1, 
  441. 			}, 
  442. 			 
  443. 			restricted_camera = "nav_vtol_flyby_camera 002", 
  444. 		}, 
  445. 		 
  446. 		stag_dive_bombers_01 = { 
  447. 			name = "Group_stag_dive_bombers 001", 
  448. 			vtols = { 
  449. 				{ 
  450. 					vtol = "veh_stag_dive_bomber 001", 
  451. 					chars = { "char_stag_dive_bomber 001" }, 
  452. 					start_path = "path_stag_dive_bomber_01_ 001", 
  453. 					looping_path = "path_stag_dive_bomber_01_ 002", 
  454. 					thread_id = -1, 
  455. 				}, 
  456. 				{ 
  457. 					vtol = "veh_stag_dive_bomber 002", 
  458. 					chars = { "char_stag_dive_bomber 002" }, 
  459. 					start_path = "path_stag_dive_bomber_02_ 001", 
  460. 					looping_path = "path_stag_dive_bomber_02_ 002", 
  461. 					thread_id = -1, 
  462. 				}, 
  463. 			}, 
  464. 			 
  465. 			restricted_camera = "nav_vtol_dive_bomb_camera 001", 
  466. 			death_path = "path_stag_dive_bomber_death 001", 
  467. 		}, 
  468. 		 
  469. 		-- Group for the cargo plane formation that the player's tank smashes through 
  470. 		stag_cargo_plane = { 
  471. 			name = "Group_stag_cargo_plane 001", 
  472. 			planes = { 
  473. 				{ chars = { "char_stag_cargo_pilot 001" }, plane = "veh_stag_cargo_plane 001", path = "path_stag_cargo_plane 001", thread_id = INVALID_THREAD_HANDLE }, 
  474. 				{ chars = { "char_stag_cargo_pilot 002" }, plane = "veh_stag_cargo_plane 002", path = "path_stag_cargo_plane 002", thread_id = INVALID_THREAD_HANDLE }, 
  475. 				{ chars = { "char_stag_cargo_pilot 003" }, plane = "veh_stag_cargo_plane 003", path = "path_stag_cargo_plane 003", thread_id = INVALID_THREAD_HANDLE }, 
  476. 				{ chars = { "char_stag_cargo_pilot 004" }, plane = "veh_stag_cargo_plane 004", path = "path_stag_cargo_plane 004", thread_id = INVALID_THREAD_HANDLE }, 
  477. 				{ chars = { "char_stag_cargo_pilot 005" }, plane = "veh_stag_cargo_plane 005", path = "path_stag_cargo_plane 005", thread_id = INVALID_THREAD_HANDLE }, 
  478. 				{ chars = { "char_stag_cargo_pilot 006" }, plane = "veh_stag_cargo_plane 006", path = "path_stag_cargo_plane 006", thread_id = INVALID_THREAD_HANDLE }, 
  479. 				{ chars = { "char_stag_cargo_pilot 007" }, plane = "veh_stag_cargo_plane 007", path = "path_stag_cargo_plane 007", thread_id = INVALID_THREAD_HANDLE }, 
  480. 				{ chars = { "char_stag_cargo_pilot 008" }, plane = "veh_stag_cargo_plane 008", path = "path_stag_cargo_plane 008", thread_id = INVALID_THREAD_HANDLE }, 
  481. 				{ chars = { "char_stag_cargo_pilot 009" }, plane = "veh_stag_cargo_plane 009", path = "path_stag_cargo_plane 009", thread_id = INVALID_THREAD_HANDLE }, 
  482. 				{ chars = { "char_stag_cargo_pilot 010" }, plane = "veh_stag_cargo_plane 010", path = "path_stag_cargo_plane 010", thread_id = INVALID_THREAD_HANDLE }, 
  483. 			} 
  484. 		}, 
  485. 		 
  486. 		skydiving_tank = { 
  487. 			name = "Group_skydiving_tank 001", 
  488. 			tank_group = { 
  489. 				tank = "veh_skydiving_tank 001", 
  490. 				chars = { "char_skydiving_tank_driver 001", "char_skydiving_tank_gunner 001" }, 
  491. 				orient = "nav_skydiving_tank_orient 001", 
  492. 				dest = "nav_skydiving_tank_pos 001", 
  493. 				fire_handle = -1, 
  494. 				exp_handle = -1, 
  495. 				contrail_handles = { }, 
  496. 			},		 
  497. 		}, 
  498. 	} 
  499.  
  500. -- Navpoints -- 
  501. 	M18_navpoints = { 
  502. 		player_start_cargo_plane = { "nav_player_local_start 001", "nav_player_remote_start 001" }, 
  503. 		player_start_escape = { "nav_player_local_start 002", "nav_player_remote_start 002" }, 
  504. 		player_start_free_fall = { "nav_player_local_start 003", "nav_player_remote_start 003" }, 
  505. 		player_end = { "nav_player_local_end 001", "nav_player_remote_end 001" }, 
  506. 		turbulance_direction_01 = "nav_turbulance_direction 001", 
  507. 		 
  508. 		cargo_dust = { 
  509. 			"vfx_dust_drop 001", "vfx_dust_drop 002", "vfx_dust_drop 003", "vfx_dust_drop 004", "vfx_dust_drop 005", 
  510. 			"vfx_dust_drop 006", "vfx_dust_drop 007", "vfx_dust_drop 008", "vfx_dust_drop 009", "vfx_dust_drop 010", 
  511. 			"vfx_dust_drop 011", "vfx_dust_drop 012" 
  512. 		},		 
  513. 		 
  514. 		cabin_door_marker = "nav_cabin_door 001", 
  515. 		cockpit_door_marker = "nav_cockpit_door 001", 
  516. 		 
  517. 		gun_crate_orients = { "OpenCrate_Offset", "OpenCrate_Offset<001>", "OpenCrate_Offset<002>" }, 
  518. 		 
  519. 		grunt_catwalk_start = "nav_grunt_catwalk 001", 
  520. 		grunt_catwalk_positions = { "nav_grunt_catwalk_dest 001", "nav_grunt_catwalk_dest 002" }, 
  521. 									 
  522. 		cargo_door_ejection_point = "nav_door_ejection_point 001", 
  523. 		plane_box_turbulance = { "nav_plane_box_turbulance 001", "nav_plane_box_turbulance 002", "nav_plane_box_turbulance 003", "nav_plane_box_turbulance 004" }, 
  524. 		 
  525. 		player_tank_center_pos = "nav_player_tank_center", 
  526. 		player_tank_orient_01 = "nav_player_tank_orient 001", 
  527. 		player_tank_orient_02 = "nav_player_tank_orient 002", 
  528. 		player_tank_orient_03 = "nav_player_tank_orient 003", 
  529. 		player_tank_orient_04 = "nav_player_tank_orient 004", 
  530. 		 
  531. 		cargo_plane_start_pos = "nav_stag_cargo_plane 001", 
  532. 		player_tank_fall_pos = "nav_player_tank_fall_pos 001", 
  533.  
  534. 		debris_emitter_pos_01 = "nav_debris_flow_emitter 001", 
  535. 		debris_emitter_pos_02 = "nav_debris_flow_emitter 002", 
  536. 		debris_emitter_pos_03 = "nav_debris_flow_emitter 003", 
  537. 	} 
  538. 	 
  539. 	M18_paths = { 
  540. 		cargo_plane_crash_02 = { "path_stag_cargo_plane_crash 001", "path_stag_cargo_plane_crash 002", "path_stag_cargo_plane_crash 003", "path_stag_cargo_plane_crash 004" }, 
  541. 	} 
  542.  
  543. -- Triggers -- 
  544. 	M18_triggers = { 
  545. 		start_combat = "tgr_combat 001", 
  546. 		cabin_door = "tgr_cabin_door 001", 
  547. 		cabin_door_region = "tgr_cabin_door_destroy 001", 
  548. 		cockpit_door_region = "tgr_cockpit_door_destroy 001", 
  549. 		-- to_tank = "tgr_to_tank 001", 
  550. 		stumble_01 = "tgr_stumble 001", 
  551. 		stumble_02 = "tgr_stumble 002", 
  552. 		tank_region = "tgr_tank_region 001", 
  553. 		gun_crate_001 = "tgr_gun_crate 001", 
  554. 		gun_crate_002 = "tgr_gun_crate 002", 
  555. 		gun_crate_003 = "tgr_gun_crate 003", 
  556. 		falling_tank_01 = "tgr_falling_tank 001", 
  557. 		falling_tank_02 = "tgr_falling_tank 002", 
  558. 		falling_tank_03 = "tgr_falling_tank 003", 
  559. 		falling_tank_04 = "tgr_falling_tank 004", 
  560. 	} 
  561.  
  562. -- Characters -- 
  563.  
  564. -- Vehicles -- 
  565.  
  566. -- Mesh Movers --  
  567. 	M18_movers = { 
  568. 		cockpit_door = "mov_cockpit_door 001", 
  569. 		cabin_door = "mov_cabin_door 001", 
  570. 		lower_door = "mov_lower_door 001",  
  571. 		cargo_bay_door = "mov_cargo_bay_door 001", 
  572. 		gun_crate = { "mvr_stag_crate_open 001", "mvr_stag_crate_open 002", "mvr_stag_crate_open 003" }, 
  573. 		plane_boxes_01 = {  
  574. 			{ box = "mov_plane_box_01_ 001", launch_dir = "nav_plane_box_01_ 001", impulse = 1500, delay = 0.4 }, 
  575. 			{ box = "mov_plane_box_01_ 002", launch_dir = "nav_plane_box_01_ 002", impulse = 200, delay = 0.1 }, 
  576. 			{ box = "mov_plane_box_01_ 003", launch_dir = "nav_plane_box_01_ 003", impulse = 2000, delay = 0.4 }, 
  577. 			{ box = "mov_plane_box_01_ 004", launch_dir = "nav_plane_box_01_ 004", impulse = 200, delay = 0.3 }, 
  578. 			{ box = "mov_plane_box_01_ 005", launch_dir = "nav_plane_box_01_ 005", impulse = 200, delay = 0.2 }, 
  579. 			{ box = "mov_plane_box_01_ 006", launch_dir = "nav_plane_box_01_ 006", impulse = 200, delay = 0.3 }, 
  580. 			{ box = "mov_plane_box_01_ 007", launch_dir = "nav_plane_box_01_ 007", impulse = 200, delay = 0.1 }, 
  581. 			{ box = "mov_plane_box_01_ 008", launch_dir = "nav_plane_box_01_ 008", impulse = 200, delay = 0.3 }, 
  582.  
  583. 			{ box = "mov_plane_box_02_ 001", launch_dir = "nav_plane_box_02_ 001", impulse = 2000, delay = 0.2 }, 
  584. 			{ box = "mov_plane_box_02_ 002", launch_dir = "nav_plane_box_02_ 002", impulse = 250, delay = 0.4 }, 
  585.  
  586. 			{ box = "mov_plane_box_03_ 001", launch_dir = "nav_plane_box_03_ 001", impulse = 1200, delay = 0.3 }, 
  587. 			{ box = "mov_plane_box_03_ 002", launch_dir = "nav_plane_box_03_ 002", impulse = 200, delay = 0.2 }, 
  588. 			{ box = "mov_plane_box_03_ 003", launch_dir = "nav_plane_box_03_ 003", impulse = 200, delay = 0.5 }, 
  589. 			{ box = "mov_plane_box_03_ 004", launch_dir = "nav_plane_box_03_ 004", impulse = 200, delay = 0.3 }, 
  590. 			{ box = "mov_plane_box_03_ 005", launch_dir = "nav_plane_box_03_ 005", impulse = 200, delay = 0.4 }, 
  591. 			{ box = "mov_plane_box_03_ 006", launch_dir = "nav_plane_box_03_ 006", impulse = 200, delay = 0.4 }, 
  592. 			{ box = "mov_plane_box_03_ 007", launch_dir = "nav_plane_box_03_ 007", impulse = 2000, delay = 0.1 }, 
  593. 		}, 
  594. 			 
  595. 		free_fall_debris = {  
  596. 			"mov_free_fall_debris 001", "mov_free_fall_debris 002", "mov_free_fall_debris 003", "mov_free_fall_debris 004", "mov_free_fall_debris 005",  
  597. 			"mov_free_fall_debris 006", "mov_free_fall_debris 007", "mov_free_fall_debris 008", "mov_free_fall_debris 009", "mov_free_fall_debris 010", 
  598. 			"mov_free_fall_debris 011", "mov_free_fall_debris 012",	"mov_free_fall_debris 013", "mov_free_fall_debris 014", "mov_free_fall_debris 015", 
  599. 			"mov_free_fall_debris 016", "mov_free_fall_debris 017", "mov_free_fall_debris 018",	"mov_free_fall_debris 019", "mov_free_fall_debris 020", 
  600. 			"mov_free_fall_debris 021", "mov_free_fall_debris 022", "mov_free_fall_debris 023", "mov_free_fall_debris 024", "mov_free_fall_debris 025", 
  601. 			"mov_free_fall_debris 026", "mov_free_fall_debris 027", "mov_free_fall_debris 028", "mov_free_fall_debris 029", "mov_free_fall_debris 030", 
  602. 			"mov_free_fall_debris 031", "mov_free_fall_debris 032", "mov_free_fall_debris 033", "mov_free_fall_debris 034", "mov_free_fall_debris 035", 
  603. 								 
  604. 			"mov_free_fall_battlebox 001", "mov_free_fall_battlebox 002", "mov_free_fall_battlebox 003", "mov_free_fall_battlebox 004", "mov_free_fall_battlebox 005",  
  605. 			"mov_free_fall_battlebox 006", "mov_free_fall_battlebox 007", "mov_free_fall_battlebox 008", "mov_free_fall_battlebox 009", "mov_free_fall_battlebox 010", 
  606. 			"mov_free_fall_battlebox 011", "mov_free_fall_battlebox 012", 
  607. 		}, 
  608. 		 
  609. 		free_fall_debris_02 = {  
  610. 			"mov_free_fall_debris_02 001", "mov_free_fall_debris_02 002", "mov_free_fall_debris_02 003", "mov_free_fall_debris_02 004", "mov_free_fall_debris_02 005",  
  611. 			"mov_free_fall_debris_02 006", "mov_free_fall_debris_02 007", "mov_free_fall_debris_02 008", "mov_free_fall_debris_02 009", "mov_free_fall_debris_02 010", 
  612. 			"mov_free_fall_debris_02 011", "mov_free_fall_debris_02 012", "mov_free_fall_debris_02 013", "mov_free_fall_debris_02 014", "mov_free_fall_debris_02 015", 
  613. 			"mov_free_fall_debris_02 016", "mov_free_fall_debris_02 017", "mov_free_fall_debris_02 018", "mov_free_fall_debris_02 019", "mov_free_fall_debris_02 020", 
  614. 			"mov_free_fall_debris_02 021", "mov_free_fall_debris_02 022", "mov_free_fall_debris_02 023", "mov_free_fall_debris_02 024", "mov_free_fall_debris_02 025", 
  615. 			"mov_free_fall_debris_02 026", "mov_free_fall_debris_02 027", "mov_free_fall_debris_02 028", "mov_free_fall_debris_02 029", "mov_free_fall_debris_02 030", 
  616. 			"mov_free_fall_debris_02 031", "mov_free_fall_debris_02 032", "mov_free_fall_debris_02 033", "mov_free_fall_debris_02 034", "mov_free_fall_debris_02 035", 
  617. 						 
  618. 			--[[			 
  619. 			"mov_free_fall_battlebox_02 001", "mov_free_fall_battlebox_02 002", "mov_free_fall_battlebox_02 003", "mov_free_fall_battlebox_02 004", "mov_free_fall_battlebox_02 005",  
  620. 			"mov_free_fall_battlebox_02 006", "mov_free_fall_battlebox_02 007", "mov_free_fall_battlebox_02 008", "mov_free_fall_battlebox_02 009", "mov_free_fall_battlebox_02 010", 
  621. 			"mov_free_fall_battlebox_02 011", "mov_free_fall_battlebox_02 012", 
  622. 			--]] 
  623. 		}, 
  624. 								 
  625. 		wreckage_debris = {  
  626. 			"mov_wreckage_debris 001", "mov_wreckage_debris 002", "mov_wreckage_debris 003", "mov_wreckage_debris 004", "mov_wreckage_debris 005",   
  627. 			"mov_wreckage_debris 006", "mov_wreckage_debris 007", "mov_wreckage_debris 008", "mov_wreckage_debris 009", "mov_wreckage_debris 010",  
  628. 			"mov_wreckage_debris 011", "mov_wreckage_debris 012", "mov_wreckage_debris 013", "mov_wreckage_debris 014", "mov_wreckage_debris 015",  
  629. 			"mov_wreckage_debris 016", "mov_wreckage_debris 017", "mov_wreckage_debris 018", "mov_wreckage_debris 019", "mov_wreckage_debris 020",  
  630. 			"mov_wreckage_debris 021", "mov_wreckage_debris 022", "mov_wreckage_debris 023", "mov_wreckage_debris 024", "mov_wreckage_debris 025",  
  631. 			"mov_wreckage_debris 026", "mov_wreckage_debris 027", "mov_wreckage_debris 028", "mov_wreckage_debris 029", "mov_wreckage_debris 030",  
  632. 			"mov_wreckage_debris 031", "mov_wreckage_debris 032", "mov_wreckage_debris 033", "mov_wreckage_debris 034", "mov_wreckage_debris 035",  
  633. 			"mov_wreckage_debris 036", "mov_wreckage_debris 037", "mov_wreckage_debris 038", "mov_wreckage_debris 039", "mov_wreckage_debris 040",  
  634. 			"mov_wreckage_debris 041", "mov_wreckage_debris 042", "mov_wreckage_debris 043", "mov_wreckage_debris 044", "mov_wreckage_debris 045",  
  635. 			"mov_wreckage_debris 046", "mov_wreckage_debris 047", "mov_wreckage_debris 048", "mov_wreckage_debris 049", "mov_wreckage_debris 050",  
  636. 			"mov_wreckage_debris 051", "mov_wreckage_debris 052", "mov_wreckage_debris 053", "mov_wreckage_debris 054", "mov_wreckage_debris 055",  
  637. 			"mov_wreckage_debris 056", "mov_wreckage_debris 057", "mov_wreckage_debris 058", "mov_wreckage_debris 059", "mov_wreckage_debris 060",  
  638. 			"mov_wreckage_debris 061", "mov_wreckage_debris 062", "mov_wreckage_debris 063", "mov_wreckage_debris 064", "mov_wreckage_debris 065",  
  639. 		} 
  640. 	}  
  641.  
  642. -- Text -- 
  643. 	M18_objectives = { 
  644. 		get_to_the_cockpit = { 
  645. 			tag = "M18_OBJ_GET_TO_COCKPIT", 
  646. 			icon = OI_ASSET_USE, 
  647. 		}, 
  648. 		search_for_gun = { 
  649. 			tag = "M18_OBJ_SEARCH_FOR_GUN", 
  650. 			icon = OI_ASSET_USE, 
  651. 		}, 
  652. 		destroy_cockpit = { 
  653. 			tag = "M18_OBJ_DESTROY_COCKPIT", 
  654. 			icon = OI_ASSET_KILL, 
  655. 		}, 
  656. 		escape_in_tank = { 
  657. 			tag = "M18_OBJ_ESCAPE_IN_TANK", 
  658. 			icon = OI_ASSET_LOCATION, 
  659. 		}, 
  660. 		survive = { 
  661. 			tag = "M18_OBJ_SURVIVE", 
  662. 			icon = OI_ASSET_KILL, 
  663. 		}, 
  664. 		bail_out_of_tank = { 
  665. 			tag = "M18_OBJ_BAIL_FROM_TANK", 
  666. 			icon = OI_ASSET_USE, 
  667. 		}, 
  668. 		kill_tank_gunner = { 
  669. 			tag = "M18_OBJ_KILL_THE_GUNNER", 
  670. 			icon = OI_ASSET_KILL, 
  671. 		}, 
  672. 		hijack_tank = { 
  673. 			tag = "M18_OBJ_HIJACK_TANK", 
  674. 			icon = OI_ASSET_LOCATION, 
  675. 		}, 
  676. 	} 
  677. 	 
  678. 	M18_placholder_dialog = { 
  679. 		intro_lines = { 
  680. 			{ text = "Player: I'm in.", duration = 1.5 }, 
  681. 			{ text = "Viola: Took you long enough.", duration = 2.0	}, 
  682. 			{ text = "Player: How about you jump out of the plane next time.", duration = 5.0 }, 
  683. 			{ text = "Viola: ... Just keep your eyes open.", duration = 1.0 }, 
  684. 			{ text = "Viola: STAG's probably got some gear onboard that you could use.", duration = 4.0 }, 
  685. 			{ text = "Player: I do need a new microwave.", duration = 1.0 }, 
  686. 			{ text = "Viola: [[sigh]...", duration = 5.0 }, 
  687. 		}, 
  688. 		 
  689. 		found_gun = { 
  690. 			{ text = "Player: What do we have here?", duration = 2.0 },		 
  691. 			{ text = "Viola: What did you find?", duration = 1.5 },	 
  692. 			{ text = "Player: Not quite sure. Definitely beats the hell outa a microwave!", duration = 4.0 }, 
  693. 			{ text = "Viola: Well, whatever it is, be careful with it.", duration = 4.0 }, 
  694. 		}, 
  695. 		 
  696. 		door_open_no_gun = { 
  697. 			{ text = "Player: The door won't budge.", duration = 2.0 }, 
  698. 			{ text = "Viola: Well, then find something to blow it open.  Isn't that your specialty?", duration = 3.0 }, 
  699. 			{ text = "Player: You don't need to ask me twice.", duration = 3.0 }, 
  700. 		}, 
  701. 		 
  702. 		door_open_with_gun = { 
  703. 			{ text = "Player: The door won't budge.", duration = 2.0 }, 
  704. 			{ text = "Viola: Well, then find something to blow it open.", duration = 4.0 }, 
  705. 			{ text = "Viola: Maybe your new microwave will do the trick.", duration = 3.0 }, 
  706. 			{ text = "Player: I know one way to find out.", duration = 2.5 }, 
  707. 			{ text = "Viola: Don't do anything stupid, now.", duration = 2.0 }, 
  708. 			{ text = "Player: You know me too well.", duration = 3.0 }, 
  709. 		}, 
  710. 		 
  711. 		aquired_gun = { 
  712. 			{ text = "Player: What do we have here?", duration = 2.0 },		 
  713. 			{ text = "Viola: What did you find?", duration = 1.5 },	 
  714. 			{ text = "Player: Not quite sure. Definitely beats the hell outa a microwave!", duration = 4.0 }, 
  715. 			{ text = "Viola: Maybe your new microwave will do the trick on the door.", duration = 1.5 }, 
  716. 			{ text = "Player: I know one way to find out.", duration = 2.5 }, 
  717. 			{ text = "Viola: Don't do anything stupid, now.", duration = 2.0 }, 
  718. 			{ text = "Player: You know me too well.", duration = 3.0 },			 
  719. 		}, 
  720. 		 
  721. 		door_damaged_no_gun = { 
  722. 			{ text = "Player: This fucking door is solid.", duration = 2.0 }, 
  723. 			{ text = "Viola: Take a look around - there's got to be something that can open the door.", duration = 3.0 }, 
  724. 			{ text = "Viola: You are on a STAG military plane after all.", duration = 2.0 }, 
  725. 			{ text = "Player: Yeah, yeah.", duration = 3.0 }, 
  726. 		}, 
  727. 		 
  728. 		door_damaged_with_gun = { 
  729. 			{ text = "Player: Fuck this door!", duration = 2.0 }, 
  730. 			{ text = "Viola: Perhaps it's time to try that new microwave you found.", duration = 3.0 }, 
  731. 		}, 
  732. 		 
  733. 		too_far_away = { 
  734. 			{ 
  735. 				{ text = "Player: This sonic gun fucking sucks!", duration = 3.0 }, 
  736. 				{ text = "Viola: Maybe you're just too far away.", duration = 2.0 }, 
  737. 				{ text = "Viola: Sound energy dissipates quickly, you know.", duration = 4.0 }, 
  738. 				{ text = "Player: What is this? The fucking Learning channel?", duration = 2.0 }, 
  739. 				{ text = "Player: Do you want to open the door, or not?", duration = 2.0 }, 
  740. 			}, 
  741. 			{ 
  742. 				{ text = "Player: This gun is fucking worthless!", duration = 3.0 }, 
  743. 				{ text = "Viola: Try getting closer to the door.", duration = 2.0 }, 
  744. 			}, 
  745. 		}, 
  746. 		 
  747. 		door_destroyed = { 
  748. 			{ text = "Player: Fucking Shit!", duration = 2.0 }, 
  749. 			{ text = "Viola: What's wrong", duration = 1.0 }, 
  750. 			{ text = "Player: I'm fine... but this plane is fucked!", duration = 1.0 }, 
  751. 			{ text = "Viola: You need to get out of there, NOW!", duration = 1.0 }, 
  752. 			{ text = "Player: I've got an idea!", duration = 2.0 }, 
  753. 			{ text = "Viola: Wait, what are you about to do?", duration = 6.0 }, 
  754. 			{ text = "Viola: Shit!", duration = 1.0 }, 
  755. 		}, 
  756. 	} 
  757. 				 
  758. -- Help Text 
  759. 	M18_help_text = { 
  760. 		get_closer_to_door = "M18_HELP_GET_CLOSER_TO_DOOR", 
  761. 		clearing_debris = "M18_HELP_CLEARING_DEBRIS", 
  762. 	} 
  763.  
  764. -- Threads -- 
  765. 	M18_threads = { 
  766. 		dialog = -1, 
  767. 		place_holder_dialog = -1, 
  768. 		box_jiggle = -1, 
  769. 		plane_dust = -1, 
  770. 		debris_flow_speed = -1, 
  771. 		random_clouds = -1, 
  772. 		vtol_collide = -1, 
  773. 		local_player_steal_tank = -1, 
  774. 		remote_player_steal_tank = -1, 
  775. 		cargo_plane_crash_02 = -1, 
  776. 	} 
  777.  
  778. -- Checkpoints -- 
  779. 	M18_checkpoints = { 
  780. 		start = MISSION_START_CHECKPOINT, -- defined in ug_lib.lua. 
  781. 		cargo_plane_escape = "m18_checkpoint_escape", 
  782. 		tank_free_fall = "m18_checkpoint_free_fall", 
  783. 		dive_bombers = "m18_checkpoint_dive_bombers", 
  784. 		debug_bail_out = "m18_debug_checkpoint_bail_out", 
  785. 	} 
  786. 	 
  787. -- Cutscenes -- 
  788. 	M18_cutscenes = { 
  789. 		mission_intro = "18_in", 
  790. 		tank_zscene = "18_Z01", 
  791. 		mission_outro = "18_out", 
  792. 	} 
  793.  
  794. -- Conversations -- 
  795. 	M18_convo = { 
  796. 		mission_start = { 
  797. 			name = "M18_Mission_Start", 
  798. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  799. 		}, 
  800. 		plane_combat = { 
  801. 			name = "M18_Plane_Combat", 
  802. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  803. 		}, 
  804. 		cockpit_locked_no_gun = { 
  805. 			name = "M18_Cockpit_Door", 
  806. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  807. 		}, 
  808. 		falling_out_bad = { 
  809. 			name = "M18_Falling_Out_Is_Bad", 
  810. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  811. 		}, 
  812. 		sonic_gun_failed_01 = { 
  813. 			name = "M18_Not_Working_Door_1", 
  814. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  815. 		}, 
  816. 		sonic_gun_failed_02 = { 
  817. 			name = "M18_Not_Working_Door_2", 
  818. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  819. 		}, 
  820. 		sonic_gun = { 
  821. 			name = "M18_Sonic_Gun", 
  822. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  823. 		}, 
  824. 		not_close_enough = { 
  825. 			name = "M18_Not_Close_Enough", 
  826. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  827. 		}, 
  828. 		cockpit_gone = { 
  829. 			name = "M18_Cockpit_Gone", 
  830. 			is_convo = true, load_direct = false, in_queue = false, started = false, completed = false, ended = false,	 
  831. 		}, 
  832. 		gooing_people = { 
  833. 			name = "M18_Gooing_People_01", 
  834. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  835. 		}, 
  836. 		blast_containers = { 
  837. 			name = "M18_Blast_Container_Aside", 
  838. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false, 
  839. 		}, 
  840. 		damn_stumbles = { 
  841. 			name = "M18_Damn_Stumbles", 
  842. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  843. 		}, 
  844. 		begin_drop = { 
  845. 			name = "M18_Beginning_Of_Tank_Drop", 
  846. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  847. 		}, 
  848. 		vtol_hit_01 = { 
  849. 			name = "M18_VTOL_Hit_01", 
  850. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  851. 		}, 
  852. 		falling_again = { 
  853. 			name = "M18_Falling_Yet_Again", 
  854. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  855. 		}, 
  856. 		vtol_hit_02 = { 
  857. 			name = "M18_VTOL_Hit_02", 
  858. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  859. 		}, 
  860. 		generic_falling_01 = { 
  861. 			name = "M18_Generic_Tank_01", 
  862. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  863. 		}, 
  864. 		generic_falling_02 = { 
  865. 			name = "M18_Generic_Tank_02", 
  866. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  867. 		}, 
  868. 		generic_falling_03 = { 
  869. 			name = "M18_Generic_Tank_03", 
  870. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  871. 		}, 
  872. 		generic_falling_04 = { 
  873. 			name = "M18_Generic_Tank_04", 
  874. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  875. 		}, 
  876. 		generic_falling_05 = { 
  877. 			name = "M18_Generic_Tank_05", 
  878. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  879. 		}, 
  880. 		generic_falling_06 = { 
  881. 			name = "M18_Generic_Tank_06", 
  882. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  883. 		}, 
  884. 		generic_falling_07 = { 
  885. 			name = "M18_Generic_Tank_07", 
  886. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  887. 		}, 
  888. 		generic_falling_08 = { 
  889. 			name = "M18_Generic_Tank_08", 
  890. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  891. 		}, 
  892. 		exit_tank = { 
  893. 			name = "M18_Exit_The_Tank_01", 
  894. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  895. 		},		 
  896. 		steal_plane = { 
  897. 			name = "M18_Steal_Plane_01", 
  898. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  899. 		},	 
  900. 		plane_blows_up = { 
  901. 			name = "M18_Plane_Blows_Up_01", 
  902. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  903. 		},	 
  904. 		dive_through = { 
  905. 			name = "M18_Dive_Through_Plane_Wreck_01", 
  906. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  907. 		},	 
  908. 		while_skydiving = { 
  909. 			name = "M18_While_Skydiving_01", 
  910. 			is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  911. 		},	 
  912. 		tank_health = { 
  913. 			{ 
  914. 				name = "M18_Tank_Health_01", 
  915. 				is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  916. 			}, 
  917. 			{ 
  918. 				name = "M18_Tank_Health_02", 
  919. 				is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  920. 			}, 
  921. 			{ 
  922. 				name = "M18_Tank_Health_03", 
  923. 				is_convo = false, play_2d = false, character = LOCAL_PLAYER, in_queue = false, started = false, completed = false, ended = false,	 
  924. 			}, 
  925. 		}, 
  926. 	} 
  927. 	 
  928. -- Personas -- 
  929. 	M18_personas = { 
  930. 		viola = { 
  931. 			name = "Suko", 
  932. 			persona_id = -1, 
  933. 		}, 
  934. 	} 
  935. 	 
  936. -- Audio Emitters -- 
  937. 	M18_audio_emitters = { 
  938. 		plane_interior = { 
  939. 			"M18_interior_cargo_plane<001>", 
  940. 			"Cargo_rattles_a", "Cargo_rattles_a<002>", "Cargo_rattles_a<003>", "Cargo_rattles_a<004>", "Cargo_rattles_a<005>", 
  941. 			"Cargo_rattles_a<006>", "Cargo_rattles_a<007>", "Cargo_rattles_a<008>", "Cargo_rattles_a<009>", "Cargo_rattles_a<010>", 
  942. 			"Cargo_rattles_a<011>", "Cargo_rattles_a<012>", "Cargo_rattles_a<013>", "Cargo_rattles_a<014>", "Cargo_rattles_a<015>", 
  943. 			"Cargo_rattles_a<016>", "Cargo_rattles_a<017>", "Cargo_rattles_a<018>", "Cargo_rattles_a<019>", "Cargo_rattles_a<020>", 
  944. 			"Cargo_rattles_a<021>", "Cargo_rattles_a<022>", "Cargo_rattles_a<023>", "Cargo_rattles_a<024>", 
  945. 			"Cargo_rattles_b", "Cargo_rattles_b<001>", "Cargo_rattles_b<002>", "Cargo_rattles_b<003>", "Cargo_rattles_b<004>", 
  946. 			"Cargo_rattles_b<005>", "Cargo_rattles_b<006>", "Cargo_rattles_b<007>", "Cargo_rattles_b<008>", "Cargo_rattles_b<009>", 
  947. 			"Cargo_rattles_b<010>", 
  948. 		}, 
  949. 		plane_crashing = { 
  950. 			"M18_plane_crash_cargo", "M18_interior_after_Explo<001>", "M18_alarm_klaxxon", 
  951. 		}, 
  952. 	} 
  953. 	 
  954. -- Audio Events -- 
  955. 	M18_audio_events = { 
  956. 		kick_door = "M18_sfx_PC_kick_locked_door", 
  957. 		destroy_door = "M18_sfx_PC_smash_door", 
  958. 		destroy_cockpit = "M18_sfx_PC_destroy_cockpit", 
  959. 		 
  960. 		plane_violent_shake = "M18_sfx_plane_violent_shake", 
  961. 		plane_shudder = "M18_sfx_plane_shudder",		 
  962. 		 
  963. 		skydiving_wind = "M18_amb_skydiving_wind", 
  964. 		 
  965. 		vtol_flyby = "M18_sfx_VTOL_flybys", 
  966. 		vtol_whalla = "M18_VTOL_walla", 
  967. 		vtol_whalla_stop = "m18_VTOL_walla_STOP", 
  968. 		 
  969. 		cargo_plane_flying = "m18_sfx_plane_fly_beneath", 
  970. 		cargo_plane_crashing = "m18_sfx_plane_plummet", 
  971. 		tank_hit_wing = "m18_sfx_tank_hit_plane", 
  972. 		cargo_plane_wing_groan = "m18_sfx_plane_wing_groan", 
  973. 		 
  974. 		-- music -- 
  975. 		music_start = "M18_music_mission_start", 
  976. 		music_plane_crashing = "M18_music_plane_crash", 
  977. 		music_skydive_start = "M18_music_tank_skydive", 
  978. 		music_bail_out = "M18_music_tank_bail_out", 
  979. 		music_mission_complete = "M18_music_tank_skydive_end", 
  980. 		music_stop = "M18_music_STOP", 
  981. 		music_escape_checkpoint = "M18_music_cargo_plane_checkpoint", 
  982. 		music_skydive_checkpoint = "M18_music_tank_skydive_checkpoint", 
  983. 	} 
  984.  
  985. -- Script Interiors -- 
  986. 	M18_interiors = { 
  987. 		skydiving_volume = "int_skydiving_volume 001", 
  988. 	} 
  989. 	 
  990. -- HUD display states -- 
  991. 	M18_hud_states = { 
  992. 		hide_minimap = -1, 
  993. 	} 
  994. 	 
  995. -- List of enemy spawns in the free fall sections -- 
  996. 	M18_free_fall_spawns = { 
  997. 		set_01 = { 
  998. 			{ group = M18_groups.stag_free_fall_01, min_threat_level = 4, max_duration = 20.0, line =  "" }, 
  999. 			{ group = M18_groups.stag_free_fall_02, min_threat_level = 5, max_duration = 20.0, line =  M18_convo.generic_falling_01 }, 
  1000. 			{ group = M18_groups.stag_free_fall_03, min_threat_level = 6, max_duration = 20.0, line =  "" }, 
  1001. 			{ group = M18_groups.stag_free_fall_04, min_threat_level = 0, max_duration = 20.0, line =  M18_convo.generic_falling_03 }, 
  1002. 		}, 
  1003. 		set_02 = { 
  1004. 			{ group = M18_groups.stag_free_fall_05, min_threat_level = 2, max_duration = 20.0, line =  "" }, 
  1005. 			{ group = M18_groups.stag_free_fall_06, min_threat_level = 5, max_duration = 20.0, line =  M18_convo.generic_falling_05 }, 
  1006. 			{ group = M18_groups.stag_free_fall_07, min_threat_level = 0, max_duration = 20.0, line =  "" }, 
  1007. 		}, 
  1008. 	} 
  1009. 		 
  1010. -- Other -- 
  1011. 	M18_runtime = { 
  1012. 		num_grunts_to_reach_catwalk = 0, 
  1013. 	 
  1014. 		-- Counts for the first group of enemies 
  1015. 		num_free_fall_chars_alive = 0, 
  1016. 		num_free_fall_vehicles_alive = 0, 
  1017. 		 
  1018. 		debris_flow_handle = 0, 
  1019. 		debris_flow_handle_02 = 0, 
  1020. 		wreckage_debris_flow_handle = 0, 
  1021. 		 
  1022. 		debirs_fire_handles = { }, 
  1023. 		 
  1024. 		convo_queue = { 
  1025. 			playing  = { 
  1026. 				thread_id = -1, 
  1027. 				conv_handle = INVALID_CONVERSATION_HANDLE, 
  1028. 				convo_table = nil, 
  1029. 			}, 
  1030. 			list = {}, 
  1031. 			size = 0, 
  1032. 		}, 
  1033. 		 
  1034. 		skydiving_tanks = { }, 
  1035. 	} 
  1036. 	 
  1037. -- Mission Scripting Flags -- 
  1038. 	M18_flags = { 
  1039. 		sonic_gun_failed_once = false, 
  1040. 		sonic_gun_aquired = false, 
  1041. 		played_too_far_away_conversation = false, 
  1042. 		cabin_door_open_attempted = false, 
  1043. 		in_door_destruction_region_local = false, 
  1044. 		in_door_destruction_region_remote = false, 
  1045. 		in_cabin_destruction_region_local = false, 
  1046. 		in_cabin_destruction_region_remote = false, 
  1047. 		cabin_door_destroyed = false, 
  1048. 		cockpit_door_destroyed = false, 
  1049. 		triggered_tank_region = false, 
  1050. 		steal_tank_gunner_killed = false, 
  1051. 	} 
  1052. 	 
  1053. -- VFX -- 
  1054. 	M18_vfxs = { 
  1055. 		cockpit_door_explosion = { nav = "vfx_cockpit_door_exp 001", handle = -1 }, 
  1056. 		cargo_plane_interior_explosion = { nav = "vfx_plane_interior_exp 001", handle = -1 }, 
  1057. 		stag_cargo_plane_explosion = { nav = "vfx_cargo_plane_exp 001", handle = -1 }, 
  1058. 		 
  1059. 		plane_wind = { nav = "vfx_plane_cabin_wind 001", handle = -1 }, 
  1060. 		bottom_clouds = { nav = "vfx_bottom_clouds 001", handle = -1 }, 
  1061. 		clouds = { nav = "vfx_clouds 001", handle = -1 }, 
  1062. 		city = { nav = "vfx_city 001", handle = -1 }, 
  1063. 		random_clouds = { nav = "vfx_random_clouds 001", handle = -1 }, 
  1064. 		random_clouds_remote = { nav = "vfx_random_clouds 001", handle = -1 }, 
  1065. 		tank_streamers = { nav = "vfx_tank_streamers 001", handle = -1 }, 
  1066. 		 
  1067. 		debris_fire = { nav = "vfx_fire_debris 001", handle = -1 }, 
  1068. 		car_exp = { nav = "vfx_car_explosion 001", handle = -1 }, 
  1069. 		 
  1070. 		cargo_plane_smoke = { nav = "vfx_cargo_plane_smoke 001", handle = -1 }, 
  1071. 	} 
  1072. 	 
  1073. local M18_CONVO_PLAY_LAST = 0 
  1074. local M18_CONVO_PLAY_NEXT = 1 
  1075. local M18_CONVO_PLAY_IMMEDIATE = 2 
  1076.  
  1077.  
  1078. -- ************************* 
  1079. -- 
  1080. -- Standard functions 
  1081. -- 
  1082. -- ************************* 
  1083.  
  1084. -- This is the primary entry point for the mission, and is responsible for starting up the mission 
  1085. -- at the specified checkpoint. 
  1086. -- CALLED FROM CODE 
  1087. -- 
  1088. -- m18_checkpoint:	The checkpoint the mission should begin at 
  1089. -- is_restart:					TRUE if the mission is restarting, FALSE otherwise 
  1090. -- 
  1091. function m18_start(m18_checkpoint, is_restart) 
  1092. 	-- Do the initial fade-out 
  1093. 	mission_start_fade_out(0.0) 
  1094. 	 
  1095. 	city_zone_swap("m18", true) 
  1096. 	city_zone_swap("m18fx", true) 
  1097. 	 
  1098. 	-- Dismiss the players' party 
  1099. 	party_dismiss_all() 
  1100.  
  1101. 	-- Check if this mission starting from the beginning 
  1102. 	if (m18_checkpoint == M18_checkpoints.start) then 
  1103. 		if (is_restart == false) then 
  1104. 			-- First time playing mission 
  1105. 			 
  1106. 			-- Play an intro cutscene??? 
  1107. 			if (M18_cutscenes.mission_intro ~= "") then 
  1108. 				cutscene_play(M18_cutscenes.mission_intro, nil, M18_navpoints.player_start_cargo_plane, false) 
  1109. 				--bink_play(M18_cutscenes.mission_intro) 
  1110. 			end 
  1111. 		else 
  1112. 			teleport_coop(M18_navpoints.player_start_cargo_plane[1], M18_navpoints.player_start_cargo_plane[2]) 
  1113. 		end 
  1114. 	end 
  1115.  
  1116. 	-- Handle mission initialization for the current checkpoint 
  1117. 	m18_initialize(m18_checkpoint) 
  1118. 	 
  1119. 	-- Start fading in 
  1120. 	mission_start_fade_in() 
  1121.  
  1122. 	-- Run the mission from the current checkpoint 
  1123. 	m18_run(m18_checkpoint) 
  1124. end 
  1125.  
  1126. -- This is the primary function responsible for cleaning up the entire mission 
  1127. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  1128. -- 
  1129. function m18_cleanup() 
  1130. 	--[[ INSERT ANY MISSION SPECIFIC CLEAN-UP ]]-- 
  1131. 	 
  1132. 	-- Call the cleanup helper for the free fall section of the mission 
  1133. 	m18_cleanup_cargo_plane_open_cockpit() 
  1134. 	m18_cleanup_cargo_plane_interior() 
  1135. 	m18_cleanup_tank_free_fall() 
  1136.  
  1137. 	-- Cleanup any groups that are still loaded 
  1138. 	for i, group in pairs(M18_groups) do 
  1139. 		if (group_is_loaded(group.name) == true) then 
  1140. 			group_destroy(group.name) 
  1141. 		end 
  1142. 	end 
  1143. 	 
  1144. 	-- Stop any active threads 
  1145. 	for i, thread in pairs(M18_threads) do 
  1146. 		if (thread ~= -1 and thread_check_done(thread) == false) then 
  1147. 			thread_kill(thread) 
  1148. 		end 
  1149. 	end 
  1150. 	for i, plane in pairs(M18_groups.stag_cargo_plane.planes) do 
  1151. 		if (thread_check_done(plane.thread_id) == false) then 
  1152. 			thread_kill(plane.thread_id) 
  1153. 		end 
  1154. 	end 
  1155. 		 
  1156. 	-- Unload any loaded personas 
  1157. 	for i, persona in pairs(M18_personas) do 
  1158. 		if (persona.persona_id ~= -1) then 
  1159. 			audio_persona_remove_2d(persona.persona_id) 
  1160. 			persona.persona_id = -1 
  1161. 		end 
  1162. 	end 
  1163. 	 
  1164. 	-- Make sure any VFX are cleaned up 
  1165. 	for i, vfx in pairs(M18_vfxs) do 
  1166. 		if (vfx.handle ~= -1) then 
  1167. 			effect_stop(vfx.handle) 
  1168. 			vfx.handle = -1 
  1169. 		end 
  1170. 	end 
  1171. 	 
  1172. 	-- Kill the fire VFX on any wreckage debris 
  1173. 	for i, effect_handle in pairs(M18_runtime.debirs_fire_handles) do 
  1174. 		if (effect_handle ~= -1) then 
  1175. 			effect_stop(effect_handle) 
  1176. 			effect_handle = -1 
  1177. 		end 
  1178. 	end 
  1179.  
  1180. 	-- Kill all the triggers 
  1181. 	for i, trigger in pairs(M18_triggers) do 
  1182. 		on_trigger("", trigger) 
  1183. 		trigger_enable(trigger, false) 
  1184. 	end 
  1185. 	 
  1186. 	-- Remove the fake notoriety 
  1187. 	hud_set_fake_notoriety("Police", false, 0) 
  1188. 	 
  1189. 	-- Restore the HUD 
  1190. 	for i, hud_state in pairs(M18_hud_states) do 
  1191. 		if (hud_state ~= -1) then 
  1192. 			hud_display_remove_state(hud_state) 
  1193. 			hud_state = -1 
  1194. 		end 
  1195. 	end 
  1196. 	 
  1197. 	-- Kill any playing conversation 
  1198. 	m18_helper_conversation_kill_all() 
  1199. 	 
  1200. 	-- Kill all the audio emitters 
  1201. 	for i, emitter in pairs(M18_audio_emitters) do 
  1202. 		if (type(emitter) == "table") then 
  1203. 			for j, sub_emitter in pairs(emitter) do 
  1204. 				audio_ambient_emitter_stop(sub_emitter) 
  1205. 			end 
  1206. 		else 
  1207. 			audio_ambient_emitter_stop(emitter) 
  1208. 		end 
  1209. 	end 
  1210. 	 
  1211. 	-- Clear any restricted camera 
  1212. 	camera_restrict_set_active(false) 
  1213. 	skydive_set_player_dive_fall_speed() 
  1214. 	 
  1215. 	-- Reset the wind 
  1216. 	wind_override_clear() 
  1217. 	 
  1218. 	-- Remove all temporary weapons and re-enable the weapon radial 
  1219. 	inv_weapon_remove_temporary(LOCAL_PLAYER, M18_tweak_values.player_smg) 
  1220. 	inv_weapon_remove_temporary(REMOTE_PLAYER, M18_tweak_values.player_smg) 
  1221. 	inv_weapon_disable_all_slots(false)	-- enable 
  1222. 	 
  1223. 	character_set_skydiving(LOCAL_PLAYER, false) 
  1224. 	inv_weapon_remove_temporary(LOCAL_PLAYER, "Pistol-Gang") 
  1225. 	clear_animation_state(LOCAL_PLAYER) 
  1226. 	character_set_never_fall(LOCAL_PLAYER, false) 
  1227. 	if (coop_is_active() == true) then 
  1228. 		character_set_skydiving(REMOTE_PLAYER, false) 
  1229. 		inv_weapon_remove_temporary(REMOTE_PLAYER, "Pistol-Gang") 
  1230. 		clear_animation_state(REMOTE_PLAYER) 
  1231. 		character_set_never_fall(REMOTE_PLAYER, false) 
  1232. 	end 
  1233. 	 
  1234. 	notoriety_reset("police") 
  1235. 	 
  1236. 	-- Turn peds, vehicles, and action nodes back on 
  1237. 	spawning_pedestrians(true) 
  1238. 	spawning_vehicles(true) 
  1239. 	action_nodes_enable(true)	 
  1240. 	 
  1241. 	city_zone_swap("m18", false) 
  1242. 	city_zone_swap("m18fx", false) 
  1243. end 
  1244.  
  1245.  
  1246. -- Called when the mission has ended with success 
  1247. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  1248. -- 
  1249. function m18_success() 
  1250. 	local skip_teleport = true 
  1251. 	m18_coop_skip(skip_teleport) -- do the stuff we'd do in the skip case 
  1252. end 
  1253.  
  1254.  
  1255. -- ************************* 
  1256. -- 
  1257. -- Local functions 
  1258. -- 
  1259. -- ************************* 
  1260.  
  1261. -- Initialize the mission for the specified checkpoint 
  1262. -- 
  1263. -- checkpoint:		Checkpoint to initialize the mission to 
  1264. -- 
  1265. function m18_initialize(checkpoint) 
  1266. 	-- Set the mission author 
  1267. 	set_mission_author("Matt.Gawalek") 
  1268.  
  1269. 	-- Common initialization 
  1270. 	m18_initialize_common() 
  1271.  
  1272. 	-- Checkpoint specific initialization 
  1273. 	m18_initialize_checkpoint(checkpoint) 
  1274. end 
  1275.  
  1276. -- *************************************************** 
  1277. -- m18_initialize Helper Functions 
  1278. -- *************************************************** 
  1279.  
  1280. -- Handle any common initialization 
  1281. -- 
  1282. function m18_initialize_common() 
  1283. 	-- Load the persona for Viola 
  1284. 	M18_personas.viola.persona_id = audio_persona_load_2d(M18_personas.viola.name) 
  1285. 	 
  1286. 	-- Kick of a thread to process conversation VO 
  1287. 	M18_threads.dialog = thread_new("m18_thread_process_conversations") 
  1288. 	 
  1289. 	-- Hide the minimap 
  1290. 	M18_hud_states.hide_minimap = hud_display_create_state() 
  1291. 	hud_display_set_element(M18_hud_states.hide_minimap, HUD_ELEM_MINIMAP, HUD_FADE_HIDDEN) 
  1292. 	hud_display_commit_state(M18_hud_states.hide_minimap) 
  1293. 	 
  1294. 	-- Hide all the debris that will be spawned when the cargo plane explodes 
  1295. 	for i, debris in pairs(M18_movers.wreckage_debris) do 
  1296. 		mesh_mover_hide(debris) 
  1297. 	end 
  1298. 	 
  1299. 	-- Lock the cargo bay door 
  1300. 	door_lock(M18_movers.cargo_bay_door, true) 
  1301. 	 
  1302. 	-- Disable notoriety 
  1303. 	notoriety_set_max("police", 0) 
  1304. 	 
  1305. 	-- Turn off peds, vehicles, and action nodes 
  1306. 	spawning_pedestrians(false) 
  1307. 	spawning_vehicles(false) 
  1308. 	action_nodes_enable(false) 
  1309. 	 
  1310. 	-- Set the cancel warp locations 
  1311. 	mission_set_cancel_warp_location(M18_navpoints.player_end[1], M18_navpoints.player_end[2]) 
  1312. end 
  1313.  
  1314. -- Checkpoint specific initialization 
  1315. -- 
  1316. -- checkpoint:		The checkpoint to be initialized 
  1317. function m18_initialize_checkpoint(checkpoint) 
  1318.  
  1319. 	if (checkpoint == M18_checkpoints.start) then 
  1320. 		-- Initialize the cargo plane interior 
  1321. 		m18_initialize_cargo_plane_interior() 
  1322. 		 
  1323. 	elseif (checkpoint == M18_checkpoints.cargo_plane_escape) then 
  1324. 		-- Initialize the cargo plane escape sequence 
  1325. 		m18_initialize_cargo_plane_escape() 
  1326. 		 
  1327. 		-- Start the music at the right spot 
  1328. 		audio_object_post_event(M18_audio_events.music_escape_checkpoint, nil, nil, LOCAL_PLAYER) 
  1329. 		 
  1330. 	elseif (checkpoint == M18_checkpoints.tank_free_fall or checkpoint == M18_checkpoints.dive_bombers) then 
  1331. 		-- Initialize the tank free falling  
  1332. 		m18_initialize_tank_free_fall(true) 
  1333. 		 
  1334. 		-- Start the music at the right spot 
  1335. 		audio_object_post_event(M18_audio_events.music_skydive_checkpoint, nil, nil, LOCAL_PLAYER) 
  1336. 		 
  1337. 	elseif (checkpoint == M18_checkpoints.debug_bail_out) then 
  1338. 		-- Create the group for the cargo plane that the tank is going to smash into 
  1339. 		group_create_hidden(M18_groups.stag_cargo_plane.name, true) 
  1340. 		 
  1341. 		-- Initialize the tank free falling  
  1342. 		m18_initialize_tank_free_fall() 
  1343. 		 
  1344. 		skydive_setup_tank_bailout(1)		 
  1345.  
  1346. 		interior_disable_exterior(M18_interiors.skydiving_volume, false) 
  1347. 		if (M18_vfxs.city.handle ~= -1) then 
  1348. 			effect_stop(M18_vfxs.city.handle)	 
  1349. 			M18_vfxs.city.handle = -1 
  1350. 		end 
  1351. 		--[[ 
  1352. 		if (M18_vfxs.bottom_clouds.handle ~= -1) then 
  1353. 			effect_stop(M18_vfxs.bottom_clouds.handle)	 
  1354. 			M18_vfxs.bottom_clouds.handle = -1 
  1355. 		end	 
  1356. 		--]] 
  1357. 		 
  1358. 		-- Start the music at the right spot 
  1359. 		audio_object_post_event(M18_audio_events.music_skydive_checkpoint, nil, nil, LOCAL_PLAYER) 
  1360. 		 
  1361. 		-- Make sure the player's tank is using the right orient 
  1362. 		vehicle_skydiving_start(M18_groups.player_tank.tank, M18_navpoints.player_tank_orient_04) 
  1363. 		vehicle_skydiving_move_to_do(M18_groups.player_tank.tank, M18_navpoints.player_tank_center_pos, 0.0, 2.0) 
  1364. 	end 
  1365. end 
  1366.  
  1367. -- Common initialization for the cargo plane checkpoints  
  1368. function m18_initialize_cargo_plane_common() 
  1369. 	-- Change to the scripted camera to pull it it tighter to the player 
  1370. 	camera_script_enable() 
  1371.  
  1372. 	-- Create all the script objects for the cargo plane 
  1373. 	-- Create all the script objects for the cargo plane 
  1374. 	group_create(M18_groups.cargo_plane_tanks.name, true) 
  1375. 	 
  1376. 	-- Initialize the tanks 
  1377. 	for i, tank in pairs(M18_groups.cargo_plane_tanks.tanks) do 
  1378. 		set_unjackable_flag(tank, true) 
  1379. 		turn_invulnerable(tank) 
  1380. 	end 
  1381. 	 
  1382. 	-- Turn on the ambient audio emitters 
  1383. 	for i, emitter in pairs(M18_audio_emitters.plane_interior) do 
  1384. 		audio_ambient_emitter_start(emitter) 
  1385. 	end 
  1386. 	 
  1387. 	inv_weapon_add_temporary(LOCAL_PLAYER, "Pistol-Gang", 1, true, true) 
  1388. 	if (coop_is_active() == true) then 
  1389. 		inv_weapon_add_temporary(REMOTE_PLAYER, "Pistol-Gang", 1, true, true) 
  1390. 	end 
  1391. end 
  1392.  
  1393. -- *************************************************** 
  1394. -- m18_run Helper Functions 
  1395. -- *************************************************** 
  1396.  
  1397. -- This is the primary function responsible for running the entire mission from start to finish. 
  1398. -- 
  1399. -- first_checkpoint:	The first checkpoint to begin running the mission at 
  1400. -- 
  1401. function m18_run(first_checkpoint) 
  1402. 	local current_checkpoint = first_checkpoint 
  1403.  
  1404. 	-- Run the mission from the beginning 
  1405. 	if (current_checkpoint == M18_checkpoints.start) then 
  1406. 		-- Cargo Plane [Part 1] - Destroy the cockpit 
  1407. 		m18_run_cargo_plane_open_cockpit() 
  1408. 		m18_cleanup_cargo_plane_open_cockpit() 
  1409. 		 
  1410. 		-- Set the checkpoint 
  1411. 		current_checkpoint = M18_checkpoints.cargo_plane_escape 
  1412. 		mission_set_checkpoint(M18_checkpoints.cargo_plane_escape, true) 
  1413. 	end 
  1414. 	 
  1415. 	if (current_checkpoint == M18_checkpoints.cargo_plane_escape) then 
  1416. 		-- Cargo Plane Escape [Part 1] - Escape 
  1417. 		m18_run_cargo_plane_escape() 
  1418. 		 
  1419. 		-- Cargo Plane Escape [Part 2] - Transition to Tank Free Fall 
  1420. 		m18_run_cargo_plane_escape_scene() 
  1421. 		 
  1422. 		-- Clean-up the cargo plane and setup the free fall 
  1423. 		m18_cleanup_cargo_plane_interior() 
  1424. 		m18_initialize_tank_free_fall(true) 
  1425.  
  1426. 		mission_start_fade_in() -- fade back in after. the cutscene left the screen faded out 
  1427. 		 
  1428. 		-- Set the checkpoint 
  1429. 		current_checkpoint = M18_checkpoints.tank_free_fall 
  1430. 		mission_set_checkpoint(M18_checkpoints.tank_free_fall, true) 
  1431. 	end 
  1432. 		 
  1433. 	if (current_checkpoint == M18_checkpoints.tank_free_fall) then 
  1434. 		-- Tank Free Fall [Part 1] - Kill the initial bad guys 
  1435. 		m18_run_ff_set_01() 
  1436. 			 
  1437. 		-- Tank Free Fall [Part 2] - VTOL flybys (including the VTOL that crashes into the player's tank) 
  1438. 		m18_run_ff_vtol_flybys_01() 
  1439. 			 
  1440. 		-- Tank Free Fall [Part 3] - Tank flip exposes more enemies to kill 
  1441. 		m18_run_ff_set_02() 
  1442. 		 
  1443. 		-- Tank Free Fall [Part 4] - Second VTOL flybys 
  1444. 		m18_run_ff_vtol_flybys_02() 
  1445. 		 
  1446. 		current_checkpoint = M18_checkpoints.dive_bombers 
  1447. 		mission_set_checkpoint(M18_checkpoints.dive_bombers, true) 
  1448. 	end 
  1449. 	 
  1450. 	if (current_checkpoint == M18_checkpoints.dive_bombers) then 
  1451. 		-- Process dive-bomber wave 01 
  1452. 		m18_run_ff_vtol_dive_bombers_01()		 
  1453. 		 
  1454. 		current_checkpoint = M18_checkpoints.debug_bail_out 
  1455. 	end 
  1456. 	 
  1457. 	if (current_checkpoint == M18_checkpoints.debug_bail_out) then 
  1458. 		-- Tank Free Fall [Part 4] - The tank smashes into a cargo plane 
  1459. 		m18_run_bail_out_of_tank() 
  1460. 		m18_run_hijack_skydiving_tank() 
  1461. 	end 
  1462. 	 
  1463. 	delay(2.0) 
  1464. 	 
  1465. 	--[[ DO SOME IMMEDIATE CLEANUP ]]-- 
  1466. 	 
  1467. 	-- Start fading out now 
  1468. 	mission_start_fade_out() 
  1469. 	 
  1470. 	-- Kill the thread processing the random clouds (needs to happen before we clean up M18_vfx) 
  1471. 	thread_kill(M18_threads.random_clouds) 
  1472. 	 
  1473. 	-- Make sure any VFX are cleaned up 
  1474. 	for i, vfx in pairs(M18_vfxs) do 
  1475. 		if (vfx.handle ~= -1) then 
  1476. 			effect_stop(vfx.handle) 
  1477. 			vfx.handle = -1 
  1478. 		end 
  1479. 	end 
  1480. 	 
  1481. 	-- Kill the fire VFX on any wreckage debris 
  1482. 	for i, effect_handle in pairs(M18_runtime.debirs_fire_handles) do 
  1483. 		if (effect_handle ~= -1) then 
  1484. 			effect_stop(effect_handle) 
  1485. 			effect_handle = -1 
  1486. 		end 
  1487. 	end 
  1488. 	 
  1489. 	-- Make sure there aren't any special vehicle VFX still playing 
  1490. 	for i, tank_group in pairs(M18_runtime.skydiving_tanks) do 
  1491. 		m18_helper_cleanup_skydiving_tank_common(tank_group) 
  1492. 	end 
  1493. 	m18_helper_cleanup_skydiving_tank_common(M18_groups.player_tank) 
  1494. 	m18_helper_cleanup_skydiving_tank_common(M18_groups.skydiving_tank.tank_group) 
  1495. 	 
  1496. 	-- Cleanup any groups that are still loaded 
  1497. 	for i, group in pairs(M18_groups) do 
  1498. 		if (group_is_loaded(group.name) == true) then 
  1499. 			group_destroy(group.name) 
  1500. 		end 
  1501. 	end 
  1502. 	 
  1503. 	-- Call mission success?? 
  1504. 	mission_end_success("m18", M18_cutscenes.mission_outro, M18_navpoints.player_end) 
  1505. end 
  1506.  
  1507.  
  1508. --[[ 
  1509. 	Cargo Plane [Part 1] - Destroy the cockpit 
  1510. --]] 
  1511.  
  1512. -- Initialize the cargo plane interior 
  1513. function m18_initialize_cargo_plane_interior() 
  1514. 	group_create(M18_groups.cargo_plane_interior.name, true) 
  1515. 	 
  1516. 	-- Initialize the grunts 
  1517. 	for i, squad in pairs(M18_groups.cargo_plane_interior.grunt_squads) do 
  1518. 		for j, grunt in pairs(squad.grunts) do 
  1519. 			character_set_combat_ready(grunt, true) 
  1520. 			follower_make_independent(grunt, true) 
  1521. 			ai_set_action_delay(grunt, "throw grenade", 9999) 
  1522. 			on_take_damage("m18_cb_gooing_people", grunt) 
  1523. 		end 
  1524. 	end 
  1525. 	 
  1526. 	-- Make the dead guys dead 
  1527. 	for i, dead_guy in pairs(M18_groups.cargo_plane_interior.dead_guys) do 
  1528. 		character_kill(dead_guy) 
  1529. 	end	 
  1530.  
  1531. 	-- Force equip whatever's in the pistol slot 
  1532. 	local pistol_type = inv_item_in_slot(LOCAL_PLAYER, "pistol") 
  1533. 	inv_item_equip(pistol_type) 
  1534. 	 
  1535. 	-- Handle any common initialization for the cargo plane 
  1536. 	m18_initialize_cargo_plane_common() 
  1537. 	 
  1538. 	-- Start the camera shake for the cargo plane interior 
  1539. 	camera_shake_play_looping("cargo_plane_interior", M18_tweak_values.escape_looping_cam_shake_amount) 
  1540. 	 
  1541. 	-- Make all of the boxes invulnerable (until the player gets the sonic gun) 
  1542. 	for i, box_group in pairs(M18_movers.plane_boxes_01) do 
  1543. 		mesh_mover_set_invulnerable(box_group.box, true) 
  1544. 	end 
  1545. 	 
  1546. 	-- Start the camera shake for the cargo plane interior 
  1547. 	camera_shake_play_looping(M18_tweak_values.ambient_plane_camera_shake, M18_tweak_values.ambient_plane_camera_shake_intensity) 
  1548. 	 
  1549. 	delay(0.2) 
  1550. end 
  1551.  
  1552. -- Setup and process the mission leading up to the player destroying the cockpit door 
  1553. function m18_run_cargo_plane_open_cockpit() 
  1554. 	-- Add the objective text 
  1555. 	objective_text(0, M18_objectives.get_to_the_cockpit.tag, nil, nil, SYNC_ALL, M18_objectives.get_to_the_cockpit.icon) 
  1556. 	 
  1557. 	-- Start the music 
  1558. 	audio_object_post_event(M18_audio_events.music_start, nil, nil, LOCAL_PLAYER) 
  1559. 	 
  1560. 	hud_set_fake_notoriety("Police", true, 1)  
  1561. 	 
  1562. 	M18_runtime.num_grunts_to_reach_catwalk = 0 
  1563. 	 
  1564. 	-- Register a callback for when a sonic gun is picked-up by the player 
  1565. 	M18_flags.sonic_gun_aquired = false 
  1566.  
  1567. 	-- Enable the trigger for the cabin door 
  1568. 	M18_flags.cabin_door_open_attempted = false 
  1569. 	trigger_enable(M18_triggers.cabin_door, true) 
  1570. 	on_trigger("m18_cb_triggered_cabin_door", M18_triggers.cabin_door) 
  1571. 	marker_add_trigger(M18_triggers.cabin_door, MINIMAP_ICON_USE, INGAME_EFFECT_LOCATION, OI_ASSET_USE, OI_FLAGS_FULL) 
  1572. 	 
  1573. 	-- Enable the trigger for the cockpit door destruction region 
  1574. 	M18_flags.in_cabin_destruction_region_local = false 
  1575. 	M18_flags.in_cabin_destruction_region_remote = false 
  1576. 	trigger_enable(M18_triggers.cabin_door_region, true) 
  1577. 	on_trigger("m18_cb_cabin_door_region_entered", M18_triggers.cabin_door_region) 
  1578. 	on_trigger_exit("m18_cb_cabin_door_region_exited", M18_triggers.cabin_door_region) 
  1579. 	 
  1580. 	-- Setup the cabin door that gets destroyed by the sonic gun 
  1581. 	M18_flags.cabin_door_destroyed = false 
  1582. 	M18_flags.cockpit_door_destroyed = false  
  1583. 	set_current_hit_points(M18_movers.cabin_door, 100000000) 
  1584. 	set_current_hit_points(M18_movers.cockpit_door, 100000000) 
  1585. 	on_take_damage("m18_cb_damaged_cabin_door", M18_movers.cabin_door) 
  1586. 	on_take_damage("m18_cb_damaged_cockpit_door", M18_movers.cockpit_door) 
  1587. 	 
  1588. 	trigger_enable(M18_triggers.start_combat, true) 
  1589. 	on_trigger("m18_start_combat_cb", M18_triggers.start_combat) 
  1590.  
  1591. 	-- Wait until the cabin door has been destroyed 
  1592. 	while(M18_flags.cabin_door_destroyed == false) do 
  1593. 		thread_yield() 
  1594. 	end 
  1595. 	 
  1596. 	-- Enable the trigger for the cockpit door destruction region 
  1597. 	M18_flags.in_door_destruction_region_local = false 
  1598. 	M18_flags.in_door_destruction_region_remote = false 
  1599. 	trigger_enable(M18_triggers.cockpit_door_region, true) 
  1600. 	on_trigger("m18_cb_cargo_door_region_entered", M18_triggers.cockpit_door_region) 
  1601. 	on_trigger_exit("m18_cb_cargo_door_region_exited", M18_triggers.cockpit_door_region) 
  1602. 	marker_add(M18_navpoints.cockpit_door_marker, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  1603. 	 
  1604. 	delay(1.0) 
  1605. 	m18_helper_conversation_play(M18_convo.mission_start, M18_CONVO_PLAY_LAST, 0.2) 
  1606. 	 
  1607. 	-- Wait until the cock pit door has been destroyed 
  1608. 	while(M18_flags.cockpit_door_destroyed == false) do 
  1609. 		thread_yield() 
  1610. 	end 
  1611. end 
  1612.  
  1613. -- Callback for when the player triggers the combat area in the plane interior 
  1614. function m18_start_combat_cb(player, trigger) 
  1615. 	-- Kill the trigger 
  1616. 	trigger_enable(M18_triggers.start_combat, false) 
  1617. 	on_trigger("", M18_triggers.start_combat) 
  1618. 	ai_do_scripted_move(M18_groups.cargo_plane_interior.grunt_squads.catwalk.grunts[1], M18_navpoints.grunt_catwalk_positions[1], true, false) 
  1619. 	-- ai_do_scripted_move(M18_groups.cargo_plane_interior.grunt_squads.catwalk.grunts[2], M18_navpoints.grunt_catwalk_positions[2], true, false) 
  1620. 	 
  1621. 	-- Queue up a conversation 
  1622. 	delay(2.0) 
  1623. 	m18_helper_conversation_play(M18_convo.plane_combat, M18_CONVO_PLAY_LAST, 3.0) 
  1624. 	m18_helper_conversation_play(M18_convo.falling_out_bad, M18_CONVO_PLAY_LAST, 1.5) 
  1625. end 
  1626.  
  1627. -- Callback for when the player attempts to open the cock pit door manualy (and fails to do so) 
  1628. -- 
  1629. -- player:		Player that attempted to open the cockpit door 
  1630. -- trigger:		The trigger 
  1631. function m18_cb_triggered_cabin_door(player, trigger) 
  1632. 	M18_flags.sonic_gun_failed_once = false 
  1633. 	 
  1634. 	-- Handle special behavior if this is the first attempt to open the door 
  1635. 	if (M18_flags.cabin_door_open_attempted == false) then 
  1636. 		-- Remove the marker for the trigger region 
  1637. 		marker_remove_trigger(M18_triggers.cabin_door) 
  1638. 		trigger_enable(M18_triggers.cabin_door, false) 
  1639. 		 
  1640. 		-- Get the animation group for the player's currently equipped weapon 
  1641. 		local anim_group = nil 
  1642. 		local equipped_weapon = inv_item_get_equipped_item(player) 
  1643. 		if (equipped_weapon ~= nil) then 
  1644. 			anim_group = inv_item_get_anim_group(equipped_weapon) 
  1645. 		end 
  1646. 		 
  1647. 		-- Make sure they have a weapon of the right type equipped to play the animation (pistol, dualpistol, rifle, or RPG) 
  1648. 		if (anim_group ~= "Pistol" and anim_group ~= "DualPistol" and anim_group ~= "Rifle" and anim_group ~= "RPG") then 
  1649. 			-- Force equip the pistol we previously gave the player 
  1650. 			inv_item_equip(inv_item_in_slot(player, "Pistol"), player) 
  1651. 		end 
  1652.  
  1653. 		-- Play the "door locked" action on the player that is trying to open the door -- 
  1654. 		action_play(player, "door locked", "", false, 0.27, true, true, M18_navpoints.cabin_door_marker) 
  1655. 		 
  1656. 		-- Play the thud audio for the kick 
  1657. 		audio_object_post_event(M18_audio_events.kick_door, nil, nil, M18_triggers.cabin_door) 
  1658. 		 
  1659. 		-- Wait for the animation to finish all the way 
  1660. 		while(action_play_is_finished(player,0.7) == false) do 
  1661. 			thread_yield() 
  1662. 		end 
  1663. 		 
  1664. 		-- Play a conversation 
  1665. 		m18_helper_conversation_play(M18_convo.cockpit_locked_no_gun, M18_CONVO_PLAY_NEXT, 1.5, player) 
  1666. 		delay(2.0) 
  1667. 		 
  1668. 		-- They don't have the sonic gun, so mark the gun and update the objective 
  1669. 		trigger_enable(M18_triggers.gun_crate_001, true) 
  1670. 		trigger_enable(M18_triggers.gun_crate_002, true) 
  1671. 		trigger_enable(M18_triggers.gun_crate_003, true) 
  1672. 		on_trigger("m18_cb_gun_crate_empty", M18_triggers.gun_crate_001) 
  1673. 		on_trigger("m18_cb_gun_crate_empty", M18_triggers.gun_crate_002) 
  1674. 		on_trigger("m18_cb_gun_crate_give_sonic_gun", M18_triggers.gun_crate_003) 
  1675. 		marker_add_trigger(M18_triggers.gun_crate_001, MINIMAP_ICON_USE, INGAME_EFFECT_LOCATION, OI_ASSET_USE, OI_FLAGS_FULL) 
  1676. 		marker_add_trigger(M18_triggers.gun_crate_002, MINIMAP_ICON_USE, INGAME_EFFECT_LOCATION, OI_ASSET_USE, OI_FLAGS_FULL) 
  1677. 		marker_add_trigger(M18_triggers.gun_crate_003, MINIMAP_ICON_USE, INGAME_EFFECT_LOCATION, OI_ASSET_USE, OI_FLAGS_FULL) 
  1678. 		objective_text(0, M18_objectives.search_for_gun.tag, nil, nil, SYNC_ALL, M18_objectives.search_for_gun.icon) 
  1679.  
  1680. 		M18_flags.cabin_door_open_attempted = true 
  1681. 	end 
  1682. end 
  1683.  
  1684. -- Callback for when a player enters the cabin door destruction region 
  1685. -- 
  1686. -- player:		The player that entered the region around the cabin door 
  1687. -- trigger:		The trigger that the player entered 
  1688. function m18_cb_cabin_door_region_entered(player, trigger) 
  1689. 	-- Update the status on the player entering the region 
  1690. 	if (player == LOCAL_PLAYER) then 
  1691. 		M18_flags.in_cabin_destruction_region_local = true 
  1692. 	elseif (player == REMOTE_PLAYER) then 
  1693. 		M18_flags.in_cabin_destruction_region_remote = true 
  1694. 	end 
  1695. end 
  1696.  
  1697. -- Callback for when a player enters the cargo door destruction region 
  1698. -- 
  1699. -- player:		The player that entered the region around the cockpit door 
  1700. -- trigger:		The trigger that the player entered 
  1701. function m18_cb_cargo_door_region_entered(player, trigger) 
  1702. 	-- Update the status on the player entering the region 
  1703. 	if (player == LOCAL_PLAYER) then 
  1704. 		M18_flags.in_door_destruction_region_local = true 
  1705. 	elseif (player == REMOTE_PLAYER) then 
  1706. 		M18_flags.in_door_destruction_region_remote = true 
  1707. 	end 
  1708. end 
  1709.  
  1710. -- Callback for when a player exits the cabin door destruction region 
  1711. -- 
  1712. -- player:		The player the exited the region around the cabin door 
  1713. -- trigger:		The trigger that the player exited 
  1714. function m18_cb_cabin_door_region_exited(player, trigger) 
  1715. 	-- Update the status on the player leaving the region 
  1716. 	if (player == LOCAL_PLAYER) then 
  1717. 		M18_flags.in_cabin_destruction_region_local = false 
  1718. 	elseif (player == REMOTE_PLAYER) then 
  1719. 		M18_flags.in_cabin_destruction_region_remote = false 
  1720. 	end 
  1721. end 
  1722.  
  1723. -- Callback for when a player exits the cargo door destruction region 
  1724. -- 
  1725. -- player:		The player the exited the region around the cockpit door 
  1726. -- trigger:		The trigger that the player exited 
  1727. function m18_cb_cargo_door_region_exited(player, trigger) 
  1728. 	-- Update the status on the player leaving the region 
  1729. 	if (player == LOCAL_PLAYER) then 
  1730. 		M18_flags.in_door_destruction_region_local = false 
  1731. 	elseif (player == REMOTE_PLAYER) then 
  1732. 		M18_flags.in_door_destruction_region_remote = false 
  1733. 	end 
  1734. end 
  1735.  
  1736. -- Callback for when the player enters the Get-To-A-Tank trigger 
  1737. -- function m18_cb_to_tank_trigger() 
  1738. -- 	vehicle_suppress_npc_exit(M18_groups.cargo_plane_tanks.tanks[4], true) 
  1739. -- 	vehicle_enter(M18_groups.cargo_plane_interior.grunt_squads.mechanics.grunts[1], M18_groups.cargo_plane_tanks.tanks[4], 0, false, false) 
  1740. -- end 
  1741.  
  1742. -- Callback for when the cockpit door is damaged by the sonic gun 
  1743. -- 
  1744. -- mover:			The mover that was damaged (the door) 
  1745. -- attacker:		The person that damaged the door 
  1746. -- hitpoints:		The remaining hitpoints for the door 
  1747. -- from_explosion:	Whether the damage came from an explosion 
  1748. -- from_melee:		Whether the damage came from a melee attack 
  1749. -- from_sonic:		Whether the damage came from a sonic gun attack 
  1750. function m18_cb_damaged_cockpit_door(mover, attacker, hitpoints, from_explosion, from_melee, from_sonic) 
  1751. 	if (from_sonic == true) then 
  1752. 		-- If all weapons have been aquired, then check if the player attacking the door is in the destruction region 
  1753. 		if (M18_flags.sonic_gun_aquired == true and ((M18_flags.in_door_destruction_region_local == true and attacker == LOCAL_PLAYER) or 
  1754. 			(M18_flags.in_door_destruction_region_remote == true and attacker == REMOTE_PLAYER)) ) then 
  1755. 			 
  1756. 			-- The destruction conditions have been met, destroy the door 
  1757. 			set_current_hit_points(M18_movers.cockpit_door, 0) 
  1758. 			 
  1759. 			-- Play some SFX 
  1760. 			audio_object_post_event(M18_audio_events.destroy_cockpit, nil, nil, M18_navpoints.cockpit_door_marker) 
  1761. 			 
  1762. 			-- Flag the cockpit door as destroyed 
  1763. 			M18_flags.cockpit_door_destroyed = true 
  1764. 	 
  1765. 			-- Play the explosion effect 
  1766. 			M18_vfxs.cockpit_door_explosion.handle = effect_play(M18_vfxs.cockpit_door_explosion.nav) 
  1767. 		else 
  1768. 			-- The player that damaged the door is not in the destruction region, repair the door 
  1769. 			set_current_hit_points(M18_movers.cockpit_door, 100000000) 
  1770. 			 
  1771. 			-- Check if all players have the weapon 
  1772. 			if (M18_flags.sonic_gun_aquired == true) then 
  1773. 				if (M18_flags.played_too_far_away_conversation == false) then 
  1774. 					-- Play a conversation, to tell the player to get closer 
  1775. 					m18_helper_conversation_play(M18_convo.not_close_enough, M18_CONVO_PLAY_NEXT, 1.0, attacker) 
  1776. 					-- m18_run_placeholder_dialog_lines(M18_placholder_dialog.too_far_away[1], false) 
  1777. 					M18_flags.played_too_far_away_conversation = true 
  1778. 				else 
  1779. 					-- Play a conversation, to tell the player to get closer 
  1780. 					-- m18_run_placeholder_dialog_lines(M18_placholder_dialog.too_far_away[2], false) 
  1781. 				end 
  1782. 			end 
  1783. 		end 
  1784. 	end 
  1785. end 
  1786.  
  1787. -- Callback for when the cabin door is damaged 
  1788. -- 
  1789. -- mover:			The mover that was damaged (the door) 
  1790. -- attacker:		The person that damaged the door 
  1791. -- hitpoints:		The remaining hitpoints for the door 
  1792. -- from_explosion:	Whether the damage came from an explosion 
  1793. -- from_melee:		Whether the damage came from a melee attack 
  1794. -- from_sonic:		Whether the damage came from a sonic gun attack 
  1795. function m18_cb_damaged_cabin_door(mover, attacker, hitpoints, from_explosion, from_melee, from_sonic) 
  1796. 	if (from_sonic == true) then 
  1797. 		-- If all weapons have been aquired, then check if the player attacking the door is in the destruction region 
  1798. 		if (M18_flags.sonic_gun_aquired == true and ((M18_flags.in_cabin_destruction_region_local == true and attacker == LOCAL_PLAYER) or 
  1799. 			(M18_flags.in_cabin_destruction_region_remote == true and attacker == REMOTE_PLAYER)) ) then 
  1800. 			 
  1801. 			-- The destruction conditions have been met, destroy the door 
  1802. 			set_current_hit_points(M18_movers.cabin_door, 0) 
  1803. 			audio_object_post_event(M18_audio_events.destroy_door, nil, nil, M18_navpoints.cabin_door_marker) 
  1804. 			 
  1805. 			-- Flag the cockpit door as destroyed 
  1806. 			M18_flags.cabin_door_destroyed = true 
  1807. 	 
  1808. 			-- Cleanup the cabin door mover 
  1809. 			on_take_damage("", M18_movers.cabin_door) 
  1810. 		 
  1811. 			marker_remove(M18_navpoints.cabin_door_marker) 
  1812. 			marker_remove_trigger(M18_triggers.cabin_door) 
  1813. 		else 
  1814. 			-- The player that damaged the door is not in the destruction region, repair the door 
  1815. 			--mesh_mover_reset(M18_movers.cabin_door) 
  1816. 			set_current_hit_points(M18_movers.cabin_door, 100000000) 
  1817. 			 
  1818. 			-- Check if all players have the weapon 
  1819. 			if (M18_flags.sonic_gun_aquired == true) then 
  1820. 				if (M18_flags.played_too_far_away_conversation == false) then 
  1821. 					-- Play a conversation, to tell the player to get closer 
  1822. 					m18_helper_conversation_play(M18_convo.not_close_enough, M18_CONVO_PLAY_NEXT, 1.0, attacker) 
  1823. 					-- m18_run_placeholder_dialog_lines(M18_placholder_dialog.too_far_away[1], false) 
  1824. 					M18_flags.played_too_far_away_conversation = true 
  1825. 				else 
  1826. 					-- Play a conversation, to tell the player to get closer 
  1827. 					-- m18_run_placeholder_dialog_lines(M18_placholder_dialog.too_far_away[2], false) 
  1828. 				end 
  1829. 			end 
  1830. 		end 
  1831. 	elseif (character_is_player(attacker)) then 
  1832. 		if (M18_flags.cabin_door_open_attempted == true) then 
  1833. 			if (M18_flags.sonic_gun_aquired == true) then 
  1834. 				-- Play a conversation, to tell the player to try the sonic gun 
  1835. 				-- m18_run_placeholder_dialog_lines(M18_placholder_dialog.door_damaged_with_gun, false) 
  1836. 			else 
  1837. 				-- Play a conversation, to tell the player to look for the gun 
  1838. 				if (m18_helper_conversation_playing_or_queued(M18_convo.cockpit_locked_no_gun) == false) then 
  1839. 					m18_helper_conversation_play(M18_convo.cockpit_locked_no_gun, M18_CONVO_PLAY_NEXT, 1.0, attacker) 
  1840. 				end 
  1841. 			end 
  1842. 		end 
  1843. 	end 
  1844. end 
  1845.  
  1846. -- Callback for when the player gooes someone in the interior 
  1847. function m18_cb_gooing_people(npc, attacker, hitpoints, from_explosion, from_melee, from_sonic) 
  1848. 	if ((from_sonic == true) and (hitpoints <= 0)) then 
  1849. 		m18_helper_conversation_play(M18_convo.gooing_people, M18_CONVO_PLAY_NEXT, 1.0, attacker) 
  1850. 		for i, squad in pairs(M18_groups.cargo_plane_interior.grunt_squads) do 
  1851. 			for j, grunt in pairs(squad.grunts) do 
  1852. 				if (character_exists(grunt)) then 
  1853. 					on_take_damage("", grunt) 
  1854. 				end 
  1855. 			end 
  1856. 		end 
  1857. 	end 
  1858. end 
  1859.  
  1860. -- Clean-up the portion of the mission leading up to opening the cockpit door 
  1861. function m18_cleanup_cargo_plane_open_cockpit() 
  1862. 	-- Exit the special camera mode 
  1863. 	camera_script_disable() 
  1864.  
  1865. 	-- Clean-up the sonic guns 
  1866. 	trigger_enable(M18_triggers.gun_crate_001, false) 
  1867. 	trigger_enable(M18_triggers.gun_crate_002, false) 
  1868. 	trigger_enable(M18_triggers.gun_crate_003, false) 
  1869. 	marker_remove_trigger(M18_triggers.gun_crate_001, SYNC_ALL) 
  1870. 	marker_remove_trigger(M18_triggers.gun_crate_002, SYNC_ALL) 
  1871. 	marker_remove_trigger(M18_triggers.gun_crate_003, SYNC_ALL) 
  1872. 	on_trigger("", M18_triggers.gun_crate_001) 
  1873. 	on_trigger("", M18_triggers.gun_crate_002) 
  1874. 	on_trigger("", M18_triggers.gun_crate_003) 
  1875. 	 
  1876. 	-- Cleanup the Get-To-A-Tank trigger 
  1877. 	-- on_trigger("", M18_triggers.to_tank) 
  1878. 	 
  1879. 	-- Cleanup the cabin door trigger 
  1880. 	on_trigger("", M18_triggers.cabin_door) 
  1881. 	trigger_enable(M18_triggers.cabin_door, false) 
  1882. 	marker_remove_trigger(M18_triggers.cabin_door) 
  1883. 	 
  1884. 	-- Cleanup the cabin door destruction trigger 
  1885. 	on_trigger("", M18_triggers.cabin_door_region) 
  1886. 	on_trigger_exit("", M18_triggers.cabin_door_region) 
  1887. 	trigger_enable(M18_triggers.cabin_door_region) 
  1888. 	 
  1889. 	-- Cleanup the cabin door mover 
  1890. 	on_take_damage("", M18_movers.cabin_door) 
  1891. 	marker_remove(M18_navpoints.cabin_door_marker) 
  1892. 	 
  1893. 	-- Cleanup the cockpit door destruction trigger 
  1894. 	on_trigger("", M18_triggers.cockpit_door_region) 
  1895. 	on_trigger_exit("", M18_triggers.cockpit_door_region) 
  1896. 	trigger_enable(M18_triggers.cockpit_door_region) 
  1897. 	 
  1898. 	-- Cleanup the cockpit door mover 
  1899. 	on_take_damage("", M18_movers.cockpit_door) 
  1900. 	marker_remove(M18_navpoints.cockpit_door_marker) 
  1901. 	 
  1902. 	-- Stop the camera shake 
  1903. 	camera_shake_stop() 
  1904. end 
  1905.  
  1906.  
  1907. --[[ 
  1908. 	Cargo Plane Escape [Part 1] - Escape 
  1909. --]] 
  1910.  
  1911. -- Initialize the cargo plane escape sequence 
  1912. function m18_initialize_cargo_plane_escape() 
  1913. 	-- Set the ragdoll restore position, so characters don't get teleported outside of the cargo plane 
  1914. 	character_ragdoll_set_last_resort_position(M18_navpoints.player_start_escape[1]) 
  1915.  
  1916. 	-- Teleport the players to the cargo plane 
  1917. 	teleport_coop(M18_navpoints.player_start_escape[1], M18_navpoints.player_start_escape[2], true) 
  1918. 	 
  1919. 	-- Handle any common initialization for the cargo plane 
  1920. 	m18_initialize_cargo_plane_common() 
  1921. 		 
  1922. 	-- Give the players the sonic gun 
  1923. 	inv_weapon_add_temporary(LOCAL_PLAYER, "Special-SonicGun", 1, true, true, false) 
  1924. 	if (coop_is_active() == true) then 
  1925. 		inv_weapon_add_temporary(REMOTE_PLAYER, "Special-SonicGun", 1, true, true, false) 
  1926. 	end 
  1927. 	 
  1928. 	-- Destroy the cockpit door 
  1929. 	set_current_hit_points(M18_movers.cockpit_door, 0) 
  1930. 	set_current_hit_points(M18_movers.cabin_door, 0) 
  1931. 	--mesh_mover_kill(M18_movers.cockpit_door) 
  1932. 	--mesh_mover_kill(M18_movers.cabin_door) 
  1933. end 
  1934.  
  1935. -- Setup and process for the player escaping the cargo plane in a tank 
  1936. function m18_run_cargo_plane_escape() 
  1937. 	-- Start some camera shakes 
  1938. 	camera_shake_play("explosion_very_large", M18_tweak_values.escape_initial_cam_shake_amount) 
  1939. 	camera_shake_play_looping("m18_plane_crash", M18_tweak_values.escape_looping_cam_shake_amount) 
  1940. 	trigger_enable(M18_triggers.stumble_01, true) 
  1941. 	on_trigger("m18_stumble_cb_alt", M18_triggers.stumble_01) 
  1942. 	trigger_enable(M18_triggers.stumble_02, true) 
  1943. 	on_trigger("m18_stumble_cb", M18_triggers.stumble_02) 
  1944. 	 
  1945. 	-- Start a thread to make the boxes on the plane jiggle around in the turbulance 
  1946. 	M18_threads.box_jiggle = thread_new("m18_thread_process_box_jiggle") 
  1947. 	 
  1948. 	-- Start a thread to play some dust VFX falling from the cargo plane ceiling 
  1949. 	M18_threads.plane_dust = thread_new("m18_thread_do_plane_dust_vfx") 
  1950. 	 
  1951. 	-- Play the music 
  1952. 	audio_object_post_event(M18_audio_events.music_plane_crashing, nil, nil, LOCAL_PLAYER) 
  1953. 	 
  1954. 	-- Call the stumble callback directly to make everyone stumble 
  1955. 	m18_stumble_cb() 
  1956.  
  1957. 	-- Set some fake notoriety (HUD) 
  1958. 	hud_set_fake_notoriety("Police", true, 3)  
  1959. 	 
  1960. 	-- Make them drunk 
  1961. 	drug_effect_set_override_values(M18_tweak_values.escape_drunk_amount, M18_tweak_values.escape_high_amount) 
  1962. 	 
  1963. 	-- Turn on the cabin wind VFX 
  1964. 	M18_vfxs.plane_wind.handle = effect_play(M18_vfxs.plane_wind.nav, true, SYNC_ALL) 
  1965. 	 
  1966. 	-- Start the plane crashing audio emitters 
  1967. 	for i, emitter in pairs(M18_audio_emitters.plane_crashing) do 
  1968. 		audio_ambient_emitter_start(emitter) 
  1969. 	end 
  1970. 	 
  1971. 	-- Open the lower door, spawn dudes 
  1972. 	door_open(M18_movers.lower_door) 
  1973. 	group_create(M18_groups.stag_reinf.name) 
  1974. 	for i, char in pairs(M18_groups.stag_reinf.chars) do 
  1975. 		ai_do_scripted_advance(char, LOCAL_PLAYER) 
  1976. 	end 
  1977. 	 
  1978. 	-- Setup the trigger for the escape tank 
  1979. 	on_trigger("m18_cb_tank_region_entered", M18_triggers.tank_region) 
  1980. 	trigger_enable(M18_triggers.tank_region, true) 
  1981. 	 
  1982. 	delay(1.0) 
  1983. 	-- Play the conersation that is triggered by opening the door 
  1984. 	m18_helper_conversation_play(M18_convo.cockpit_gone, M18_CONVO_PLAY_IMMEDIATE, 1.0) 
  1985. 	 
  1986. 	m18_helper_topple_boxes(M18_movers.plane_boxes_01) 
  1987. 	 
  1988. 	-- Add a new objective to escape 
  1989. 	objective_text(0, M18_objectives.escape_in_tank.tag, nil, nil, SYNC_ALL, M18_objectives.escape_in_tank.icon) 
  1990. 	marker_add_trigger(M18_triggers.tank_region, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION) 
  1991. 	hud_timer_set(1, M18_tweak_values.escape_time_limit, "m18_cb_escape_time_expired") 
  1992. 	 
  1993. 	-- Start prepping the Z-scene 
  1994. 	zscene_prep(M18_cutscenes.tank_zscene) 
  1995. 	 
  1996. 	delay(5.0) 
  1997. 	m18_helper_conversation_play(M18_convo.blast_containers, M18_CONVO_PLAY_LAST, 1.0) 
  1998. 	 
  1999. 	-- Wait until a players is in the tank trigger regoin  
  2000. 	M18_flags.triggered_tank_region = false 
  2001. 	while(M18_flags.triggered_tank_region == false) do 
  2002. 		thread_yield() 
  2003. 	end 
  2004. end 
  2005.  
  2006. -- Callback for when a player enters the tank trigger region 
  2007. --  
  2008. -- player:		The player the entered the tank region 
  2009. -- trigger:		The trigger that was entered (the tank region) 
  2010. function m18_cb_tank_region_entered(player, trigger) 
  2011. 	M18_flags.triggered_tank_region = true 
  2012. end 
  2013.  
  2014. -- Callback for when the time limit has expired 
  2015. function m18_cb_escape_time_expired() 
  2016. 	-- Blow up the plane 
  2017. 	M18_vfxs.cargo_plane_interior_explosion.handle = effect_play(M18_vfxs.cargo_plane_interior_explosion.nav) 
  2018. 	 
  2019. 	-- Kill the characters 
  2020. 	character_kill(LOCAL_PLAYER, true) 
  2021. 	if (coop_is_active() == true) then 
  2022. 		character_kill(REMOTE_PLAYER, true) 
  2023. 	end 
  2024. end 
  2025.  
  2026. -- 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) 
  2027. -- 
  2028. -- player: 			Player to play the stumble animation for 
  2029. -- stumble_dir:		Navpoint indicating the direction to stumble 
  2030. -- direction_anim:	specific animation to play 
  2031. function m18_thread_do_play_stumble_animation(player, stumble_dir, direction_anim) 
  2032. 	player_release_human_shield(player, true) 
  2033. 	if (direction_anim ~= "") then 
  2034. 	 	action_play(player, stumble_dir) 
  2035. 	else 
  2036. 		action_play(player, "Plane Cabin Stumble") 
  2037. 	end 
  2038. end 
  2039.  
  2040. -- Stumble callback for the trigger stumbles. 
  2041. function m18_stumble_cb() 
  2042. 	-- Play some plane turbulance noises 
  2043. 	audio_object_post_event(M18_audio_events.plane_shudder) 
  2044. 	 
  2045. 	-- Start a thread to play some dust VFX falling from the cargo plane ceiling 
  2046. 	M18_threads.plane_dust = thread_new("m18_thread_do_plane_dust_vfx") 
  2047.  
  2048. 	-- Play the player stumbles 
  2049. 	thread_new("m18_thread_do_play_stumble_animation", LOCAL_PLAYER, "Plane Stumble Left", false) 
  2050. 	if (coop_is_active() == true) then 
  2051. 		thread_new("m18_thread_do_play_stumble_animation", REMOTE_PLAYER, "Plane Stumble Left", false) 
  2052. 	end 
  2053. 	 
  2054. 	-- Play a stumble on all the enemies 
  2055. 	if (group_is_loaded(M18_groups.cargo_plane_interior.name) == true) then 
  2056. 		for i, char in pairs(M18_groups.cargo_plane_interior.chars) do 
  2057. 			if (m18_helper_human_can_play_anim(char) == true) then 
  2058. 				action_play_do(char, "Plane Stumble Left") 
  2059. 			end 
  2060. 		end 
  2061. 	end 
  2062. 	if (group_is_loaded(M18_groups.stag_reinf.name) == true) then 
  2063. 		for i, char in pairs(M18_groups.stag_reinf.chars) do 
  2064. 			if (m18_helper_human_can_play_anim(char) == true) then 
  2065. 				action_play_do(char, "Plane Stumble Right") 
  2066. 			end 
  2067. 		end 
  2068. 	end 
  2069. end 
  2070.  
  2071. -- Stumble callback for the trigger stumbles. 
  2072. function m18_stumble_cb_alt() 
  2073. 	-- Play some conversation 
  2074. 	m18_helper_conversation_play(M18_convo.damn_stumbles, M18_CONVO_PLAY_LAST, 1.0) 
  2075.  
  2076. 	-- Play some plane turbulance noises 
  2077. 	audio_object_post_event(M18_audio_events.plane_violent_shake) 
  2078. 	 
  2079. 	-- Start a thread to play some dust VFX falling from the cargo plane ceiling 
  2080. 	M18_threads.plane_dust = thread_new("m18_thread_do_plane_dust_vfx") 
  2081.  
  2082. 	-- Play the player stumbles 
  2083. 	thread_new("m18_thread_do_play_stumble_animation", LOCAL_PLAYER, "Plane Stumble Right", false) 
  2084. 	if (coop_is_active() == true) then 
  2085. 		thread_new("m18_thread_do_play_stumble_animation", REMOTE_PLAYER, "Plane Stumble Right", false) 
  2086. 	end 
  2087. 	 
  2088. 	-- Play a stumble on all the enemies 
  2089. 	if (group_is_loaded(M18_groups.cargo_plane_interior.name) == true) then 
  2090. 		for i, char in pairs(M18_groups.cargo_plane_interior.chars) do 
  2091. 			if (m18_helper_human_can_play_anim(char) == true) then 
  2092. 				action_play(char, "Plane Stumble Left") 
  2093. 			end 
  2094. 		end 
  2095. 	end 
  2096. 	if (group_is_loaded(M18_groups.stag_reinf.name) == true) then 
  2097. 		for i, char in pairs(M18_groups.stag_reinf.chars) do 
  2098. 			if (m18_helper_human_can_play_anim(char) == true) then 
  2099. 				action_play(char, "Plane Stumble Right") 
  2100. 			end 
  2101. 		end 
  2102. 	end 
  2103. end 
  2104.  
  2105. -- Helper to check if a human is ready to play a custom animation 
  2106. --  
  2107. -- char_name:	Name of the characer 
  2108. -- 
  2109. -- returns:		TRUE if the character is ready to play an animation, FALSE otherwise	 
  2110. function m18_helper_human_can_play_anim(char_name) 
  2111. 	-- Check if they're ready (checks that they aren't dead, ragdolled 
  2112. 	if (character_is_ready(char_name) == false) then 
  2113. 		return false 
  2114. 	end 
  2115. 	if (character_playing_combat_move(char_name) == true) then 
  2116. 		return false 
  2117. 	end 
  2118. 	if (character_is_jumping(char_name) == true) then 
  2119. 		return false 
  2120. 	end 
  2121. 	 
  2122. 	return true 
  2123. end 
  2124.  
  2125. --[[ 
  2126. 	Cargo Plane Escape [Part 2] - Transition to Tank Free Fall 
  2127. --]] 
  2128.  
  2129. -- Cleanup for the cargo plane interior 
  2130. function m18_cleanup_cargo_plane_interior() 
  2131. 	-- Clear the ragdoll restore position 
  2132. 	character_ragdoll_clear_last_resort_position() 
  2133.  
  2134. 	-- Clean-up the tanks in the cargo plane 
  2135. 	if (group_is_loaded(M18_groups.cargo_plane_tanks.name) == true) then 
  2136. 		group_destroy(M18_groups.cargo_plane_tanks.name) 
  2137. 	end 
  2138.  
  2139. 	-- Remove the HUD timer 
  2140. 	hud_timer_stop(1) 
  2141. 	 
  2142. 	-- Kill the box giggle thread 
  2143. 	if (M18_threads.box_jiggle ~= -1) then 
  2144. 		thread_kill(M18_threads.box_jiggle) 
  2145. 		M18_threads.box_jiggle = -1 
  2146. 	end 
  2147. 	 
  2148. 	-- Cleanup the grunts 
  2149. 	for i, squad in pairs(M18_groups.cargo_plane_interior.grunt_squads) do 
  2150. 		for j, grunt in pairs(squad.grunts) do 
  2151. 			-- Clear any callbacks that may have been registered for this grunt 
  2152. 			on_detection("", grunt) 
  2153. 			on_ai_do_action_complete("", grunt) 
  2154. 			on_take_damage("", grunt) 
  2155. 		end 
  2156. 	end 
  2157. 	 
  2158. 	-- Remove the sonic gun items for the player's inventory 
  2159. 	inv_weapon_remove_temporary(LOCAL_PLAYER, "Special-SonicGun") 
  2160. 	if (coop_is_active() == true) then 
  2161. 		inv_weapon_remove_temporary(REMOTE_PLAYER, "Special-SonicGun") 
  2162. 	end 
  2163. 	 
  2164. 	-- Clean-up any callback on a tank trigger region 
  2165. 	trigger_enable(M18_triggers.tank_region, false) 
  2166. 	marker_remove_trigger(M18_triggers.tank_region) 
  2167. 	on_trigger("", M18_triggers.tank_region) 
  2168. 	 
  2169. 	-- Clean-up stumble triggers 
  2170. 	trigger_enable(M18_triggers.stumble_01, false) 
  2171. 	on_trigger("", M18_triggers.stumble_01) 
  2172. 	trigger_enable(M18_triggers.stumble_02, false) 
  2173. 	on_trigger("", M18_triggers.stumble_02) 
  2174. 	 
  2175. 	-- Stop any camera shakes 
  2176. 	camera_shake_stop() 
  2177. 	 
  2178. 	-- Clean-up any VFX 
  2179. 	if (M18_vfxs.plane_wind.handle ~= -1) then 
  2180. 		effect_stop(M18_vfxs.plane_wind.handle) 
  2181. 		M18_vfxs.plane_wind.handle = -1 
  2182. 	end 
  2183. 	 
  2184. 	-- Stop the drug effects 
  2185. 	drug_effect_clear_override_values() 
  2186. 	 
  2187. 	-- Destroy the group for the cargo plane interior 
  2188. 	if (group_is_loaded(M18_groups.cargo_plane_interior.name) == true) then 
  2189. 		group_destroy(M18_groups.cargo_plane_interior.name) 
  2190. 		group_destroy(M18_groups.stag_reinf.name) 
  2191. 	end 
  2192. 	 
  2193. 	-- Stop the audio emitters 
  2194. 	for i, emitter in pairs(M18_audio_emitters.plane_interior) do 
  2195. 		audio_ambient_emitter_stop(emitter) 
  2196. 	end 
  2197. 	for i, emitter in pairs(M18_audio_emitters.plane_crashing) do 
  2198. 		audio_ambient_emitter_stop(emitter) 
  2199. 	end 
  2200. end 
  2201.  
  2202. -- Handle running the setup and teardown for the escape Zscene 
  2203. function m18_run_cargo_plane_escape_scene() 
  2204. 	-- Remove the HUD timer 
  2205. 	hud_timer_stop(1) 
  2206. 	 
  2207. 	-- Clean-up any callback on a tank trigger region 
  2208. 	trigger_enable(M18_triggers.tank_region, false) 
  2209. 	marker_remove_trigger(M18_triggers.tank_region) 
  2210. 	on_trigger("", M18_triggers.tank_region) 
  2211. 	 
  2212. 	cutscene_play(M18_cutscenes.tank_zscene, nil, nil, false)	-- don't fade back in. we need to clean-up the plane and setup the free fall afterwards 
  2213. 	 
  2214. 	-- Start the skydiving music 
  2215. 	audio_object_post_event(M18_audio_events.music_skydive_start, nil, nil, LOCAL_PLAYER)	 
  2216. end 
  2217.  
  2218.  
  2219. --[[ 
  2220. 	Tank Free Fall - [Part 1] Kill the initial bad guys 
  2221. --]] 
  2222.  
  2223. function m18_initialize_tank_free_fall(play_tank_anim) 
  2224. 	-- Add a new objective 
  2225. 	objective_text(0, M18_objectives.survive.tag, nil, nil, SYNC_ALL, M18_objectives.survive.icon) 
  2226. 	 
  2227. 	-- Make sure the player is not in any sort of vehicle 
  2228. 	vehicle_exit_teleport(LOCAL_PLAYER) 
  2229. 	if (coop_is_active() == true) then 
  2230. 		vehicle_exit_teleport(REMOTE_PLAYER) 
  2231. 	end 
  2232. 	 
  2233. 	-- Turn off vehicle weapon physics so that the skydiving tank animations work nicely with the turret 
  2234. 	vehicle_disable_weapon_physics(true) 
  2235.  
  2236. 	-- Setup the players' tank 
  2237. 	group_create(M18_groups.player_tank.name, true) 
  2238. 	vehicle_skydiving_start(M18_groups.player_tank.tank, M18_navpoints.player_tank_orient_01) 
  2239. 	vehicle_skydiving_move_to_do(M18_groups.player_tank.tank, M18_groups.player_tank.tank) 
  2240. 	 
  2241. 	-- Register a callback for when the player's tank is destroyed and make the remote player invulnerable (since they can be struck by gunfire) 
  2242. 	on_vehicle_destroyed("m18_player_tank_destroyed_cb", M18_groups.player_tank.tank) 
  2243. 	if (coop_is_active() == true) then 
  2244. 		turn_invulnerable(REMOTE_PLAYER, false) 
  2245. 	end 
  2246.  
  2247. 	-- Teleport the players and create the tank group 
  2248. 	teleport_coop(M18_navpoints.player_start_free_fall[1], M18_navpoints.player_start_free_fall[2], true) 
  2249. 	 
  2250. 	-- Disable rendering exterior objects (steelport city) 
  2251. 	interior_disable_exterior(M18_interiors.skydiving_volume, true)	 
  2252. 		 
  2253. 	-- Teleport the player(s) into the tank 
  2254. 	vehicle_enter_teleport(LOCAL_PLAYER, M18_groups.player_tank.tank, 0, true) 
  2255. 	set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false) 
  2256. 	if (coop_is_active() == true) then 
  2257. 		vehicle_enter_teleport(REMOTE_PLAYER, M18_groups.player_tank.tank, 1, true) 
  2258. 		set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false) 
  2259. 	end 
  2260. 	 
  2261. 	-- HACK: Disable notoriety after vehicle_enter(putting the players into the tank raises notoriety, which causes some problems in the mission) 
  2262. 	notoriety_set_max("police", 0) 
  2263. 	notoriety_set_min("police", 0) 
  2264. 	notoriety_set("police", 0) -- HACK: setting the min after the level is 5 doesn't drop the level to 0, so we set that manually 
  2265. 	 
  2266. 	-- Setup the player's tank, and set the tank invulnerable 
  2267. 	m18_helper_setup_skydiving_tank_common(M18_groups.player_tank, true) 
  2268. 	turn_invulnerable(M18_groups.player_tank.tank) 
  2269. 	 
  2270. 	-- Set the global wind override 
  2271. 	wind_override_set(0.0, 1.0, 0.0, 12.0) 
  2272. 	 
  2273. 	-- Play the skydiving VFX 
  2274. 	M18_vfxs.bottom_clouds.handle = effect_play(M18_vfxs.bottom_clouds.nav, true, SYNC_ALL) 
  2275. 	M18_vfxs.clouds.handle = effect_play_on_human(M18_vfxs.clouds.nav, LOCAL_PLAYER, nil, true, SYNC_ALL) 
  2276. 	M18_vfxs.city.handle = effect_play(M18_vfxs.city.nav, true, SYNC_ALL) 
  2277. 	 
  2278. 	M18_threads.random_clouds = thread_new("m18_thread_generate_clouds") 
  2279. 	 
  2280. 	-- Play some wind audio attacked to the player 
  2281. 	audio_object_post_event(M18_audio_events.skydiving_wind, nil, nil, LOCAL_PLAYER) 
  2282. 	if (coop_is_active() == true) then 
  2283. 		audio_object_post_event(M18_audio_events.skydiving_wind, nil, nil, REMOTE_PLAYER) 
  2284. 	end 
  2285. 	 
  2286. 	-- Setup the debris flows 
  2287. 	M18_runtime.debris_flow_handle = debris_flow_create() 
  2288. 	for i, mover in pairs(M18_movers.free_fall_debris) do 
  2289. 		debris_flow_add_object(M18_runtime.debris_flow_handle, mover, 10.0, 15.0, 5.0, true, true) 
  2290. 	end 
  2291. 	debris_flow_set_active(M18_runtime.debris_flow_handle, M18_navpoints.debris_emitter_pos_01, 15.0, 60.0, 350.0, LOCAL_PLAYER) 
  2292. 	 
  2293. 	M18_runtime.debris_flow_handle_02 = debris_flow_create() 
  2294. 	for i, mover in pairs(M18_movers.free_fall_debris_02) do 
  2295. 		debris_flow_add_object(M18_runtime.debris_flow_handle_02, mover, 10.0, 15.0, 5.0, true, true) 
  2296. 	end 
  2297. 	debris_flow_set_active(M18_runtime.debris_flow_handle_02, M18_navpoints.debris_emitter_pos_01, 15.0, 60.0, 350.0, LOCAL_PLAYER) 
  2298. 	 
  2299. 	M18_runtime.wreckage_debris_flow_handle = debris_flow_create() 
  2300. 	for i, debris in pairs(M18_movers.wreckage_debris) do 
  2301. 		debris_flow_add_object(M18_runtime.wreckage_debris_flow_handle, debris, 30.0, 50.0, 5.0, true, true) 
  2302. 		if (rand_int(1, 4) == 1) then 
  2303. 			M18_runtime.debirs_fire_handles[#M18_runtime.debirs_fire_handles + 1] = effect_play_on_script_object(M18_vfxs.debris_fire.nav, debris, nil, true) 
  2304. 		end 
  2305. 	end	 
  2306. 	debris_flow_add_avoid_object(M18_runtime.wreckage_debris_flow_handle, M18_groups.skydiving_tank.tank_group.tank)	 
  2307. 	 
  2308. 	-- Disable police notoriety spawning 
  2309. 	notoriety_force_no_spawn("Police", true) 
  2310. 	notoriety_force_no_spawn("stag", true) 
  2311. 	 
  2312. 	-- Disable players going into the downed state (can not be revived while free falling) 
  2313. 	set_players_can_be_downed(LOCAL_PLAYER, false) 
  2314. 	if (coop_is_active() == true) then 
  2315. 		set_players_can_be_downed(REMOTE_PLAYER, false) 
  2316. 	end 
  2317. 	 
  2318. 	-- Start a camera shake 
  2319. 	camera_shake_play_looping("cargo_plane_interior", M18_tweak_values.skydive_looping_cam_shake_amount) 
  2320. 	 
  2321. 	if (play_tank_anim == true) then 
  2322. 		-- Create a thread to kick off the player's tank animation so it's start while the screen is fading in 
  2323. 		thread_new("m18_delay_tank_start_animation_thread") 
  2324. 	end 
  2325. end 
  2326.  
  2327. -- Thread to delay setting the player's tank start animation 
  2328. function m18_delay_tank_start_animation_thread() 
  2329. 	delay(0.2) 
  2330.  
  2331. 	-- Start the player's tank animating 
  2332. 	vehicle_anim_start(M18_groups.player_tank.tank, "", "tank roll a")			 
  2333. end 
  2334.  
  2335. -- Setup and process Wave 01 of attackers in the Part 1 of the tank free fall 
  2336. function m18_run_ff_set_01() 
  2337. 	-- Tell the ai to stay above the tank 
  2338. 	skydive_set_elev_angles_deg(10, 30) 
  2339. 	hud_set_fake_notoriety("Police", true, 5) 
  2340. 	 
  2341. 	-- Play a VO line 
  2342. 	m18_helper_conversation_play(M18_convo.begin_drop, M18_CONVO_PLAY_NEXT, 1.0) 
  2343. 	 
  2344. 	M18_threads.debris_flow_speed = thread_new("m18_process_debris_flow_speed_thread") 
  2345. 	 
  2346. 	-- Process the enemy waves in the first spawn set 
  2347. 	for i, enemy_wave in pairs(M18_free_fall_spawns.set_01) do 
  2348. 		-- Create the wave, and then set them up 
  2349. 		group_create_hidden(enemy_wave.group.name, true)	 
  2350. 		m18_helper_setup_free_fall_wave(enemy_wave.group) 
  2351. 		 
  2352. 		if (enemy_wave.line ~= "") then 
  2353. 			m18_helper_conversation_play(enemy_wave.line, M18_CONVO_PLAY_NEXT, 1.0) 
  2354. 		end 
  2355. 	 
  2356. 		-- Wait until we've gone under the minimum threat level or the maximum duration time has been reached 
  2357. 		local elapsed_time = 0.0 
  2358. 		while(m18_helper_get_free_fall_threat_level() > enemy_wave.min_threat_level and elapsed_time < enemy_wave.max_duration) do 
  2359. 			thread_yield() 
  2360. 			elapsed_time = elapsed_time + get_frame_time() 
  2361. 		end 
  2362. 	end 
  2363. 	 
  2364. 	-- while(M18_runtime.num_free_fall_vehicles_alive > 0) do 
  2365. 	-- 	thread_yield() 
  2366. 	-- end 
  2367. end 
  2368.  
  2369. -- Function to process the debris flow objects speeding up 
  2370. function m18_process_debris_flow_speed_thread() 
  2371. --[[ 
  2372. 	local iterations = 10 
  2373. 	local iteration_delay = M18_tweak_values.debris_flow_time_to_max_speed / iterations 
  2374. 	for i=1, iterations do 
  2375. 		local speed_mult = M18_tweak_values.debris_flow_min_speed_mult + ((1.0 - M18_tweak_values.debris_flow_min_speed_mult) * (i / iterations)) 
  2376. 		debris_flow_set_active(M18_runtime.debris_flow_handle, M18_navpoints.debris_emitter_pos_01, 15.0, 60.0, 200.0, LOCAL_PLAYER, speed_mult, false) 
  2377. 		delay(iteration_delay) 
  2378. 	end 
  2379. --]] 
  2380. end 
  2381.  
  2382.  
  2383. --[[ 
  2384. 	Tank Free Fall - [Part 2] VTOL flybys (including the VTOL that crashes into the player's tank) 
  2385. --]] 
  2386.  
  2387. -- Run the first encounter with VTOLs as they do fly-bys past the player(s) 
  2388. function m18_run_ff_vtol_flybys_01() 
  2389. 	-- Create the VTOL 01 group 
  2390. 	group_create_hidden(M18_groups.stag_vtol_flyby_01.name, true) 
  2391.  
  2392. 	-- Remove all the object indicators on all the enemies in the first enemy set 
  2393. 	m18_helper_clear_free_fall_wave_markers() 
  2394. 	 
  2395. 	-- Set the restricted camera 
  2396. 	-- camera_restrict_set_limits( -5, 5, -5, 5 ) 
  2397. 	-- camera_restrict_target_object() 
  2398. 	-- camera_restrict_set_active(true) 
  2399. 	m18_helper_conversation_play(M18_convo.generic_falling_02, M18_CONVO_PLAY_NEXT, 3.0) 
  2400. 	-- camera_restrict_target_object(M18_groups.stag_vtol_flyby_01.restricted_camera, 2000) 
  2401. 	-- camera_restrict_set_limits( -25, 25, -35, 35 ) 
  2402. 	 
  2403. 	-- Loop over each VTOL group, and spawn a new thread to setup and process their pathfind 
  2404. 	for i, vtol_group in pairs(M18_groups.stag_vtol_flyby_01.vtol_groups) do 
  2405. 		vtol_group.thread_id = thread_new("m18_run_vtol_flyby_hide_thread", vtol_group, 200) 
  2406. 	end 
  2407. 	 
  2408. 	-- Setup the VTOL that will collide with the player's tank 
  2409. 	turn_invulnerable(M18_groups.stag_vtol_flyby_01.vtol_collide.vtol)	-- make sure the player doesn't kill this VTOL before it collides with the tank 
  2410. 	on_collision("m18_vtol_collision_cb", M18_groups.stag_vtol_flyby_01.vtol_collide.vtol) 
  2411. 	M18_threads.vtol_collide = thread_new("m18_run_vtol_flyby_thread", M18_groups.stag_vtol_flyby_01.vtol_collide, 200) 
  2412. 	 
  2413. 	delay(3.0) 
  2414.  
  2415. 	-- Wait for the VTOL that collides with the tank to finish it's animation 
  2416. 	while(thread_check_done(M18_threads.vtol_collide) == false) do 
  2417. 		thread_yield() 
  2418. 	end 
  2419. 	 
  2420. 	-- Detonate the VTOL at the end of it's path 
  2421. 	turn_vulnerable(M18_groups.stag_vtol_flyby_01.vtol_collide.vtol) 
  2422. 	vehicle_detonate(M18_groups.stag_vtol_flyby_01.vtol_collide.vtol) 
  2423. 	--vehicle_set_smoke_and_fire_state(M18_groups.player_tank.tank, true, false) 
  2424. 	camera_shake_play("explosion_very_large", M18_tweak_values.skydive_collision_cam_shake_amount) 
  2425. 	 
  2426. 	-- Set the new orientation for the player's tank (as a result of the collision/explosion) 
  2427. 	vehicle_skydiving_start(M18_groups.player_tank.tank, M18_navpoints.player_tank_orient_02) 
  2428. 	vehicle_skydiving_move_to_do(M18_groups.player_tank.tank, M18_groups.player_tank.tank) 
  2429. 	vehicle_anim_start(M18_groups.player_tank.tank, "", "tank roll b") 
  2430.  
  2431. 	delay(1.0) 
  2432. 	 
  2433. 	-- Play a VO line 
  2434. 	m18_helper_conversation_play(M18_convo.vtol_hit_01, M18_CONVO_PLAY_NEXT, 3.0) 
  2435. 	 
  2436. 	-- Play a VO line 
  2437. 	m18_helper_conversation_play(M18_convo.falling_again, M18_CONVO_PLAY_NEXT, 1.0) 
  2438.  
  2439. 	-- Destroy the group of VTOLs 
  2440. 	group_destroy(M18_groups.stag_vtol_flyby_01.name)	 
  2441. 	 
  2442. 	-- Clear the restricted camera 
  2443. 	camera_restrict_set_active(false) 
  2444. end 
  2445.  
  2446.  
  2447. --[[ 
  2448. 	Tank Free Fall - [Part 3] Tank flip exposes more enemies to kill 
  2449. --]] 
  2450.  
  2451. -- Setup and process the 2nd set of enemies 
  2452. function m18_run_ff_set_02() 
  2453. 	-- Restore the markers 
  2454. 	m18_helper_restore_free_fall_wave_markers() 
  2455. 	M18_runtime.num_free_fall_chars_alive = 0 
  2456. 	M18_runtime.num_free_fall_vehicles_alive = 0 
  2457.  
  2458. 	-- Process the enemy waves in the second spawn set 
  2459. 	for i, enemy_wave in pairs(M18_free_fall_spawns.set_02) do 
  2460. 		-- Create the wave, and then set them up 
  2461. 		group_create_hidden(enemy_wave.group.name, true)	 
  2462. 		m18_helper_setup_free_fall_wave(enemy_wave.group) 
  2463. 		 
  2464. 		if (enemy_wave.line ~= "") then 
  2465. 			m18_helper_conversation_play(enemy_wave.line, M18_CONVO_PLAY_NEXT, 1.0) 
  2466. 		end 
  2467. 	 
  2468. 		-- Wait until we've gone under the minimum thread level or the maximum duration time has been reached 
  2469. 		local elapsed_time = 0.0 
  2470. 		while(m18_helper_get_free_fall_threat_level() > enemy_wave.min_threat_level and elapsed_time < enemy_wave.max_duration) do 
  2471. 			thread_yield() 
  2472. 			elapsed_time = elapsed_time + get_frame_time() 
  2473. 		end 
  2474. 	end 
  2475. 		 
  2476. 	-- while(M18_runtime.num_free_fall_vehicles_alive > 0) do 
  2477. 	-- 	thread_yield() 
  2478. 	-- end 
  2479. end 
  2480.  
  2481. -- Run the second encounter with VTOLs as they do fly-bys past the player(s) 
  2482. function m18_run_ff_vtol_flybys_02() 
  2483. 	-- Create the VTOL flyby 02 group 
  2484. 	group_create_hidden(M18_groups.stag_vtol_flyby_02.name, true) 
  2485. 	 
  2486. 	-- Remove all the object indicators on all the enemies in the first enemy set 
  2487. 	m18_helper_clear_free_fall_wave_markers() 
  2488. 	 
  2489. 	-- camera_restrict_set_limits( -5, 5, -5, 5 ) 
  2490. 	-- camera_restrict_target_object() 
  2491. 	-- camera_restrict_set_active(true) 
  2492. 	m18_helper_conversation_play(M18_convo.generic_falling_06, M18_CONVO_PLAY_NEXT, 3.0) 
  2493. 	-- camera_restrict_target_object(M18_groups.stag_vtol_flyby_02.restricted_camera, 2000) 
  2494. 	-- camera_restrict_set_limits( -25, 25, -35, 35 ) 
  2495.  
  2496. 	-- Create a thread for each VTOL to process it's pathfind 
  2497. 	for i, vtol_group in pairs(M18_groups.stag_vtol_flyby_02.vtol_groups) do 
  2498. 		vtol_group.thread_id = thread_new("m18_run_vtol_flyby_hide_thread", vtol_group, 200) 
  2499. 	end 
  2500. 	 
  2501. 	-- Setup the VTOL that will collide with the player's tank 
  2502. 	turn_invulnerable(M18_groups.stag_vtol_flyby_02.vtol_collide.vtol)	-- make sure the player doesn't kill this VTOL before it collides with the tank 
  2503. 	on_collision("m18_vtol_collision_cb", M18_groups.stag_vtol_flyby_02.vtol_collide.vtol) 
  2504. 	M18_threads.vtol_collide = thread_new("m18_run_vtol_flyby_thread", M18_groups.stag_vtol_flyby_02.vtol_collide, 200) 
  2505. 	 
  2506.  
  2507. 	-- Wait for the VTOL that collides with the tank to finish it's animation 
  2508. 	while(thread_check_done(M18_threads.vtol_collide) == false) do 
  2509. 		thread_yield() 
  2510. 	end 
  2511. 	 
  2512. 	-- Detonate the VTOL at the end of it's path 
  2513. 	turn_vulnerable(M18_groups.stag_vtol_flyby_02.vtol_collide.vtol) 
  2514. 	vehicle_detonate(M18_groups.stag_vtol_flyby_02.vtol_collide.vtol) 
  2515. 	camera_shake_play("explosion_very_large", M18_tweak_values.skydive_collision_cam_shake_amount) 
  2516.  
  2517. 	-- Play the VO line 
  2518. 	m18_helper_conversation_play(M18_convo.vtol_hit_02, M18_CONVO_PLAY_NEXT, 1.0)	 
  2519. 	 
  2520. 	-- Clear the restricted camera 
  2521. 	camera_restrict_set_active(false) 
  2522. 	--vehicle_set_smoke_and_fire_state(M18_groups.player_tank.tank, true, true) 
  2523. 	 
  2524. 	vehicle_anim_start(M18_groups.player_tank.tank, "", "tank roll c") 
  2525. 	 
  2526. 	group_destroy(M18_groups.stag_vtol_flyby_02.name) 
  2527. end 
  2528.  
  2529. -- Thread to process a dive-bombing VTOL 
  2530. -- 
  2531. -- vtol_table:		Lua table defining the dive-bombing VTOL 
  2532. function m18_thread_process_vtol_dive_bomb(vtol_table) 
  2533. 	-- Setup the VTOL 
  2534. 	vehicle_show(vtol_table.vtol) 
  2535. 	vehicle_enter_group_teleport(vtol_table.chars, vtol_table.vtol) 
  2536. 	for i, char in pairs(vtol_table.chars) do 
  2537. 		character_show(char) 
  2538. 		character_set_skydiving(char, true) 
  2539. 		turn_invulnerable(char) 
  2540. 	end 
  2541. 	 
  2542. 	-- Add an object indicatoro 
  2543. 	marker_add(vtol_table.vtol, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  2544. 	 
  2545. 	-- Start the pathfinding 
  2546. 	helicopter_set_path_orientation(vtol_table.vtol, 4, M18_groups.player_tank.tank) 
  2547. 	helicopter_fly_to_direct_dont_stop(vtol_table.vtol, 12.0, vtol_table.start_path) 
  2548. 	repeat 
  2549. 		helicopter_fly_to_direct_dont_stop(vtol_table.vtol, 7.0, vtol_table.looping_path) 
  2550. 		thread_yield() 
  2551. 	until (vehicle_is_destroyed(vtol_table.vtol) == true) 
  2552. end 
  2553.  
  2554. -- Process the mission sequence with the dive-bombing VTOLs 
  2555. function m18_run_ff_vtol_dive_bombers_01() 
  2556. 	-- Change the player tank's orient 
  2557. 	vehicle_skydiving_start(M18_groups.player_tank.tank, M18_navpoints.player_tank_orient_03) 
  2558. 	vehicle_set_smoke_and_fire_state(M18_groups.player_tank.tank, true, true) 
  2559. 	 
  2560. 	group_create_hidden(M18_groups.stag_dive_bombers_01.name, true) 
  2561. 	 
  2562. 	-- Set the restricted camera 
  2563. 	camera_restrict_set_limits( -20, 20, -20, 20 ) 
  2564. 	camera_restrict_target_object() 
  2565. 	camera_restrict_set_active(true) 
  2566. 	camera_restrict_target_object(M18_groups.stag_dive_bombers_01.restricted_camera, 2000) 
  2567. 	 
  2568. 	-- Kick off threads to process the VTOL dive bomb behavior 
  2569. 	M18_runtime.num_ff_part_03_vehicles = 0 
  2570. 	for i, vtol_table in pairs(M18_groups.stag_dive_bombers_01.vtols) do 
  2571. 		vtol_table.thread_id = thread_new("m18_thread_process_vtol_dive_bomb", vtol_table) 
  2572. 		 
  2573. 		local new_min = get_max_hit_points(vtol_table.vtol) * 0.2 
  2574. 		set_min_hit_points(vtol_table.vtol, new_min) 
  2575. 		 
  2576. 		on_damage("m18_dive_bomber_damaged_cb", vtol_table.vtol, 0.3) 
  2577. 		on_vehicle_destroyed("m18_dive_bomb_vtol_destroyed_cb", vtol_table.vtol) 
  2578. 		 
  2579. 		M18_runtime.num_ff_part_03_vehicles = M18_runtime.num_ff_part_03_vehicles + 1 
  2580. 	end 
  2581. 	M18_runtime.num_ff_part_03_vehicles_alive = M18_runtime.num_ff_part_03_vehicles 
  2582. 	 
  2583. 	-- Play some audio for the VTOLs 
  2584. 	audio_object_post_event(M18_audio_events.vtol_whalla, nil, nil, M18_groups.stag_dive_bombers_01.vtols[1].vtol) 
  2585. 	 
  2586. 	-- Create the group for the cargo plane that the tank is going to smash into 
  2587. 	group_create_hidden(M18_groups.stag_cargo_plane.name) 
  2588. 	 
  2589. 	-- Enable rendering exterior objects (steelport city) 
  2590. 	delay(4.0) 
  2591. 	interior_disable_exterior(M18_interiors.skydiving_volume, false) 
  2592. 	if (M18_vfxs.city.handle ~= -1) then 
  2593. 		effect_stop(M18_vfxs.city.handle)	 
  2594. 		M18_vfxs.city.handle = -1 
  2595. 	end 
  2596. 	--[[ 
  2597. 	if (M18_vfxs.bottom_clouds.handle ~= -1) then 
  2598. 		effect_stop(M18_vfxs.bottom_clouds.handle)	 
  2599. 		M18_vfxs.bottom_clouds.handle = -1 
  2600. 	end	 
  2601. 	--]] 
  2602. 		 
  2603. 	-- Wait until all the VTOLs have been destroyed 
  2604. 	while(M18_runtime.num_ff_part_03_vehicles_alive > 0) do 
  2605. 		thread_yield() 
  2606. 	end 
  2607. 	 
  2608. 	-- Stop the Whalla audio 
  2609. 	audio_object_post_event(M18_audio_events.vtol_whalla_stop, nil, nil, M18_groups.stag_dive_bombers_01.vtols[1].vtol) 
  2610. 	 
  2611. 	-- Make the tank flip, and set a new orient 
  2612. 	vehicle_skydiving_start(M18_groups.player_tank.tank, M18_navpoints.player_tank_orient_04) 
  2613. 	vehicle_skydiving_move_to_do(M18_groups.player_tank.tank, M18_navpoints.player_tank_center_pos, 0.0, 2.0) 
  2614. 	vehicle_anim_start(M18_groups.player_tank.tank, "", "tank roll b") 
  2615. 	camera_shake_play("explosion_very_large", M18_tweak_values.skydive_collision_cam_shake_amount) 
  2616. 	 
  2617. 	delay(2.0) 
  2618. 	 
  2619. 	group_destroy(M18_groups.stag_dive_bombers_01.name) 
  2620. 	 
  2621. 	-- Clear the restricted camera 
  2622. 	camera_restrict_set_active(false) 
  2623. end 
  2624.  
  2625. -- Callback for when a dive bomber VTOL has taken enough damage to get destroyed 
  2626. -- 
  2627. -- victim:	VTOL that was damage 
  2628. function m18_dive_bomber_damaged_cb(victim) 
  2629. 	-- Remove this callback 
  2630. 	on_damage("", victim) 
  2631. 	 
  2632. 	-- If this is the last dive bomber, then we need to crash it into the player's tank 
  2633. 	if (M18_runtime.num_ff_part_03_vehicles_alive == 1) then 
  2634. 		m18_helper_conversation_play(M18_convo.generic_falling_04, M18_CONVO_PLAY_NEXT, 3.0) 
  2635. 		turn_invulnerable(victim) 
  2636. 		marker_remove(victim) 
  2637. 		for i, vtol_group in pairs(M18_groups.stag_dive_bombers_01.vtols) do 
  2638. 			if (vtol_group.vtol == victim) then 
  2639. 				thread_kill(vtol_group.thread_id) 
  2640. 			end 
  2641. 		end 
  2642. 		 
  2643. 		--vehicle_set_smoke_and_fire_state(victim, true, false) 
  2644. 		M18_runtime.debirs_fire_handles[#M18_runtime.debirs_fire_handles + 1] = effect_play_on_script_object(M18_vfxs.debris_fire.nav, victim, nil, true) 
  2645. 		helicopter_fly_to_direct_dont_stop(victim, -1, M18_groups.stag_dive_bombers_01.death_path) 
  2646. 	end 
  2647. 	 
  2648. 	-- Remove the marker 
  2649. 	marker_remove(victim) 
  2650. 	 
  2651. 	-- Make it skydiving so the debris floats 
  2652. 	vehicle_skydiving_start(victim)  
  2653. 	 
  2654. 	-- Make it go bomb 
  2655. 	set_min_hit_points(victim, 0) 
  2656. 	turn_vulnerable(victim)	 
  2657. 	vehicle_detonate(victim) 
  2658. end 
  2659.  
  2660. -- Callback when a vehicle from free fall 03 is destroyed 
  2661. function m18_dive_bomb_vtol_destroyed_cb(vehicle) 
  2662. 	-- Decrement the number of vehicles alive 
  2663. 	M18_runtime.num_ff_part_03_vehicles_alive = M18_runtime.num_ff_part_03_vehicles_alive - 1 
  2664. 	 
  2665. 	-- Clean-up the destroyed vehicle 
  2666. 	on_vehicle_destroyed("", vehicle) 
  2667. 	marker_remove(vehicle) 
  2668. end 
  2669.  
  2670. -- Helper function to setup each plane in the cargo plane formation 
  2671. -- 
  2672. -- cargo_plane_group:	Lua table defining the cargo plane  
  2673. function m18_helper_setup_cargo_plane_thread(cargo_plane_group) 
  2674. 	vehicle_set_invulnerable_to_player_explosives(cargo_plane_group.plane, true) 
  2675. 	vehicle_enter_group_teleport(cargo_plane_group.chars, cargo_plane_group.plane) 
  2676. 	for i, char in pairs(cargo_plane_group.chars) do 
  2677. 		character_set_skydiving(char, true) 
  2678. 	end 
  2679. 	vehicle_max_speed(cargo_plane_group.plane, 120.0) 
  2680. 	helicopter_set_path_orientation(cargo_plane_group.plane, HELI_PF_PATH_PITCH) 
  2681. 	helicopter_fly_to_do(cargo_plane_group.plane, 120.0, true, "", true, cargo_plane_group.path, 0.0, false, false, true) 
  2682. 	 
  2683. 	-- Wait until the plane is a certain distance away from the player's tank, then play a whosh SFX 
  2684. 	while (get_dist(cargo_plane_group.plane, LOCAL_PLAYER, false, true) > 100.0) do 
  2685. 		thread_yield() 
  2686. 	end 
  2687. 	audio_object_post_event(M18_audio_events.vtol_flyby, nil, nil, cargo_plane_group.plane)	 
  2688. end 
  2689.  
  2690. -- Process the player bailing out of the tank to avoid colliding with the cargo plane 
  2691. function m18_run_bail_out_of_tank() 
  2692. 	skydive_setup_tank_bailout(1) 
  2693.  
  2694. 	-- Remove the city VFX 
  2695. 	if (M18_vfxs.city.handle ~= -1) then 
  2696. 		effect_stop(M18_vfxs.city.handle) 
  2697. 		M18_vfxs.city.handle = -1 
  2698. 	end 
  2699. 	 
  2700. 	skydive_set_player_dive_fall_speed(M18_tweak_values.tank_impact_start_player_fall_speed) 
  2701. 	 
  2702. 	-- Create the group for the skydiving tank the player will steal 
  2703. 	group_create_hidden(M18_groups.skydiving_tank.name, true) 
  2704. 	turn_invulnerable(M18_groups.skydiving_tank.tank_group.tank) 
  2705. 	for i, char in pairs(M18_groups.skydiving_tank.tank_group.chars) do 
  2706. 		turn_invulnerable(char) 
  2707. 	end 
  2708. 	m18_helper_setup_skydiving_tank_common(M18_groups.skydiving_tank.tank_group, true) 
  2709. 	vehicle_anim_start(M18_groups.skydiving_tank.tank_group.tank, "mad18 stag tank", "") 
  2710. 	 
  2711. 	-- Wait to make sure the player's tank is safely within the player's skydiving boundary 
  2712. 	while(get_dist(M18_groups.player_tank.tank, M18_navpoints.player_tank_center_pos) > 1.0) do 
  2713. 		thread_yield() 
  2714. 	end 
  2715. 	delay(5.0)	 
  2716. 	vehicle_freeze(M18_groups.player_tank.tank, true) 
  2717. 	 
  2718. 	-- Setup the cargo plane formation 
  2719. 	group_show(M18_groups.stag_cargo_plane.name) 
  2720.  
  2721. 	for i, plane in pairs(M18_groups.stag_cargo_plane.planes) do 
  2722. 		if (i ~= 1) then 
  2723. 			plane.thread_id = thread_new("m18_helper_setup_cargo_plane_thread", plane) 
  2724. 		end 
  2725. 	end 
  2726. 	 
  2727. 	skydive_setup_tank_bailout(2) 
  2728. 	turn_invulnerable(M18_groups.stag_cargo_plane.planes[1].plane) 
  2729. 	vehicle_freeze(M18_groups.stag_cargo_plane.planes[1].plane, true) 
  2730.  
  2731. 	-- Play some engine audio on the giant cargo planes 
  2732. 	audio_object_post_event(M18_audio_events.cargo_plane_flying, nil, nil, M18_groups.stag_cargo_plane.planes[1].plane) 
  2733. 	audio_object_post_event(M18_audio_events.cargo_plane_flying, nil, nil, M18_groups.stag_cargo_plane.planes[2].plane) 
  2734. 	 
  2735. 	delay(1.5) 
  2736.  
  2737. 	-- Do the restricted camera to focus on the cargo plane 
  2738. 	camera_restrict_set_limits(-20, 20, -20, 20) 
  2739. 	camera_restrict_target_object(nil, 0) 
  2740. 	camera_restrict_set_active(true) 
  2741. 	camera_restrict_target_object(M18_groups.stag_cargo_plane.planes[1].plane, 2000) 
  2742. 	 
  2743. 	-- Add a new objective 
  2744. 	delay(1.0) 
  2745. 	objective_text(0, M18_objectives.bail_out_of_tank.tag, nil, nil, SYNC_ALL, M18_objectives.bail_out_of_tank.icon) 
  2746.  
  2747. 	-- Play the VO line 
  2748. 	m18_helper_conversation_play(M18_convo.exit_tank, M18_CONVO_PLAY_NEXT, 1.0) 
  2749. 	 
  2750. 	-- Allow the player's to exit the vehicle now 
  2751. 	hud_prompt(LOCAL_PLAYER, "M18_BAIL_FROM_TANK", "m18_cb_local_player_exited_tank") -- BORKED 
  2752. 	if (coop_is_active() == true) then 
  2753. 		hud_prompt(REMOTE_PLAYER, "M18_BAIL_FROM_TANK", "m18_cb_remote_player_exited_tank") 
  2754. 	end 
  2755. 	 
  2756. 	-- Stop the camera shake 
  2757. 	camera_shake_stop() 
  2758. 	 
  2759. 	m18_helper_conversation_play(M18_convo.steal_plane, M18_CONVO_PLAY_NEXT, 1.0) 
  2760. 	 
  2761. 	skydive_set_player_dive_fall_speed(M18_tweak_values.steal_tank_player_fall_speed) 
  2762.  
  2763. 	-- Wait until the animation has gotten to the point where the tank impacts the cargo plane 
  2764. 	while(vehicle_anim_finished(M18_groups.player_tank.tank, 0.745) == false) do 
  2765. 		thread_yield() 
  2766. 	end	 
  2767. 	 
  2768. 	-- Start the cargo plane on it's crash path 
  2769. 	M18_threads.cargo_plane_crash_02 = thread_new("m18_process_plane_crash_thread") 
  2770. 	 
  2771. 	-- Remove the HUD prompt and if a player is still in the tank, kill them now (since they may be invulnerable) 
  2772. 	hud_prompt_clear(LOCAL_PLAYER) 
  2773. 	if (character_is_in_vehicle(LOCAL_PLAYER) == true) then 
  2774. 		character_kill(LOCAL_PLAYER, true) 
  2775. 	end 
  2776. 	if (coop_is_active() == true) then 
  2777. 		hud_prompt_clear(REMOTE_PLAYER) 
  2778. 		if (character_is_in_vehicle(REMOTE_PLAYER) == true) then 
  2779. 			character_kill(REMOTE_PLAYER, true) 
  2780. 		end 
  2781. 	end 
  2782. 	 
  2783. 	-- Detonate the the tank and play an explosion and some VFX 
  2784. 	vehicle_set_keyframed_physics(M18_groups.player_tank.tank, false) 
  2785. 	turn_vulnerable(M18_groups.player_tank.tank) 
  2786. 	vehicle_detonate(M18_groups.player_tank.tank) 
  2787. 	 
  2788. 	M18_vfxs.stag_cargo_plane_explosion.handle = effect_play(M18_vfxs.stag_cargo_plane_explosion.nav) 
  2789. 	m18_helper_conversation_play(M18_convo.plane_blows_up, M18_CONVO_PLAY_NEXT, 1.0) 
  2790. 	 
  2791. 	-- Update the plane's audio, and add some explosion audio 
  2792. 	audio_object_post_event(M18_audio_events.cargo_plane_crashing, nil, nil, M18_groups.stag_cargo_plane.planes[1].plane) 
  2793. 	audio_object_post_event(M18_audio_events.tank_hit_wing, nil, nil, M18_groups.stag_cargo_plane.planes[1].plane) 
  2794.  
  2795. 	-- Update the debris flow again, now that the player's are outside of the tank 
  2796. 	debris_flow_add_avoid_object(M18_runtime.debris_flow_handle, M18_groups.skydiving_tank.tank_group.tank) 
  2797. 	debris_flow_add_avoid_object(M18_runtime.debris_flow_handle_02, M18_groups.skydiving_tank.tank_group.tank) 
  2798. 	debris_flow_set_active(M18_runtime.debris_flow_handle, M18_navpoints.debris_emitter_pos_03, 0.0, 40.0, 300.0, LOCAL_PLAYER, 1.0) 
  2799. 	debris_flow_set_active(M18_runtime.debris_flow_handle_02, M18_navpoints.debris_emitter_pos_03, 0.0, 40.0, 300.0, LOCAL_PLAYER, 1.0) 
  2800. 	 
  2801. 	-- Show all the wreckage debris 
  2802. 	for i, debris in pairs(M18_movers.wreckage_debris) do 
  2803. 		if (rand_int(1, 4) == 1) then 
  2804. 			M18_runtime.debirs_fire_handles[#M18_runtime.debirs_fire_handles + 1] = effect_play_on_script_object(M18_vfxs.debris_fire.nav, debris, nil, true) 
  2805. 		end 
  2806. 	end 
  2807. 	debris_flow_set_active(M18_runtime.wreckage_debris_flow_handle, M18_navpoints.debris_emitter_pos_03, 10.0, 25.0, 300.0, LOCAL_PLAYER, 1.0, true) 
  2808. 	 
  2809. 	thread_yield() 
  2810. 	explosion_create("Car Bomb Big", M18_vfxs.stag_cargo_plane_explosion.nav) 
  2811. 	 
  2812. 	delay(0.1) 
  2813. 	 
  2814. 	-- Play some groan audio on the wing 
  2815. 	audio_object_post_event(M18_audio_events.cargo_plane_wing_groan, nil, nil, M18_groups.stag_cargo_plane.planes[1].plane) 
  2816. 	 
  2817. end 
  2818.  
  2819. function m18_process_plane_crash_thread() 
  2820. 	-- Destroy the components 
  2821. 	vehicle_component_detach(M18_groups.stag_cargo_plane.planes[1].plane, "engine_RMid", true) 
  2822. 	vehicle_component_detach(M18_groups.stag_cargo_plane.planes[1].plane, "R_End", true) 
  2823. 	vehicle_component_detach(M18_groups.stag_cargo_plane.planes[1].plane, "Object01", true) 
  2824. 	 
  2825. 	M18_vfxs.cargo_plane_smoke.handle = effect_play_on_script_object(M18_vfxs.cargo_plane_smoke.nav, M18_groups.stag_cargo_plane.planes[1].plane, "headlight_glare", true, SYNC_ALL, 2) 
  2826.  
  2827. 	-- Wait until the animation has gotten to the point where the tank impacts the cargo plane 
  2828. 	while(vehicle_anim_finished(M18_groups.stag_cargo_plane.planes[1].plane, 0.9) == false) do 
  2829. 		thread_yield() 
  2830. 	end 
  2831. 	 
  2832. 	effect_stop(M18_vfxs.cargo_plane_smoke.handle) 
  2833. 	M18_vfxs.cargo_plane_smoke.handle = effect_play_on_script_object(M18_vfxs.stag_cargo_plane_explosion.nav, M18_groups.stag_cargo_plane.planes[1].plane, "headlight_glare", true, SYNC_ALL, 2) 
  2834. 	 
  2835. 	delay(0.1) 
  2836. 	vehicle_hide(M18_groups.stag_cargo_plane.planes[1].plane) 
  2837. end 
  2838.  
  2839. -- Function to check if all players have bailed from the tank (and does some setup if they have) 
  2840. function m18_check_all_players_bailed_from_tank() 
  2841. 	local player_in_tank = false 
  2842. 	if (character_is_in_vehicle(LOCAL_PLAYER) == true) then 
  2843. 		player_in_tank = true 
  2844. 	elseif (coop_is_active() == true and character_is_in_vehicle(REMOTE_PLAYER) == true) then 
  2845. 		player_in_tank = true 
  2846. 	end 
  2847. 	 
  2848. 	if (player_in_tank == false) then 
  2849. 		objective_text_clear(0) 
  2850. 		 
  2851. 		-- Make the player's tank invulnerable and clear the on destroyed callback 
  2852. 		turn_invulnerable(M18_groups.player_tank.tank) 
  2853. 		on_vehicle_destroyed("", M18_groups.player_tank.tank) 
  2854. 		 
  2855. 		-- Change to the bail out music 
  2856. 		audio_object_post_event(M18_audio_events.music_bail_out, nil, nil, LOCAL_PLAYER) 
  2857. 	end 
  2858. end 
  2859.  
  2860. -- Callback for when a player bails out of the tank 
  2861. function m18_cb_local_player_exited_tank(player) 
  2862. 	-- Clear the HUD prompt and the restricted camera 
  2863. 	hud_prompt_clear(LOCAL_PLAYER) 
  2864. 	camera_restrict_set_active(false, LOCAL_PLAYER) 
  2865.  
  2866. 	-- Exit the vehicle, equip dual SMGs, and start skydiving 
  2867. 	set_animation_state(LOCAL_PLAYER, "FreeFalling_Dive_AIM") 
  2868. 	action_play(LOCAL_PLAYER, "exit mission") 
  2869. 	vehicle_exit_teleport(LOCAL_PLAYER, true) 
  2870. 	 
  2871. 	character_set_skydiving(LOCAL_PLAYER, true) 
  2872. 	inv_weapon_add_temporary(LOCAL_PLAYER, M18_tweak_values.player_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  2873. 	inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SMG, false, SYNC_LOCAL) 
  2874. 	clear_animation_state(LOCAL_PLAYER) 
  2875. 	 
  2876. 	-- Check if all the players have exited the tank 
  2877. 	m18_check_all_players_bailed_from_tank() 
  2878. 	 
  2879. 	-- Force them into a vertical dive, if the tank has already crossed the threshold that triggers the vertical dive 
  2880. 	character_set_skydiving_state(LOCAL_PLAYER, 8, true) 
  2881. 	 
  2882. 	-- Register a callback for when the playered is damaged 
  2883. 	on_take_damage("m18_player_damaged_while_diving_cb", LOCAL_PLAYER) 
  2884. end 
  2885.  
  2886. -- Callback for when a player bails out of the tank 
  2887. function m18_cb_remote_player_exited_tank() 
  2888. 	-- Clear the HUD prompt and the restricted camera 
  2889. 	hud_prompt_clear(REMOTE_PLAYER) 
  2890. 	camera_restrict_set_active(false, REMOTE_PLAYER) 
  2891.  
  2892. 	-- Exit the vehicle, equip dual SMGs, and start skydiving 
  2893. 	set_animation_state(REMOTE_PLAYER, "FreeFalling_Dive_AIM") 
  2894. 	action_play(REMOTE_PLAYER, "exit mission") 
  2895. 	vehicle_exit_teleport(REMOTE_PLAYER, true) 
  2896. 	 
  2897. 	character_set_skydiving(REMOTE_PLAYER, true) 
  2898. 	inv_weapon_add_temporary(REMOTE_PLAYER, M18_tweak_values.player_smg, 1, true, true, true)	-- SMG has unlimited ammo and is equipped immediatly, and dual weidling 
  2899. 	inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SMG, false, SYNC_LOCAL) 
  2900. 	clear_animation_state(REMOTE_PLAYER) 
  2901. 	 
  2902. 	-- Check if all the players have exited the tank 
  2903. 	m18_check_all_players_bailed_from_tank() 
  2904. 	 
  2905. 	-- Force them into a vertical dive, if the tank has already crossed the threshold that triggers the vertical dive 
  2906. 	character_set_skydiving_state(REMOTE_PLAYER, 8, true) 
  2907. 	 
  2908. 	-- Make them vunlerable again (since they're no longer in the tank) 
  2909. 	turn_vulnerable(REMOTE_PLAYER, false) 
  2910. 	 
  2911. 	-- Register a callback for when the playered is damaged 
  2912. 	on_take_damage("m18_player_damaged_while_diving_cb", REMOTE_PLAYER)	 
  2913. end 
  2914.  
  2915. -- Process the player entering the skydiving tank 
  2916. function m18_run_hijack_skydiving_tank() 
  2917. 	-- Add a new objective, and object indicator 
  2918. 	objective_text(0, M18_objectives.hijack_tank.tag, nil, nil, SYNC_ALL, M18_objectives.hijack_tank.icon) 
  2919. 	marker_add(M18_groups.skydiving_tank.tank_group.tank, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_ALL) 
  2920.  
  2921. 	-- Enable the triggers for the falling tank 
  2922. 	trigger_enable(M18_triggers.falling_tank_01, true) 
  2923. 	trigger_enable(M18_triggers.falling_tank_02, true) 
  2924. 	trigger_enable(M18_triggers.falling_tank_03, true) 
  2925. 	trigger_enable(M18_triggers.falling_tank_04, true) 
  2926. 	on_trigger("m18_cb_triggered_falling_tank_region", M18_triggers.falling_tank_01) 
  2927. 	on_trigger("m18_cb_triggered_falling_tank_region", M18_triggers.falling_tank_02) 
  2928. 	on_trigger("m18_cb_triggered_falling_tank_region", M18_triggers.falling_tank_03) 
  2929. 	on_trigger("m18_cb_triggered_falling_tank_region", M18_triggers.falling_tank_04) 
  2930. 	 
  2931. 	-- Put the player's into the regular diving state (so they get the normal camera) 
  2932. 	character_set_skydiving_state(LOCAL_PLAYER, 1, true) 
  2933. 	if (coop_is_active() == true) then 
  2934. 		character_set_skydiving_state(REMOTE_PLAYER, 1, true) 
  2935. 	end 
  2936. 	 
  2937. 	delay(1.0) 
  2938.  
  2939. 	-- Show the tank the player is going to steal (and make it vulnerable again) 
  2940. 	group_show(M18_groups.skydiving_tank.name) 
  2941. 	local tank_group = M18_groups.skydiving_tank.tank_group 
  2942. 	vehicle_disable_chase(tank_group.tank, true) 
  2943. 	vehicle_disable_flee(tank_group.tank, true) 
  2944. 	vehicle_enter_group_teleport(tank_group.chars, tank_group.tank) 
  2945. 	vehicle_set_keyframed_physics(tank_group.tank, true) 
  2946. 	 
  2947. 	-- Set the tank skydiving 
  2948. 	vehicle_skydiving_start(tank_group.tank, tank_group.orient) 
  2949. 	vehicle_skydiving_move_to_do(tank_group.tank, tank_group.dest, (M18_tweak_values.steal_tank_fall_speed - 1.0), M18_tweak_values.steal_tank_fall_speed) 
  2950. 	 
  2951. 	-- Setup the player skydiving for this sequence 
  2952. 	M18_threads.local_player_steal_tank = thread_new("m18_thread_process_player_steal_tank_pose", LOCAL_PLAYER) 
  2953. 	if (coop_is_active()) then 
  2954. 		M18_threads.local_player_steal_tank = thread_new("m18_thread_process_player_steal_tank_pose", REMOTE_PLAYER) 
  2955. 	end 
  2956. 	 
  2957. 	-- Loop over each character, and set them up 
  2958. 	for j, char in pairs(tank_group.chars) do 
  2959. 		if (character_is_dead(char) == false) then 
  2960. 			ai_add_enemy_target(char, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE) 
  2961. 			npc_weapon_spread(char, M18_tweak_values.steal_tank_ai_spread_mult) 
  2962. 			set_trailing_aim_flag(char, false) 
  2963. 			turn_vulnerable(char) 
  2964. 		end 
  2965. 	end 
  2966.  
  2967. 	delay(5.0) 
  2968. 	turn_vulnerable(tank_group.tank) 
  2969. 	for i, char in pairs(tank_group.chars) do 
  2970. 		turn_vulnerable(char) 
  2971. 	end	 
  2972.  
  2973. 	skydive_set_player_dive_fall_speed(M18_tweak_values.steal_tank_player_fall_speed) 
  2974. 	 
  2975. 	-- Wait until the player gets close enough to the tank 
  2976. 	local player_reached_tank = false 
  2977. 	while(player_reached_tank == false) do 
  2978. 		if (get_dist(M18_groups.skydiving_tank.tank_group.tank, LOCAL_PLAYER) < M18_tweak_values.steal_tank_success_radius) then 
  2979. 			player_reached_tank = true 
  2980. 		end 
  2981. 		if (coop_is_active() == true and get_dist(M18_groups.skydiving_tank.tank_group.tank, REMOTE_PLAYER) < M18_tweak_values.steal_tank_success_radius) then 
  2982. 			player_reached_tank = true 
  2983. 		end 
  2984. 		 
  2985. 		thread_yield() 
  2986. 	end 
  2987. 	 
  2988. 	-- Remove the callback on the kill trigger 
  2989. 	on_trigger("", M18_triggers.falling_tank_04) 
  2990. 	 
  2991. 	-- Enter the tank 
  2992. 	marker_remove(M18_groups.skydiving_tank.tank_group.tank, SYNC_ALL) 
  2993. 	character_kill(M18_groups.skydiving_tank.tank_group.chars[1]) 
  2994. 	character_kill(M18_groups.skydiving_tank.tank_group.chars[2]) 
  2995. 	vehicle_anim_start(M18_groups.skydiving_tank.tank_group.tank, "", "M18 Enter Tank") 
  2996. 	vehicle_enter(LOCAL_PLAYER, M18_groups.skydiving_tank.tank_group.tank, 0, true, true, false, "M18 Enter Tank") 
  2997.  
  2998. 	-- Play the mission completion music 
  2999. 	audio_object_post_event(M18_audio_events.music_mission_complete, nil, nil, LOCAL_PLAYER) 
  3000. 	 
  3001. 	--[[ 
  3002. 	vehicle_enter_teleport(LOCAL_PLAYER, M18_groups.skydiving_tank.tank_group.tank) 
  3003. 	if (coop_is_active() == true) then 
  3004. 		vehicle_enter_teleport(REMOTE_PLAYER, M18_groups.skydiving_tank.tank_group.tank) 
  3005. 	end 
  3006. 	--]] 
  3007. end 
  3008.  
  3009. -- Callback as the tank enters the various triggers while falling (so we can increase the threat from the tank 
  3010. -- 
  3011. -- triggerer:	Human that entered the trigger region 
  3012. -- trigger:		Trigger that was entered 
  3013. function m18_cb_triggered_falling_tank_region(triggerer, trigger) 
  3014. 	if (trigger == M18_triggers.falling_tank_01) then 
  3015. 		npc_refire_rate_override(M18_groups.skydiving_tank.tank_group.chars[1], M18_tweak_values.steal_tank_driver_refire_rates[1]) 
  3016. 		npc_refire_rate_override(M18_groups.skydiving_tank.tank_group.chars[2], M18_tweak_values.steal_tank_gunner_refire_rates[1]) 
  3017. 		m18_helper_conversation_play(M18_convo.dive_through, M18_CONVO_PLAY_NEXT, 1.0) 
  3018. 	elseif (trigger == M18_triggers.falling_tank_02) then 
  3019. 		npc_refire_rate_override(M18_groups.skydiving_tank.tank_group.chars[1], M18_tweak_values.steal_tank_driver_refire_rates[2]) 
  3020. 		npc_refire_rate_override(M18_groups.skydiving_tank.tank_group.chars[2], M18_tweak_values.steal_tank_gunner_refire_rates[2]) 
  3021. 		m18_helper_conversation_play(M18_convo.while_skydiving, M18_CONVO_PLAY_NEXT, 1.0) 
  3022. 	elseif (trigger == M18_triggers.falling_tank_03) then 
  3023. 		npc_refire_rate_override(M18_groups.skydiving_tank.tank_group.chars[1], M18_tweak_values.steal_tank_driver_refire_rates[3]) 
  3024. 		npc_refire_rate_override(M18_groups.skydiving_tank.tank_group.chars[2], M18_tweak_values.steal_tank_gunner_refire_rates[3]) 
  3025. 		set_perfect_aim(M18_groups.skydiving_tank.tank_group.chars[1], true) 
  3026. 		set_perfect_aim(M18_groups.skydiving_tank.tank_group.chars[2], true) 
  3027. 		 
  3028. 	elseif (trigger == M18_triggers.falling_tank_04) then 
  3029. 		ai_add_enemy_target(M18_groups.skydiving_tank.tank_group.chars[1], LOCAL_PLAYER, ATTACK_NOW_NEVER_LOSE) 
  3030. 		--delay(1.0) 
  3031. 		--force_fire_target_do(M18_groups.skydiving_tank.tank_group.chars[1], LOCAL_PLAYER) 
  3032. 		delay(0.1) 
  3033. 		explosion_create("Tank_Rpg", LOCAL_PLAYER, M18_groups.skydiving_tank.tank_group.chars[1], false) 
  3034. 		character_kill(LOCAL_PLAYER, true) 
  3035. 		if (coop_is_active() == true) then 
  3036. 			character_kill(REMOTE_PLAYER, true) 
  3037. 		end 
  3038. 	end 
  3039. end 
  3040.  
  3041. -- Function to process the player as they approach the tank they must steal (so we can stop their dive when the get close enough) 
  3042. -- 
  3043. -- player_name:		Name of the player the thread is processing 
  3044. function m18_thread_process_player_steal_tank_pose(player_name) 
  3045. 	local delta_y = 0 
  3046. 	repeat 
  3047. 		local player_x, player_y, player_z = get_object_pos(player_name) 
  3048. 		local tank_x, tank_y, tank_z = get_object_pos(M18_groups.skydiving_tank.tank_group.tank) 
  3049. 		delta_y = player_y - tank_y 
  3050. 		 
  3051. 		thread_yield() 
  3052. 	until (delta_y < M18_tweak_values.steal_tank_stop_dive_elev) 
  3053. 	 
  3054. 	skydive_set_player_dive_fall_speed(M18_tweak_values.steal_tank_fall_speed) 
  3055. end 
  3056.  
  3057. -- Callback for when a player is damage while diving to steal a tank 
  3058. function m18_player_damaged_while_diving_cb(player_name, attacker, damage_amt, from_exp) 
  3059. 	-- If this isn't from an explosion, then play the collision animation on the player (since this must have been from hitting debris) 
  3060. 	if (from_exp == false and attacker == nil) then 
  3061. 		audio_object_post_event("object_impact", "object_type", "generic_medium_wood", player_name) 
  3062. 		if (action_play_is_finished(player_name)) then 
  3063. 			audio_play_persona_line(player_name, "voc_pain") 
  3064. 			action_play(player_name, "FreeFall Collision") 
  3065. 		end 
  3066. 	end 
  3067. end 
  3068.  
  3069. -- Clean for the tank free fall section of the mission 
  3070. function m18_cleanup_tank_free_fall() 
  3071. 	-- Turn vehicle weapon physics back on 
  3072. 	vehicle_disable_weapon_physics(true) 
  3073.  
  3074. 	if (M18_runtime.debris_flow_handle ~= 0) then 
  3075. 		debris_flow_destroy(M18_runtime.debris_flow_handle) 
  3076. 		M18_runtime.debris_flow_handle = 0 
  3077. 	end 
  3078. 	if (M18_runtime.debris_flow_handle_02 ~= 0) then 
  3079. 		debris_flow_destroy(M18_runtime.debris_flow_handle_02) 
  3080. 		M18_runtime.debris_flow_handle_02 = 0 
  3081. 	end 
  3082. 	if (M18_runtime.wreckage_debris_flow_handle ~= 0) then 
  3083. 		debris_flow_destroy(M18_runtime.wreckage_debris_flow_handle) 
  3084. 		M18_runtime.wreckage_debris_flow_handle = 0 
  3085. 	end 
  3086. 	 
  3087. 	-- Allow the players to freely enter/exit vehicles again 
  3088. 	set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true) 
  3089. 	if (coop_is_active() == true) then 
  3090. 		set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true) 
  3091. 	end 
  3092. 	 
  3093. 	for i, set in pairs(M18_free_fall_spawns) do 
  3094. 		for j, wave in pairs(set) do 
  3095. 			m18_helper_cleanup_free_fall_wave(wave.group) 
  3096. 		end 
  3097. 	end 
  3098.  
  3099. 	-- Clean-up the first wave of VTOL flybys 
  3100. 	for i, vtol_group in pairs(M18_groups.stag_vtol_flyby_01.vtol_groups) do 
  3101. 		if (vtol_group.thread_id ~= -1 and thread_check_done(vtol_group.thread_id) == false) then 
  3102. 			thread_kill(vtol_group.thread_id) 
  3103. 		end 
  3104. 		on_vehicle_destroyed("", vtol_group.vtol) 
  3105. 	end 
  3106. 	 
  3107. 	-- Clean-up the second wave of VTOL flybys 
  3108. 	for i, vtol_group in pairs(M18_groups.stag_vtol_flyby_02.vtol_groups) do 
  3109. 		if (vtol_group.thread_id ~= -1 and thread_check_done(vtol_group.thread_id) == false) then 
  3110. 			thread_kill(vtol_group.thread_id) 
  3111. 		end 
  3112. 		on_vehicle_destroyed("", vtol_group.vtol) 
  3113. 	end 
  3114. 	 
  3115. 	-- Clean-up the dive bombers 
  3116. 	for i, vtol_group in pairs(M18_groups.stag_dive_bombers_01.vtols) do 
  3117. 		if (vtol_group.thread_id ~= -1 and thread_check_done(vtol_group.thread_id) == false) then 
  3118. 			thread_kill(vtol_group.thread_id) 
  3119. 		end 
  3120. 		on_damage("", vtol_group.vtol) 
  3121. 		on_vehicle_destroyed("", vtol_group.vtol) 
  3122. 	end 
  3123. 	 
  3124. 	-- Make sure there aren't any special vehicle VFX still playing 
  3125. 	for i, tank_group in pairs(M18_runtime.skydiving_tanks) do 
  3126. 		m18_helper_cleanup_skydiving_tank_common(tank_group) 
  3127. 	end 
  3128. 	m18_helper_cleanup_skydiving_tank_common(M18_groups.player_tank) 
  3129. 	m18_helper_cleanup_skydiving_tank_common(M18_groups.skydiving_tank.tank_group) 
  3130. 	 
  3131. 	thread_kill(M18_threads.random_clouds) 
  3132.  
  3133. 	on_death("", M18_groups.skydiving_tank.tank_group.chars[2]) 
  3134. 	 
  3135. 	-- Clean-up the collide VTOL 
  3136. 	on_vehicle_destroyed("", M18_groups.stag_vtol_flyby_01.vtol_collide.vtol)	 
  3137. 	on_collision("", M18_groups.stag_vtol_flyby_01.vtol_collide.vtol) 
  3138. 	on_vehicle_destroyed("", M18_groups.stag_vtol_flyby_02.vtol_collide.vtol)	 
  3139. 	on_collision("", M18_groups.stag_vtol_flyby_02.vtol_collide.vtol) 
  3140. 	 
  3141. 	-- Clear the on destroyed callback on the player's tank 
  3142. 	on_vehicle_destroyed("", M18_groups.player_tank.tank) 
  3143. 	if (coop_is_active() == true) then 
  3144. 		turn_vulnerable(REMOTE_PLAYER) 
  3145. 	end 
  3146. 	 
  3147. 	-- Remove the player on-damaged callbacks 
  3148. 	on_take_damage("", LOCAL_PLAYER) 
  3149. 	if (coop_is_active() == true) then 
  3150. 		on_take_damage("", REMOTE_PLAYER) 
  3151. 	end 
  3152. 	 
  3153. 	marker_remove(M18_groups.skydiving_tank.tank_group.tank) 
  3154. 	 
  3155. 	hud_prompt_clear(LOCAL_PLAYER) 
  3156. 	if (coop_is_active() == true) then 
  3157. 		hud_prompt_clear(REMOTE_PLAYER) 
  3158. 	end 
  3159. 	 
  3160. 	-- Allow players to go into the downed state  
  3161. 	set_players_can_be_downed(LOCAL_PLAYER, true) 
  3162. 	if (coop_is_active() == true) then 
  3163. 		set_players_can_be_downed(REMOTE_PLAYER, true) 
  3164. 	end 
  3165. 	 
  3166. 	-- Re-enable police notoriety spawning 
  3167. 	notoriety_force_no_spawn("Police", false) 
  3168. 	notoriety_force_no_spawn("stag", false) 
  3169. end 
  3170.  
  3171.  
  3172. -- *************************************************** 
  3173. -- Miscellaneous m18 Helper Funcrtions 
  3174. -- *************************************************** 
  3175.  
  3176. -- Calculate the current threat level for free falling (count the number of tanks and guys on screen) 
  3177. function m18_helper_get_free_fall_threat_level() 
  3178. 	return M18_runtime.num_free_fall_chars_alive + (M18_runtime.num_free_fall_vehicles_alive * M18_tweak_values.enemy_tank_threat_level) 
  3179. end 
  3180.  
  3181. -- Helper to setup a skydiving enemy STAG guy 
  3182. -- 
  3183. -- diver_table:		Lua table defining the STAG skydiver 
  3184. function m18_helper_setup_diver(diver_table) 
  3185. 	character_show(diver_table.name) 
  3186. 	character_set_skydiving(diver_table.name, true) 
  3187. 	ai_add_enemy_target(diver_table.name, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE) 
  3188. 	npc_leash_to_nav(diver_table.name, diver_table.nav, 3.0) 
  3189. 	skydive_move_to_do(diver_table.name, diver_table.nav, false, 0, false, diver_table.forced_dive) 
  3190. 	marker_add(diver_table.name, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL) 
  3191. 	ai_set_action_delay(diver_table.name, "fire", rand_float(1.0, 6.0)) 
  3192. 	turn_invulnerable(diver_table.name, true) 
  3193. 	npc_suppress_persona(diver_table.name, true) 
  3194. 	set_trailing_aim_flag(diver_table.name) 
  3195. end 
  3196.  
  3197. -- Setup a wave of free falling STAG enemies 
  3198. -- 
  3199. -- group_table:		Lua table defining the STAG wave group 
  3200. function m18_helper_setup_free_fall_wave(group_table) 
  3201. 	-- Loop over all the skydiving guys, and set them into the correct state 
  3202. 	if (group_table.skydive_chars ~= nil) then 
  3203. 		for i, skydive_char in pairs(group_table.skydive_chars) do 
  3204. 			if (character_is_dead(skydive_char.name) == false) then 
  3205. 				-- Set the skydiving state and give them to attack the player(s) 
  3206. 				m18_helper_setup_diver(skydive_char) 
  3207. 				 
  3208. 				-- Register for when this guy dies, so we can keep a count 
  3209. 				on_death("m18_free_fall_character_killed_cb", skydive_char.name) 
  3210. 				M18_runtime.num_free_fall_chars_alive = M18_runtime.num_free_fall_chars_alive + 1 
  3211. 			end 
  3212. 		end 
  3213. 	end 
  3214. 	 
  3215. 	-- Setup all the tanks 
  3216. 	if (group_table.tank_groups ~= nil) then 
  3217. 		local delay_time = 2.0 
  3218. 		for i, tank_group in pairs(group_table.tank_groups) do 
  3219. 			if (vehicle_is_destroyed(tank_group.tank) == false) then 
  3220. 				-- Setup the tank 
  3221. 				tank_group.thread_id = thread_new("m18_run_tank_fall_in_thread", tank_group, delay_time) 
  3222. 				 
  3223. 				-- Register for when this vehicle is destroyed and add an object indicator 
  3224. 				on_vehicle_destroyed("m18_free_fall_vehicle_destroyed_cb", tank_group.tank) 
  3225. 				M18_runtime.num_free_fall_vehicles_alive = M18_runtime.num_free_fall_vehicles_alive + 1 
  3226. 			end 
  3227. 			 
  3228. 			delay_time = delay_time + 3.0 
  3229. 		end 
  3230. 	end 
  3231. end 
  3232.  
  3233. -- Cleanup a wave of free falling STAG enemies 
  3234. -- 
  3235. -- group_table:		Lua table defining the STAG wave group 
  3236. function m18_helper_cleanup_free_fall_wave(group_table) 
  3237. 	-- Loop over all the skydiving guys, and clear any callbacks 
  3238. 	if (group_table.skydive_chars ~= nil) then 
  3239. 		for i, skydive_char in pairs(group_table.skydive_chars) do 
  3240. 			on_death("", skydive_char.name) 
  3241. 		end 
  3242. 	end 
  3243. 	 
  3244. 	-- Kill any running threads and remove and callbacks for the tanks 
  3245. 	if (group_table.tank_groups ~= nil) then 
  3246. 		for i, tank_group in pairs(group_table.tank_groups) do 
  3247. 			m18_helper_cleanup_skydiving_tank_common(tank_group) 
  3248. 		end 
  3249. 	end 
  3250. end 
  3251.  
  3252. -- Helper to remove the markers on enemies in the free fall waves 
  3253. function m18_helper_clear_free_fall_wave_markers() 
  3254. 	-- Remove all the object indicators on all the enemies in the first enemy set 
  3255. 	for i, spawn_set in pairs(M18_free_fall_spawns) do 
  3256. 		for j, wave in pairs(spawn_set) do 
  3257. 			if (group_is_loaded(wave.group.name) == true) then 
  3258. 				if (wave.group.skydive_chars ~= nil) then 
  3259. 					for k, skydive_char in pairs(wave.group.skydive_chars) do 
  3260. 						marker_remove(skydive_char.name) 
  3261. 					end 
  3262. 				end	 
  3263. 				if (wave.group.tank_groups ~= nil) then 
  3264. 					for k, tank_group in pairs(wave.group.tank_groups) do 
  3265. 						marker_remove(tank_group.tank) 
  3266. 					end 
  3267. 				end 
  3268. 			end 
  3269. 		end 
  3270. 	end 
  3271. end 
  3272.  
  3273. -- Helper to restore the markers on enemies in the free fall waves 
  3274. function m18_helper_restore_free_fall_wave_markers() 
  3275. 	-- Remove all the object indicators on all the enemies in the first enemy set 
  3276. 	for i, spawn_set in pairs(M18_free_fall_spawns) do 
  3277. 		for j, wave in pairs(spawn_set) do 
  3278. 			if (group_is_loaded(wave.group.name) == true) then 
  3279. 				if (wave.group.skydive_chars ~= nil) then 
  3280. 					for k, skydive_char in pairs(wave.group.skydive_chars) do 
  3281. 						if (character_is_dead(skydive_char.name) == false) then 
  3282. 							marker_add(skydive_char.name, MINIMAP_ICON_KILL, OI_ASSET_KILL) 
  3283. 						end 
  3284. 					end 
  3285. 				end	 
  3286. 				if (wave.group.tank_groups ~= nil) then 
  3287. 					for k, tank_group in pairs(wave.group.tank_groups) do 
  3288. 						if (vehicle_is_destroyed(tank_group.tank) == false) then 
  3289. 							marker_add(tank_group.tank, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL) 
  3290. 						end 
  3291. 					end 
  3292. 				end 
  3293. 			end 
  3294. 		end 
  3295. 	end 
  3296. end 
  3297.  
  3298. -- Callback for when an ememy character from Part 1 is killed 
  3299. -- 
  3300. -- victim:		The character that was killed 
  3301. -- attacker:	The character that killed the victim 
  3302. function m18_free_fall_character_killed_cb(victim, attacker) 
  3303. 	-- Decrement the number of guys alive 
  3304. 	M18_runtime.num_free_fall_chars_alive = M18_runtime.num_free_fall_chars_alive - 1 
  3305. 	 
  3306. 	marker_remove(victim) 
  3307. 	 
  3308. 	-- Clean-up the dead guy 
  3309. 	on_death("", victim) 
  3310. end 
  3311.  
  3312. -- Callback for when an enemy vehicle from Part 1 is killed 
  3313. -- 
  3314. -- vehicle:		The vehicle that was destroyed 
  3315. function m18_free_fall_vehicle_destroyed_cb(vehicle) 
  3316. 	-- Decrement the number of vehicles alive 
  3317. 	M18_runtime.num_free_fall_vehicles_alive = M18_runtime.num_free_fall_vehicles_alive - 1 
  3318. 	 
  3319. 	-- Clean-up the destroyed vehicle 
  3320. 	on_vehicle_destroyed("", vehicle) 
  3321. 	marker_remove(vehicle) 
  3322. 	 
  3323. 	m18_cb_skydiving_vehicle_destroyed_common(vehicle) 
  3324. end 
  3325.  
  3326.  
  3327. -- A helper function to display the placeholder dialog lines 
  3328. -- 
  3329. -- dialog:		Lua table speicifying the a set of dialog lines (as defined in M18_placholder_dialog) 
  3330. function m18_run_placeholder_dialog_lines(dialog, override) 
  3331. 	-- If a previous dialog thread is still active, then kill it first 
  3332. 	if (M18_threads.place_holder_dialog ~= -1 and thread_check_done(M18_threads.place_holder_dialog) == false) then 
  3333. 		if (override == false) then 
  3334. 			return 
  3335. 		end 
  3336. 		 
  3337. 		thread_kill(M18_threads.place_holder_dialog) 
  3338. 		thread_yield() 
  3339. 	end 
  3340.  
  3341. 	-- Start the new thread 
  3342. 	M18_threads.place_holder_dialog = thread_new("m18_process_placeholder_dialog_thread", dialog) 
  3343. end 
  3344.  
  3345. -- Setup for the VTOLs that flyby the player 
  3346. -- 
  3347. -- vtol_group:		The VTOL group Lua table (as defined at the top of this file) 
  3348. function m18_helper_setup_vtol_flyby_group(vtol_group) 
  3349. 	vehicle_enter_group_teleport(vtol_group.chars, vtol_group.vtol) 
  3350. 	for j, char in pairs(vtol_group.chars) do 
  3351. 		character_set_skydiving(char, true) 
  3352. 		ai_add_enemy_target(char, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true) 
  3353. 	end 
  3354. end 
  3355.  
  3356. -- Thread to process launching a box with a delay 
  3357. function m18_thread_launch_box(box_group) 
  3358. 	delay(box_group.delay) 
  3359. 	mesh_mover_apply_impulse(box_group.box, box_group.launch_dir, box_group.impulse) 
  3360. end 
  3361.  
  3362. -- Function to process toppling a set of boxes 
  3363. function m18_helper_topple_boxes(box_set) 
  3364. 	for i, box_group in pairs(box_set) do 
  3365. 		thread_new("m18_thread_launch_box", box_group) 
  3366. 	end 
  3367. end 
  3368.  
  3369. -- Check if a particular conversation is done 
  3370. -- 
  3371. -- convo_table:		Conversation Lua table (see M18_conversations) 
  3372. function m18_helper_conversation_check_done(convo_table) 
  3373. 	if (convo_table.in_queue == false) then 
  3374. 		return true 
  3375. 	else 
  3376. 		return convo_table.ended 
  3377. 	end 
  3378. end 
  3379.  
  3380. -- Check if a particular conversation is playing or queued 
  3381. -- 
  3382. -- conver_table:	Conversatino Lua table (see M18_conversations) 
  3383. function m18_helper_conversation_playing_or_queued(convo_table) 
  3384. 	return (convo_table.in_queue == true or (convo_table.started == true and convo_table.ended == false)) 
  3385. end 
  3386.  
  3387. -- Helper to play conversations, by adding them to the cue 
  3388. -- 
  3389. -- convo_table:		Conversation Lua table (see M18_conversations) 
  3390. -- priority:		Desired priority for the conversation 
  3391. -- delay:			Amonut of time to dalya after this conversation before playing the next conversation (in seconds) 
  3392. -- player:			Player who should be speaking in the conversation, or nil to always play on the host (defaults to nil) 
  3393. function m18_helper_conversation_play(convo_table, priority, delay, player) 
  3394. 	if (m18_helper_conversation_check_done(convo_table) == false) then 
  3395. 		return 
  3396. 	end 
  3397.  
  3398. 	convo_table.in_queue = true 
  3399. 	convo_table.started = false 
  3400. 	convo_table.completed = false 
  3401. 	convo_table.ended = false 
  3402. 	convo_table.delay = delay 
  3403. 	convo_table.player = player 
  3404. 	 
  3405. 	if (priority == M18_CONVO_PLAY_LAST) then 
  3406. 		-- Insert this entry at the end of hte lsit 
  3407. 		M18_runtime.convo_queue.list[M18_runtime.convo_queue.size] = convo_table 
  3408. 		M18_runtime.convo_queue.size = M18_runtime.convo_queue.size + 1 
  3409. 	elseif (priority == M18_CONVO_PLAY_NEXT) then 
  3410. 		-- Shift the list to the right 
  3411. 		for i = M18_runtime.convo_queue.size - 1, 0, -1 do 
  3412. 			M18_runtime.convo_queue.list[i + 1] = M18_runtime.convo_queue.list[i] 
  3413. 		end 
  3414. 		M18_runtime.convo_queue.list[0] = convo_table 
  3415. 		M18_runtime.convo_queue.size = M18_runtime.convo_queue.size + 1 
  3416. 	elseif (priority == M18_CONVO_PLAY_IMMEDIATE) then 
  3417. 		-- Shift the list to the right 
  3418. 		for i = M18_runtime.convo_queue.size - 1, 0, -1 do 
  3419. 			M18_runtime.convo_queue.list[i + 1] = M18_runtime.convo_queue.list[i] 
  3420. 		end 
  3421. 		M18_runtime.convo_queue.list[0] = convo_table 
  3422. 		M18_runtime.convo_queue.size = M18_runtime.convo_queue.size + 1	 
  3423. 	 
  3424. 		-- Stop any actively playing conversations, and start this one immediatly 
  3425. 		m18_helper_conversation_cleanup_playing(true) 
  3426. 	end 
  3427. end 
  3428.  
  3429. -- Kill any active conversation, and clear out the conversation queue 
  3430. function m18_helper_conversation_kill_all() 
  3431. 	-- Stop any active conversation 
  3432. 	m18_helper_conversation_cleanup_playing(false) 
  3433. 	 
  3434. 	-- Clear out the queue 
  3435. 	for i = 0, M18_runtime.convo_queue.size - 1 do 
  3436. 		M18_runtime.convo_queue.list[i].ended = true 
  3437. 	end 
  3438. 	M18_runtime.convo_queue.size = 0 
  3439. end 
  3440.  
  3441. -- Cleanup any playing conversation 
  3442. function m18_helper_conversation_cleanup_playing(wait_for_end) 
  3443. 	-- Stop the thread processing a playing conversation 
  3444. 	if (M18_runtime.convo_queue.playing.thread_id ~= -1) then 
  3445. 		thread_kill(M18_runtime.convo_queue.playing.thread_id) 
  3446. 		M18_runtime.convo_queue.playing.thread_id = -1 
  3447. 	end 
  3448. 	-- Cleanup and conversation data for a playing conversation 
  3449. 	if (M18_runtime.convo_queue.playing.conv_handle ~= INVALID_CONVERSATION_HANDLE) then 
  3450. 		if (M18_runtime.convo_queue.playing.convo_table.is_convo == true) then 
  3451. 			audio_conversation_end(M18_runtime.convo_queue.playing.conv_handle) 
  3452. 			if (wait_for_end) then 
  3453. 				audio_conversation_wait_for_end(M18_runtime.convo_queue.playing.conv_handle) 
  3454. 			end 
  3455. 		else 
  3456. 			audio_stop(M18_runtime.convo_queue.playing.conv_handle) 
  3457. 		end 
  3458. 		M18_runtime.convo_queue.playing.conv_handle = INVALID_CONVERSATION_HANDLE 
  3459. 	end 
  3460. 	-- Mark the playing conversation as ended 
  3461. 	if (M18_runtime.convo_queue.playing.convo_table ~= nil) then 
  3462. 		M18_runtime.convo_queue.playing.convo_table.ended = true 
  3463. 		M18_runtime.convo_queue.playing.convo_table.in_queue = false 
  3464. 	end 
  3465. end 
  3466.  
  3467. -- Thread to process playing a single converation 
  3468. function m18_thread_play_convo(convo_table) 
  3469. 	-- Add this conversatin to the playing conversation data 
  3470. 	M18_runtime.convo_queue.playing.convo_table = convo_table 
  3471. 	convo_table.started = true	-- it has now started 
  3472. 	convo_table.in_queue = false 
  3473. 	 
  3474. 	-- Handle playing a conversation or one-off line 
  3475. 	if (convo_table.is_convo == true) then 
  3476. 		-- Play the conversation 
  3477. 		if (convo_table.load_direct == false) then 
  3478. 			if (convo_table.player ~= nil) then 
  3479. 				M18_runtime.convo_queue.playing.conv_handle = audio_conversation_load_player(convo_table.name, convo_table.player) 
  3480. 			else 
  3481. 				M18_runtime.convo_queue.playing.conv_handle = audio_conversation_load(convo_table.name) 
  3482. 			end 
  3483. 		else 
  3484. 			M18_runtime.convo_queue.playing.conv_handle = audio_conversation_load_direct(convo_table.name) 
  3485. 		end 
  3486. 		 
  3487. 		-- Play the conversation and wait for it to end 
  3488. 		audio_conversation_play(M18_runtime.convo_queue.playing.conv_handle) 
  3489. 		audio_conversation_wait_for_end(M18_runtime.convo_queue.playing.conv_handle) 
  3490. 		audio_conversation_end(M18_runtime.convo_queue.playing.conv_handle) 
  3491. 	else 
  3492. 		-- Play the dialog line 
  3493. 		if (convo_table.play_2d == true) then 
  3494. 			M18_runtime.convo_queue.playing.conv_handle = audio_play_persona_line_2d(convo_table.character, convo_table.name) 
  3495. 		else 
  3496. 			M18_runtime.convo_queue.playing.conv_handle = audio_play_persona_line(convo_table.character, convo_table.name) 
  3497. 		end 
  3498. 		 
  3499. 		-- Wait for the line to finish 
  3500. 		while(audio_is_playing(M18_runtime.convo_queue.playing.conv_handle) == true) do 
  3501. 			thread_yield() 
  3502. 		end 
  3503. 	end 
  3504. 	 
  3505. 	-- Do some book-keeping 
  3506. 	M18_runtime.convo_queue.playing.conv_handle = INVALID_CONVERSATION_HANDLE 
  3507. 	convo_table.completed = true 
  3508. 	convo_table.ended = true 
  3509. 	 
  3510. 	-- Delay the desired amount 
  3511. 	delay(convo_table.delay) 
  3512. end 
  3513.  
  3514. -- Process the conversation queue (should be running the duration of the mission) 
  3515. function m18_thread_process_conversations() 
  3516. 	-- Loop forever 
  3517. 	while(true) do 
  3518. 		-- Wait until something is added to the queue and there isn't an active conversation thread playing 
  3519. 		while(M18_runtime.convo_queue.size == 0 or thread_check_done(M18_runtime.convo_queue.playing.thread_id) == false) do 
  3520. 			thread_yield() 
  3521. 		end 
  3522. 		 
  3523. 		-- Play the first conversation from the queue, and then remove it from the qeue 
  3524. 		M18_runtime.convo_queue.playing.thread_id = thread_new("m18_thread_play_convo", M18_runtime.convo_queue.list[0]) 
  3525. 		for i = 1, M18_runtime.convo_queue.size do 
  3526. 			M18_runtime.convo_queue.list[i - 1] = M18_runtime.convo_queue.list[i] 
  3527. 		end 
  3528. 		M18_runtime.convo_queue.size = M18_runtime.convo_queue.size - 1 
  3529. 		 
  3530. 		-- Wait for the active conversation thread to end 
  3531. 		while(thread_check_done(M18_runtime.convo_queue.playing.thread_id) == false) do 
  3532. 			thread_yield() 
  3533. 		end 
  3534. 		M18_runtime.convo_queue.playing.thread_id = INVALID_THREAD_HANDLE 
  3535. 		 
  3536. 		delay(0.2) 
  3537. 	end 
  3538. end 
  3539.  
  3540. -- Function to setup common skydiving tank properties 
  3541. -- 
  3542. -- tank_group:				Lua table defining the tank group 
  3543. --set_destroyed_callback:	TRUE to set the default vehicle destroyed callback, FALSE if a callback is already set (callback should call destroyed common) 
  3544. function m18_helper_setup_skydiving_tank_common(tank_group, set_destroyed_callback) 
  3545. 	-- Start the looping "wobble" animation 
  3546. 	vehicle_anim_start(tank_group.tank, "MAD18 Tank", "") 
  3547. 	 
  3548. 	-- Attach some contrail effects to the tank 
  3549. 	for i, tag in pairs(M18_tweak_values.tank_streamers_tags) do 
  3550. 		for j=0, 1 do 
  3551. 			tank_group.contrail_handles[1 + (i - 1) * 2 + j] = effect_play_on_script_object(M18_vfxs.tank_streamers.nav, tank_group.tank, tag, true, SYNC_ALL, (j + 1)) 
  3552. 		end 
  3553. 	end		 
  3554. 	 
  3555. 	-- Store this tank in the skydiving tanks, and register the damage callback 
  3556. 	M18_runtime.skydiving_tanks[#M18_runtime.skydiving_tanks + 1] = tank_group 
  3557. 	vehicle_disable_explosion_and_damage_vfx(tank_group.tank, true) 
  3558. 	on_damage("m18_cb_skydiving_vehicle_damaged", tank_group.tank, 0.2) 
  3559. 	 
  3560. 	if (set_destroyed_callback == true) then 
  3561. 		on_vehicle_destroyed("m18_cb_skydiving_vehicle_destroyed_common", tank_group.tank) 
  3562. 	end 
  3563. end 
  3564.  
  3565. -- Function to cleanup common skydiving tank properties 
  3566. -- 
  3567. -- tank_group:		Lua table defining the tank group 
  3568. function m18_helper_cleanup_skydiving_tank_common(tank_group) 
  3569. 	if (tank_group.thread_id ~= nil and thread_check_done(tank_group.thread_id) == false) then 
  3570. 		thread_kill(tank_group.thread_id) 
  3571. 		tank_group.thread_id = INVALID_THREAD_HANDLE 
  3572. 	end 
  3573. 	if (tank_group.fire_handle ~= -1) then 
  3574. 		effect_stop(tank_group.fire_handle) 
  3575. 		tank_group.fire_handle = -1 
  3576. 	end 
  3577. 	if (tank_group.exp_handle ~= -1) then 
  3578. 		effect_stop(tank_group.exp_handle) 
  3579. 		tank_group.exp_handle = -1 
  3580. 	end 
  3581. 	for i, handle in pairs(tank_group.contrail_handles) do 
  3582. 		if (handle ~= nil) then 
  3583. 			effect_stop(handle) 
  3584. 			tank_group.contrail_handles[i] = nil 
  3585. 		end 
  3586. 	end	 
  3587. 	on_damage("", tank_group.tank) 
  3588. 	on_vehicle_destroyed("", tank_group.tank) 
  3589. end 
  3590.  
  3591. -- ************************* 
  3592. -- 
  3593. -- Callback functions 
  3594. -- 
  3595. -- ************************* 
  3596.  
  3597. -- Gun crate functions 
  3598. function m18_cb_gun_crate_empty(player, trigger) 
  3599. 	-- Disable the trigger and remove the marker 
  3600. 	trigger_enable(trigger, false) 
  3601. 	marker_remove_trigger(trigger, SYNC_ALL) 
  3602.  
  3603. 	-- Play a rummaging animation 
  3604. 	local orientation_nav = M18_navpoints.gun_crate_orients[1] 
  3605. 	local crate_mover = M18_movers.gun_crate[1] 
  3606. 	if (trigger == M18_triggers.gun_crate_002) then 
  3607. 		orientation_nav = M18_navpoints.gun_crate_orients[2] 
  3608. 		crate_mover = M18_movers.gun_crate[2] 
  3609. 	end 
  3610. 	door_open(crate_mover, false, true, player, "M18  Open Crate", orientation_nav) 
  3611. 	 
  3612. 	--action_play(player, "M18  Open Crate", "M18  Open Crate", false, 0.8, true, true, orientation_nav) 
  3613. 	delay(2.0) 
  3614.  
  3615. 	-- Play some dialog 
  3616. 	if (M18_flags.sonic_gun_failed_once) then 
  3617. 		m18_helper_conversation_play(M18_convo.sonic_gun_failed_02, M18_CONVO_PLAY_IMMEDIATE, 1.0, player) 
  3618. 	else 
  3619. 		m18_helper_conversation_play(M18_convo.sonic_gun_failed_01, M18_CONVO_PLAY_IMMEDIATE, 1.0, player) 
  3620. 		M18_flags.sonic_gun_failed_once = true 
  3621. 	end 
  3622. end 
  3623.  
  3624. -- Callback for when the crate containing the sonic gun is opened 
  3625. -- 
  3626. -- player:		player that opened the crate with the sonic gun 
  3627. -- trigger:		trigger volume for the crate 
  3628. function m18_cb_gun_crate_give_sonic_gun(player, trigger) 
  3629. 	-- Disable the trigger and remove the marker 
  3630. 	trigger_enable(trigger, false) 
  3631. 	marker_remove_trigger(trigger, SYNC_ALL) 
  3632. 	 
  3633. 	-- Play a rummaging animation 
  3634. 	door_open(M18_movers.gun_crate[3], false, true , player, "M18  Open Crate", M18_navpoints.gun_crate_orients[3]) 
  3635. 	 
  3636. 	-- action_play(player, "M18  Open Crate", "M18  Open Crate", false, 0.8, true, true, M18_navpoints.gun_crate_orients[3]) 
  3637. 	delay(2.0) 
  3638. 	 
  3639. 	-- Add this weapon again as a temporary weapon, so that the player cannot drop it 
  3640. 	local equip = true 
  3641. 	inv_weapon_add_temporary(LOCAL_PLAYER, "Special-SonicGun", 1, true, equip, false) 
  3642. 	if (coop_is_active() == true) then 
  3643. 		-- MLG (06/30/11): Always equip the sonic gun 
  3644. 		--local equip = inv_item_is_equipped("Special-SonicGun", REMOTE_PLAYER)	-- obey whatever the equip status was after picking up the sonic gun 
  3645. 		 
  3646. 		inv_weapon_add_temporary(REMOTE_PLAYER, "Special-SonicGun", 1, true, equip, false) 
  3647. 	end 
  3648. 	 
  3649. 	-- They have gotten the sonic gun 
  3650. 	M18_flags.sonic_gun_aquired = true 
  3651. 	 
  3652. 	-- Remove other triggers 
  3653. 	trigger_enable(M18_triggers.gun_crate_001, false) 
  3654. 	trigger_enable(M18_triggers.gun_crate_002, false) 
  3655. 	trigger_enable(M18_triggers.gun_crate_003, false) 
  3656. 	marker_remove_trigger(M18_triggers.gun_crate_001, SYNC_ALL) 
  3657. 	marker_remove_trigger(M18_triggers.gun_crate_002, SYNC_ALL) 
  3658. 	marker_remove_trigger(M18_triggers.gun_crate_003, SYNC_ALL) 
  3659. 	 
  3660. 	-- Make all of the boxes vulnerable now 
  3661. 	for i, box_group in pairs(M18_movers.plane_boxes_01) do 
  3662. 		mesh_mover_set_invulnerable(box_group.box, false) 
  3663. 	end	 
  3664. 	 
  3665. 	-- If the player(s) have already attempted to open the door, then we need to update some object indicators 
  3666. 	if (M18_flags.cabin_door_open_attempted == true) then 
  3667. 		-- Setup the door to be destroyed 
  3668. 		marker_add(M18_navpoints.cabin_door_marker, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  3669. 		objective_text(0, M18_objectives.destroy_cockpit.tag, nil, nil, SYNC_ALL, M18_objectives.destroy_cockpit.icon) 
  3670. 		 
  3671. 		-- Start a dialog conversation 
  3672. 		m18_helper_conversation_play(M18_convo.sonic_gun, M18_CONVO_PLAY_NEXT, 1.0, player) 
  3673. 	end 
  3674. end 
  3675.  
  3676. -- Common processing for when a grunt detects a player 
  3677. function m18_grunt_detection_common_cb(grunt, player) 
  3678. 	-- Unregister the grunt's on_detection callback 
  3679. 	on_detection("", grunt) 
  3680. 	 
  3681. 	-- Cleanup his idle animation state 
  3682. 	clear_animation_state(grunt) 
  3683. 	npc_combat_enable(grunt, true) 
  3684. 	follower_make_independent(grunt, false) 
  3685. end 
  3686.  
  3687. -- Callback for when a grunt with attack immediate orders detects a player 
  3688. function m18_grunt_detection_attack_immediate_cb(grunt, player) 
  3689. 	-- Do common processing/cleanup on this grunt 
  3690. 	m18_grunt_detection_common_cb(grunt, player) 
  3691. 	 
  3692. 	-- Start attacking the player 
  3693. 	npc_leash_remove(grunt) 
  3694. 	ai_add_enemy_target(grunt, player, ATTACK_NOW, false) 
  3695. end 
  3696.  
  3697. -- Callback for when a grunt with defend orders detects a player 
  3698. function m18_grunt_detection_defend_cb(grunt, player) 
  3699. 	-- Do common processing/cleanup on this grunt 
  3700. 	m18_grunt_detection_common_cb(grunt, player) 
  3701.  
  3702. 	-- Tell him to take cover 
  3703. 	ai_do_scripted_take_cover(grunt) 
  3704. end 
  3705.  
  3706. -- Callback for when a grunt with move to cat walk orders detects a player 
  3707. function m18_grunt_detection_cat_walk_cb(grunt, player) 
  3708. 	-- Do common processing/cleanup on this grunt 
  3709. 	m18_grunt_detection_common_cb(grunt, player) 
  3710.  
  3711. 	-- Do a scripted rush up to the cat-walk, and then advance to the player 
  3712. 	npc_leash_remove(grunt) 
  3713. 	ai_do_scripted_move(grunt, M18_navpoints.grunt_catwalk_start, true, true) 
  3714. 	on_ai_do_action_complete("m18_grunt_reached_catwalk_cb", grunt) 
  3715. 	 
  3716. end 
  3717.  
  3718. -- Callback for when a grunt reaches the catwalk (so that we can tell them which node to run to based on the order they reach the cat walk) 
  3719. function m18_grunt_reached_catwalk_cb(grunt) 
  3720. 	-- Clear the ai action complete callback 
  3721. 	on_ai_do_action_complete("", grunt) 
  3722. 	 
  3723. 	-- Move the grunt to the appropriate navpoint on the catwalk, and increment our count 
  3724. 	M18_runtime.num_grunts_to_reach_catwalk = M18_runtime.num_grunts_to_reach_catwalk + 1 
  3725. 	ai_do_scripted_move(grunt, M18_navpoints.grunt_catwalk_positions[M18_runtime.num_grunts_to_reach_catwalk], true, true) 
  3726. end 
  3727.  
  3728. -- Find a skydiving vehicle Lua table, by vehicle name 
  3729. -- 
  3730. -- vehicle_name:	Name of the vehicle to search for 
  3731. function m18_helper_find_skydiving_vehicle(vehicle_name) 
  3732. 	for i, tank_group in pairs(M18_runtime.skydiving_tanks) do 
  3733. 		if (tank_group.tank == vehicle_name) then 
  3734. 			return tank_group 
  3735. 		end 
  3736. 	end 
  3737. 	 
  3738. 	return nil 
  3739. end 
  3740.  
  3741. -- Callback when one a skydiving vehicles gets damaged 
  3742. -- 
  3743. -- vehicle_name:	Name of the vehicle that was damaged 
  3744. function m18_cb_skydiving_vehicle_damaged(vehicle_name) 
  3745. 	-- Remove the on_damage callback 
  3746. 	on_damage("", vehicle_name) 
  3747. 	 
  3748. 	-- Find the vehicle, and turn it on fire 
  3749. 	local vehicle_table = m18_helper_find_skydiving_vehicle(vehicle_name) 
  3750. 	if (vehicle_table ~= nil) then 
  3751. 		if (vehicle_table.fire_handle == -1) then 
  3752. 			-- We found the vehicle, spawn some fire on it 
  3753. 			vehicle_table.fire_handle = effect_play_on_script_object(M18_vfxs.debris_fire.nav, vehicle_table.tank, nil, true) 
  3754. 			return 
  3755. 		end		 
  3756. 	end 
  3757. end 
  3758.  
  3759. -- Callback when one of the debris vehicles gets destroyed 
  3760. -- 
  3761. -- vehicle_name:	Name of the vehicle that was destroyed 
  3762. function m18_cb_skydiving_vehicle_destroyed_common(vehicle_name) 
  3763. 	-- Remove the callback and trigger an explosion 
  3764. 	on_vehicle_destroyed("", vehicle_name) 
  3765. 	 
  3766. 	-- Find the vehicle and turn it on fire 
  3767. 	local vehicle_table = m18_helper_find_skydiving_vehicle(vehicle_name) 
  3768. 	if (vehicle_table ~= nil) then 
  3769. 		if (vehicle_table.fire_handle == -1) then 
  3770. 			-- We found the vehicle, spawn some fire on it 
  3771. 			vehicle_table.fire_handle = effect_play_on_script_object(M18_vfxs.debris_fire.nav, vehicle_table.tank, nil, true) 
  3772. 			return 
  3773. 		end 
  3774. 		 
  3775. 		vehicle_table.exp_handle = explosion_create("Mission02 Car Exp", vehicle_table.tank, nil, true, M18_vfxs.car_exp.nav) 
  3776. 	end 
  3777. end 
  3778.  
  3779. -- Callback for whent he player's tank has been destroyed 
  3780. function m18_player_tank_destroyed_cb() 
  3781. 	character_kill(LOCAL_PLAYER, true) 
  3782. 	if (coop_is_active() == true) then 
  3783. 		character_kill(REMOTE_PLAYER, true) 
  3784. 	end 
  3785. end 
  3786.  
  3787. -- Callback for when one of the flyby vehicles is destroyed 
  3788. function m18_flyby_vtol_destroyed_cb(vehicle) 
  3789. 	-- Remove the keyframed physics, so the VTOL can explode properly 
  3790. 	vehicle_set_keyframed_physics(vehicle, false) 
  3791. 	 
  3792. 	-- Remove the marker 
  3793. 	marker_remove(vehicle) 
  3794. end 
  3795.  
  3796. -- Callback for when a VTOL collides with an object (used to check when a VTOL collides with the player's  
  3797. function m18_vtol_collision_cb(vehicle, collided_with) 
  3798. 	if (collided_with == M18_groups.player_tank.tank) then 
  3799. 		on_collision("", vehicle) 
  3800. 		thread_kill(M18_threads.vtol_collide) 
  3801. 	end 
  3802. end 
  3803.  
  3804. -- ************************* 
  3805. -- 
  3806. -- Thread functions 
  3807. -- 
  3808. -- ************************* 
  3809.  
  3810. -- Process the placeholder dialog lines 
  3811. -- 
  3812. -- dialog:		Lua table speicifying the a set of dialog lines (as defined in M18_placholder_dialog) 
  3813. function m18_process_placeholder_dialog_thread(dialog) 
  3814. 	for i, line in pairs(dialog) do 
  3815. 		message(line.text, 8.0) 
  3816. 		delay(line.duration) 
  3817. 	end 
  3818. end 
  3819.  
  3820. -- Processing for "dropping" the enemy tanks in from above the player 
  3821. -- 
  3822. -- tank_group:		The tank group Lua table (as defined at the top of this file) 
  3823. function m18_run_tank_fall_in_thread(tank_group, delay_time) 
  3824. 	-- Wait for the delay time 
  3825. 	delay(delay_time) 
  3826.  
  3827. 	-- Setup the tank 
  3828. 	vehicle_show(tank_group.tank) 
  3829. 	if (vehicle_is_destroyed(tank_group.tank) == false) then 
  3830. 		-- Make sure the AI doesn't try and flee or chase (they can't anyways, and it caused them not to fire) 
  3831. 		vehicle_disable_chase(tank_group.tank, true) 
  3832. 		vehicle_disable_flee(tank_group.tank, true) 
  3833. 		 
  3834. 		m18_helper_setup_skydiving_tank_common(tank_group, false) 
  3835. 	 
  3836. 		-- Set the tank skydiving, and teleport all the characters into the tank 
  3837. 		vehicle_skydiving_start(tank_group.tank, tank_group.orient) 
  3838. 		if (tank_group.dest ~= nil) then 
  3839. 			vehicle_skydiving_move_to_do(tank_group.tank, tank_group.dest, 8.0, 8.0) 
  3840. 		end 
  3841. 		vehicle_enter_group_teleport(tank_group.chars, tank_group.tank) 
  3842. 		 
  3843. 		-- Add an object indicatoro 
  3844. 		marker_add(tank_group.tank, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL) 
  3845. 	end 
  3846. 	 
  3847. 	-- Loop over each character, and set them up 
  3848. 	for j, char in pairs(tank_group.chars) do 
  3849. 		character_show(char) 
  3850. 		if (character_is_dead(char) == false) then 
  3851. 			-- Set them skydiving, give them attack orders, and register a callback for when they die 
  3852. 			--character_set_skydiving(char, true) 
  3853. 			ai_add_enemy_target(char, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE) 
  3854. 		end 
  3855. 	end 
  3856. end 
  3857.  
  3858. -- Processing for the VTOL flyby pathfind 
  3859. -- 
  3860. -- vtol_group:		The VTOL group Lua table (as defined at the top of this file) 
  3861. function m18_run_vtol_flyby_thread(vtol_group) 
  3862. 	delay(vtol_group.delay) 
  3863.  
  3864. 	-- Register a callback for when the VTOL is destroyed (so we can remove the keyframed physics) 
  3865. 	on_vehicle_destroyed("m18_flyby_vtol_destroyed_cb", vtol_group.vtol) 
  3866.  
  3867. 	-- Set the vehicle as skydiving (so the debris will have zero gravity if the VTOL gets destroyed 
  3868. 	vehicle_skydiving_start(vtol_group.vtol) 
  3869.  
  3870. 	-- Move the VTOL into place and start the vehicle animation 
  3871. 	vehicle_set_special_override_never_ghost(vtol_group.vtol, true) 
  3872. 	 
  3873. 	vtol_flyby_animation_for_m18(vtol_group.vtol, vtol_group.animation, vtol_group.start_pos, vtol_group.speed_multiplier) 
  3874. 	 
  3875. 	delay(1.0)	 
  3876. 	 
  3877. 	-- Make sure the VTOL objects are visible 
  3878. 	vehicle_show(vtol_group.vtol) 
  3879. 	for i, char in pairs(vtol_group.chars) do 
  3880. 		character_show(char) 
  3881. 	end 
  3882. 	 
  3883. 	-- Add a marker for the VTOL 
  3884. 	marker_add(vtol_group.vtol, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL)	 
  3885. 	 
  3886. 	if (vtol_group.whoosh_trigger ~= nil) then 
  3887. 		-- Wait until the animation reaches the whoosh trigger 
  3888. 		while (vehicle_anim_finished(vtol_group.vtol, vtol_group.whoosh_trigger) == false) do 
  3889. 			thread_yield() 
  3890. 		end 
  3891. 		audio_object_post_event(M18_audio_events.vtol_flyby, nil, nil, vtol_group.vtol) 
  3892. 	end 
  3893. 	 
  3894. 	-- Wait until the animation is finished 
  3895. 	while(vehicle_anim_playing(vtol_group.vtol) == true) do 
  3896. 		thread_yield() 
  3897. 	end 
  3898. 	 
  3899. 	-- Remove the marker 
  3900. 	marker_remove(vtol_group.vtol) 
  3901. end 
  3902.  
  3903. -- Processing for the vTOL flyby pathfind, but also hides the vehicle once the pathfind has completed 
  3904. -- 
  3905. -- vtol_group:		The VTOL group Lua table (as defined at the top of this file) 
  3906. -- speed:			The speed for the pathfind 
  3907. function m18_run_vtol_flyby_hide_thread(vtol_group, speed) 
  3908. 	-- Setup the vtol group and then wait the specified delay 
  3909. 	m18_helper_setup_vtol_flyby_group(vtol_group) 
  3910.  
  3911. 	-- Do the base pathfind 
  3912. 	m18_run_vtol_flyby_thread(vtol_group, speed) 
  3913.  
  3914. 	-- If the VTOL was not destroyed, then hide it 
  3915. 	if (vehicle_is_destroyed(vtol_group.vtol) == false) then 
  3916. 		vehicle_hide(vtol_group.vtol) 
  3917. 		for i, char in pairs(vtol_group.chars) do 
  3918. 			character_hide(char) 
  3919. 		end	 
  3920. 	end 
  3921. end 
  3922.  
  3923. -- Thread to process randomly generated cloud VFX 
  3924. function m18_thread_generate_clouds() 
  3925. 	-- loop forever 
  3926. 	while(true) do 
  3927. 		delay(rand_int(M18_tweak_values.skydive_cloud_min_cooldown_time, M18_tweak_values.skydive_cloud_max_cooldown_time)) 
  3928. 		 
  3929. 		-- Make sure we clean up the old effect first 
  3930. 		if (M18_vfxs.random_clouds.handle ~= -1) then 
  3931. 			effect_stop(M18_vfxs.random_clouds.handle) 
  3932. 			thread_yield() 
  3933. 		end 
  3934. 		if (M18_vfxs.random_clouds_remote.handle ~= -1) then 
  3935. 			effect_stop(M18_vfxs.random_clouds_remote.handle) 
  3936. 			thread_yield() 
  3937. 		end 
  3938. 		 
  3939. 		-- Play the cloud "puff" effect 
  3940. 		M18_vfxs.random_clouds.handle = effect_play_on_human(M18_vfxs.random_clouds.nav, LOCAL_PLAYER, nil, false, SYNC_LOCAL) 
  3941. 		if (coop_is_active() == true) then 
  3942. 			M18_vfxs.random_clouds_remote.handle = effect_play_on_human(M18_vfxs.random_clouds_remote.nav, REMOTE_PLAYER, nil, false, SYNC_REMOTE) 
  3943. 		end 
  3944. 	end 
  3945. end 
  3946.  
  3947. -- Thread to process giggling the boxes from turbulance 
  3948. function m18_thread_process_box_jiggle() 
  3949. 	while(true) do 
  3950. 		delay(rand_float(M18_tweak_values.escape_box_impulse_delay[1], M18_tweak_values.escape_box_impulse_delay[2])) 
  3951. 		local impulse = rand_int(M18_tweak_values.escape_box_impulse_amount[1], M18_tweak_values.escape_box_impulse_amount[2]) 
  3952. 		local direction = M18_navpoints.plane_box_turbulance[rand_int(1, #(M18_navpoints.plane_box_turbulance))] 
  3953. 		 
  3954. 		for i, box_group in pairs(M18_movers.plane_boxes_01) do 
  3955. 			mesh_mover_apply_impulse(box_group.box, direction, impulse) 
  3956. 		end 
  3957. 	 
  3958. 		thread_yield() 
  3959. 	end 
  3960. end 
  3961.  
  3962. -- Thread to process the dust VFX in the cargo plane cabin during turbulance 
  3963. function m18_thread_do_plane_dust_vfx() 
  3964. 	-- Trigger the turbulance VFX 
  3965. 	local idx = rand_int(1, #(M18_navpoints.cargo_dust)) 
  3966. 	for i, nav in pairs(M18_navpoints.cargo_dust) do 
  3967. 		effect_play(nav) 
  3968. 		delay(0.07) 
  3969.  
  3970. 		idx = idx + 1 
  3971. 		if (idx > #(M18_navpoints.cargo_dust)) then 
  3972. 			idx = 1 
  3973. 		end 
  3974. 	end 
  3975. end 
  3976.  
  3977.