./m22.lua

  1. --[[ 
  2. 	m22.lua 
  3. 	SR3 Mission Script 
  4. 	DATE: 08-09-10 
  5. 	AUTHOR:	John Karczewski 
  6. ]]-- 
  7.  
  8.  
  9. -- Debug flags -- 
  10.  
  11. -- Tweakable Parameters -- 
  12. 	 
  13. 	-- Battle Zones -- 
  14. 	NUM_ZONES_TO_COMPLETE_TO_SUCCEED = 2 
  15. 	NOTORIETY_FAILSAFE_TIME = 1 * 60 -- Time before notoriety spawns are automatically re-enabled during battle zones. 
  16. 	NUM_ZONE_ENEMIES_TO_RELEASE = 20  -- Number of initial spawn enemies that will be released immediately when they are killed. 
  17. 	 
  18. 	-- Stop Killbane -- 
  19. 	NUM_HITS_TO_STOP_PLANE = 4 
  20. 	 
  21. 	-- Save the Saints -- 
  22. 	STATUE_EXPLOSION_TIME = 300  -- seconds 
  23. 	 
  24. 	-- Boss Battle --  
  25. 	PLAYER_STARTING_FART_IN_JAR_AMMO = 0 
  26. 	FART_IN_JAR_RESPAWN_TIME = 15 -- seconds 
  27. 	 
  28. 	-- Kia -- 
  29. 	KIA_VTOL_RESPAWN_TIME = 5 
  30. 	VTOL_HOVER_TIME = 5 
  31. 	KIA_COOP_REINFORCEMENTS_TIME = 10 
  32. 	 
  33. 	KIA_WEAPON_SPREAD_MULTIPLIER = 0.25 
  34. 	KIA_DESIRED_PLAYER_KEEP_DISTANCE = 10.0	-- distance from the player Kia will try to maintain 
  35. 	KIA_ATTACK_POSITION_LEASH_RADIUS = 5.0 -- leash radius while Kia is at an attack navpoint position 
  36. 	KIA_DEFENSIVE_POSITION_LEASH_RADIUS = 1.0 -- defensive leash radius (while in cover) 
  37. 	KIA_NUM_TIMES_TO_VOMIT = 2 -- number of times Kia should vomit when hit with a FIAJ 
  38. 	KIA_DAMAGE_MULTIPLIER_HUMAN_SHIELD = 0.5 -- damage multiplier for Kia when she has Shaundi as a human shield 
  39. 	KIA_DAMAGE_MULTIPLIER_VOMITING = 1.75 -- damage multiplier for Kia when she is vomiting from a FIAJ 
  40. 	 
  41. 	KIA_ATTACK_VTOL_IDLE_TIME = 10.0 
  42. 	KIA_ATTACK_VTOL_PRE_ATTACK_TIME = 3.0 
  43. 	KIA_ATTACK_VTOL_POST_ATTACK_TIME = 2.0 
  44. 	KIA_ATTACK_VTOL_RESAPWN_TIME = 20.0 
  45. 	 
  46. 	KIA_TEMPORARY_WEAPON = "Special-SonicGun" 
  47. 	KIA_TEMPORARY_GRENADE = "flashbang" 
  48. 	KIA_FIAJ_REACTION_SYNCED_ANIM = "M22_Human_Shield_FIAJ" 
  49.  
  50. -- Groups -- 
  51.  
  52. 	M22_groups = { 
  53. 	 
  54. 	--------------------------- 
  55. 	----- ZONE ONE GROUPS ----- 
  56. 	--------------------------- 
  57. 	 
  58. 	--[[ 
  59. 		Zone_One_Initial = {  
  60. 			name = "Group_battle_zone 001", 
  61. 			members = { "NPC_sind_one 001", "NPC_sind_one 002", "NPC_sind_one 003", "NPC_sind_one 004", "NPC_sind_one 005", 
  62. 						"NPC_sind_one 006", "NPC_sind_one 007", "NPC_sind_one 008", "NPC_sind_one 009", "NPC_sind_one 010", 
  63. 						"NPC_sind_one 011", "NPC_sind_one 012", "NPC_sind_one 013", "NPC_sind_one 014", "NPC_sind_one 015", 
  64. 						"NPC_sind_one 016", "NPC_sind_one 017", "NPC_sind_one 018", "NPC_sind_one 019", "NPC_sind_one 020", 
  65. 						"NPC_sind_one 021", "NPC_sind_one 022", "NPC_sind_one 023", "NPC_sind_one 024", 
  66. 						 
  67. 						"NPC_stag_one 001", "NPC_stag_one 002", "NPC_stag_one 003", "NPC_stag_one 004", "NPC_stag_one 005", 
  68. 						"NPC_stag_one 006", "NPC_stag_one 007", "NPC_stag_one 008", "NPC_stag_one 009", "NPC_stag_one 010", 
  69. 						"NPC_stag_one 011", "NPC_stag_one 012", "NPC_stag_one 013", "NPC_stag_one 014", "NPC_stag_one 015", 
  70. 						"NPC_stag_one 016", "NPC_stag_one 017", "NPC_stag_one 018", "NPC_stag_one 019", "NPC_stag_one 020", 
  71. 						"NPC_stag_one 021", "NPC_stag_one 022", "NPC_stag_one 023", "NPC_stag_one 024" }, 
  72. 						 
  73. 			vehicles = { "veh_Zone1_synd 001", "veh_Zone1_synd 002", "veh_Zone1_synd 003", 
  74. 						"veh_Zone1_synd 004", "veh_Zone1_synd 005", "veh_Zone1_synd 006", "veh_Zone1_stag 001", "veh_Zone1_stag 002", 
  75. 						"veh_Zone1_stag 003", "veh_Zone1_stag 004", "veh_Zone1_stag 005", "veh_Zone1_stag 006", "veh_Zone1_stag 007" }, 
  76. 		}, 
  77.  
  78. 		Zone_One_Courtesy = { 
  79. 			name = "Group_battle_zone_courtesy 001", 
  80. 			vehicles = { "Vehicle_Zone1_Courtesy 001", "Vehicle_Zone1_Courtesy 002" }, 
  81. 		}, 
  82. 	--]] 
  83. 		 
  84. 		--------------------------- 
  85. 		----- ZONE TWO GROUPS ----- 
  86. 		---------------------------	 
  87. 		 
  88. 		Zone_Two_Initial = {  
  89. 			name = "Group_battle_zone 002", 
  90. 			members = { "NPC_sind_two 001", "NPC_sind_two 002", "NPC_sind_two 003", "NPC_sind_two 004", "NPC_sind_two 005", 
  91. 						"NPC_sind_two 006", "NPC_sind_two 007", "NPC_sind_two 008", "NPC_sind_two 009", "NPC_sind_two 010", 
  92. 						"NPC_sind_two 011", "NPC_sind_two 012", "NPC_sind_two 013", "NPC_sind_two 014", "NPC_sind_two 015", 
  93. 						"NPC_sind_two 016", "NPC_sind_two 017", "NPC_sind_two 018", "NPC_sind_two 019", "NPC_sind_two 020", 
  94. 						"NPC_sind_two 021", "NPC_sind_two 022", "NPC_sind_two 023", "NPC_sind_two 024", 
  95. 						 
  96. 						"NPC_stag_two 001", "NPC_stag_two 002", "NPC_stag_two 003", "NPC_stag_two 004", "NPC_stag_two 005", 
  97. 						"NPC_stag_two 006", "NPC_stag_two 007", "NPC_stag_two 008", "NPC_stag_two 009", "NPC_stag_two 010", 
  98. 						"NPC_stag_two 011", "NPC_stag_two 012", "NPC_stag_two 013", "NPC_stag_two 014", "NPC_stag_two 015", 
  99. 						"NPC_stag_two 016", "NPC_stag_two 017", "NPC_stag_two 022", "NPC_stag_two 023", "NPC_stag_two 024",  
  100. 						"NPC_stag_two 025", "NPC_stag_two 026", "NPC_stag_two 027", "NPC_stag_two 028" }, 
  101. 		}, 
  102. 		 
  103. 		Zone_Two_Vehicles = { 
  104. 			name = "Group_battle_zone_vehicles 2", 
  105. 			spawned = false, 
  106. 		}, 
  107. 		 
  108. 		Zone_Two_Courtesy = {  
  109. 			name = "Group_battle_zone_courtesy 002", 
  110. 			vehicles = { "Vehicle_Zone2_Courtesy 001", "Vehicle_Zone2_Courtesy 002" }, 
  111. 		}, 
  112. 		 
  113. 		Zone_Two_Saints = { 
  114. 			name = "Group_BZ2_Saints 001", 
  115. 			cars = { 
  116. 				{ 
  117. 					vehicle = "veh_bz2_saint 001", 
  118. 					members = { "npc_bz2_saint 001", "npc_bz2_saint 002", "npc_bz2_saint 003" }, 
  119. 				}, 
  120. 				{ 
  121. 					vehicle = "veh_bz2_saint 002", 
  122. 					members = { "npc_bz2_saint 004", "npc_bz2_saint 005", "npc_bz2_saint 006" }, 
  123. 				}, 
  124. 			}, 
  125. 			start_positions = { 
  126. 				{ 
  127. 					nav = "nav_BZ2_saints_start 001",  
  128. 					path = "path_bz2_saints 1", 
  129. 				}, 
  130. 				{ 
  131. 					nav = "nav_BZ2_saints_start 002",  
  132. 					path = "path_bz2_saints 2", 
  133. 				}, 
  134. 				{ 
  135. 					nav = "nav_BZ2_saints_start 003", 
  136. 					path = "path_bz2_saints 3", 
  137. 				}, 
  138. 			}, 
  139. 		}, 
  140. 	 
  141.  
  142. 		--------------------------- 
  143. 		----- ZONE Three GROUPS --- 
  144. 		---------------------------	 
  145. 		 
  146. 		Zone_Three_Initial = {  
  147. 			name = "Group_battle_zone 003", 
  148. 			members = { "NPC_sind_three 001", "NPC_sind_three 002", "NPC_sind_three 003", "NPC_sind_three 004", "NPC_sind_three 005", 
  149. 						"NPC_sind_three 006", "NPC_sind_three 007", "NPC_sind_three 008", "NPC_sind_three 009", "NPC_sind_three 010", 
  150. 						"NPC_sind_three 011", "NPC_sind_three 012", "NPC_sind_three 013", "NPC_sind_three 014", "NPC_sind_three 015", 
  151. 						"NPC_sind_three 016", "NPC_sind_three 017", "NPC_sind_three 018", "NPC_sind_three 019", "NPC_sind_three 020", 
  152. 						"NPC_sind_three 021", "NPC_sind_three 022", "NPC_sind_three 023", "NPC_sind_three 024", 
  153.  
  154. 						"NPC_stag_three 001", "NPC_stag_three 002", "NPC_stag_three 003", "NPC_stag_three 004", "NPC_stag_three 005", 
  155. 						"NPC_stag_three 006", "NPC_stag_three 007", "NPC_stag_three 008", "NPC_stag_three 009", "NPC_stag_three 010", 
  156. 						"NPC_stag_three 011", "NPC_stag_three 012", "NPC_stag_three 013", "NPC_stag_three 014", "NPC_stag_three 015", 
  157. 						"NPC_stag_three 016", "NPC_stag_three 017", "NPC_stag_three 018", "NPC_stag_three 019", "NPC_stag_three 020", 
  158. 						"NPC_stag_three 021", "NPC_stag_three 022", "NPC_stag_three 023", "NPC_stag_three 024" }, 
  159. 		}, 
  160. 		 
  161. 		Zone_Three_Vehicles = { 
  162. 			name = "Group_battle_zone_vehicles 3", 
  163. 			spawned = false, 
  164. 		}, 
  165. 		 
  166. 		Zone_Three_Courtesy = { 
  167. 			name = "Group_battle_zone_courtesy 003", 
  168. 			vehicles = { "Vehicle_Zone3_Courtesy 001", "Vehicle_Zone3_Courtesy 002" }, 
  169. 		}, 
  170. 		 
  171. 		Zone_Three_Saints = { 
  172. 			name = "Group_BZ3_Saints 001", 
  173. 			cars = { 
  174. 				{ 
  175. 					vehicle = "veh_bz3_saint 001", 
  176. 					members = { "npc_bz3_saint 001", "npc_bz3_saint 002", "npc_bz3_saint 003" }, 
  177. 				}, 
  178. 				{ 
  179. 					vehicle = "veh_bz3_saint 002", 
  180. 					members = { "npc_bz3_saint 004", "npc_bz3_saint 005", "npc_bz3_saint 006" }, 
  181. 				},				 
  182. 			}, 
  183. 			start_positions = { 
  184. 				{ 
  185. 					nav = "nav_BZ3_saints_start 001",  
  186. 					path = "path_bz3_saints 1", 
  187. 				}, 
  188. 				{ 
  189. 					nav = "nav_BZ3_saints_start 002",  
  190. 					path = "path_bz3_saints 2", 
  191. 				}, 
  192. 				{ 
  193. 					nav = "nav_BZ3_saints_start 003", 
  194. 					path = "path_bz3_saints 3", 
  195. 				}, 
  196. 			}, 
  197. 		}, 
  198. 		 
  199. 		--------------------------- 
  200. 		----- ZONE FOUR GROUPS ---- 
  201. 		---------------------------	 
  202. 		 
  203. 		Zone_Four_Initial = {  
  204. 			name = "Group_battle_zone 004", 
  205. 			members = { "NPC_sind_four 001", "NPC_sind_four 002", "NPC_sind_four 003", "NPC_sind_four 004", "NPC_sind_four 005", 
  206. 						"NPC_sind_four 006", "NPC_sind_four 007", "NPC_sind_four 008", "NPC_sind_four 009", "NPC_sind_four 010", 
  207. 						"NPC_sind_four 011", "NPC_sind_four 015", "NPC_sind_four 016", "NPC_sind_four 017",	"NPC_sind_four 018", 
  208. 						"NPC_sind_four 019", "NPC_sind_four 020", "NPC_sind_four 021", "NPC_sind_four 022",	"NPC_sind_four 024",  
  209. 						"NPC_sind_four 025", "NPC_sind_four 026", "NPC_sind_four 029", "NPC_sind_four 030", 
  210.  
  211. 						"NPC_stag_four 001", "NPC_stag_four 002", "NPC_stag_four 003", "NPC_stag_four 004", "NPC_stag_four 005", 
  212. 						"NPC_stag_four 006", "NPC_stag_four 007", "NPC_stag_four 008", "NPC_stag_four 009", "NPC_stag_four 010", 
  213. 						"NPC_stag_four 011", "NPC_stag_four 012", "NPC_stag_four 013", "NPC_stag_four 014", "NPC_stag_four 015", 
  214. 						"NPC_stag_four 016", "NPC_stag_four 017", "NPC_stag_four 018", "NPC_stag_four 019", "NPC_stag_four 020", 
  215. 						"NPC_stag_four 021", "NPC_stag_four 022", "NPC_stag_four 023", "NPC_stag_four 024" }, 
  216. 		}, 
  217. 		 
  218. 		Zone_Four_Vehicles = { 
  219. 			name = "Group_battle_zone_vehicles 4", 
  220. 			spawned = false, 
  221. 		}, 
  222. 		 
  223. 		Zone_Four_Courtesy = { 
  224. 			name = "Group_battle_zone_courtesy 004", 
  225. 			vehicles = { "Vehicle_Zone4_Courtesy 001", "Vehicle_Zone4_Courtesy 002" }, 
  226. 		}, 
  227. 		 
  228. 		Zone_Four_Saints = { 
  229. 			name = "Group_BZ4_Saints 001", 
  230. 			cars = { 
  231. 				{ 
  232. 					vehicle = "veh_bz4_saint 001", 
  233. 					members = { "npc_bz4_saint 001", "npc_bz4_saint 002", "npc_bz4_saint 003" }, 
  234. 				}, 
  235. 				{ 
  236. 					vehicle = "veh_bz4_saint 002", 
  237. 					members = { "npc_bz4_saint 004", "npc_bz4_saint 005", "npc_bz4_saint 006" }, 
  238. 				} 
  239. 			}, 
  240. 			start_positions = { 
  241. 				{ 
  242. 					nav = "nav_BZ4_saints_start 001",  
  243. 					path = "path_bz4_saints 1", 
  244. 				}, 
  245. 				{ 
  246. 					nav = "nav_BZ4_saints_start 002",  
  247. 					path = "path_bz4_saints 2", 
  248. 				}, 
  249. 				{ 
  250. 					nav = "nav_BZ4_saints_start 003", 
  251. 					path = "path_bz4_saints 3", 
  252. 				}, 
  253. 			}, 
  254. 		}, 
  255.  
  256. 		 
  257. 		--------------------------- 
  258. 		----- ARMORY GROUPS ----- 
  259. 		---------------------------	 
  260. 		 
  261. 		Armory_Initial = {  
  262. 			name = "Group_armory", 
  263. 			members = { "NPC_synd_armory 001", "NPC_synd_armory 002", "NPC_synd_armory 003", "NPC_synd_armory 005", "NPC_synd_armory 006", 
  264. 						"NPC_synd_armory 007", "NPC_synd_armory 008", "NPC_synd_armory 009", "NPC_synd_armory 010",	"NPC_synd_armory 011", 
  265. 						"NPC_synd_armory 012", "NPC_synd_armory 013", "NPC_synd_armory 014", "NPC_synd_armory 015",	"NPC_synd_armory 016", 
  266. 						"NPC_synd_armory 017", "NPC_synd_armory 018", "NPC_synd_armory 019", "NPC_synd_armory 020",	"NPC_synd_armory 021", 
  267. 						"NPC_synd_armory 022", "NPC_synd_armory 023", "NPC_synd_armory 024", "NPC_synd_armory 025", 
  268.  
  269. 						"NPC_stag_armory 001", "NPC_stag_armory 003", "NPC_stag_armory 004", "NPC_stag_armory 005",	"NPC_stag_armory 006", 
  270. 						"NPC_stag_armory 007", "NPC_stag_armory 009", "NPC_stag_armory 010", "NPC_stag_armory 011", "NPC_stag_armory 012", 
  271. 						"NPC_stag_armory 013", "NPC_stag_armory 014", "NPC_stag_armory 015", "NPC_stag_armory 016", "NPC_stag_armory 017", 
  272. 						"NPC_stag_armory 018", "NPC_stag_armory 019", "NPC_stag_armory 020", "NPC_stag_armory 021", "NPC_stag_armory 022", 
  273. 						"NPC_stag_armory 023", "NPC_stag_armory 024", "NPC_stag_armory 025", "NPC_stag_armory 026" }, 
  274. 		}, 
  275. 		 
  276. 		Armory_Vehicles = { 
  277. 			name = "Group_armory_vehicles", 
  278. 			spawned = false, 
  279. 		}, 
  280. 		 
  281. 		Armory_Courtesy = { 
  282. 			name = "Group_Courtesy_Armory", 
  283. 			vehicles = { "Vehicle_Armory_Courtesy 001", "Vehicle_Armory_Courtesy 002" }, 
  284. 		}, 
  285.  
  286. 		Statue_Boats = { 
  287. 			name = "Group_heli", 
  288. 			members = { "veh_StatueHeli", "veh_StatueHeli<001>" }, 
  289. 		}, 
  290. 		 
  291. 		--------------------------- 
  292. 		----- MISC GROUPS ----- 
  293. 		---------------------------	 
  294. 		 
  295. 		Start_Vehicle = { 
  296. 			name = "Group_Start_Vehicle", 
  297. 			vehicles = { "Vehicle_Courtesy 001", "Vehicle_Courtesy 002" }, 
  298. 		}, 
  299. 		 
  300. 		Oleg_and_Pierce = { 
  301. 			name = "Group_Oleg_and_Pierce", 
  302. 			members = { "Oleg_gameplay", "Pierce_gameplay"}, 
  303. 			oleg = "Oleg_gameplay", 
  304. 			pierce = "Pierce_gameplay" 
  305. 		}, 
  306. 		 
  307. 		Angel = { 
  308. 			name = "Group_Angel", 
  309. 			members = { "Angel_gameplay" }, 
  310. 			vehicle = "Angel_Car", 
  311. 			npc = "Angel_gameplay" 
  312. 		}, 
  313. 		 
  314. 		Angels_Attackers = { 
  315. 			name = "Group_Angels_Attackers", 
  316. 			members = { "Angel_attacker_NPC 001", "Angel_attacker_NPC 002", "Angel_attacker_NPC 003", 
  317. 						"Angel_attacker_NPC 004", "Angel_attacker_NPC 005", "Angel_attacker_NPC 006", 
  318. 						"Angel_attacker_NPC 007", "Angel_attacker_NPC 008" }, 
  319. 			vehicles = { "Angel_attacker_Car 001", "Angel_attacker_Car 002" } 
  320. 		}, 
  321. 		 
  322. 		Airport = { 
  323. 			name = "Group airport initial", 
  324. 			members = { "Killbane_gameplay" }, 
  325. 			killbane = "Killbane_gameplay" -- The cutscene creates a dude named "Killbane" that conflicts... 
  326. 		}, 
  327. 		 
  328. 		Airport_Roadblock_one = { 
  329. 			name = "Group airport roadblock 001", 
  330. 			members = { "Roadblock_1_NPC 001", "Roadblock_1_NPC 002", "Roadblock_1_NPC 003", "Roadblock_1_NPC 004", 
  331. 						"Roadblock_1_NPC 005", "Roadblock_1_NPC 006", "Roadblock_1_NPC 007", "Roadblock_1_NPC 008" }, 
  332. 			cars = { "Roadblock_1_Vehicle 001", "Roadblock_1_Vehicle 002", "Roadblock_1_Vehicle 003", "Roadblock_1_Vehicle 004", 
  333. 					 "Roadblock_1_Vehicle 005", "Roadblock_1_Vehicle 006", "Roadblock_1_Vehicle 007", "Roadblock_1_Vehicle 008" } 
  334. 		}, 
  335. 		 
  336. 		Airport_Roadblock_two = { 
  337. 			name = "Group airport roadblock 002", 
  338. 			members = { "Roadblock_2_NPC 001", "Roadblock_2_NPC 002", "Roadblock_2_NPC 003", "Roadblock_2_NPC 004" }, 
  339. 			cars = { "Roadblock_2_Vehicle 001", "Roadblock_2_Vehicle 002", "Roadblock_2_Vehicle 003", "Roadblock_2_Vehicle 004" } 
  340. 		}, 
  341.  
  342. 		Airport_Roadblock_three = { 
  343. 			name = "Group airport roadblock 003", 
  344. 			members = { "Roadblock_3_NPC 001", "Roadblock_3_NPC 002", "Roadblock_3_NPC 003", "Roadblock_3_NPC 004" }, 
  345. 			cars = { "Roadblock_3_Vehicle 001", "Roadblock_3_Vehicle 002", "Roadblock_3_Vehicle 003", "Roadblock_3_Vehicle 004" } 
  346. 		}, 
  347. 		 
  348. 		Airport_Roadblock_four = { 
  349. 			name = "Group airport roadblock 004", 
  350. 			members = { "Roadblock_4_NPC 001", "Roadblock_4_NPC 002", "Roadblock_4_NPC 003", "Roadblock_4_NPC 004" }, 
  351. 			cars = { "Roadblock_4_Vehicle 001", "Roadblock_4_Vehicle 002", "Roadblock_4_Vehicle 003", "Roadblock_4_Vehicle 004" } 
  352. 		}, 
  353. 		 
  354. 		Killbane_QTE = { 
  355. 			name = "Group_killbane_qte", 
  356. 			members = "Killbane_qte", 
  357. 			killbane = "Killbane_qte" 
  358. 		}, 
  359. 		 
  360. 		Killbane_QTE_Nomask = { 
  361. 			name = "Group_killbane_qte_nomask", 
  362. 			members = "Killbane_qte_nomask", 
  363. 			killbane = "Killbane_qte_nomask" 
  364. 		}, 
  365. 		 
  366. 		Kia = { 
  367. 			name = "Group_kia", 
  368. 			members = "Kia_gameplay", 
  369. 			kia = "Kia_gameplay", 
  370. 		}, 
  371. 		 
  372. 		Kia_Thugs = { 
  373. 			name = "Group_kia_thugs", 
  374. 			members = { "Kia_Thug 001", "Kia_Thug 002", "Kia_Thug 003", "Kia_Thug 004", "Kia_Thug 005", "Kia_Thug 006",  
  375. 						"Kia_Thug 007", "Kia_Thug 008", "Kia_Thug 009", "Kia_Thug 010", "Kia_Thug 011", "Kia_Thug 012" },		 
  376. 		}, 
  377. 		 
  378. 		Kia_Vtol1 = { 
  379. 			name = "Group_kia_vtol 001", 
  380. 			vtols = { 
  381. 				{ 
  382. 					vtol = "veh_kia_vtol 001", 
  383. 					members = { "char_kia_vtol_pilot 001" }, 
  384. 					path_intro = "path_kia_vtol_intro 001", 
  385. 					path_looping = "path_kia_vtol_loop 001", 
  386. 					loop_speed = 130, 
  387. 					thread_id = INVALID_THREAD_HANDLE, 
  388. 				}, 
  389. 				{ 
  390. 					vtol = "veh_kia_vtol 002", 
  391. 					members = { "char_kia_vtol_pilot 002" }, 
  392. 					path_intro = "path_kia_vtol_intro 002", 
  393. 					path_looping = "path_kia_vtol_loop 002", 
  394. 					loop_speed = 122, 
  395. 					thread_id = INVALID_THREAD_HANDLE, 
  396. 				},				 
  397. 				{ 
  398. 					vtol = "veh_kia_vtol 003", 
  399. 					members = { "char_kia_vtol_pilot 003" }, 
  400. 					path_intro = "path_kia_vtol_intro 003", 
  401. 					path_looping = "path_kia_vtol_loop 003", 
  402. 					loop_speed = 135, 
  403. 					thread_id = INVALID_THREAD_HANDLE, 
  404. 				}, 
  405. 			}, 
  406. 			path_break_off = "path_kia_vtol_break_off 001", 
  407. 			path_east_west = "path_kia_vtol_east_west 001", 
  408. 			path_west_east = "path_kia_vtol_west_east 001", 
  409. 		}, 
  410. 		 
  411. 		vtol_reinforcement = { 
  412. 			name = "Group_vtol_reinforcement", 
  413. 			members = { "Kia_Thug 001", "Kia_Thug 002", "Kia_Thug 003", "Kia_Thug 004", "Kia_Thug 005", "Kia_Thug 006", 
  414. 							"Vtol_driver 002" }, 
  415. 					vtol = "veh_reinforcement_vtol 001", 
  416. 					pilots = { "Vtol_driver 002" }, 
  417. 					drop_offs = { 
  418. 						soldiers = { "Kia_Thug 001", "Kia_Thug 002", "Kia_Thug 003", 
  419. 										"Kia_Thug 004", "Kia_Thug 005", "Kia_Thug 006" }, 
  420. 						path = "Vtol_landing_path 001", 
  421. 					}, 
  422. 					thread_id = -1, 
  423. 		}, 
  424. 		 
  425. 		vtol_coop_reinforcement = { 
  426. 			name = "Group_vtol_coop_rein", 
  427. 			members = { "Kia_Thug_Coop 001", "Kia_Thug_Coop 002", "Kia_Thug_Coop 003", "Kia_Thug_Coop 004", 
  428. 							"Vtol_driver 003" }, 
  429. 					vtol = "veh_reinforcement_vtol 002", 
  430. 					pilots = { "Vtol_driver 003" }, 
  431. 					drop_offs = { 
  432. 						soldiers = { "Kia_Thug_Coop 001", "Kia_Thug_Coop 002", "Kia_Thug_Coop 003", "Kia_Thug_Coop 004" }, 
  433. 						path = "Vtol_landing_path 002", 
  434. 					}, 
  435. 					thread_id = -1, 
  436. 		}, 
  437. 		 
  438. 		Statue_Base = { 
  439. 			name = "Group_statue_base", 
  440. 			members = { "Synd_Statue_NPC 001", "Synd_Statue_NPC 002", "Synd_Statue_NPC 003", "Synd_Statue_NPC 004", "Synd_Statue_NPC 005", 
  441. 						"Synd_Statue_NPC 006", "Synd_Statue_NPC 007", "Synd_Statue_NPC 008", "Synd_Statue_NPC 009", "Synd_Statue_NPC 010", 
  442. 						"Synd_Statue_NPC 011", "Synd_Statue_NPC 012", "Synd_Statue_NPC 013", "Synd_Statue_NPC 014", "Synd_Statue_NPC 015", 
  443. 						"Synd_Statue_NPC 016", "Stag_Statue_NPC 001", "Stag_Statue_NPC 002", "Stag_Statue_NPC 003", "Stag_Statue_NPC 004", 
  444. 						"Stag_Statue_NPC 005", "Stag_Statue_NPC 006", "Stag_Statue_NPC 007", "Stag_Statue_NPC 008", "Stag_Statue_NPC 009", 
  445. 						"Stag_Statue_NPC 010", "Stag_Statue_NPC 011", "Stag_Statue_NPC 012", "Stag_Statue_NPC 013", "Stag_Statue_NPC 014", 
  446. 						"Stag_Statue_NPC 015", "Stag_Statue_NPC 016" } 
  447. 		},		 
  448. 		 
  449. 		Statue = { 
  450. 			name = "Group_statue", 
  451. 			members = { "Trapped_Saint 001", "Trapped_Saint 002", "Trapped_Saint 003", "Trapped_Saint 004" }, 
  452. 			saints = { "Trapped_Saint 001", "Trapped_Saint 002", "Trapped_Saint 003", "Trapped_Saint 004" }, 
  453. 		}, 
  454. 		 
  455. 		Statue_CTE = { 
  456. 			name = "Group_CTE_Statue_Stags", 
  457. 		}, 
  458. 		 
  459. 		Viola = { 
  460. 			name = "Group_Viola", 
  461. 			members = { "Viola_gameplay" }, 
  462. 			viola = "Viola_gameplay" 
  463. 		}, 
  464. 		 
  465. 		Kinzie = { 
  466. 			name = "Group_Kinzie", 
  467. 			members = { "Kinzie" }, 
  468. 			kinzie = "Kinzie", 
  469. 		}, 
  470. 		Hostages = { 
  471. 			name = "Group_Hostages", 
  472. 			members = { "Mayor_Hostage", "Shaundi_Hostage" }, 
  473. 			shaundi = "Shaundi_Hostage", 
  474. 			mayor = "Mayor_Hostage", 
  475. 		}, 
  476. 		 
  477. 		Kia_battle_props = { 
  478. 			name = "Group_kia_boss_battle_props", 
  479. 			fart_jars = { "Itm_fart_jar 001", "Itm_fart_jar 002", "Itm_fart_jar 003", "Itm_fart_jar 004" }, 
  480. 		}, 
  481. 		 
  482. 		BattleZone_Finale1 = { 
  483. 			name = "Group_BZfinale1", 
  484. 			members = { "npc_BZFinale1 Brute1", }, 
  485. 		}, 
  486. 		 
  487. 		BattleZone_Finale1v2 = { 
  488. 			name = "Group_BZfinale1v2", 
  489. 			members = { "npc_BZFinale1 Brute2", }, 
  490. 		}, 
  491. 		 
  492. 		BattleZone_Finale2 = { 
  493. 			name = "Group_BZfinale2", 
  494. 			members = { "npc_BZFinale2 Stag 001", "npc_BZFinale2 Stag 002" }, 
  495. 			vehicle = "veh_BZFinale2 Tank", 
  496. 		}, 
  497. 		 
  498. 		BattleZone_Finale3v1 = { 
  499. 			name = "Group_BZfinale3v1", 
  500. 			members = { "npc_BZFinale3 Brute" }, 
  501. 		}, 
  502. 		 
  503. 		BattleZone_Finale3v2 = { 
  504. 			name = "Group_BZfinale3v2", 
  505. 			members = { "npc_BZFinale3 Stag 001", "npc_BZFinale3 Stag 002" }, 
  506. 			vehicles = { "veh_BZFinale3 Tank" }, 
  507. 		}, 
  508. 		 
  509. 		Armory_Finale1 = { 
  510. 			name = "Group_ARMFinale1", 
  511. 			members = { "npc_ARMFinale Brute1" }, 
  512. 		}, 
  513. 		 
  514. 		Armory_Finale2 = { 
  515. 			name = "Group_ARMFinale2", 
  516. 			members = { "npc_ARMFinale Brute2" }, 
  517. 		}, 
  518. 		 
  519. 		Armory_Finale3 = { 
  520. 			name = "Group_ARMFinale3", 
  521. 			members = { "npc_ARMFinale Stag 001", "npc_ARMFinale Stag 002" }, 
  522. 			vehicles = { "veh_ARMFinale Tank" }, 
  523. 		}, 
  524. 		 
  525. 		Statue_Spawn1 = { 
  526. 			name = "Group_Statue_Spawn1", 
  527. 			members = { "Statue_Stag 001", "Statue_Stag 002" }, 
  528. 		}, 
  529. 		 
  530. 		Statue_Spawn2 = { 
  531. 			name = "Group_Statue_Spawn2", 
  532. 			members = { "Statue_Stag 003", "Statue_Stag 004" }, 
  533. 		}, 
  534. 		 
  535. 		Statue_Spawn3 = { 
  536. 			name = "Group_Statue_Spawn3", 
  537. 			members = { "Statue_Stag 005", "Statue_Stag 006" }, 
  538. 		}, 
  539. 		 
  540. 		Statue_Spawn4 = { 
  541. 			name = "Group_Statue_Spawn4", 
  542. 			members = { "Statue_Stag 007", "Statue_Stag 008" }, 
  543. 		}, 
  544. 		 
  545. 		Statue_Spawn5 = { 
  546. 			name = "Group_Statue_Spawn5", 
  547. 			members = { "Statue_Stag 009", "Statue_Stag 010" }, 
  548. 		}, 
  549. 		 
  550. 	} 
  551. 	 
  552. 	Battle_Zone_Groups = {  
  553. 		-- MLG: Removing Battlezone area 1 since we wanted to reduce the number of battlezones 
  554. 		--[[ 
  555. 		{ 
  556. 			initial_spawn = M22_groups.Zone_One_Initial,  
  557. 			courtesy_vehicles = M22_groups.Zone_One_Courtesy, 
  558. 			boss_spawn_regions = { "sr_BZ1_region 001", "sr_BZ1_region 002", "sr_BZ1_region 003",  
  559. 									"sr_BZ1_region 004", "sr_BZ1_region 005", "sr_BZ1_region 006" },					 
  560. 			center_pos = "Battle_Zone_Navpoint 001", 
  561. 			player_starts = { "nav_player_start_bz01_ 001", "nav_player_start_bz01_ 002" }, 
  562. 			trigger = "BZ1_Spawn_Trigger", 
  563. 			battle_area = "BZ1_Battle_Area", 
  564. 			required_kills = 26, 
  565. 			cleared = false, 
  566. 			index = 1, 
  567. 		}, 
  568. 		--]] 
  569. 		{ 
  570. 			initial_spawn = M22_groups.Zone_Two_Initial,  
  571. 			initial_vehicles = M22_groups.Zone_Two_Vehicles, 
  572. 			courtesy_vehicles = M22_groups.Zone_Two_Courtesy, 
  573. 			saints_group = M22_groups.Zone_Two_Saints, 
  574. 			boss_spawn_regions = { "sr_BZ2_region 001", "sr_BZ2_region 002", "sr_BZ2_region 003", 
  575. 									"sr_BZ2_region 004", "sr_BZ2_region 005", "sr_BZ2_region 006" }, 
  576. 			center_pos = "Battle_Zone_Navpoint 002", 
  577. 			player_starts = { "nav_player_start_bz02_ 001", "nav_player_start_bz02_ 002" }, 
  578. 			trigger = "BZ2_Spawn_Trigger", 
  579. 			battle_area = "BZ2_Battle_Area", 
  580. 			required_kills = 26, 
  581. 			cleared = false, 
  582. 			index = 1, 
  583. 		}, 
  584. 		{ 
  585. 			initial_spawn = M22_groups.Zone_Three_Initial,  
  586. 			initial_vehicles = M22_groups.Zone_Three_Vehicles, 
  587. 			courtesy_vehicles = M22_groups.Zone_Three_Courtesy, 
  588. 			saints_group = M22_groups.Zone_Three_Saints, 
  589. 			boss_spawn_regions = { "sr_BZ3_region 001", "sr_BZ3_region 002", "sr_BZ3_region 003", 
  590. 									"sr_BZ3_region 004", "sr_BZ3_region 005", "sr_BZ3_region 006" },			 
  591. 			center_pos = "Battle_Zone_Navpoint 003", 
  592. 			player_starts = { "nav_player_start_bz03_ 001", "nav_player_start_bz03_ 002" }, 
  593. 			trigger = "BZ3_Spawn_Trigger", 
  594. 			battle_area = "BZ3_Battle_Area", 
  595. 			required_kills = 26, 
  596. 			cleared = false, 
  597. 			index = 2, 
  598. 		}, 
  599. 		{ 
  600. 			initial_spawn = M22_groups.Zone_Four_Initial,  
  601. 			initial_vehicles = M22_groups.Zone_Four_Vehicles, 
  602. 			courtesy_vehicles = M22_groups.Zone_Four_Courtesy, 
  603. 			boss_spawn_regions = { "sr_BZ4_region 001", "sr_BZ4_region 002", "sr_BZ4_region 003", 
  604. 									"sr_BZ4_region 004", "sr_BZ4_region 005", "sr_BZ4_region 006" },		 
  605. 			saints_group = M22_groups.Zone_Four_Saints, 
  606. 			center_pos = "Battle_Zone_Navpoint 004", 
  607. 			player_starts = { "nav_player_start_bz04_ 001", "nav_player_start_bz04_ 002" }, 
  608. 			trigger = "BZ4_Spawn_Trigger", 
  609. 			battle_area = "BZ4_Battle_Area", 
  610. 			required_kills = 26, 
  611. 			cleared = false, 
  612. 			index = 3, 
  613. 		}, 
  614. 	} 
  615. 	 
  616. 	Battle_Zone_Finales = { 
  617. 		{ M22_groups.BattleZone_Finale1, M22_groups.BattleZone_Finale1v2 }, 
  618. 		{ M22_groups.BattleZone_Finale2 }, 
  619. 		{ M22_groups.BattleZone_Finale3v1, M22_groups.BattleZone_Finale3v2 }, 
  620. 		{ M22_groups.Armory_Finale1, M22_groups.Armory_Finale2, M22_groups.Armory_Finale3 }, 
  621. 	} 
  622. 	 
  623. 	Armory_battle_zone = { 
  624. 		initial_spawn = M22_groups.Armory_Initial, 
  625. 		initial_vehicles = M22_groups.Armory_Vehicles, 
  626. 		courtesy_vehicles = M22_groups.Armory_Courtesy, 
  627. 		boss_spawn_regions = { "sr_ARM_region 001", "sr_ARM_region 002", "sr_ARM_region 003",  
  628. 								"sr_ARM_region 004", "sr_ARM_region 005", "sr_ARM_region 006" }, 
  629. 		center_pos = "Armory_Navpoint", 
  630. 		player_starts = { "nav_player_start_armory_ 001", "nav_player_start_armory_ 002" }, 
  631. 		trigger = "Armory_Spawn_Trigger", 
  632. 		battle_area = "Armory_Battle_Area", 
  633. 		required_kills = 20, 
  634. 		cleared = false, 
  635. 		index = 5, 
  636. 	} 
  637.  
  638. 	cte_plane_group = { 
  639. 		name = "m22_cte_plane_01" 
  640. 		 
  641. 	} 
  642. 	 
  643. 	cte_kia_group = { 
  644. 		name = "Group_CTE_Kia" 
  645. 		 
  646. 	}	 
  647.  
  648. -- Navpoints -- 
  649. 	M22_navpoints = { 
  650. 		local_start = "Local_Player_Start", 
  651. 		remote_start = "Remote_Player_Start", 
  652. 		rail_begin = "Airport_Rail_Begin", 
  653. 		roadblock_one_move_tos = { "Roadblock_1_Nav 001", "Roadblock_1_Nav 002", "Roadblock_1_Nav 003", "Roadblock_1_Nav 004", 
  654. 								   "Roadblock_1_Nav 005", "Roadblock_1_Nav 006", "Roadblock_1_Nav 007", "Roadblock_1_Nav 008" }, 
  655. 		roadblock_two_move_tos = { "Roadblock_2_Nav 001", "Roadblock_2_Nav 002", "Roadblock_2_Nav 003", "Roadblock_2_Nav 004" }, 
  656. 		roadblock_three_move_tos = { "Roadblock_3_Nav 001", "Roadblock_3_Nav 002", "Roadblock_3_Nav 003", "Roadblock_3_Nav 004" }, 
  657. 		roadblock_four_move_tos = { "Roadblock_4_Nav 001", "Roadblock_4_Nav 002", "Roadblock_4_Nav 003", "Roadblock_4_Nav 004" }, 
  658. 		player_angel_start = { "nav_player_start_stop_kb 001", "nav_player_start_stop_kb 002" }, 
  659. 		player_kbfight_start = { "Local_kbfight_start", "Remote_kbfight_start" }, 
  660. 		player_kia_fight_start = { "Local_Kia_Fight_Start", "Remote_Kia_Fight_Start" }, 
  661. 		player_dock_start = { "nav_player_start_dock 001", "nav_player_start_dock 002" }, 
  662. 		statue_obs_deck = "Statue_Obs_Deck_Navpoint", 
  663. 		statue_boat_loc = "nav_statue_boat_location", 
  664. 		kia_attack_navs = { "Nav_kia_attack_pos 001", "Nav_kia_attack_pos 002", "Nav_kia_attack_pos 003", "Nav_kia_attack_pos 004" }, 
  665. 		kia_defence_east_navs= { "Nav_kia_defense_pos_east 001", "Nav_kia_defense_pos_east 002", "Nav_kia_defense_pos_east 003", 
  666. 									"Nav_kia_defense_pos_east 004", "Nav_kia_defense_pos_east 005", "Nav_kia_defense_pos_east 006" }, 
  667. 		kia_defence_west_navs= { "Nav_kia_defense_pos_west 001", "Nav_kia_defense_pos_west 002", "Nav_kia_defense_pos_west 003", 
  668. 									"Nav_kia_defense_pos_west 004", "Nav_kia_defense_pos_west 005", "Nav_kia_defense_pos_west 006" }, 
  669. 		kia_vtol_east_attack = { "nav_kia_vtol_idle_east 001", "nav_kia_vtol_attack_east 001" }, 
  670. 		kia_vtol_west_attack = { "nav_kia_vtol_idle_west 001", "nav_kia_vtol_attack_west 001" }, 
  671. 	} 
  672.  
  673. -- Triggers -- 
  674. 	M22_triggers = { 
  675. 		kill_killbane_perimeter = "Kill_Killbane_Perimeter_Trigger", 
  676. 		kill_killbane = "Kill_Killbane_Trigger", 
  677. 		save_saints_perimeter = "Save_Saints_Perimeter_Trigger", 
  678. 		save_saints = "Save_Saints_Trigger", 
  679. 		roadblock_one = "Roadblock_Trigger 001", 
  680. 		roadblock_two = "Roadblock_Trigger 002", 
  681. 		roadblock_three = "Roadblock_Trigger 003", 
  682. 		roadblock_four = "Roadblock_Trigger 004", 
  683. 		statue_elevator = "Statue_Elevator_Trigger", 
  684. 		statue_explosion_region = "Explosion_Region", 
  685. 		untie = { "Untie_Saint_Trigger 001", "Untie_Saint_Trigger 002", "Untie_Saint_Trigger 003", "Untie_Saint_Trigger 004" }, 
  686. 		First_Floor = "First_Floor_Trigger", 
  687. 		Second_Floor = "Second_Floor_Trigger", 
  688. 		Player_reached_top = "Player_reached_top_trigger", 
  689. 		Kia_Breadcrumb = "Kia_Breadcrumb_Trigger", 
  690. 		Kia_Boss_Area = "Trigger_Kia_Boss_Area 001", 
  691. 		fart_jars = { "Fart_jar_trigger 001", "Fart_jar_trigger 002", "Fart_jar_trigger 003", "Fart_jar_trigger 004" }, 
  692. 	} 
  693.  
  694. -- Characters -- 
  695. 	M22_characters =  { 
  696. 		Killbane = M22_groups.Airport.killbane, 
  697. 		Killbane_QTE = "", -- Initialized when we spawn Killbane, he may be masked or unmasked. 
  698. 		Kia = M22_groups.Kia.kia, 
  699. 		Oleg = M22_groups.Oleg_and_Pierce.oleg, 
  700. 		Pierce =  M22_groups.Oleg_and_Pierce.pierce, 
  701. 		Angel = M22_groups.Angel.npc, 
  702. 		Viola = M22_groups.Viola.viola, 
  703. 		Mayor = M22_groups.Hostages.mayor, 
  704. 		Shaundi = M22_groups.Hostages.shaundi, 
  705. 	} 
  706.  
  707. -- Vehicles -- 
  708. 	M22_vehicles = { 
  709. 		Start = M22_groups.Start_Vehicle.vehicle, 
  710. 		Killbanes_Plane = "Killbane_Plane", 
  711. 		Angels_Car = M22_groups.Angel.vehicle, 
  712. 		Kia_Vtol1 = M22_groups.Kia_Vtol1.vtol, 
  713. 	} 
  714.  
  715. -- Mesh Movers -- 
  716. 	M22_movers = { 
  717. 		c4 = {	"C4_Mover 001", "C4_Mover 002", "C4_Mover 003", "C4_Mover 004" }, 
  718. 		first_floor = { "C4_Mover 005", "C4_Mover 006", "C4_Mover 007", "C4_Mover 008" }, 
  719. 	} 
  720.  
  721. -- Text -- 
  722.  
  723. -- Threads -- 
  724. 	M22_threads = { 
  725. 		convo_handle = INVALID_THREAD_HANDLE, 
  726. 		drive_convo_handle = INVALID_THREAD_HANDLE, 
  727. 		battle_zone_gps = INVALID_THREAD_HANDLE, 
  728. 		battle_zone_instance = INVALID_THREAD_HANDLE, 
  729. 		battle_zone_followers = INVALID_THREAD_HANDLE, 
  730. 		battle_zone_saints = INVALID_THREAD_HANDLE, 
  731. 		battle_zone_notoriety_failsafe = INVALID_THREAD_HANDLE, 
  732. 		killbane_path_handle = INVALID_THREAD_HANDLE, 
  733. 		kill_killbane_dialog = INVALID_THREAD_HANDLE, 
  734. 		player_path_handle = INVALID_THREAD_HANDLE,	 
  735. 		vtol_one_handle = INVALID_THREAD_HANDLE, 
  736. 		vtol_two_handle = INVALID_THREAD_HANDLE, 
  737. 		kill_kia_dialog = INVALID_THREAD_HANDLE, 
  738. 		burt_dialog = INVALID_THREAD_HANDLE, 
  739. 		kia_boss_handle = INVALID_THREAD_HANDLE, 
  740. 		kia_vomit_handle = INVALID_THREAD_HANDLE, 
  741. 		respawn_handles = { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, 
  742. 							INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE }, 
  743. 		player_car_speed_handle = INVALID_THREAD_HANDLE, 
  744. 		roadblock_driveto_handles = { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, 
  745. 												INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE }, 
  746. 		audio_failsafe = INVALID_THREAD_HANDLE, 
  747. 	} 
  748.  
  749. -- Checkpoints -- 
  750. 	M22_checkpoints = { 
  751. 		CHECKPOINT_START = MISSION_START_CHECKPOINT,			-- defined in ug_lib.lua 
  752. 		 
  753. 		BATTLE_ZONE_1 = "m22_checkpoint_text_battle_zone_1", 
  754. 		BATTLE_ZONE_2 = "m22_checkpoint_text_battle_zone_2", 
  755. 		BATTLE_ZONE_3 = "m22_checkpoint_text_battle_zone_3", 
  756. 		--BATTLE_ZONE_4 = "m22_checkpoint_text_battle_zone_4", 
  757. 		 
  758. 		-- These checkpoint save when the player completes their 3rd battle zone 
  759. 		-- Depending on which zone we are, trigger a different checkpoint so that we can  
  760. 		-- warp them and their homies back to the correct zone if they die. 
  761. 		GOTO_ARMORY1 = "m22_checkpoint_text_get_to_the_armory1", -- DT 
  762. 		GOTO_ARMORY2 = "m22_checkpoint_text_get_to_the_armory2", -- NW 
  763. 		GOTO_ARMORY3 = "m22_checkpoint_text_get_to_the_armory3", -- SW 
  764. 		 
  765. 		ARMORY_FIGHT = "m22_checkpoint_text_armory_fight", 
  766. 		MAKE_YOUR_CHOICE = "m22_checkpoint_text_make_your_choice", 
  767. 		HELP_ANGEL = "m22_checkpoint_text_help_angel", 
  768. 		STOP_KILLBANE = "m22_checkpoint_text_stop_killbane_from_escaping", 
  769. 		KILL_KILLBANE = "m22_checkpoint_text_kill_killbane", 
  770. 		GOTO_SAINTS = "m22_checkpoint_text_go_to_statue", 
  771. 		SAVE_SAINTS = "m22_checkpoint_text_save_saints", 
  772. 		KILL_KIA = "m22_checkpoint_text_kill_kia", 
  773. 		 
  774. 		DEBUG_AIRPORT_CHOICE = "m22_debug_checkpoint_airport_choice", 
  775. 		DEBUG_STATUE_CHOICE = "m22_debug_checkpoint_statue_choice", 
  776. 		DEBUG_STATUE_CTE = "m22_debug_checkpoint_statue_cte", 
  777. 	} 
  778. 	 
  779. -- Cutscenes -- 
  780. 	M22_cutscenes = { 
  781. 		mission_intro = "22_in", 
  782. 		choice = "22_choice", 
  783. 		mission_killbane_outro = "22_out1", 
  784. 		mission_kia_outro = "22_out2", 
  785. 		plane_destroyed = "22_Z01" 
  786. 	} 
  787.  
  788. 	-- Replaced by "22_choice" cutscene. 
  789. 	--[[ 
  790. 	M22_cte_choice_01 = { 
  791. 		name = "m22_cte_01", 
  792. 	} 
  793. 	 
  794. 	M22_cte_statue_01 = { 
  795. 		name = "m22_cte_02", 
  796. 	} 
  797. 	--]] 
  798.  
  799. 	M22_cte_statue_02 = { 
  800. 		name = "m22_cte_03", 
  801. 	} 
  802. 	 
  803. -- Conversations -- 
  804. 	M22_conversations = { 
  805. 		mission_start = { 
  806. 			name = "M22_Mission_Start", 
  807. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  808. 		}, 
  809. 		--[[ 
  810. 		drive_convos = { 
  811. 			{ 
  812. 				name = "M22_Drive_01", 
  813. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  814. 			}, 
  815. 			{ 
  816. 				name = "M22_Drive_02", 
  817. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  818. 			}, 
  819. 			{ 
  820. 				name = "M22_Drive_03", 
  821. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  822. 			}, 
  823. 		}, 
  824. 		]]-- 
  825. 		boss_battle_intros = { 
  826. 			{ 
  827. 				name = "M22_Gang_Fight_01", 
  828. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  829. 			}, 
  830. 			--[[ 
  831. 			{ 
  832. 				name = "M22_Gang_Fight_02", 
  833. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  834. 			}, 
  835. 			{ 
  836. 				name = "M22_Gang_Fight_03", 
  837. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  838. 			}, 
  839. 			]]-- 
  840. 			{ 
  841. 				name = "M22_Second_Battle_Zone",  
  842. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  843. 			},	 
  844. 		}, 
  845. 		--[[ 
  846. 		boss_battle_middle = { 
  847. 			{ 
  848. 				name = "M22_First_Battle_Zone",  
  849. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  850. 			}, 
  851. 			{ 
  852. 				name = "M22_Second_Battle_Zone",  
  853. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  854. 			},				 
  855. 			{ 
  856. 				name = "M22_Third_Battle_Zone",  
  857. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  858. 			}, 
  859. 		}, 
  860. 		]]-- 
  861. 		boss_battle_complete = { 
  862. 			--[[ 
  863. 			{ 
  864. 				name = "M22_End_First_Battle_Zone", 
  865. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  866. 			}, 
  867. 			]]-- 
  868. 			{ 
  869. 				name = "M22_End_Second_Battle_Zone", 
  870. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  871. 			}, 
  872. 			{ 
  873. 				name = "M22_End_Third_Battle_Zone", 
  874. 				handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  875. 			}, 
  876. 		}, 
  877. 		armory = { 
  878. 			name = "M22_Armory", 
  879. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  880. 		}, 
  881. 		armory_fight = { 
  882. 			name = "M22_Armory_Fight", 
  883. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  884. 		}, 
  885. 		armory_middle = { 
  886. 			name = "M22_Armory_Battle_Zone", 
  887. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  888. 		}, 
  889. 		choice_phone_call = { 
  890. 			name = "M22_Choice_Call", 
  891. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  892. 		}, 
  893. 		convincing_call = { 
  894. 			name = "M22_Convincing", 
  895. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  896. 		}, 
  897. 		 
  898. 		-- Save Shaundi  
  899. 		kinzie_phone_call = { 
  900. 			name = "M22_Kinzie_Phone_Call", 
  901. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  902. 		}, 
  903. 		kinzie_monument = { 
  904. 			name = "M22_Kinzie_Monument", 
  905. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  906. 		}, 
  907. 		 
  908. 		-- CUT 
  909. 		--[[ 
  910. 		viola_monument = { 
  911. 			name = "M22_Viola_Monument", 
  912. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  913. 		}, 
  914. 		--]] 
  915. 		 
  916. 		kia_fight = { 
  917. 			name = "M22_Kia_Fight", 
  918. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  919. 		}, 
  920. 		 
  921. 		-- Kill Killbane 
  922. 		angel_phone_call = { 
  923. 			name = "M22_Angel_Under_Fire", 
  924. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  925. 		}, 
  926. 		angel_car_chase = { 
  927. 			name = "M22_Angel_Car_Chase", 
  928. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  929. 		}, 
  930. 		angel_car_chase2 = { 
  931. 			name = "M22_More_Angel_Car_Case", 
  932. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  933. 		}, 
  934. 		angel_shoot_plane = { 
  935. 			name = "M22_Angel_Shoot_Plane", 
  936. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  937. 		}, 
  938. 		 
  939. 		-- CUT 
  940. 		--[[ 
  941. 		plane_shot_down = { 
  942. 			name = "M22_Plane_Shot_Down", 
  943. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  944. 		}, 
  945. 		--]] 
  946. 		 
  947. 		-- CUT 
  948. 		--[[ 
  949. 		killbane_fight_01 = { 
  950. 			name = "M22_Killbane_Fight_01", 
  951. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  952. 		}, 
  953. 		--]] 
  954. 		 
  955. 		killbane_fight_04 = { 
  956. 			name = "M22_Killbane_Fight_04", 
  957. 			handle = INVALID_CONVERSATION_HANDLE, played = false, direct = false, 
  958. 		}, 
  959. 	} 
  960. 	 
  961. 	M22_dialog_lines = { 
  962. 		pierce_saints_arrive = { "M22_First_Battle_Saints_Arrive", "M22_Second_Battle_Saints_Arrive" }, 
  963. 		pierce_leave_oleg = { "M22_Oleg_Fell_Behind_01", "M22_Oleg_Fell_Behind_02" }, 
  964. 		player_armory_clear = "M22_End_Armory_Battle_Zone", 
  965. 		 
  966. 		choice_call = { "M22_Choice_Call_01", "M22_Choice_Call_02" }, 
  967. 		--kia_vs_vtol = "m22_vtol_attacking_kia", 
  968. 		oleg_convincing = "M22_Convincing_02", 
  969. 		pierce_convincing = "M22_Convincing_01", 
  970. 		kinzie_dock = "M22_Kinzie_Monument_01", 
  971. 		killbane_fight_02 = "M22_Killbane_Fight_02", 
  972. 		killbane_fight_03 = "M22_Killbane_Fight_03", 
  973. 		 
  974. 		burt_encouragement = { "M22_Burt_Encouragement_01", "M22_Burt_Encouragement_02", "M22_Burt_Encouragement_03", "M22_Burt_Encouragement_04", "M22_Burt_Encouragement_05" }, 
  975. 		burt_damaged = { "M22_Burt_Collateral_Damage_01", "M22_Burt_Collateral_Damage_02", "M22_Burt_Collateral_Damage_03", "M22_Burt_Collateral_Damage_04", "M22_Burt_Collateral_Damage_05" }, 
  976. 		burt_fiaj = { "M22_Burt_React_FIAJ_01", "M22_Burt_React_FIAJ_02", "M22_Burt_React_FIAJ_03", "M22_Burt_React_FIAJ_04", "M22_Burt_React_FIAJ_05" }, 
  977. 		 
  978. 		shaundi_grab_fiaj = "M22_Pick_Up_Grenades", 
  979. 		shaundi_grab_fiaj_nag = "M22_Nag_About_Grenades", 
  980. 		player_grabbed_fiaj = "M22_Pick_Up_Grenades_02", 
  981. 		 
  982. 		angel_attacked = { "M22_Angel_Being_Attacked_01", "M22_Angel_Being_Attacked_02", "M22_Angel_Being_Attacked_03" }, 
  983. 		angel_chase = { "M22_More_Angel_Car_Chase_02_01", "M22_More_Angel_Car_Chase_03_01" }, 
  984. 		angel_encourage_shoot = { "M22_Angel_Encourage_Plane_Shot_01", "M22_Angel_Encourage_Shot_02", "M22_Angel_Encourage_Shot_03" }, 
  985. 		plane_down = "M22_Plane_Shot_Down", 
  986. 	} 
  987. 	 
  988. 	M22_personas = { 
  989. 		kinzie = { 
  990. 			name = "Kinzie", 
  991. 			persona_id = INVALID_PERSONA_HANDLE, 
  992. 		}, 
  993. 		oleg = { 
  994. 			name = "Oleg", 
  995. 			persona_id = INVALID_PERSONA_HANDLE, 
  996. 		}, 
  997. 		pierce = { 
  998. 			name = "Pierce", 
  999. 			persona_id = INVALID_PERSONA_HANDLE, 
  1000. 		}, 
  1001. 		kia = { 
  1002. 			name = "Kia", 
  1003. 			persona_id = INVALID_PERSONA_HANDLE, 
  1004. 		}, 
  1005. 		angel = { 
  1006. 			name = "Angel", 
  1007. 			persona_id = INVALID_PERSONA_HANDLE, 
  1008. 		}, 
  1009. 	} 
  1010. 	 
  1011. 	M22_audio_events = { 
  1012. 		music_start = "M22_Hero_Music_Start", 
  1013. 		music_start_checkpoint = "M22_Hero_Music_Checkpoint", 
  1014. 		music_fade_out = "M22_Hero_Music_Fade", 
  1015. 		music_stop = "M22_Hero_Music_Stop", 
  1016. 		music_kia_start = "M22_Kia_Music_Start", 
  1017. 		music_kia_finish = "M22_Kia_Music_Finish", 
  1018. 		music_kia_stop = "M22_Kia_Music_Stop", 
  1019. 		battle_ambience_start = "M22_Battle_Ambience", 
  1020. 		battle_anbience_stop = "M22_Battle_Ambience_Stop", 
  1021. 		music_kb_zscene_fade = "M22_Hero_Fade_Zscene", 
  1022. 	} 
  1023. 		 
  1024. 	 
  1025. 	M22_roadblocks = { 
  1026. 		-- Example 
  1027. 		--{ layout = "police_lvl2_2lane", navpoint = "nav_roadblock", handle = -1 }, 
  1028. 		{layout = "m22_skirmish_4lane", navpoint = "nav_dt_roadblock 001", handle = -1}, 
  1029. 		{layout = "m22_skirmish_4lane", navpoint = "nav_dt_roadblock 002", handle = -1}, 
  1030. 		{layout = "m22_wreckage_2lane", navpoint = "nav_dt_roadblock 003", handle = -1}, 
  1031. 		{layout = "m22_skirmish_4lane", navpoint = "nav_dt_roadblock 004", handle = -1}, 
  1032. 		{layout = "m22_skirmish_4lane", navpoint = "nav_dt_roadblock 005", handle = -1}, 
  1033. 		{layout = "m22_wreckage_4lane", navpoint = "nav_dt_roadblock 006", handle = -1}, 
  1034. 		{layout = "m22_skirmish_2lane", navpoint = "nav_dt_roadblock 007", handle = -1}, 
  1035. 		{layout = "m22_skirmish_2lane", navpoint = "nav_dt_roadblock 008", handle = -1}, 
  1036. 		{layout = "m22_wreckage_2lane", navpoint = "nav_ne_roadblock 001", handle = -1}, 
  1037. 		{layout = "m22_skirmish_2lane", navpoint = "nav_ne_roadblock 002", handle = -1}, 
  1038. 		{layout = "m22_skirmish_4lane", navpoint = "nav_ne_roadblock 003", handle = -1}, 
  1039. 		{layout = "m22_wreckage_4lane", navpoint = "nav_ne_roadblock 004", handle = -1}, 
  1040. 		{layout = "m22_skirmish_4lane", navpoint = "nav_ne_roadblock 005", handle = -1}, 
  1041. 		{layout = "m22_skirmish_2lane", navpoint = "nav_ne_roadblock 006", handle = -1}, 
  1042. 		{layout = "m22_wreckage_2lane", navpoint = "nav_nw_roadblock 001", handle = -1}, 
  1043. 		{layout = "m22_skirmish_4lane", navpoint = "nav_nw_roadblock 002", handle = -1}, 
  1044. 		{layout = "m22_skirmish_2lane", navpoint = "nav_nw_roadblock 003", handle = -1}, 
  1045. 		{layout = "m22_wreckage_2lane", navpoint = "nav_nw_roadblock 004", handle = -1}, 
  1046. 		{layout = "m22_skirmish_2lane", navpoint = "nav_nw_roadblock 005", handle = -1}, 
  1047. 		{layout = "m22_skirmish_4lane", navpoint = "nav_nw_roadblock 006", handle = -1}, 
  1048. 		{layout = "m22_wreckage_4lane", navpoint = "nav_sw_roadblock 001", handle = -1}, 
  1049. 		{layout = "m22_skirmish_2lane", navpoint = "nav_sw_roadblock 002", handle = -1}, 
  1050. 		{layout = "m22_wreckage_2lane", navpoint = "nav_sw_roadblock 003", handle = -1}, 
  1051. 		{layout = "m22_skirmish_4lane", navpoint = "nav_sw_roadblock 004", handle = -1}, 
  1052. 		{layout = "m22_wreckage_2lane", navpoint = "nav_sw_roadblock 005", handle = -1}, 
  1053. 		{layout = "m22_skirmish_4lane", navpoint = "nav_sw_roadblock 006", handle = -1}, 
  1054. 	} 
  1055. 	 
  1056. 	m22_statue_spawn_regions = { 
  1057. 		"sr_statue_spawn_region 001", "sr_statue_spawn_region 002", "sr_statue_spawn_region 003", "sr_statue_spawn_region 004", 
  1058. 		"sr_statue_spawn_region 005", "sr_statue_spawn_region 006", "sr_statue_spawn_region 007", "sr_statue_spawn_region 008", 
  1059. 	} 
  1060. 	 
  1061. 	M22_anims = { 
  1062. 		fiaj_reactions = { 
  1063. 			{ intro = "Stand_to_FIAJ_ReactA", outro = "FIAJ_ReactA_To_Stand" }, 
  1064. 			{ intro = "Stand_to_FIAJ_ReactB", outro = "FIAJ_ReactB_To_Stand" }, 
  1065. 			{ intro = "Stand_to_FIAJ_ReactC", outro = "FIAJ_ReactC_To_Stand" }, 
  1066. 			{ intro = "Stand_to_FIAJ_ReactD", outro = "FIAJ_ReactD_To_Stand" }, 
  1067. 		}, 
  1068. 	} 
  1069. 	 
  1070. -- Other -- 
  1071. 	in_coop = false 
  1072. 	Completed_m23 = false 
  1073. 	Completed_m24 = false 
  1074. 	 
  1075. 	NO_ZONE = 0 
  1076. 	ZONE_ACTIVE = 1 
  1077. 	STAG = true 
  1078. 	SYND = false 
  1079. 	 
  1080. 	Active_conversation = { 
  1081. 		convo_table = nil 
  1082. 	} 
  1083. 	 
  1084. 	Current_bz = {  
  1085. 		zone = NO_ZONE,  
  1086. 		num_initial_stag_alive = 0,  
  1087. 		num_initial_synd_alive = 0,  
  1088. 		kills = 0,  
  1089. 		num_bosses = 0, 
  1090. 		bosses_killed = 0, 
  1091. 		num_enemies_released = 0, 
  1092. 	} 
  1093. 	 
  1094. 	Nearest_bz_center = "" 
  1095. 	 
  1096. 	Number_of_zones_cleared = 0 
  1097. 	Latest_zone_cleared = 0 
  1098. 	 
  1099. 	Local_player_zone = NO_ZONE		-- These are either FIRST/SECOND 
  1100. 	Remote_player_zone = NO_ZONE	-- Tells us what zones the players are in. 
  1101. 	 
  1102. 	Mission_23_name = "m23" 
  1103. 	Mission_24_name = "m24" 
  1104. 	 
  1105. 	-- Armory 
  1106. 	Armory_reached = false 
  1107. 	 
  1108. 	-- Player Choice 
  1109. 	Player_choice = "none" 
  1110. 	Next_mission = Mission_23_name -- default to mission 23 for mission_win 
  1111. 	 
  1112. 	-- Airport 
  1113. 	M22_ROCKET_LAUNCHER = "Explosive-RocketLauncher" 
  1114. 	M22_SONICWAVE_GUN = "Special-SonicGun" 
  1115. 	M22_RC_GUN = "Special-RCVehicleGun" 
  1116. 	 
  1117. 	M22_PLAYER_KB_LOADOUT = { M22_ROCKET_LAUNCHER } 
  1118. 	M22_PLAYER_SONIC_LOADOUT = { M22_SONICWAVE_GUN } 
  1119. 	 
  1120. 	Airport_player_path = { 
  1121. 		"Player Airport Spline 001", 
  1122. 		"Player Airport Spline 001b", 
  1123. 		"Player Airport Spline 002", 
  1124. 		"Player Airport Spline 003", 
  1125. 		"Player Airport Spline 004", 
  1126. 		"Player Airport Spline 005", 
  1127. 		"Player Airport Spline 006", 
  1128. 	} 
  1129. 	Airport_Killbane_Path1 = "Killbane Airport Spline 001" 
  1130. 	Airport_Killbane_Path2 = "Killbane Airport Spline 002" 
  1131. 	Airport_Killbane_Path3 = "Killbane Airport Spline 003" 
  1132. 	Airport_Killbane_Path4 = "Killbane Airport Spline 004" 
  1133. 	Airport_Killbane_Path5 = "Killbane Airport Spline 005" 
  1134. 	 
  1135. 	Num_plane_hits = 0 
  1136. 	 
  1137. 	Killbane_qte_finished = false 
  1138. 	 
  1139. 	-- Statue 
  1140. 	 
  1141. 	M22_statue_populated = false 
  1142. 	 
  1143. 	Num_c4_left_to_destroy = 0 
  1144. 	Total_c4_to_destroy = 0 
  1145. 	Num_c4_left_first_floor = 0 
  1146. 	Player_used_elevator = false 
  1147. 	First_floor_cleared = false 
  1148. 	Second_floor_reached = false 
  1149. 	Player_reached_breadcrumb = false 
  1150. 	Player_reached_top = false 
  1151. 	Player_got_fiaj = false 
  1152. 	M22_burt_can_play_damage_line = true 
  1153. 	 
  1154. 	Vtol_path1 = "Vtol_path 001" 
  1155. 	Vtol_path2 = "Vtol_path 002" 
  1156. 	 
  1157. 	Battle_zone_boss_hud_bar_factor = 3 
  1158. 	 
  1159. 	-- Kia Boss Battle 
  1160. 	Kia_boss_ai = { 
  1161. 		current_navpoint = nil, 
  1162. 		attack_vtol_side = nil, 
  1163. 		attack_vtol_attacking = false, 
  1164. 	} 
  1165. 	 
  1166. 	M22_cur_cell_call_name = "" 
  1167. 		 
  1168.  
  1169.  
  1170. -- ************************* 
  1171. -- 
  1172. -- Standard functions 
  1173. -- 
  1174. -- ************************* 
  1175.  
  1176. -- This is the primary entry point for the mission, and is responsible for starting up the mission 
  1177. -- at the specified checkpoint. 
  1178. -- CALLED FROM CODE 
  1179. -- 
  1180. -- m22_checkpoint:	The checkpoint the mission should begin at 
  1181. -- is_restart:					TRUE if the mission is restarting, FALSE otherwise 
  1182. -- 
  1183. function m22_start(m22_checkpoint, is_restart) 
  1184. 	in_coop = coop_is_active() 
  1185.  
  1186. 	--m22_checkpoint = M22_checkpoints.ARMORY_FIGHT 
  1187. 	-- Check if this mission starting from the beginning 
  1188. 	if (m22_checkpoint == M22_checkpoints.CHECKPOINT_START) then 
  1189. 		if (is_restart == false) then 
  1190. 			-- First time playing mission 
  1191. 			local cutscene_navs = { "Local_Player_Start", "Remote_Player_Start" } 
  1192. 			-- Play an intro cutscene??? 
  1193. 			if (M22_cutscenes.mission_intro ~= "") then 
  1194. 				cutscene_play(M22_cutscenes.mission_intro, nil, cutscene_navs, false) 
  1195. 			end 
  1196. 		end 
  1197. 	end 
  1198.  
  1199. 	-- Handle mission initialization for the current checkpoint 
  1200. 	m22_initialize(m22_checkpoint) 
  1201.  
  1202. 	-- Run the mission from the current checkpoint 
  1203. 	m22_run(m22_checkpoint) 
  1204. 	 
  1205. end 
  1206.  
  1207. -- This is the primary function responsible for cleaning up the entire mission 
  1208. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  1209. -- 
  1210. function m22_cleanup() 
  1211. 	hud_timer_stop(1) 
  1212. 	 
  1213. 	-- Cleanup the QTE system 
  1214. 	qte_cleanup() 
  1215. 	 
  1216. 	-- Disable zone swaps 
  1217. 	city_zone_swap("planecrash", DISABLE) -- Cleanup Killbane plane crash 
  1218. 	city_zone_swap("burn", DISABLE) -- Turn off the city burning 
  1219. 	 
  1220. 	-- If the player is replaying this mission, and the statue got blown 
  1221. 	-- up previously, redo that. 
  1222. 	if Completed_m23 == true and Completed_m24 == false then 
  1223. 		city_zone_swap("rubble", true) 
  1224. 	end 
  1225. 	 
  1226. 	m22_cleanup_battle_zones() 
  1227. 	m22_cleanup_goto_armory_sequence() 
  1228. 	m22_cleanup_kill_kia() 
  1229. 	 
  1230. 	m22_cleanup_triggers(M22_triggers) 
  1231. 	m22_cleanup_threads(M22_threads) 
  1232. 	m22_cleanup_movers(M22_movers) 
  1233. 	m22_cleanup_conversations() 
  1234. 	m22_cleanup_personas() 
  1235. 	cleanup_groups(M22_groups) 
  1236. 	mission_waypoint_remove() 
  1237. 	 
  1238. 	shop_ignore_clerk(false) 
  1239. 	 
  1240. 	--boss_battle_kia_active(false) 
  1241. 	 
  1242. 	on_qte_animation_trigger("") 
  1243. 	on_human_killed("") 
  1244. 	on_projectile_hit("") 
  1245. 	notoriety_force_no_spawn("police", DISABLE) 
  1246. 	notoriety_force_no_spawn("stag", false) -- AC: Test 
  1247. 	notoriety_force_no_spawn("luchadores", DISABLE) 
  1248. 	 
  1249. 	notoriety_force_no_spawn_group("stag_tank", false) 
  1250. 	notoriety_force_no_spawn_group("stag_attack_heli", false) 
  1251. 	notoriety_force_no_spawn_group("stag_heli", false) 
  1252. 	notoriety_force_no_spawn_group("stag_riot", false) 
  1253. 	 
  1254. 	-- Remove Fake Notoriety 
  1255. 	hud_set_fake_notoriety("police", false) 
  1256. 	hud_set_fake_notoriety("luchadores", false) 
  1257. 	 
  1258. 	set_stag_active(DISABLE) 
  1259. 	notoriety_set_can_decay(ENABLE) 
  1260. 	--notoriety_force_no_spawn("syndicate", false) 
  1261. 	 
  1262. 	disable_specific_notoriety_group("stag", 2, "G_STAG_CopCar", false) 
  1263. 	disable_specific_notoriety_group("stag", 3, "G_STAG_CopCar", false) 
  1264. 	disable_specific_notoriety_group("stag", 4, "G_STAG_CopCar", false) 
  1265. 	disable_specific_notoriety_group("stag", 5, "G_STAG_CopCar", false) 
  1266. 	disable_specific_notoriety_group("stag", 2, "G_STAG_BikeCop", false) 
  1267. 	disable_specific_notoriety_group("stag", 3, "G_STAG_BikeCop", false) 
  1268. 	 
  1269. 	for i, spawn in pairs(m22_statue_spawn_regions) do 
  1270. 		cleanup_spawn_regions(m22_statue_spawn_regions[i], false) 
  1271. 	end 
  1272. 	cleanup_spawn_groups(M22_groups.Statue_Spawn1.name) 
  1273. 	cleanup_spawn_groups(M22_groups.Statue_Spawn2.name) 
  1274. 	cleanup_spawn_groups(M22_groups.Statue_Spawn3.name) 
  1275. 	cleanup_spawn_groups(M22_groups.Statue_Spawn4.name) 
  1276. 	cleanup_spawn_groups(M22_groups.Statue_Spawn5.name) 
  1277. 	 
  1278. 	-- turn roadblocks and ambient roadblocks back on 
  1279. 	roadblocks_ambient_traffic_enable(true) 
  1280. 	roadblocks_enable(true) 
  1281. 	 
  1282. 	set_civilians_flee(DISABLE) 
  1283. 	 
  1284. 	flashpoints_enable(ENABLE) -- reenable flashpoints 
  1285. 	 
  1286. 	on_death("", M22_characters.Oleg) 
  1287. 	on_death("", M22_characters.Pierce) 
  1288. 	on_dismiss("", M22_characters.Pierce) 
  1289. 	 
  1290. 	-- Cleanup on_death callback for the tied up saints 
  1291. 	for i, saint in pairs(M22_groups.Statue.saints) do 
  1292. 		on_death("", saint) 
  1293. 	end 
  1294. 	 
  1295. 	set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true) 
  1296. 	 
  1297. 	-- Make sure all the weapon slots are enabled again 
  1298. 	inv_weapon_disable_all_slots(DISABLE) 
  1299. 	 
  1300. 	if in_coop then 
  1301. 		set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true) 
  1302. 	end 
  1303. 	 
  1304. 	-- Destroy the roadblocks around the city 
  1305. 	for i, roadblock in pairs(M22_roadblocks) do 
  1306. 		roadblock_destroy(roadblock.handle) 
  1307. 	end 
  1308. 	 
  1309. 	-- Reset density of peds and traffic 
  1310. 	set_ped_density(1) 
  1311. 	set_traffic_density(1) 
  1312. 	spawning_pedestrians(true) 
  1313. 	 
  1314. 	-- Reset parked car spawning. 
  1315. 	parking_spot_reset_max() 
  1316. 	 
  1317. 	audio_object_post_event("M22_QTE_Music_Stop", nil, nil, LOCAL_PLAYER) 
  1318. 	audio_object_post_event(M22_audio_events.music_kia_stop, nil, nil, LOCAL_PLAYER) 
  1319. 	 
  1320. 	inv_remove_temp_loadout(M22_PLAYER_KB_LOADOUT) 
  1321. 	 
  1322. 	player_movement_enable(LOCAL_PLAYER) 
  1323. 	if coop_is_active() then 
  1324. 		player_movement_enable(REMOTE_PLAYER) 
  1325. 	end 
  1326. end 
  1327.  
  1328. -- Called when the mission has ended with success 
  1329. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  1330. -- 
  1331. function m22_success() 
  1332. 	--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]-- 
  1333. 	if (Next_mission == Mission_23_name) then 
  1334. 		game_choice_set_state( MISSION_22_CHOICE, M22_CHOICE_KILLBANE_KILL ) 
  1335. 	else 
  1336. 		game_choice_set_state( MISSION_22_CHOICE, M22_CHOICE_KILLBANE_ESCAPE ) 
  1337. 	end 
  1338.  
  1339. 	local skip_teleport = true 
  1340. 	m22_coop_skip(skip_teleport) -- do the stuff we'd do in the skip case 
  1341. end 
  1342.  
  1343.  
  1344. -- ************************* 
  1345. -- 
  1346. -- Local functions 
  1347. -- 
  1348. -- ************************* 
  1349.  
  1350. -- Initialize the mission for the specified checkpoint 
  1351. -- 
  1352. -- checkpoint:		Checkpoint to initialize the mission to 
  1353. -- 
  1354. function m22_initialize(checkpoint) 
  1355. 	-- Make sure the screen is completly faded out 
  1356. 	mission_start_fade_out(0.0) 
  1357.  
  1358. 	-- Set the mission author 
  1359. 	set_mission_author("John Karczewski") 
  1360.  
  1361. 	-- Common initialization 
  1362. 	m22_initialize_common() 
  1363.  
  1364. 	-- Checkpoint specific initialization 
  1365. 	m22_initialize_checkpoint(checkpoint) 
  1366.  
  1367. 	-- Reduce density of peds and traffic 
  1368. 	set_ped_density(0.25) 
  1369. 	set_traffic_density(0.1) 
  1370. 	 
  1371. 	-- Start fading in  
  1372. 	mission_start_fade_in() 
  1373. end 
  1374.  
  1375.  
  1376. -- This is the primary function responsible for running the entire mission from start to finish. 
  1377. -- 
  1378. -- first_checkpoint:	The first checkpoint to begin running the mission at 
  1379. -- 
  1380. function m22_run(first_checkpoint) 
  1381. 	local current_checkpoint = first_checkpoint 
  1382.  
  1383. 	-- Run the mission from the beginning or from a battle zone checkpoint 
  1384. 	if (current_checkpoint == M22_checkpoints.CHECKPOINT_START or m22_checkpoint_is_battle_zone(current_checkpoint) == true) then 
  1385. 		m22_process_battle_zone_sequence() 
  1386. 		 
  1387. 		current_checkpoint = m22_set_post_battle_zone_checkpoint() 
  1388. 	end 
  1389. 	 
  1390. 	if  (m22_checkpoint_is_get_to_armory(current_checkpoint) == true) then 
  1391. 		m22_goto_armory_sequence() 
  1392. 		 
  1393. 		current_checkpoint = M22_checkpoints.ARMORY_FIGHT 
  1394. 		mission_set_checkpoint(M22_checkpoints.ARMORY_FIGHT, true) 
  1395. 	end 
  1396. 	 
  1397. 	if current_checkpoint == M22_checkpoints.ARMORY_FIGHT then 
  1398. 		m22_process_armory_fight() 
  1399. 		 
  1400. 		-- Play dialog lines prior to the cutscene 
  1401. 		--[[ 
  1402. 		M22_threads.convo_handle = thread_new("m22_play_cell_convo", M22_conversations.mission_start.name, true) 
  1403. 		local line_handle = audio_play_persona_line_2d(M22_personas.angel.persona_id, M22_dialog_lines.choice_call[1]) 
  1404. 		-- Wait for the line to finish 
  1405. 		while (audio_is_playing(line_handle) == true)do 
  1406. 			thread_yield() 
  1407. 		end 
  1408. 		audio_stop(line_handle) 
  1409. 		]]-- 
  1410. 		m22_play_cell_convo(M22_dialog_lines.choice_call[1], true, M22_personas.angel.persona_id) 
  1411. 	 
  1412. 		local line_handle = audio_play_persona_line(LOCAL_PLAYER, M22_dialog_lines.choice_call[2]) 
  1413. 		--delay(1.0) 
  1414. 		-- Wait for the line to finish 
  1415. 		m22_wait_for_foley_safe(line_handle, 60.0) 
  1416. 		audio_stop(line_handle) 
  1417. 		 
  1418. 		-- Play the cutscene 
  1419. 		cutscene_play(M22_cutscenes.choice, nil, { Armory_battle_zone.center_pos, Armory_battle_zone.center_pos }) 
  1420. 		 
  1421. 		current_checkpoint = M22_checkpoints.MAKE_YOUR_CHOICE 
  1422. 		mission_set_checkpoint(M22_checkpoints.MAKE_YOUR_CHOICE) 
  1423. 	end 
  1424. 	 
  1425. 	-- Replaced by "22_choice" cutscene. 
  1426. 	--[[ 
  1427. 	if current_checkpoint == M22_checkpoints.DEBUG_AIRPORT_CHOICE then 
  1428. 		m22_choice_airport_cutscene() 
  1429. 		 
  1430. 		current_checkpoint = M22_checkpoints.DEBUG_STATUE_CHOICE 
  1431. 	end 
  1432. 	 
  1433. 	if current_checkpoint == M22_checkpoints.DEBUG_STATUE_CHOICE then 
  1434. 		m22_choice_statue_cutscene() 
  1435. 	 
  1436. 		current_checkpoint = M22_checkpoints.MAKE_YOUR_CHOICE 
  1437. 		mission_set_checkpoint(M22_checkpoints.MAKE_YOUR_CHOICE) 
  1438. 	end 
  1439. 	--]] 
  1440. 	 
  1441. 	if current_checkpoint == M22_checkpoints.MAKE_YOUR_CHOICE then 
  1442. 		m22_process_player_choice_sequence() 
  1443. 		 
  1444. 		if (Player_choice == "killbane") then 
  1445. 			current_checkpoint = M22_checkpoints.STOP_KILLBANE 
  1446. 			mission_set_checkpoint(M22_checkpoints.STOP_KILLBANE) 
  1447. 		else 
  1448. 			current_checkpoint = M22_checkpoints.DEBUG_STATUE_CTE 
  1449. 		end 
  1450. 	end	 
  1451. 	 
  1452. 	if current_checkpoint == M22_checkpoints.STOP_KILLBANE then 
  1453. 		m22_protect_angel_sequence() 
  1454. 		m22_in_transit_to_airport() 
  1455. 		m22_setup_killbane_chase_sequence() 
  1456. 		m22_process_killbane_chase_sequence() 
  1457. 		 
  1458. 		audio_object_post_event(M22_audio_events.music_kb_zscene_fade, nil, nil, LOCAL_PLAYER) 
  1459. 		 
  1460. 		-- Setup the killbane fight and cinematic (need a screen fade here since we need to apply the zone-swap) 
  1461. 		mission_start_fade_out(0.0) 
  1462. 		m22_setup_kill_killbane() 
  1463. 		mission_start_fade_in() 
  1464. 		 
  1465. 		current_checkpoint = M22_checkpoints.KILL_KILLBANE 
  1466. 		mission_set_checkpoint(M22_checkpoints.KILL_KILLBANE, true) -- don't save out their vehicle 
  1467. 	end 
  1468. 	 
  1469. 	if current_checkpoint == M22_checkpoints.KILL_KILLBANE then		 
  1470. 		m22_killbane_plane_destroyed_scene() 
  1471. 		m22_process_kill_killbane() 
  1472. 		Player_choice = "killbane" 
  1473. 	end 
  1474. 	 
  1475. 	if current_checkpoint == M22_checkpoints.DEBUG_STATUE_CTE then 
  1476. 		m22_arrived_at_dock_sequence() 
  1477. 		m22_c4_objective_cte() 
  1478. 		 
  1479. 		current_checkpoint = M22_checkpoints.GOTO_SAINTS 
  1480. 		mission_set_checkpoint(M22_checkpoints.GOTO_SAINTS, false) 
  1481. 	end 
  1482. 	 
  1483. 	if current_checkpoint == M22_checkpoints.GOTO_SAINTS then 
  1484. 		m22_go_to_statue_sequence() 
  1485. 		m22_setup_save_the_saints()	 
  1486. 		 
  1487. 		fade_out(0.5) 
  1488. 		fade_out_block() 
  1489. 		teleport_coop(M22_navpoints.statue_obs_deck, M22_navpoints.statue_obs_deck, true) 
  1490. 		 
  1491. 		-- Equip the sonic gun. 
  1492. 		m22_equip_temp_weapons_for_save_saints() 
  1493. 		 
  1494. 		fade_in(0.5) 
  1495. 		fade_in_block() 
  1496. 		 
  1497. 		m22_cleanup_statue_courtesy_boats() 
  1498. 	 
  1499. 		current_checkpoint = M22_checkpoints.SAVE_SAINTS 
  1500. 		mission_set_checkpoint(M22_checkpoints.SAVE_SAINTS, false) 
  1501. 	end 
  1502.  
  1503. 	if current_checkpoint == M22_checkpoints.SAVE_SAINTS then 
  1504. 		m22_process_save_the_saints() 
  1505. 		m22_cleanup_save_the_saints() 
  1506. 		 
  1507. 		current_checkpoint = M22_checkpoints.KILL_KIA 
  1508. 		mission_set_checkpoint(M22_checkpoints.KILL_KIA, true) -- don't save out their vehicle 
  1509. 	end 
  1510. 	 
  1511. 	if current_checkpoint == M22_checkpoints.KILL_KIA then 
  1512. 		m22_process_kill_kia() 
  1513. 		m22_cleanup_kill_kia() 
  1514. 		Player_choice = "shaundi" 
  1515. 	end 
  1516. 	 
  1517. 	-- Call mission success?? 
  1518. 	if Player_choice == "killbane" then 
  1519. 		mission_end_success("m22", M22_cutscenes.mission_killbane_outro, M22_navpoints.player_kbfight_start) 
  1520. 	else 
  1521. 		fade_out(0.5) 
  1522. 		fade_out_block() 
  1523. 		mission_set_completed( "m22" ) 
  1524. 		mission_unlock( "m24" ) 
  1525. 		mission_autosave() 
  1526. 		mission_end_to_activity( "m22", "m24" ) 
  1527. 	end 
  1528. end 
  1529.  
  1530. -- Primary function to process all of the battlezones the player must clear before moving on in the mission 
  1531. function m22_process_battle_zone_sequence() 
  1532. 	-- Enable all the battlezone triggers 
  1533. 	for i, battle_zone in pairs(Battle_Zone_Groups) do 
  1534. 		on_trigger("m22_zone_triggered_cb", battle_zone.trigger) 
  1535. 		on_trigger_exit("m22_zone_exited_cb", battle_zone.trigger) 
  1536. 		trigger_enable(battle_zone.trigger, true) 
  1537. 	end 
  1538.  
  1539. 	if (Number_of_zones_cleared == 0) then 
  1540. 		-- Play some dialog 
  1541. 		M22_threads.convo_handle = thread_new("m22_play_cell_convo", M22_conversations.mission_start.name, true) 
  1542. 	end 
  1543. 	 
  1544. 	local oleg_tutorial_displayed = false 
  1545. 	 
  1546. 	-- Loop until all the zones have been completed 
  1547. 	while (Number_of_zones_cleared < NUM_ZONES_TO_COMPLETE_TO_SUCCEED) do 
  1548. 		-- Update the object text to get to the battle zone 
  1549. 		objective_text_clear(0) 
  1550. 		objective_text_clear(1) 
  1551. 		objective_text( 0, "m22_obj_goto_battlezone", "", "", SYNC_LOCAL, OI_ASSET_LOCATION) 
  1552. 		objective_text( 1, "m22_obj_goto_battlezone", "", "", SYNC_REMOTE, OI_ASSET_LOCATION) 
  1553. 		 
  1554. 		-- Initialize the current battle zone data 
  1555. 		Current_bz.zone = NO_ZONE 
  1556. 		 
  1557. 		-- Setup all the battle zones triggers (for any remaining battle zones) 
  1558. 		m22_show_remaining_battle_zones() 
  1559. 		 
  1560. 		-- Begin plotting GPS paths to the nearest battle zone. 
  1561. 		M22_threads.battle_zone_gps = thread_new("m22_thread_neareast_battlezone_gps") 
  1562. 		 
  1563. 		-- Set the notoriery respawn timers 
  1564. 		notoriety_force_no_spawn("stag",false) 
  1565. 		notoriety_force_no_spawn("luchadores", false) 
  1566. 		notoriety_spawn_group_set_delay("luchadores", 80000) 
  1567. 		notoriety_spawn_group_set_delay("stag", 80000) 
  1568. 		 
  1569. 		-- Set the ped/traffic density for traveling between zones 
  1570. 		set_ped_density(0.25) 
  1571. 		set_traffic_density(0.1) 
  1572. 		spawning_pedestrians(true) 
  1573. 		 
  1574. 		-- Make Oleg invulnerable 
  1575. 		turn_invulnerable(M22_characters.Oleg, true) 
  1576. 		 
  1577. 		-- Start a thread to process when to play the driving conversation 
  1578. 	--	M22_threads.drive_convo_handle = thread_new("m22_thread_process_drive_convo") 
  1579. 		 
  1580. 		-- Start the ambient battle audio until the player reaches a battle area 
  1581. 		audio_object_post_event(M22_audio_events.battle_ambience_start, nil, nil, LOCAL_PLAYER) 
  1582. 		 
  1583. 		-- Display a tutorial telling the player that they can leave Oleg behind after completing  
  1584. 		-- the first battle zone. 
  1585. 		if Number_of_zones_cleared == 1 and oleg_tutorial_displayed == false then 
  1586. 			oleg_tutorial_displayed = true 
  1587. 			tutorial_start("mis_22_oleg_follow", 5000, true, true)  
  1588. 		end 
  1589.  
  1590. 		-- Wait until the player has reached one fo the battle zone areas 
  1591. 		Current_bz.zone = NO_ZONE 
  1592. 		while (Current_bz.zone == NO_ZONE) do 
  1593. 			thread_yield() 
  1594. 		end 
  1595. 		 
  1596. 		-- Stop auto-updating the GPS. 
  1597. 		mission_waypoint_remove() 
  1598. 		thread_kill(M22_threads.battle_zone_gps) 
  1599. 		M22_threads.battle_zone_gps = INVALID_THREAD_HANDLE 
  1600. 		 
  1601. 		-- Turn notoriety off and disable peds and traffic while in the battle zone 
  1602. 		m22_set_stag_synd_notoriety(0) 
  1603. 		set_ped_density(0.01) 
  1604. 		set_traffic_density(0.01) 
  1605. 		spawning_pedestrians(false) 
  1606. 		 
  1607. 		-- Stop the ambient battle audio while the player is in an active battle area 
  1608. 		audio_object_post_event(M22_audio_events.battle_anbience_stop, nil, nil, LOCAL_PLAYER) 
  1609. 		 
  1610. 		-- Make Oleg vulnerable again 
  1611. 		turn_vulnerable(M22_characters.Oleg) 
  1612. 		 
  1613. 		-- Kill the driving convo thread 
  1614. 		thread_kill(M22_threads.drive_convo_handle) 
  1615.  
  1616. 		-- Kick off a thread to process the battle zone instance (do this in a thread so it can be interrupted if the player leaves) 
  1617. 		M22_threads.battle_zone_instance = thread_new("m22_process_active_battle_zone_thread") 
  1618. 		 
  1619. 		-- Wait until the battle zone thread has finished (either completed, or the player left) 
  1620. 		while(thread_check_done(M22_threads.battle_zone_instance) == false) do 
  1621. 			thread_yield() 
  1622. 		end 
  1623. 		 
  1624. 		-- Clear the players' zone flags. 
  1625. 		Local_player_zone = NO_ZONE 
  1626. 		Remote_player_zone = NO_ZONE 
  1627. 		 
  1628. 		-- Turn notoriety and traffic back on 
  1629. 		m22_set_stag_synd_notoriety(3) 
  1630. 		set_ped_density(0.25) 
  1631. 		set_traffic_density(0.1) 
  1632. 		spawning_pedestrians(true) 
  1633. 		 
  1634. 		-- Clean-up the active battle zone 
  1635. 		m22_cleanup_active_battle_zone() 
  1636. 	end 
  1637. 	 
  1638. 	m22_cleanup_battle_zones() 
  1639. end 
  1640.  
  1641. -- Primary thread to process a battle zone area from start to finish 
  1642. function m22_process_active_battle_zone_thread() 
  1643. 	-- Do the initial battlezone spawn 
  1644. 	m22_spawn_battle_zone(Current_bz.zone) 
  1645. 	 
  1646. 	-- Create a thread to process the follower leash behaviors 
  1647. 	M22_threads.battle_zone_followers = thread_new("m22_thread_process_battle_zone_followers") 
  1648. 	 
  1649. 	-- Play some dialog 
  1650. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.boss_battle_intros[Number_of_zones_cleared + 1], 0.0)	 
  1651.  
  1652. 	-- Process the battle zone sections 
  1653. 	m22_process_battle_zone_kill_enemies() 
  1654. 	 
  1655. 	-- Play some dialog 
  1656. --	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.boss_battle_middle[Number_of_zones_cleared + 1], 0.0)	 
  1657. 	 
  1658. 	-- Process the finale 
  1659. 	m22_process_battle_zone_finale() 
  1660.  
  1661. 	-- Play some dialog 
  1662. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.boss_battle_complete[Number_of_zones_cleared + 1], 0.0)		 
  1663. 	 
  1664. 	-- Kick of a new thread to process the Saints reinforcements 
  1665. 	M22_threads.battle_zone_saints = thread_new("m22_thread_process_battle_zone_saint_reinforcements") 
  1666. 	 
  1667. 	m22_cleanup_active_battle_zone() 
  1668. 	 
  1669. 	-- Battle zone is complete, update our bookkeeping 
  1670. 	Current_bz.zone.cleared = true 
  1671. 	Number_of_zones_cleared = Number_of_zones_cleared + 1 
  1672. 	Latest_zone_cleared = Current_bz.zone.index 
  1673. 	Current_bz.zone = NO_ZONE 
  1674. 	 
  1675. 	-- Set the new checkpoint 
  1676. 	m22_set_battle_zone_complete_checkpoint() 
  1677. end 
  1678.  
  1679. -- Function to process the initial enemies the player must kill at a battle zone 
  1680. function m22_process_battle_zone_kill_enemies() 
  1681. 	-- Reduce density of peds and traffic 
  1682. 	set_ped_density(0.01) 
  1683. 	set_traffic_density(0.01) 
  1684. 	 
  1685. 	on_human_killed("m22_battle_zone_initial_died_cb") 
  1686. 	 
  1687. 	notoriety_force_no_spawn("stag", true) 
  1688. 	notoriety_force_no_spawn("luchadores", true) 
  1689.  
  1690. 	-- Set notoriety timer for when spawning starts up again 
  1691. 	notoriety_set_override_timer("stag", true, 3000, 5000) 
  1692. 	notoriety_set_override_timer("gang LD", true, 3000, 5000) 
  1693. 	 
  1694. 	-- Start a failsafe thread that will re-enable notoriety spawns anyway if 
  1695. 	-- something goes horribly wrong. 
  1696. 	M22_threads.battle_zone_notoriety_failsafe = thread_new("m22_thread_notoriety_failsafe") 
  1697.  
  1698. 	-- Wait until the player has almsot killed enough enemies 
  1699. 	while (Current_bz.kills < (Current_bz.zone.required_kills - 5) ) do 
  1700. 		thread_yield() 
  1701. 	end 
  1702. 	 
  1703. 	-- Wait until the player has killed enough enemies 
  1704. 	while (Current_bz.kills < Current_bz.zone.required_kills) do 
  1705. 		thread_yield() 
  1706. 	end 
  1707. 	 
  1708. 	m22_cleanup_battle_zone_kill_enemies() 
  1709. end 
  1710.  
  1711. -- Function to clean-up the initial enemies the player must kill at a battle zone 
  1712. function m22_cleanup_battle_zone_kill_enemies()	 
  1713. 	-- Remove callbacks on enemy NPCs (we don't need to count kills anymore) 
  1714. 	m22_remove_on_death_callbacks(Current_bz.zone) 
  1715. 	 
  1716. 	-- Stop the notoriety failsafe thread if it's still running. 
  1717. 	if M22_threads.battle_zone_notoriety_failsafe ~= INVALID_THREAD_HANDLE then 
  1718. 		thread_kill(M22_threads.battle_zone_notoriety_failsafe) 
  1719. 		M22_threads.battle_zone_notoriety_failsafe = INVALID_THREAD_HANDLE 
  1720. 	end 
  1721. 	 
  1722. 	on_human_killed("") 
  1723. end 
  1724.  
  1725. -- Function to process the battle zone finale (boss enemey spawns) 
  1726. function m22_process_battle_zone_finale() 
  1727. 	-- Set up spawn regions for finale boss(es) 
  1728. 	for i, spawn_region in pairs(Current_bz.zone.boss_spawn_regions)do 
  1729. 		spawn_region_enable(spawn_region, true) 
  1730. 	end 
  1731. 	 
  1732. 	-- Spawn a finale boss set 
  1733. 	for i, spawn_group in pairs(Battle_Zone_Finales[Number_of_zones_cleared + 1]) do 
  1734. 		-- Tell the group to attack the nearest player and spawn them. 
  1735. 		continuous_spawn_set_orders(spawn_group.name, "attack", "", -1) 
  1736. 		continuous_spawn_start(spawn_group.name, 1, 0, "m22_bz_boss_killed_cb", SRF_DEFAULT, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, MINIMAP_ICON_KILL) 
  1737. 	end 
  1738. 	 
  1739. 	-- Turn off override spawn times 
  1740. 	notoriety_set_override_timer("stag", false, 10000, 15000) 
  1741. 	notoriety_set_override_timer("gang LD", false, 10000, 15000) 
  1742. 		 
  1743. 	notoriety_spawn_group_set_delay("luchadores", 60000) 
  1744. 	notoriety_spawn_group_set_delay("stag", 60000) 
  1745. 	 
  1746. 	notoriety_force_no_spawn("stag", false) 
  1747. 	notoriety_force_no_spawn("luchadores", false) 
  1748. 	 
  1749. 	notoriety_spawn_group_clear_destination("stag") 
  1750. 	notoriety_spawn_group_clear_destination("luchadores") 
  1751. 	 
  1752. 	-- Wait until all the bosses have been destroyed 
  1753. 	while(Current_bz.bosses_killed < Current_bz.num_bosses) do 
  1754. 		thread_yield() 
  1755. 	end 
  1756. 	 
  1757. 	m22_cleanup_battle_zone_finale() 
  1758. end 
  1759.  
  1760. -- Function to cleanup the battle zone finale 
  1761. function m22_cleanup_battle_zone_finale() 
  1762. 	-- Cleanup any battle zone finale continuous spawns 
  1763. 	for i, finale_group in pairs(Battle_Zone_Finales[Number_of_zones_cleared + 1]) do 
  1764. 		cleanup_spawn_groups(finale_group.name) 
  1765. 	end 
  1766.  
  1767. 	-- Cleanup any battle zone spawn regions 
  1768. 	for i, spawn in pairs(Current_bz.zone.boss_spawn_regions) do 
  1769. 		continuous_spawn_regions_enable(spawn, false) 
  1770. 	end 
  1771. end 
  1772.  
  1773. -- Thread to process spawning a group of Saints reinforcements at a battle area 
  1774. function m22_thread_process_battle_zone_saint_reinforcements() 
  1775. 	local saints_group = Current_bz.zone.saints_group 
  1776. 	local dest = Current_bz.zone.center_pos 
  1777. 	local zones_cleared = Number_of_zones_cleared 
  1778.  
  1779. 	-- Setup the vehicles 
  1780. 	group_create_hidden(saints_group.name, true) 
  1781. 	for i, car_group in pairs(saints_group.cars) do 
  1782. 		vehicle_enter_group_teleport(car_group.members, car_group.vehicle) 
  1783. 	end 
  1784. 	 
  1785. 	-- Find a good navpoint set to use 
  1786. 	local best_dist = 0 
  1787. 	local best_start_pos = nil 
  1788. 	for i, start_pos in pairs(saints_group.start_positions) do 
  1789. 		local dist = get_dist_closest_player_to_object(start_pos.nav) 
  1790. 		if (dist > best_dist) then 
  1791. 			best_dist = dist 
  1792. 			best_start_pos = start_pos 
  1793. 		end 
  1794. 	end 
  1795. 	 
  1796. 	-- If we didn't find a nav greater than 50m away, then don't show the Saints 
  1797. 	if (best_start_pos == nil or best_dist < 50.0) then 
  1798. 		return 
  1799. 	end 
  1800. 	 
  1801. 	-- Teleport the cars into place, and send them towards the Battlezone 
  1802. 	for i, car_group in pairs(saints_group.cars) do 
  1803. 		-- Teleport the vehicle into place 
  1804. 		teleport_vehicle(car_group.vehicle, best_start_pos.nav) 
  1805. 		 
  1806. 		-- Show the car and Saints guys 
  1807. 		vehicle_show(car_group.vehicle) 
  1808. 		for j, member in pairs(car_group.members) do 
  1809. 			character_show(member) 
  1810. 		end 
  1811. 		 
  1812. 		-- Follow the path associated with the start position. 
  1813. 		vehicle_pathfind_navmesh_do(car_group.vehicle, best_start_pos.path, false, true, false, 1) 
  1814. 		 
  1815. 		delay(3.0) 
  1816. 	end 
  1817. 	 
  1818. 	-- Wait until at least one vehicle has arrived 
  1819. 	local arrived = false 
  1820. 	while(arrived == false) do 
  1821. 		for i, car_group in pairs(saints_group.cars) do 
  1822. 			if (vehicle_pathfind_check_done(car_group.vehicle) == 1) then 
  1823. 				arrived = true 
  1824. 			end 
  1825. 		end 
  1826. 		 
  1827. 		thread_yield() 
  1828. 	end 
  1829. 	 
  1830. 	-- Play some dialog 
  1831. 	audio_play_persona_line(M22_characters.Pierce, M22_dialog_lines.pierce_saints_arrive[zones_cleared + 1]) 
  1832. 	 
  1833. 	for i, car_group in pairs(saints_group.cars)do 
  1834. 		vehicle_exit_group(car_group.members) 
  1835. 	end 
  1836. end 
  1837.  
  1838. -- Thread to process leashing of followers at battle zones 
  1839. function m22_thread_process_battle_zone_followers() 
  1840. 	while(true) do 
  1841. 		local dist = get_dist(LOCAL_PLAYER, M22_characters.Pierce) 
  1842. 		if (dist > 25.0 or character_is_in_vehicle(LOCAL_PLAYER) == true) then 
  1843. 			follower_make_independent(M22_characters.Pierce, false) 
  1844. 		else 
  1845. 			follower_make_independent(M22_characters.Pierce, true) 
  1846. 		end 
  1847. 		 
  1848. 		dist = get_dist(LOCAL_PLAYER, M22_characters.Oleg) 
  1849. 		if (dist > 25.0 or character_is_in_vehicle(LOCAL_PLAYER) == true) then 
  1850. 			follower_make_independent(M22_characters.Oleg, false) 
  1851. 		else 
  1852. 			follower_make_independent(M22_characters.Oleg, true) 
  1853. 		end 
  1854. 		 
  1855. 		thread_yield() 
  1856. 	end 
  1857. end 
  1858.  
  1859. -- Cleanup saints reinforcements 
  1860. function m22_cleanup_battle_zone_saint_reinforcements() 
  1861. 	-- Kill the thread processing the Saints reinforcements 
  1862. 	thread_kill(M22_threads.battle_zone_saints) 
  1863.  
  1864. 	-- Clean-up the script group 
  1865. 	if (group_is_loaded(Current_bz.zone.saints_group.name) == true) then 
  1866. 		release_to_world(Current_bz.zone.saints_group.name) 
  1867. 		group_destroy(Current_bz.zone.saints_group.name) 
  1868. 	end 
  1869. end 
  1870.  
  1871. -- External clean-up function to clean-up the active battle zone (on completion, player exit, or mission cancel) 
  1872. function m22_cleanup_active_battle_zone() 
  1873. 	-- Clean-up an active battle 
  1874. 	if (Current_bz.zone ~= NO_ZONE) then 
  1875. 		m22_cleanup_battle_zone_kill_enemies() 
  1876. 		m22_cleanup_battle_zone_finale() 
  1877.  
  1878. 		-- Remove the battle area callback and radius from the minimap 
  1879. 		m22_cleanup_trigger(Current_bz.zone.battle_area) 
  1880. 		minimap_icon_remove_radius(Current_bz.zone.center_pos) 
  1881. 		marker_remove(Current_bz.zone.center_pos) 
  1882. 		 
  1883. 		-- Kill the thread processing the battle zone followers 
  1884. 		thread_kill(M22_threads.battle_zone_followers) 
  1885. 		follower_make_independent(M22_characters.Pierce, false) 
  1886. 		follower_make_independent(M22_characters.Oleg, false) 
  1887. 	end 
  1888. 	 
  1889. 	-- Turn off the progress bar 
  1890. 	hud_bar_off(0) 
  1891. 	hud_bar_off(1) 
  1892. end 
  1893.  
  1894. -- Removes enter trigger and disables battle zones 
  1895. function m22_cleanup_battle_zones() 
  1896. 	m22_cleanup_active_battle_zone() 
  1897. 	 
  1898. 	-- Clean up the zone triggers 
  1899. 	for i, battle_zone in pairs(Battle_Zone_Groups) do 
  1900. 		m22_cleanup_trigger(battle_zone.trigger) 
  1901. 		m22_cleanup_trigger(battle_zone.battle_area) 
  1902. 		 
  1903. 		m22_remove_on_death_callbacks(battle_zone) 
  1904. 	end 
  1905. 	 
  1906. 	-- Stop auto-updating the GPS. 
  1907. 	mission_waypoint_remove() 
  1908. 	thread_kill(M22_threads.battle_zone_gps) 
  1909. 	M22_threads.battle_zone_gps = INVALID_THREAD_HANDLE 
  1910. end 
  1911.  
  1912. -- Set the appropriate battle zone complete checkpoint name 
  1913. function m22_set_battle_zone_complete_checkpoint() 
  1914. 	local checkpoint_name = "m22_checkpoint_text_battle_zone_" .. Latest_zone_cleared 
  1915. 	 
  1916. 	--[[ 
  1917. 	for i, zone in pairs(Battle_Zone_Groups) do 
  1918. 		if (zone.cleared == true and i~= Latest_zone_cleared) then 
  1919. 			checkpoint_name = checkpoint_name .. "_" .. i 
  1920. 			break 
  1921. 		end 
  1922. 	end 
  1923. 	--]] 
  1924. 	 
  1925. 	mission_set_checkpoint(checkpoint_name) 
  1926. end 
  1927.  
  1928. -- The player must goto the armory 
  1929. function m22_goto_armory_sequence() 
  1930. 	objective_text_clear(0) 
  1931. 	objective_text_clear(1) 
  1932. 	objective_text( 0, "m22_obj_goto_armory", "", "", SYNC_LOCAL, OI_ASSET_LOCATION) 
  1933. 	objective_text( 1, "m22_obj_goto_armory", "", "", SYNC_REMOTE, OI_ASSET_LOCATION) 
  1934. 	 
  1935. 	-- Enable the armory trigger 
  1936. 	on_trigger("m22_armory_reached_cb", Armory_battle_zone.trigger) 
  1937. 	trigger_enable(Armory_battle_zone.trigger) 
  1938. 	marker_add_trigger(Armory_battle_zone.trigger, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  1939. 	mission_waypoint_add(Armory_battle_zone.trigger) 
  1940.  
  1941. 	-- Battle Zones are over, delay the spawning of some things 
  1942. 	notoriety_spawn_group_set_delay("stag_tank", 80000) 
  1943. 	notoriety_force_no_spawn_group("stag_tank", false) 
  1944.  
  1945. 	notoriety_spawn_group_set_delay("stag_attack_heli", 80000) 
  1946. 	notoriety_force_no_spawn_group("stag_attack_heli", false) 
  1947.  
  1948. 	notoriety_spawn_group_set_delay("stag_heli", 80000) 
  1949. 	notoriety_force_no_spawn_group("stag_heli", false) 
  1950.  
  1951. 	notoriety_spawn_group_set_delay("stag_riot", 80000) 
  1952. 	notoriety_force_no_spawn_group("stag_riot", false)	 
  1953. 	 
  1954. 	M22_threads.convo_handle = thread_new("m22_play_cell_convo", M22_conversations.armory.name, true) 
  1955. 	 
  1956. 	-- Make Oleg invulnerable 
  1957. 	turn_invulnerable(M22_characters.Oleg, true)	 
  1958. 	 
  1959. 	-- Start the ambient battle audio until the player reaches a battle area 
  1960. 	audio_object_post_event(M22_audio_events.battle_ambience_start, nil, nil, LOCAL_PLAYER) 
  1961.  
  1962. 	while not Armory_reached do 
  1963. 		thread_yield() 
  1964. 	end 
  1965. 	 
  1966. 	-- Stop the ambient battle audio while the player is in an active battle area 
  1967. 	audio_object_post_event(M22_audio_events.battle_anbience_stop, nil, nil, LOCAL_PLAYER) 
  1968. 	 
  1969. 	-- Make Oleg vulnerable again 
  1970. 	turn_vulnerable(M22_characters.Oleg)	 
  1971. 	 
  1972. 	m22_cleanup_goto_armory_sequence() 
  1973. end 
  1974.  
  1975. -- Cleanup the goto armory sequence 
  1976. function m22_cleanup_goto_armory_sequence() 
  1977. 	on_trigger("", Armory_battle_zone.trigger) 
  1978. end 
  1979.  
  1980. -- Spawns the initial forces of the armory fight 
  1981. function m22_process_armory_fight() 
  1982. 	-- Set the battle zone to the armory 
  1983. 	Current_bz.zone = Armory_battle_zone 
  1984.  
  1985. 	-- Add the battle area radius, and a marker to the center of the battle area 
  1986. 	minimap_icon_add_radius(Current_bz.zone.center_pos, trigger_get_radius(Current_bz.zone.battle_area), SYNC_ALL) 
  1987. 	marker_add(Current_bz.zone.center_pos, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL) 
  1988.  
  1989. 	-- Enable the trigger for the battle area (so we can update the marker on the battle area) 
  1990. 	on_trigger("m22_battle_area_triggered_cb", Current_bz.zone.battle_area) 
  1991. 	on_trigger_exit("m22_battle_area_exited_cb", Current_bz.zone.battle_area) 
  1992. 	trigger_enable(Current_bz.zone.battle_area, true) 
  1993. 	 
  1994. 	-- Turn notoriety off and disable peds and traffic while in the armory battle area 
  1995. 	m22_set_stag_synd_notoriety(0) 
  1996. 	set_ped_density(0.1) 
  1997. 	set_traffic_density(0.1)		 
  1998. 	spawning_pedestrians(false) 
  1999.  
  2000. 	-- Do the initial battlezone spawn 
  2001. 	m22_spawn_battle_zone(Current_bz.zone) 
  2002.  
  2003. 	-- Update the GSI 
  2004. 	objective_text_clear(0) 
  2005. 	local hud_bar_size = Armory_battle_zone.required_kills + Battle_zone_boss_hud_bar_factor * #Battle_Zone_Finales[Number_of_zones_cleared + 1] 
  2006. 	hud_bar_on(0, "Health", "m22_obj_clear_armory", hud_bar_size, SYNC_LOCAL, OI_ASSET_KILL)	 
  2007. 	hud_bar_set_value(0, hud_bar_size, SYNC_LOCAL) 
  2008. 	if (coop_is_active() == true) then 
  2009. 		objective_text_clear(1) 
  2010. 		hud_bar_on(1, "Health", "m22_obj_clear_armory", hud_bar_size, SYNC_REMOTE, OI_ASSET_KILL)	 
  2011. 		hud_bar_set_value(1, hud_bar_size, SYNC_REMOTE) 
  2012. 	end 
  2013. 	 
  2014. 	-- Wait until one of the player's has reached the Armory area 
  2015. 	while(object_is_in_trigger(Current_bz.zone.battle_area, LOCAL_PLAYER) == false and 
  2016. 			(coop_is_active() == false or object_is_in_trigger(Current_bz.zone.battle_area, REMOTE_PLAYER) == false)) do 
  2017. 		thread_yield() 
  2018. 	end 
  2019. 	 
  2020. 	-- Play some dialog 
  2021. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.armory_fight, 0.0) 
  2022. 	 
  2023. 	-- Process the armory battle zone 
  2024. 	m22_process_battle_zone_kill_enemies() 
  2025. 	 
  2026. 	-- Play some dialog 
  2027. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.armory_middle, 0.0) 
  2028. 	 
  2029. 	m22_process_battle_zone_finale() 
  2030. 	 
  2031. 	-- Play some dialog 
  2032. 	local line_handle = audio_play_persona_line(LOCAL_PLAYER, M22_dialog_lines.player_armory_clear) 
  2033. 	m22_wait_for_foley_safe(line_handle, 60.0) 
  2034. 	audio_stop(line_handle) 
  2035. 	 
  2036. 	-- Oleg and Pierce are no longer part of the player's party 
  2037. 	party_dismiss(M22_characters.Oleg) 
  2038. 	party_dismiss(M22_characters.Pierce) 
  2039. 	turn_invulnerable(M22_characters.Oleg, true)	-- shouldn't die unless the player kills them 
  2040. 	turn_invulnerable(M22_characters.Pierce, true)	-- shouldn't die unless the player kills them 
  2041. 	on_dismiss("", M22_characters.Pierce)	-- Don't fail the mission on dismissal 
  2042. 	on_death("", M22_characters.Oleg) 
  2043. 	on_death("", M22_characters.Pierce) 
  2044. 	 
  2045. 	-- Revive them if they are downed 
  2046. 	npc_revive(M22_characters.Oleg) 
  2047. 	npc_revive(M22_characters.Pierce) 
  2048. 	 
  2049. 	m22_cleanup_active_battle_zone() 
  2050. 	 
  2051. 	-- Destroy the guys we spawned 
  2052. 	if group_is_loaded(Armory_battle_zone.initial_spawn.name) then 
  2053. 		group_destroy(Armory_battle_zone.initial_spawn.name) 
  2054. 	end 
  2055. 		 
  2056. 	-- Turn peds and traffic back on 
  2057. 	set_ped_density(0.25) 
  2058. 	set_traffic_density(0.1) 
  2059. 	spawning_pedestrians(true) 
  2060. 	 
  2061. 	delay(0.5) 
  2062. end 
  2063.  
  2064. -- Depending on what the last battle zone cleared was, sets the appropriate checkpoint 
  2065. -- 
  2066. -- returns:			entry from M22_checkpoints 
  2067. function m22_set_post_battle_zone_checkpoint() 		 
  2068. 	if Latest_zone_cleared == 1 then 
  2069. 		mission_set_checkpoint(M22_checkpoints.GOTO_ARMORY1, true) 
  2070. 		return M22_checkpoints.GOTO_ARMORY1 
  2071. 	elseif Latest_zone_cleared == 2 then 
  2072. 		mission_set_checkpoint(M22_checkpoints.GOTO_ARMORY2, true) 
  2073. 		return M22_checkpoints.GOTO_ARMORY2 
  2074. 	elseif Latest_zone_cleared == 3 then 
  2075. 		mission_set_checkpoint(M22_checkpoints.GOTO_ARMORY3, true) 
  2076. 		return M22_checkpoints.GOTO_ARMORY3 
  2077. 	end	 
  2078. end 
  2079.  
  2080. function m22_setup_statue_courtesy_boats() 
  2081. 	-- Create the courtesy helicoper 
  2082. 	group_create(M22_groups.Statue_Boats, true) 
  2083. 	 
  2084. 	-- Set it up so that the player can't change the radio station 
  2085. 	radio_block(M22_groups.Statue_Boats.members[1]) 
  2086. 	radio_block(M22_groups.Statue_Boats.members[2]) 
  2087. end 
  2088.  
  2089. -- Callback when the player enters the perimeter of the statue 
  2090. function m22_save_saints_perimeter() 
  2091. 	m22_cleanup_trigger(M22_triggers.save_saints_perimeter) 
  2092. 	 
  2093. 	M22_threads.convo_handle = thread_new("m22_play_cell_convo", M22_conversations.kinzie_phone_call.name, true) 
  2094. 	 
  2095. 	group_create(M22_groups.Kinzie, true) 
  2096. end 
  2097.  
  2098. -- Callback when the player enters the perimeter of the killbane boss area 
  2099. function m22_kill_killbane_perimeter() 
  2100. 	m22_cleanup_trigger(M22_triggers.kill_killbane_perimeter) 
  2101. 	 
  2102. --	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.angel_phone_call, 0.0) 
  2103. 	M22_threads.convo_handle = thread_new("m22_play_cell_convo", M22_conversations.angel_phone_call.name, true) 
  2104. end 
  2105.  
  2106. -- Waits until the the player has hit a trigger and then determines what to do 
  2107. function m22_process_player_choice_sequence() 
  2108. 	-- Clear the objective text 
  2109. 	objective_text_clear(0) 
  2110. 	objective_text_clear(1) 
  2111. 	 
  2112. 	-- Let's add some complications 
  2113. 	-- If the player has completed the game as Host, mission 22 will become unlocked again 
  2114. 	-- We want to give the player the opportunity to play the finale the other way, so we will force their choice 
  2115. 	-- to be the one they did not select the last time 
  2116. 	local block_m23 = false 
  2117. 	local block_m24 = false 
  2118. 	 
  2119. 	if Completed_m23 and not Completed_m24 then 
  2120. 		block_m23 = true 
  2121. 	end 
  2122. 	if not Completed_m23 and Completed_m24 then 
  2123. 		block_m24 = true 
  2124. 	end	 
  2125. 	-- if both are competed, I don't know how you got here, so good luck! 
  2126. 	 
  2127. 	-- maybe change objective if it is chosen for you 
  2128. 	objective_text( 0, "m22_obj_killbane_or_shaundi", "", "", SYNC_ALL , OI_ASSET_LOCATION) 
  2129. 	 
  2130. 	-- Setup the perimiter triggers for the two choice areas 
  2131. 	if not block_m24 then 
  2132. 		on_trigger("m22_save_saints_perimeter", M22_triggers.save_saints_perimeter) 
  2133. 		trigger_enable(M22_triggers.save_saints_perimeter, true) 
  2134. 	end 
  2135. 	 
  2136. 	if not block_m23 then			 
  2137. 		on_trigger("m22_kill_killbane_perimeter", M22_triggers.kill_killbane_perimeter) 
  2138. 		trigger_enable(M22_triggers.kill_killbane_perimeter, true)	 
  2139. 	end 
  2140. 		 
  2141. 	-- Setup the player choice triggers 
  2142. 	if not block_m24 then 
  2143. 		on_trigger("m22_player_choice_cb", M22_triggers.save_saints) 
  2144. 		trigger_enable(M22_triggers.save_saints) 
  2145. 		marker_add_trigger(M22_triggers.save_saints, MINIMAP_ICON_PROTECT_ACQUIRE, INGAME_EFFECT_CHECKPOINT, OI_ASSET_DEFEND, OI_FLAGS_LOCATION, SYNC_ALL) 
  2146. 	end 
  2147. 	if not block_m23 then 
  2148. 		on_trigger("m22_player_choice_cb", M22_triggers.kill_killbane) 
  2149. 		trigger_enable(M22_triggers.kill_killbane) 
  2150. 		marker_add_trigger(M22_triggers.kill_killbane, MINIMAP_ICON_KILL, INGAME_EFFECT_CHECKPOINT, OI_ASSET_KILL_FULL, OI_FLAGS_LOCATION, SYNC_ALL) 
  2151. 	end 
  2152. 	 
  2153. 	if not block_m24 then 
  2154. 		object_indicator_add_objective_text(M22_triggers.save_saints, "PLAYER_CHOICE_M22_OPTION2_TITLE", "PLAYER_CHOICE_M22_OPTION2_BODY") 
  2155. 	end 
  2156. 	 
  2157. 	if not block_m23 then 
  2158. 		object_indicator_add_objective_text(M22_triggers.kill_killbane, "PLAYER_CHOICE_M22_OPTION1_TITLE", "PLAYER_CHOICE_M22_OPTION1_BODY") 
  2159. 	end 
  2160. 	 
  2161. 	-- add waypoint if we are forcing you to go somewhere 
  2162. 	if block_m24 then 
  2163. 		mission_waypoint_add(M22_triggers.kill_killbane) 
  2164. 	end 
  2165. 	if block_m23 then 
  2166. 		mission_waypoint_add(M22_triggers.save_saints) 
  2167. 	end 
  2168. 	 
  2169. 	-- Start playing the music "I need a Hero" 
  2170. 	delay(1.0) 
  2171. 	audio_object_post_event(M22_audio_events.music_start, nil, nil, LOCAL_PLAYER) 
  2172. 	 
  2173. 	-- Wait until the player choice phone call has finished (or the player already made it to a choice trigger) 
  2174. 	while(thread_check_done(M22_threads.convo_handle) == false and Player_choice == "none") do 
  2175. 		thread_yield() 
  2176. 	end 
  2177. 	 
  2178. 	delay(1.0) 
  2179.  
  2180. 	if group_is_loaded(M22_groups.Oleg_and_Pierce.name) then		 
  2181. 		-- Play Pierce's convincing phone call (if the player hasn't already made their choice) 
  2182. 		if (Player_choice == "none") then 
  2183. 			audio_play_persona_line(M22_groups.Oleg_and_Pierce.pierce, M22_dialog_lines.pierce_convincing) 
  2184. 			delay(0.5) 
  2185. 			 
  2186. 			-- Wait for the line to finish 
  2187. 			while audio_persona_line_playing(M22_groups.Oleg_and_Pierce.pierce) do 
  2188. 				thread_yield() 
  2189. 			end 
  2190. 		end 
  2191. 		 
  2192. 		-- Play Oleg's convincing phone call (if the player hasn't already made their choice) 
  2193. 		if (Player_choice == "none") then 
  2194. 			audio_play_persona_line(M22_groups.Oleg_and_Pierce.oleg, M22_dialog_lines.oleg_convincing) 
  2195. 			delay(0.5) 
  2196. 			 
  2197. 			-- Wait for the line to finish 
  2198. 			while audio_persona_line_playing(M22_groups.Oleg_and_Pierce.oleg) do 
  2199. 				thread_yield() 
  2200. 			end 
  2201. 		end 
  2202. 	end 
  2203.  
  2204. 	while Player_choice == "none" do 
  2205. 		thread_yield() 
  2206. 	end 
  2207. end 
  2208.  
  2209. -- Clean up left over npcs from the armory 
  2210. function m22_cleanup_statue_courtesy_boats() 
  2211. 	if group_is_loaded(M22_groups.Statue_Boats) then 
  2212. 		group_destroy(M22_groups.Statue_Boats) 
  2213. 	end 
  2214. end 
  2215.  
  2216. -- The cutscene showing the player's choices 
  2217. function m22_choice_airport_cutscene() 
  2218. 	-- Kick off a thread for the player choice conversation, and wait for it to finish 
  2219. 	-- M22_threads.convo_handle = thread_new("m22_play_cell_convo", M22_conversations.choice_phone_call.name, true) 
  2220.  
  2221. 	local line_handle = audio_play_persona_line_2d(M22_personas.angel.persona_id, M22_dialog_lines.choice_call[1]) 
  2222. 	-- Wait for the line to finish 
  2223. 	m22_wait_for_foley_safe(line_handle, 60.0) 
  2224. 	audio_stop(line_handle) 
  2225. 	 
  2226. 	line_handle = audio_play_persona_line(LOCAL_PLAYER, M22_dialog_lines.choice_call[2]) 
  2227. 	delay(1.0) 
  2228. 	-- Wait for the line to finish 
  2229. 	m22_wait_for_foley_safe(line_handle, 60.0) 
  2230. 	audio_stop(line_handle) 
  2231. 	 
  2232. 	-- Play the CTE showing the airport 
  2233. 	cutscene_in() 
  2234. 	group_create( cte_plane_group.name, true ) 
  2235. 	 
  2236. 	cutscene_play( M22_cte_choice_01.name ) 
  2237. 	while(cutscene_check_exiting() == true) do 
  2238. 		thread_yield() 
  2239. 	end 
  2240. 	 
  2241. 	group_destroy( cte_plane_group.name ) 
  2242. 	cutscene_out() 
  2243. end 
  2244.  
  2245. function m22_choice_statue_cutscene() 
  2246. 	-- Play the CTE showing the statue 
  2247. 	cutscene_in() 
  2248. 	group_create( M22_groups.Hostages.name, true ) 
  2249. 	group_create( cte_kia_group.name, true ) 
  2250. 	local teleport_navs = { Armory_battle_zone.center_pos, Armory_battle_zone.center_pos } 
  2251. 	cutscene_play( M22_cte_statue_01.name, nil, teleport_navs ) 
  2252. 	group_destroy( M22_groups.Hostages.name ) 
  2253. 	group_destroy( cte_kia_group.name ) 
  2254. 	cutscene_out() 
  2255. end 
  2256.  
  2257. -- Cutscene for the airpot angel rail sequence 
  2258. function m22_angel_rail_cutscene() 
  2259.  
  2260. 	fade_out(0.5) 
  2261.    fade_out_block() 
  2262. 	delay(1) 
  2263. 	 
  2264. 	--message("After protecting Angel he will explain in a CTE cutscene that Killbane is getting on his personal jet and will be taking off in short order.", 5) 
  2265. 	--delay(5) 
  2266. 	 
  2267. 	--message("The player tells Angel to �get me there� and they both will then run to a nearby spawned vehicle (4-door, convertible if possible) and get into it. ", 5) 
  2268. 	--message("Angel will drive.", 5) 
  2269. 	--delay(5) 
  2270. 	 
  2271. 	fade_in(0.5) 
  2272.    fade_in_block() 
  2273. end 
  2274.  
  2275. -- Handles the sequence where Angel drives the player to the airport 
  2276. function m22_in_transit_to_airport() 
  2277. 	objective_text_clear(0) 
  2278. 	objective_text( 0, "m22_obj_stop_killbane", "", "", SYNC_ALL , OI_ASSET_KILL) 
  2279. 	 
  2280. 	set_ignore_ai_flag(M22_characters.Angel) 
  2281. 	 
  2282. 	-- Setup notoriety 
  2283. 	notoriety_set("luchadores", 5) -- AC: Changed from 3 to 5 
  2284. 	notoriety_set_can_decay(false) 
  2285. 	notoriety_force_no_spawn("luchadores", false) 
  2286. 	notoriety_force_no_spawn_group("stag_tank", true) 
  2287. 	notoriety_force_no_spawn_group("stag_attack_heli", true) 
  2288. 	notoriety_force_no_spawn_group("stag_heli", true) 
  2289. 	notoriety_force_no_spawn_group("stag_riot", true) 
  2290. 	 
  2291. 	-- Set up a delay so the transition is not jarring 
  2292. 	delay(2.0) 
  2293. 	 
  2294. 	fade_out(0.5) 
  2295. 	fade_out_block() 
  2296. 	 
  2297. 	teleport_coop(M22_navpoints.player_angel_start[1], M22_navpoints.player_angel_start[2], true) 
  2298. 	 
  2299. 	inv_add_temp_loadout(M22_PLAYER_KB_LOADOUT) 
  2300. 	 
  2301. 	set_unjackable_flag(M22_vehicles.Angels_Car, false) 
  2302. 		 
  2303. 	vehicle_enter_teleport(M22_characters.Angel, M22_vehicles.Angels_Car, 0, true, true) 
  2304. 	set_seatbelt_flag(M22_characters.Angel, ENABLE) 
  2305. 	vehicle_enter_teleport(LOCAL_PLAYER, M22_vehicles.Angels_Car, 1, true, true) 
  2306. 	set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false) 
  2307. 	if in_coop then 
  2308. 		vehicle_enter_teleport(REMOTE_PLAYER, M22_vehicles.Angels_Car, 2, true, true) 
  2309. 		set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false) 
  2310. 	end 
  2311. 	 
  2312. 	fade_in(0.5) 
  2313. 	fade_in_block() 
  2314. 	 
  2315. 	vehicle_suppress_flipping(M22_vehicles.Angels_Car) 
  2316. 	vehicle_suppress_npc_exit(M22_vehicles.Angels_Car) 
  2317. 	vehicle_speed_override(M22_vehicles.Angels_Car, 45) 
  2318. 	vehicle_set_allow_ram_ped(M22_vehicles.Angels_Car, ENABLE) 
  2319. 	vehicle_set_ignore_rail_obstacles(M22_vehicles.Angels_Car, ENABLE) 
  2320. 	vehicle_ignore_repulsors(M22_vehicles.Angels_Car, ENABLE)  
  2321. 	vehicle_set_crazy(M22_vehicles.Angels_Car, ENABLE) 
  2322. 	vehicle_prevent_transition_to_ambient(M22_vehicles.Angels_Car, true) 
  2323. 	set_unjackable_flag(M22_vehicles.Angels_Car, true) 
  2324. 	vehicle_set_script_hard_goto(M22_vehicles.Angels_Car, true) 
  2325. 	 
  2326. 	-- Turn off roadblocks for this part 
  2327. 	roadblocks_enable(false) 
  2328. 	 
  2329. 	-- Infinite mass for car 
  2330. 	vehicle_infinite_mass(M22_vehicles.Angels_Car, ENABLE) 
  2331. 	 
  2332. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.angel_car_chase, 5.0) 
  2333. 	 
  2334. 	-- Don't allow this pathfind to fail.  If it does, keep trying. 
  2335. 	while get_dist(M22_vehicles.Angels_Car, "Airport_Rail_Begin") > 10.0 do 
  2336. 		vehicle_pathfind_to(M22_vehicles.Angels_Car, "Airport_Rail_Begin", false, false) 
  2337. 		thread_yield() 
  2338. 	end 
  2339. 	 
  2340. 	vehicle_set_crazy(M22_vehicles.Angels_Car, DISABLE) 
  2341. end 
  2342.  
  2343. -- Player meets up with angel and must protect him 
  2344. function m22_protect_angel_sequence() 
  2345. 	objective_text_clear(0) 
  2346. 	objective_text( 0, "m22_obj_help_angel", "", "", SYNC_ALL , OI_ASSET_DEFEND) 
  2347. 	 
  2348. 	if group_is_loaded(M22_groups.Angel.name) == false then 
  2349. 		group_create(M22_groups.Angel.name, true) 
  2350. 	end 
  2351. 	if group_is_loaded(M22_groups.Angels_Attackers.name) == false then 
  2352. 		group_create(M22_groups.Angels_Attackers.name, true) 
  2353. 	end 
  2354. 	 
  2355. 	-- Make sure the player can't enter Angel's car before he's supposed to. 
  2356. 	set_unjackable_flag(M22_vehicles.Angels_Car, true) 
  2357.  
  2358. 	marker_add(M22_groups.Angel.members[1], MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND, OI_FLAGS_DEFAULT, SYNC_ALL) 
  2359. 	process_enemy_set(M22_groups.Angels_Attackers.members) 
  2360.  
  2361. 	notoriety_force_no_spawn("luchadores", true) 
  2362. 	 
  2363. 	marker_remove(M22_groups.Angel.members[1]) 
  2364. 	 
  2365. 	-- Apparently this cutscene was cut; all it does is fade out and in... which is bad. 
  2366. 	--m22_angel_rail_cutscene() 
  2367. end 
  2368.  
  2369. -- Performs all the necessary operations to set up the chase sequence 
  2370. function m22_setup_killbane_chase_sequence() 
  2371. 	notoriety_force_no_spawn("police", false) -- turn of stag notoriety spawns for this sequence - AC: turned back on for test 
  2372. 	notoriety_force_no_spawn("luchadores", false) -- turn of notoriety spawns for now, makes rail sequence too hard - AC: turned back on for test 
  2373. 	notoriety_set("luchadores", 5) 
  2374. 	notoriety_set_can_decay(false) 
  2375.  
  2376. 	Num_plane_hits = 0 
  2377. 	group_create(M22_groups.Airport, true) 
  2378. 	 
  2379. 	vehicle_enter_teleport(M22_characters.Killbane, M22_vehicles.Killbanes_Plane, 0, true) 
  2380. 	marker_add(M22_vehicles.Killbanes_Plane, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL) 
  2381. 	on_projectile_hit("m22_projectile_hit_cb") 
  2382. 	vehicle_set_invulnerable_to_player_explosives(M22_vehicles.Killbanes_Plane, true) 
  2383. 	vehicle_suppress_flipping(M22_vehicles.Killbanes_Plane) 
  2384. 	-- Infinite mass for car 
  2385. 	vehicle_infinite_mass(M22_vehicles.Angels_Car, ENABLE) 
  2386. 	-- Infinite mass for Killbane's airplane 
  2387. 	vehicle_infinite_mass(M22_vehicles.Killbanes_Plane, ENABLE) 
  2388. 	vehicle_set_allow_ram_ped(M22_vehicles.Killbanes_Plane, ENABLE) 
  2389. 	vehicle_set_ignore_rail_obstacles(M22_vehicles.Killbanes_Plane, ENABLE) 
  2390. 	vehicle_ignore_repulsors(M22_vehicles.Killbanes_Plane, ENABLE)  
  2391. 	vehicle_set_crazy(M22_vehicles.Killbanes_Plane, ENABLE) 
  2392. 	vehicle_prevent_transition_to_ambient(M22_vehicles.Killbanes_Plane, true) 
  2393. 	set_unjackable_flag(M22_vehicles.Killbanes_Plane, true) 
  2394. 	vehicle_set_script_hard_goto(M22_vehicles.Killbanes_Plane, true) 
  2395. 	 
  2396. 	M22_threads.killbane_path_handle = thread_new("m22_airport_killbane_path_thread") 
  2397. 	M22_threads.player_path_handle = thread_new("m22_angel_car_path_thread") 
  2398. 	M22_threads.player_car_speed_handle = thread_new("m22_manage_players_car_speed_thread") 
  2399. 	 
  2400. 	on_trigger("m22_spawn_first_roadblock_cb", M22_triggers.roadblock_one) 
  2401. 	on_trigger("m22_spawn_second_roadblock_cb", M22_triggers.roadblock_two) 
  2402. 	on_trigger("m22_spawn_third_roadblock_cb", M22_triggers.roadblock_three) 
  2403. 	on_trigger("m22_spawn_fourth_roadblock_cb", M22_triggers.roadblock_four) 
  2404. 	trigger_enable(M22_triggers.roadblock_one) 
  2405. 	trigger_enable(M22_triggers.roadblock_two) 
  2406. 	trigger_enable(M22_triggers.roadblock_three) 
  2407. 	trigger_enable(M22_triggers.roadblock_four) 
  2408. end 
  2409.  
  2410. -- Waits for Killbane's plane to be destroyed before continueing 
  2411. function m22_process_killbane_chase_sequence() 
  2412. 	while(not vehicle_is_destroyed(M22_vehicles.Killbanes_Plane)) do 
  2413. 		thread_yield() 
  2414. 	end 
  2415. 	 
  2416. --	vehicle_max_speed(M22_vehicles.Angels_Car, 40) 
  2417. --	delay(3) 
  2418. 	 
  2419. --	vehicle_max_speed(M22_vehicles.Angels_Car, 20) 
  2420. --	delay(3) 
  2421. 	 
  2422. 	vehicle_max_speed(M22_vehicles.Angels_Car, 10) 
  2423. 	delay(1) 
  2424. 	 
  2425. 	vehicle_freeze(M22_vehicles.Angels_Car) 
  2426. 	 
  2427. 	 
  2428. 	delay(1.0) 
  2429. 	 
  2430. 	--[[ CONVERSATION CUT 
  2431. 	while M22_threads.convo_handle ~= INVALID_THREAD_HANDLE do 
  2432. 		-- wait for the conversation to finish 
  2433. 		thread_yield() 
  2434. 	end 
  2435. 	--]] 
  2436. 	 
  2437. 	-- remove temp weapons 
  2438. 	inv_remove_temp_loadout(M22_PLAYER_KB_LOADOUT) 
  2439. 	vehicle_exit(LOCAL_PLAYER) 
  2440. 	set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true) 
  2441. 	if in_coop then 
  2442. 		vehicle_exit(REMOTE_PLAYER) 
  2443. 		set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true) 
  2444. 	end 
  2445. 	 
  2446. 	-- Clean up the two remaining roadblocks 
  2447. 	group_destroy(M22_groups.Angel) 
  2448. 	group_destroy(M22_groups.Airport_Roadblock_three) -- cleanup the first roadblock 
  2449. 	group_destroy(M22_groups.Airport_Roadblock_four) -- cleanup the first roadblock 
  2450. end 
  2451.  
  2452. -- Simple function that performs the necessary setup for the Killbane boss portion of M22 
  2453. function m22_setup_kill_killbane() 
  2454. 	-- Teleport the players first so that we can wait for Killbane to activate in group_create 
  2455. 	teleport_coop(M22_navpoints.player_kbfight_start[1], M22_navpoints.player_kbfight_start[2]) 
  2456. 	 
  2457. 	if game_choice_get_state(MISSION_21_CHOICE) == M21_CHOICE_KILLBANE_UNMASKED then 
  2458. 		group_create_hidden(M22_groups.Killbane_QTE_Nomask.name, true) 
  2459. 		M22_characters.Killbane_QTE = M22_groups.Killbane_QTE_Nomask.killbane 
  2460. 	else 
  2461. 		group_create_hidden(M22_groups.Killbane_QTE.name, true) 
  2462. 		M22_characters.Killbane_QTE = M22_groups.Killbane_QTE.killbane 
  2463. 	end 
  2464.  
  2465. 	zscene_prep(M22_cutscenes.plane_destroyed) 
  2466. 	 
  2467. 	turn_vulnerable(M22_characters.Killbane_QTE) 
  2468. 	character_set_never_catch_fire(M22_characters.Killbane_QTE, true) 
  2469. 	set_ignore_ai_flag(M22_characters.Killbane_QTE, false) 
  2470. 	 
  2471. 	-- Apply the plane crash zone swap 
  2472. 	city_zone_swap("planecrash") 
  2473. 	 
  2474. 	-- Disable all player's weapons 
  2475. 	inv_weapon_disable_all_slots(true) 
  2476. 	 
  2477. 	inv_item_equip(nil, LOCAL_PLAYER) 
  2478. 	if in_coop then 
  2479. 		inv_item_equip(nil, REMOTE_PLAYER) 
  2480. 	end 
  2481. 	 
  2482. 	-- AC: Turn off notoriety for this 
  2483. 	notoriety_force_no_spawn("police", true) -- turn off stag notoriety spawns for this sequence 
  2484. 	notoriety_force_no_spawn("stag", true) -- AC: Test - turn off stag notoriety spawns for this sequence 
  2485. 	notoriety_force_no_spawn("luchadores", true) -- turn off notoriety spawns for now, 
  2486. 	 
  2487. 	-- Make sure Killbane is ready to go. 
  2488. 	--while (not character_is_ready(M22_characters.Killbane_QTE)) do 
  2489. 	--	thread_yield() 
  2490. 	--end 
  2491. 	 
  2492. 	while(zscene_is_loaded() == false) do 
  2493. 		thread_yield() 
  2494. 	end 
  2495. end 
  2496.  
  2497. -- Waits for Killbane to die before continueing 
  2498. function m22_process_kill_killbane() 
  2499. 	audio_object_post_event("M22_QTE_Music_Start", nil, nil, LOCAL_PLAYER) 
  2500. 	qte_start(LOCAL_PLAYER, "M22_BossFight", "m22_killbane_qte_completed_cb", M22_characters.Killbane_QTE) 
  2501. 	 
  2502. 	objective_text_clear(0) 
  2503. 	objective_text( 0, "m22_obj_kill_killbane", "", "", SYNC_ALL , OI_ASSET_KILL) 
  2504. 	 
  2505. 	-- Kick off a thread to process the dialog for this sequence 
  2506. --	M22_threads.kill_killbane_dialog = thread_new("m22_process_kill_killbane_dialog_thread") 
  2507.  
  2508. 	-- Register a callback to stop the QTE and fade out before the QTE actually finishes and 
  2509. 	-- Killbane goes all floppy on the ground. 
  2510. 	on_qte_animation_trigger("on_killbane_qte_fade_out_trigger") 
  2511.  
  2512. 	-- Wait until the QTE is finished 
  2513. 	while(not Killbane_qte_finished) do 
  2514. 		thread_yield() 
  2515. 	end 
  2516. 	 
  2517. 	-- Let the players move again. 
  2518. 	player_movement_enable(LOCAL_PLAYER) 
  2519. 	if coop_is_active() then 
  2520. 		player_movement_enable(REMOTE_PLAYER) 
  2521. 	end 
  2522. 	 
  2523. 	-- Kill the thread processing the dialog 
  2524. --	thread_kill(M22_threads.kill_killbane_dialog) 
  2525. --	M22_threads.kill_killbane_dialog = INVALID_THREAD_HANDLE 
  2526. 	 
  2527. 	Next_mission = Mission_23_name 
  2528. end 
  2529.  
  2530. function on_killbane_qte_fade_out_trigger() 
  2531. 	on_qte_animation_trigger("") 
  2532. 	qte_cleanup() 
  2533. 	fade_out(0.5) 
  2534. 	Killbane_qte_finished = true 
  2535. end 
  2536.  
  2537. -- Plays the bink of killbane emerging from the rubble 
  2538. function m22_killbane_plane_destroyed_scene() 
  2539. 	-- Prevent the players from moving, that can screw up the orientation of the QTE. 
  2540. 	player_movement_disable(LOCAL_PLAYER) 
  2541. 	if coop_is_active() then 
  2542. 		player_movement_disable(REMOTE_PLAYER) 
  2543. 	end 
  2544.  
  2545. 	-- Play the bink 
  2546. 	cutscene_play(M22_cutscenes.plane_destroyed, nil, M22_navpoints.player_kbfight_start, false) 
  2547. 	 
  2548. 	-- Unhide Killbane, he should be in place 
  2549. 	character_show(M22_characters.Killbane_QTE) 
  2550.  
  2551. 	-- Wait for Killbane to be ready before fading in. 
  2552. 	--while ( not character_is_ready(M22_characters.Killbane_QTE)) do 
  2553. 	--	thread_yield() 
  2554. 	--end 
  2555. 	 
  2556. 	fade_in(0.5) 
  2557. 	fade_in_block() 
  2558. end 
  2559.  
  2560. function m22_killbane_qte_completed_cb() 
  2561. 	Killbane_qte_finished = true 
  2562. end 
  2563.  
  2564. -- Thread to process Killbane's dialog 
  2565. function m22_process_kill_killbane_dialog_thread() 
  2566.  
  2567. 	-- Play the second dialog line 
  2568. 	m22_play_persona_line_and_wait(M22_characters.Killbane_QTE, M22_dialog_lines.killbane_fight_02) 
  2569. 	 
  2570. 	delay(5.0) 
  2571. 	 
  2572. 	-- Play the third dialog line 
  2573. 	m22_play_persona_line_and_wait(M22_characters.Killbane_QTE, M22_dialog_lines.killbane_fight_03) 
  2574. 	 
  2575. 	delay(3.0) 
  2576. 	 
  2577. 	-- Play the 4th dialog line 
  2578. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.killbane_fight_04, 0.0) 
  2579. 	while(thread_check_done(M22_threads.convo_handle) == false) do 
  2580. 		thread_yield() 
  2581. 	end 
  2582. end 
  2583.  
  2584. -- Process the sequence when the player arrives at the doc 
  2585. function m22_arrived_at_dock_sequence() 
  2586. 	objective_text_clear(0)	 
  2587. 	-- Play some dialog of the player talking to Kinzie 
  2588. 	m22_play_persona_line_and_wait(LOCAL_PLAYER, M22_dialog_lines.kinzie_dock) 
  2589. 	 
  2590. 	--delay(1.5) 
  2591. end 
  2592.  
  2593. -- Player arrived at the statue to find a battle going on 
  2594. function m22_go_to_statue_sequence() 
  2595. 	objective_text_clear(0) 
  2596. 	objective_text( 0, "m22_obj_goto_statue", "", "", SYNC_ALL, OI_ASSET_LOCATION ) 
  2597. 	 
  2598. 	m22_helper_populate_statue() 
  2599. 	 
  2600. 	group_create(M22_groups.Statue_Base.name) 
  2601.  
  2602. 	on_trigger("m22_player_used_elevator_cb", M22_triggers.statue_elevator) 
  2603. 	trigger_enable(M22_triggers.statue_elevator, true) 
  2604. 	marker_add_trigger(M22_triggers.statue_elevator, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  2605.  
  2606. 	while not Player_used_elevator do 
  2607. 		thread_yield() 
  2608. 	end 
  2609.  
  2610. 	group_destroy(M22_groups.Statue_Base.name) 
  2611. end 
  2612.  
  2613. -- Helper to spawn the initial NPCs at the statue 
  2614. function m22_helper_populate_statue() 
  2615. 	if (M22_statue_populated == false) then 
  2616. 		group_create(M22_groups.Statue.name) 
  2617. 		 
  2618. 		for i, saint in pairs(M22_groups.Statue.saints) do 
  2619. 			m22_setup_hostage(saint) 
  2620. 			set_ignore_ai_flag(saint, true) 
  2621. 			turn_invulnerable(saint) 
  2622.  
  2623. 			-- Set the animation state 
  2624. 			set_script_animation_state(saint, "hostage idle") 
  2625.  
  2626. 			-- AC Test 
  2627. 			inv_item_remove_all(M22_groups.Statue.saints[i]) 
  2628. 			 
  2629. 			-- Register some callbacks 
  2630. 			on_trigger("m22_saint_untied_cb", M22_triggers.untie[i]) 
  2631. 			on_death("m22_saint_died_cb", saint) 
  2632. 			trigger_enable(M22_triggers.untie[i], true) 
  2633. 		end		 
  2634. 		 
  2635. 		-- Set up continuous spawn 
  2636. 		for i, spawn in pairs(m22_statue_spawn_regions)do 
  2637. 			spawn_region_enable(m22_statue_spawn_regions[i], true) 
  2638. 		end 
  2639. 		continuous_spawn_start(M22_groups.Statue_Spawn1.name, 0, 1) 
  2640. 		continuous_spawn_start(M22_groups.Statue_Spawn2.name, 0, 1) 
  2641. 		continuous_spawn_start(M22_groups.Statue_Spawn3.name, 0, 1) 
  2642. 		continuous_spawn_start(M22_groups.Statue_Spawn4.name, 0, 1) 
  2643. 		continuous_spawn_start(M22_groups.Statue_Spawn5.name, 0, 1)		 
  2644. 	end 
  2645. 	 
  2646. 	M22_statue_populated = true 
  2647. end 
  2648.  
  2649. -- Sets up npcs, triggers and movers for the save the saints sequence 
  2650. function m22_setup_save_the_saints() 
  2651. 	group_create(M22_groups.Viola, true) 
  2652. 	m22_setup_hostage(M22_characters.Viola) 
  2653. 	 
  2654. 	m22_helper_populate_statue() 
  2655. 	 
  2656. 	for i, mover in pairs(M22_movers.c4) do 
  2657. 		on_mover_destroyed("m22_c4_destroyed_cb", mover) 
  2658. 		on_take_damage("m22_c4_damaged_cb", mover) 
  2659. 		on_mover_enter_water("m22_c4_entered_water_cb", mover) 
  2660. 		mesh_mover_reset(mover) 
  2661. 		mesh_mover_show(mover) 
  2662. 	--	marker_add(mover, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_DEFAULT, SYNC_ALL) 
  2663. 		Num_c4_left_to_destroy = Num_c4_left_to_destroy + 1 
  2664. 	end 
  2665. 	 
  2666. 	for i, mover in pairs(M22_movers.first_floor)do 
  2667. 		on_mover_destroyed("m22_c41_destroyed_cb", mover) 
  2668. 		on_take_damage("m22_c4_damaged_cb", mover) 
  2669. 		on_mover_enter_water("m22_c41_entered_water_cb", mover) 
  2670. 		mesh_mover_reset(mover) 
  2671. 		mesh_mover_show(mover) 
  2672. 		marker_add(mover, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_DEFAULT, SYNC_ALL) 
  2673. 		Num_c4_left_to_destroy = Num_c4_left_to_destroy + 1 
  2674. 		Num_c4_left_first_floor = Num_c4_left_first_floor + 1 
  2675. 	end 
  2676. 	 
  2677. 	trigger_enable(M22_triggers.statue_explosion_region, ENABLE) 
  2678. 	on_trigger_exit("m22_human_left_statue_cb", M22_triggers.statue_explosion_region) 
  2679. 	 
  2680. 	Total_c4_to_destroy = Num_c4_left_to_destroy 
  2681. end 
  2682.  
  2683. -- Processing function that waits until all the c4 has been destroyed 
  2684. function m22_process_save_the_saints() 
  2685. 	objective_text( 0, "m22_obj_remove_bombs", Total_c4_to_destroy - Num_c4_left_to_destroy, Total_c4_to_destroy .. " ", SYNC_ALL, OI_ASSET_USE ) 
  2686.  
  2687. 	local time_in_ms = STATUE_EXPLOSION_TIME * 1000 
  2688. 	hud_timer_set(1, time_in_ms, "m22_statue_times_up_cb") 
  2689.  
  2690. 	while(Num_c4_left_first_floor > 0)do 
  2691. 		thread_yield() 
  2692. 	end 
  2693. 	-- Disable first floor spawn regions 
  2694. 	spawn_region_enable(m22_statue_spawn_regions[1], false) 
  2695. 	spawn_region_enable(m22_statue_spawn_regions[4], false) 
  2696. 	spawn_region_enable(m22_statue_spawn_regions[5], false) 
  2697. 	spawn_region_enable(m22_statue_spawn_regions[8], false) 
  2698. 	 
  2699. 	objective_text( 0, "m22_obj_proceed_up_statue", "", "", SYNC_ALL, OI_ASSET_LOCATION ) 
  2700. 	on_trigger("m22_first_floor_cb", M22_triggers.First_Floor) 
  2701. 	trigger_enable(M22_triggers.First_Floor, true) 
  2702. 	marker_add_trigger(M22_triggers.First_Floor, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  2703. 	 
  2704. 	while not Second_floor_reached do 
  2705. 		thread_yield() 
  2706. 	end 
  2707. 	 
  2708. 	objective_text( 0, "m22_obj_remove_bombs", Total_c4_to_destroy - Num_c4_left_to_destroy, Total_c4_to_destroy .. " ", SYNC_ALL, OI_ASSET_USE ) 
  2709.  
  2710. 	--M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.viola_monument, 0.0) 
  2711.  
  2712. 	local played_music_fade = false 
  2713. 	while(Num_c4_left_to_destroy > 0) do 
  2714. 		-- If there's only 5 seconds left, start fading out the music 
  2715. 		if (played_music_fade == false and hud_timer_get_remainder(1) < 5000) then 
  2716. 			audio_object_post_event(M22_audio_events.music_fade_out, nil, nil, LOCAL_PLAYER) 
  2717. 			played_music_fade = true 
  2718. 		end 
  2719. 		thread_yield() 
  2720. 	end 
  2721. 	 
  2722. 	-- If the music isn't already fading, then stop it 
  2723. 	if (played_music_fade == false) then 
  2724. 		audio_object_post_event(M22_audio_events.music_fade_out, nil, nil, LOCAL_PLAYER) 
  2725. 	end 
  2726. end 
  2727.  
  2728. -- Cleans everything up from save the saints sequence 
  2729. function m22_cleanup_save_the_saints() 
  2730. 	 
  2731. 	on_trigger("m22_player_reached_breadcrumb_cb", M22_triggers.Kia_Breadcrumb) 
  2732. 	trigger_enable(M22_triggers.Kia_Breadcrumb, true) 
  2733. 	marker_add_trigger(M22_triggers.Kia_Breadcrumb, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  2734. 	party_dismiss_all() 
  2735. 	 
  2736. 	hud_timer_stop(1) -- stop the clock 
  2737. 	 
  2738. 	objective_text_clear(0) 
  2739. 	objective_text( 0, "m22_obj_proceed_up_statue", "", "", SYNC_ALL, OI_ASSET_LOCATION ) 
  2740. 	delay(3) 
  2741. 	 
  2742. 	while not Player_reached_breadcrumb do 
  2743. 		thread_yield() 
  2744. 	end 
  2745. 	 
  2746. 	on_trigger("m22_player_reached_top_cb", M22_triggers.Player_reached_top) 
  2747. 	trigger_enable(M22_triggers.Player_reached_top, true) 
  2748. 	marker_add_trigger(M22_triggers.Player_reached_top, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)	 
  2749. 	 
  2750. 	while not Player_reached_top do 
  2751. 		thread_yield() 
  2752. 	end 
  2753. 	 
  2754. 	for i, saint in pairs(M22_groups.Statue.saints) do 
  2755. 		on_death("", saint) 
  2756. 		m22_cleanup_trigger(M22_triggers.untie[i]) 
  2757. 	end 
  2758. 	 
  2759. 	-- Stop continuous spawn 
  2760. 	for i, spawn in pairs(m22_statue_spawn_regions)do 
  2761. 		spawn_region_enable(m22_statue_spawn_regions[i], false) 
  2762. 	end 
  2763. 	continuous_spawn_stop(M22_groups.Statue_Spawn1.name) 
  2764. 	continuous_spawn_stop(M22_groups.Statue_Spawn2.name) 
  2765. 	continuous_spawn_stop(M22_groups.Statue_Spawn3.name) 
  2766. 	continuous_spawn_stop(M22_groups.Statue_Spawn4.name) 
  2767. 	continuous_spawn_stop(M22_groups.Statue_Spawn5.name) 
  2768. 	 
  2769. 	-- remove sonic gun 
  2770. 	--inv_remove_temp_loadout(M22_PLAYER_SONIC_LOADOUT) 
  2771. 	 
  2772. 	on_trigger_exit("", M22_triggers.statue_explosion_region) 
  2773. 	trigger_enable(M22_triggers.statue_explosion_region, DISABLE) 
  2774. 	 
  2775. 	group_destroy(M22_groups.Statue.name) 
  2776. 	group_destroy(M22_groups.Viola) 
  2777. 	m22_kia_fight_cte() 
  2778. end 
  2779.  
  2780. -- Performs all the needed setup for the Kia fight 
  2781. function m22_setup_kill_kia() 
  2782. 	objective_text_clear(0) 
  2783. 	objective_text( 0, "m22_obj_kill_kia", "", "", SYNC_ALL , OI_ASSET_KILL) 
  2784. 	 
  2785. 	 
  2786. 	 
  2787. 	group_create(M22_groups.Kia, true) 
  2788. 	group_create(M22_groups.Hostages, true) 
  2789. 	group_create(M22_groups.Viola, true) 
  2790. 	group_create(M22_groups.Kia_battle_props, true) 
  2791. 	 
  2792. 	-- Setup the hostages 
  2793. 	m22_setup_hostage(M22_characters.Mayor) 
  2794. 	m22_setup_hostage(M22_characters.Shaundi) 
  2795. 	m22_setup_hostage(M22_characters.Viola) 
  2796. 	 
  2797. 	-- Setup Kia 
  2798. 	character_allow_ragdoll(M22_characters.Kia, false) 
  2799. 	character_set_immune_to_explosion_vomit(M22_characters.Kia, true) 
  2800. 	character_set_no_explosive_panic(M22_characters.Kia, true) 
  2801. 	character_set_never_catch_fire(M22_characters.Kia, true) 
  2802. 	npc_weapon_spread(M22_characters.Kia, KIA_WEAPON_SPREAD_MULTIPLIER) 
  2803. 	on_take_damage("m22_kia_damaged_cb", M22_characters.Kia) 
  2804. 	marker_add(M22_characters.Kia, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL) 
  2805. 	 
  2806. 	-- Setup Shaundi 
  2807. 	character_set_immune_to_explosion_vomit(M22_characters.Shaundi, true) 
  2808. 	character_set_no_explosive_panic(M22_characters.Shaundi, true) 
  2809. 	character_set_never_catch_fire(M22_characters.Shaundi, true) 
  2810. 	turn_invulnerable(M22_characters.Shaundi, true) -- can still be hurt by the player 
  2811. 	on_death("m22_shaundi_killed_cb", M22_characters.Shaundi) 
  2812. 	 
  2813. 	-- Setup the Mayor (Burt) 
  2814. 	on_take_damage("m22_burt_damaged_cb", M22_characters.Mayor) 
  2815. 	set_script_animation_state(M22_characters.Mayor, "hostage idle") 
  2816. 	set_script_animation_state(M22_characters.Viola, "hostage idle") 
  2817.  
  2818. 	-- Setup the Fart in a Jar ammo triggers 
  2819. 	for i, trigger in pairs(M22_triggers.fart_jars) do 
  2820. 		trigger_enable(trigger, true) 
  2821. 		marker_add_trigger(trigger, MINIMAP_ICON_USE, nil, OI_ASSET_USE, OI_FLAGS_DEFAULT, SYNC_ALL) 
  2822. 		on_trigger("m22_give_fart_in_jar_ammo_cb", trigger) 
  2823. 	end 
  2824. 	 
  2825. 	-- Setup the player killed triggers 
  2826. 	trigger_enable(M22_triggers.Kia_Boss_Area, ENABLE) 
  2827. 	on_trigger_exit("m22_human_left_statue_cb", M22_triggers.Kia_Boss_Area) 
  2828. end 
  2829.  
  2830. -- Spins until Kia dies 
  2831. function m22_process_kill_kia() 
  2832. 	-- Start boss fight music. 
  2833. 	audio_object_post_event(M22_audio_events.music_kia_start, nil, nil, LOCAL_PLAYER) 
  2834. 	 
  2835. 	M22_threads.kia_boss_handle = thread_new("m22_kia_boss_ai_thread") 
  2836.  
  2837. 	M22_threads.vtol_one_handle = thread_new("m22_process_kia_vtols_thread") 
  2838. 	if in_coop then 
  2839. 		M22_threads.vtol_two_handle = thread_new("m22_kia_coop_reinforcements_thread") 
  2840. 	end 
  2841.  
  2842. 	M22_threads.kill_kia_dialog = thread_new("m22_process_kill_kia_dialog_thread") 
  2843.  
  2844. 	while not character_is_dead(M22_characters.Kia) do 
  2845. 		thread_yield() 
  2846. 	end 
  2847. 	 
  2848. 	-- End boss fight music. 
  2849. 	audio_object_post_event(M22_audio_events.music_kia_finish, nil, nil, LOCAL_PLAYER) 
  2850. 	 
  2851. 	-- Delay so the end isn't so jarring. 
  2852. 	delay(1.0) 
  2853. 	 
  2854.  
  2855. 	thread_kill(M22_threads.kill_kia_dialog) 
  2856. 	M22_threads.kill_kia_dialog = INVALID_THREAD_HANDLE 
  2857. end 
  2858.  
  2859. -- Thread to process Kia's dialog 
  2860. function m22_process_kill_kia_dialog_thread() 
  2861. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.kia_fight, 0.0) 
  2862. 	while(thread_check_done(M22_threads.convo_handle) == false) do 
  2863. 		thread_yield() 
  2864. 	end 
  2865. 	 
  2866. 	delay(1.5) 
  2867. 	 
  2868. 	-- Tell the player to grab the FIAJ 
  2869. 	audio_play_persona_line(M22_characters.Shaundi, M22_dialog_lines.shaundi_grab_fiaj) 
  2870. 	 
  2871. 	delay(2.0) 
  2872. 	 
  2873. 	M22_threads.burt_dialog = thread_new("m22_process_burt_dialog_thread") 
  2874. 	 
  2875. 	-- Process Shaundi FIAJ nags 
  2876. 	delay(10.0) 
  2877. 	while(true) do 
  2878. 		-- Play the line 
  2879. 		audio_play_persona_line(M22_characters.Shaundi, M22_dialog_lines.shaundi_grab_fiaj_nag) 
  2880. 		 
  2881. 		-- Add a delay and then wait until Shaundi isn't actively vomitting 
  2882. 		delay(rand_int(15, 25)) 
  2883. 		while(thread_check_done(M22_threads.kia_vomit_handle) == false) do 
  2884. 			thread_yield() 
  2885. 		end 
  2886. 		 
  2887. 		-- If one of the players got a FIAJ, then stop processing the nags 
  2888. 		if (Player_got_fiaj == true) then 
  2889. 			break 
  2890. 		end 
  2891. 	end 
  2892. end 
  2893.  
  2894. -- Thread to process Burt's dialog 
  2895. function m22_process_burt_dialog_thread() 
  2896. 	while(true) do 
  2897. 		audio_play_persona_line(M22_characters.Mayor, M22_dialog_lines.burt_encouragement[rand_int(1, #M22_dialog_lines.burt_encouragement)]) 
  2898. 		 
  2899. 		delay(rand_int(15, 25)) 
  2900. 	end 
  2901. end 
  2902.  
  2903. -- Cleans up the kia fight - kills of the vtol threads 
  2904. function m22_cleanup_kill_kia() 
  2905. 	Next_mission = Mission_24_name 
  2906. 	 
  2907. 	on_take_damage("", M22_characters.Kia) 
  2908. 	marker_remove(M22_characters.Kia) 
  2909. 	 
  2910. 	on_death("", M22_characters.Shaundi) 
  2911. 	on_take_damage("", M22_characters.Mayor) 
  2912. 	 
  2913. 	m22_remove_temp_weapons_for_save_saints() 
  2914. 	 
  2915. 	on_trigger_exit("", M22_triggers.Kia_Boss_Area) 
  2916. 	trigger_enable(M22_triggers.Kia_Boss_Area, DISABLE)	 
  2917. 	 
  2918. 	-- Disable the Fart in a Jar ammo triggers 
  2919. 	for i, trigger in pairs(M22_triggers.fart_jars) do 
  2920. 		trigger_enable(trigger, false) 
  2921. 		on_trigger("", trigger) 
  2922. 	end 
  2923. 	 
  2924. 	thread_kill(M22_threads.vtol_one_handle) 
  2925. 	M22_threads.vtol_one_handle = INVALID_THREAD_HANDLE 
  2926. 	 
  2927. 	thread_kill(M22_threads.vtol_two_handle) 
  2928. 	M22_threads.vtol_two_handle = INVALID_THREAD_HANDLE 
  2929. end 
  2930.  
  2931. function m22_c4_objective_cte() 
  2932. 	fade_out(0.5) 
  2933. 	fade_out_block() 
  2934. 	 
  2935. 	-- Unhide all the C4 at the statue 
  2936. 	for i, mover in pairs(M22_movers.c4) do 
  2937. 		mesh_mover_reset(mover) 
  2938. 		mesh_mover_show(mover) 
  2939. 	end 
  2940. 	for i, mover in pairs(M22_movers.first_floor) do 
  2941. 		mesh_mover_reset(mover) 
  2942. 		mesh_mover_show(mover) 
  2943. 	end 
  2944. 	 
  2945. 	--group_create( M22_groups.Statue.name, true ) 
  2946. 	m22_setup_statue_courtesy_boats() 
  2947. 	group_create( M22_groups.Statue_CTE.name, true ) 
  2948. 	cutscene_play( M22_cte_statue_02.name, nil, M22_navpoints.player_dock_start ) 
  2949. 	group_destroy( M22_groups.Statue_CTE.name ) 
  2950. 	--group_destroy( M22_groups.Statue.name ) 
  2951. 	 
  2952. 	-- Give the players sonic guns and farts in jars. 
  2953. 	m22_give_temp_weapons_for_save_saints() 
  2954. 	 
  2955. 	--Get rid of Kinzie 
  2956. 	if group_is_loaded(M22_groups.Kinzie)then 
  2957. 		group_destroy(M22_groups.Kinzie) 
  2958. 	end 
  2959. 	 
  2960. 	-- Hide all the C4 at the statue until it's time for that objective 
  2961. 	for i, mover in pairs(M22_movers.c4) do 
  2962. 		mesh_mover_hide(mover) 
  2963. 	end 
  2964. 	for i, mover in pairs(M22_movers.first_floor) do 
  2965. 		mesh_mover_hide(mover) 
  2966. 	end 
  2967. 	 
  2968. 	fade_in(0.5) 
  2969. 	fade_in_block() 
  2970. end 
  2971.  
  2972. function m22_kia_fight_cte() 
  2973. 	fade_out(0.5) 
  2974. 	fade_out_block() 
  2975. 	 
  2976. 	message("-- CTE Plays Here --", 5) 
  2977. 	message("Kia is shown on the girder of the statue and she curses her plans being foiled by those meddling kids", 5)	 
  2978. 	 
  2979. 	m22_setup_kill_kia() 
  2980. 	delay(5) 
  2981. 	 
  2982. 	fade_in(0.5) 
  2983. 	fade_in_block() 
  2984. end 
  2985.  
  2986. -- *************************************************** 
  2987. -- m22_run Helper Functions 
  2988. -- *************************************************** 
  2989.  
  2990. -- Waits for a script foley (persona line) to finish playing,  
  2991. -- or stops the foley and continues on if a maximum wait time has 
  2992. -- expired. 
  2993. -- 
  2994. -- foley_id:  (int)   the ID of the foley to wait for. 
  2995. -- max_wait:  (float) the maximum time to wait for the foley. 
  2996. -- 
  2997. function m22_wait_for_foley_safe(foley_id, max_wait) 
  2998. 	-- Wait for anything else that was using the failsafe thread handle to finish. 
  2999. 	while M22_threads.audio_failsafe ~= INVALID_THREAD_HANDLE do 
  3000. 		thread_yield() 
  3001. 	end 
  3002. 	 
  3003. 	M22_threads.audio_failsafe = thread_new("delay", max_wait) 
  3004. 	 
  3005. 	-- Wait until the line has ended or our maximum wait time has elapsed. 
  3006. 	while audio_is_playing(foley_id) and thread_check_done(M22_threads.audio_failsafe) == false do 
  3007. 		thread_yield() 
  3008. 	end 
  3009. 	 
  3010. 	-- Kill the voice line if it's still playing. 
  3011. 	if audio_is_playing(foley_id) then 
  3012. 		audio_stop(foley_id) 
  3013. 	end 
  3014. 	 
  3015. 	thread_kill(M22_threads.audio_failsafe) 
  3016. 	M22_threads.audio_failsafe = INVALID_THREAD_HANDLE 
  3017. end 
  3018.  
  3019. -- This function adds a GPS path to the nearest battle zone. 
  3020. -- 
  3021. function m22_gps_path_to_nearest_battle() 
  3022. 	local nearest_dist = nil 
  3023. 	local nearest_group_nav = nil 
  3024. 	for i, group in pairs(Battle_Zone_Groups) do 
  3025. 		if group.cleared == false then 
  3026. 			local cur_dist = get_dist_closest_player_to_object(group.center_pos) 
  3027. 			if nearest_dist == nil or cur_dist < nearest_dist then 
  3028. 				nearest_dist = cur_dist 
  3029. 				nearest_group_nav = group.center_pos 
  3030. 			end 
  3031. 		end 
  3032. 	end 
  3033. 	 
  3034. 	if nearest_group_nav ~= nil then 
  3035. 		if Nearest_bz_center ~= nearest_group_nav then 
  3036. 			Nearest_bz_center = nearest_group_nav 
  3037. 			mission_waypoint_add(nearest_group_nav) 
  3038. 		end 
  3039. 	end 
  3040. end 
  3041.  
  3042. -- Plays a persona line on a character and waits for it to finish. 
  3043. -- 
  3044. function m22_play_persona_line_and_wait(character, persona_line) 
  3045. 	local play_success = audio_play_persona_line(character, persona_line) 
  3046. 	if play_success then 
  3047. 		delay(1.0) 
  3048. 		while(audio_persona_line_playing(character) == true) do 
  3049. 			thread_yield() 
  3050. 		end 
  3051. 	end 
  3052. end 
  3053.  
  3054. function m22_cell_convo_finished() 
  3055. 	M22_cur_cell_call_name = "" 
  3056. end 
  3057.  
  3058. function m22_play_cell_convo(conv_name, receiving_call, persona_override_id) 
  3059. 	while M22_cur_cell_call_name ~= "" do 
  3060. 		thread_yield() 
  3061. 	end 
  3062. 	M22_cur_cell_call_name = conv_name 
  3063. 	audio_play_for_mission_cellphone(conv_name, receiving_call, true, "", "m22_cell_convo_finished", persona_override_id) 
  3064. 	while M22_cur_cell_call_name ~= "" do 
  3065. 		thread_yield() 
  3066. 	end 
  3067. 	M22_cur_cell_call_name = "" 
  3068. end 
  3069.  
  3070. -- Spawns the initial npc group for a battle zone.  It then sets each member's on_death callback 
  3071. -- used for kill count management and reinforcemences. 
  3072. -- 
  3073. -- battle_zone:	(string) name of a table containing tables of the Stag and Syndicate groups 
  3074. 						 -- EX: 
  3075. 						 --	Battle_Zone_One = { Battle_Zone_One_Stag, Battle_Zone_One_Synd } 
  3076. function m22_spawn_battle_zone(battle_zone) 
  3077. 	Current_bz.num_initial_synd_alive = 0 
  3078. 	Current_bz.num_initial_stag_alive = 0 
  3079. 	Current_bz.kills = 0 
  3080. 	Current_bz.num_bosses = 0 
  3081. 	Current_bz.bosses_killed = 0 
  3082. 	Current_bz.num_enemies_released = 0 
  3083. 		 
  3084. 	-- Initialize the hud bar. 
  3085. 	m22_helper_update_battle_zone_hud() 
  3086. 	 
  3087. 	-- Spawn a finale boss set 
  3088. 	 
  3089. 	for i, spawn_group in pairs(Battle_Zone_Finales[Number_of_zones_cleared + 1]) do 
  3090. 		Current_bz.num_bosses = Current_bz.num_bosses + 1 
  3091. 	end 
  3092. 	 
  3093. 	-- Check if there are any old battle zone groups that need to be destroyed 
  3094. 	for i, battle_zone_group in pairs(Battle_Zone_Groups) do 
  3095. 		if (group_is_loaded(battle_zone_group.initial_spawn.name) == true) then 
  3096. 			group_destroy(battle_zone_group.initial_spawn.name) 
  3097. 		end 
  3098. 		if (group_is_loaded(battle_zone_group.saints_group.name) == true) then 
  3099. 			release_to_world(battle_zone_group.saints_group.name) 
  3100. 			group_destroy(battle_zone_group.saints_group.name) 
  3101. 		end 
  3102. 	end 
  3103. 	delay(1.0)	-- arbitrary time to allow group to be cleaned up 
  3104.  
  3105. 	-- Spawn the initial spawn group group 
  3106. 	group_create(battle_zone.initial_spawn.name, true) 
  3107. 	for i, member in pairs(battle_zone.initial_spawn.members) do 
  3108. 		if (character_is_dead(member) == false) then 
  3109. 			-- Set up the on death callback for all members of the initial Stag force 
  3110. 			local team = get_team(member) 
  3111. 			if (team == "STAG") then 
  3112. 				on_death("m22_battle_zone_stag_initial_died_cb", member) 
  3113. 				Current_bz.num_initial_stag_alive = Current_bz.num_initial_stag_alive + 1 
  3114. 			elseif (team == "Luchadores" or team == "Morningstar" or team == "Deckers") then 
  3115. 				on_death("m22_battle_zone_synd_initial_died_cb", member) 
  3116. 				Current_bz.num_initial_synd_alive = Current_bz.num_initial_synd_alive + 1 
  3117. 			end 
  3118. 		end 
  3119. 	end 
  3120. 	 
  3121. 	-- Spawn and immediately release the vehicles for the battle zone. 
  3122. 	if battle_zone.initial_vehicles.spawned == false then 
  3123. 		battle_zone.initial_vehicles.spawned = true 
  3124. 		group_create(battle_zone.initial_vehicles.name, true) 
  3125. 		release_to_world(battle_zone.initial_vehicles.name) 
  3126. 		group_destroy(battle_zone.initial_vehicles.name) 
  3127. 	end 
  3128.  
  3129. 	-- Spawn courtesy vehicle 
  3130. 	m22_create_player_courtesy_vehicle(battle_zone.courtesy_vehicles) 
  3131. end 
  3132.  
  3133. -- Helper function to update the the battle zone HUD 
  3134. function m22_helper_update_battle_zone_hud() 
  3135. 	-- Update the progress bar 
  3136. 	local kills_remaining = max((Current_bz.zone.required_kills - Current_bz.kills), 0) 
  3137. 	local bosses_remaining = max((#Battle_Zone_Finales[Number_of_zones_cleared + 1] - Current_bz.bosses_killed), 0) 
  3138. 	local bar_remaining = kills_remaining + bosses_remaining * Battle_zone_boss_hud_bar_factor 
  3139. 	 
  3140. 	if (Local_player_zone == ZONE_ACTIVE) then 
  3141. 		hud_bar_set_value(0, bar_remaining, SYNC_LOCAL) 
  3142. 	end 
  3143. 	if (Remote_player_zone == ZONE_ACTIVE) then 
  3144. 		hud_bar_set_value(1, bar_remaining, SYNC_REMOTE) 
  3145. 	end 
  3146. end 
  3147.  
  3148. -- Given a player, this checks the other player's current zone slot 
  3149. -- 
  3150. -- player:		(string) name of the player 
  3151. -- 
  3152. -- returns: 	FIRST/SECOND 
  3153. function m22_other_player_in_zone(player) 
  3154. 	if player == LOCAL_PLAYER then 
  3155. 		-- Need to see if the remote player is in zone 
  3156. 		return (Remote_player_zone) 
  3157. 	else 
  3158. 		return (Local_player_zone) 
  3159. 	end 
  3160. end 
  3161.  
  3162. -- Sets a player's zone slot 
  3163. -- 
  3164. -- player:		(string) name of a player 
  3165. -- 
  3166. function m22_set_players_zone(player) 
  3167. 	if LOCAL_PLAYER == player then 
  3168. 		Local_player_zone = ZONE_ACTIVE 
  3169. 	elseif REMOTE_PLAYER == player then 
  3170. 		Remote_player_zone = ZONE_ACTIVE 
  3171. 	end	 
  3172. end 
  3173.  
  3174. -- Gets a player's zone slot 
  3175. -- 
  3176. -- player:		(string) name of a player 
  3177. -- 
  3178. -- returns:		FIRST/SECOND 
  3179. function m22_get_players_zone(player) 
  3180. 	if player == LOCAL_PLAYER then 
  3181. 		return (Local_player_zone) 
  3182. 	else 
  3183. 		return (Remote_player_zone) 
  3184. 	end 
  3185. end 
  3186.  
  3187. -- Removes all on_death callbacks for a given zone 
  3188. -- 
  3189. -- zone_groups:	group of the initial stag/synd	 
  3190. function m22_remove_on_death_callbacks(zone_groups) 
  3191. 	for k, char_name in pairs(zone_groups.initial_spawn.members) do 
  3192. 		on_death("", char_name) 
  3193. 	end 
  3194. end 
  3195.  
  3196. -- Displays location markers for all unbeaten battle zones to the players 
  3197. function m22_show_remaining_battle_zones() 
  3198. 	for i, battle_zone in pairs(Battle_Zone_Groups) do 
  3199. 		if (battle_zone.cleared == false) then 
  3200. 			marker_add_trigger(battle_zone.trigger, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  3201. 		end 
  3202. 	end 
  3203. end 
  3204.  
  3205. -- Setup a STAG transport VTOL (assumes the group has already been created) *copied from M10, written by Matt G* 
  3206. -- 
  3207. -- vtol_table:		Lua table defining the STAG transport 
  3208. function m22_setup_stag_transport(vtol_table) 
  3209. 	local seat_idx = 0 
  3210. 	for i, char in pairs(vtol_table.pilots) do 
  3211. 		-- Put the pilots into the vehicle 
  3212. 		vehicle_enter_teleport(char, vtol_table.vtol, seat_idx, true) 
  3213. 		follower_remain_in_car(char, true) 
  3214. 		 
  3215. 		seat_idx = seat_idx + 1 
  3216. 	end 
  3217. 	--for i, drop_off in pairs(vtol_table.drop_offs) do 
  3218. 		for j, char in pairs(vtol_table.drop_offs.soldiers) do 
  3219. 			-- Put the soldiers into the vehicle 
  3220. 			vehicle_enter_teleport(char, vtol_table.vtol, seat_idx, true) 
  3221. 			follower_remain_in_car(char, true) 
  3222. 			 
  3223. 			seat_idx = seat_idx + 1 
  3224. 		end 
  3225. 	--end 
  3226. end 
  3227.  
  3228. -- Sets up a hostage character for the statue sequence. No ragdoll, flinching, or attacking this character. 
  3229. -- 
  3230. -- hostage_name:	(string) name of the hostage in question 
  3231. -- 
  3232. function m22_setup_hostage(hostage_name) 
  3233. 	character_allow_ragdoll(hostage_name, DISABLE) 
  3234. 	character_prevent_flinching(hostage_name, ENABLE) 
  3235. 	character_prevent_bumping(hostage_name, true) 
  3236. 	set_dont_attack_me_on_sight_flag(hostage_name, true) 
  3237. end 
  3238.  
  3239. function m22_spawn_and_move_roadblock(group_name, dest_navpoint_set_name) 
  3240. 	group_create(group_name, true) 
  3241.  
  3242. 	for i, member in pairs(group_name.members) do 
  3243. 		local car = group_name.cars[i] 
  3244. 		vehicle_enter_teleport(member, car) -- teleport each driver in their car 
  3245. 		M22_threads.roadblock_driveto_handles[i] = thread_new("m22_roadblock_drive_to_thread", member, car, dest_navpoint_set_name[i], i) 
  3246. 	end 
  3247. end 
  3248.  
  3249. -- Create a player coutesy vehicle group 
  3250. function m22_create_player_courtesy_vehicle(courtesy_vehicle_group) 
  3251. 	group_create(courtesy_vehicle_group.name, true) 
  3252. 	 
  3253. 	-- If this isn't coop, hide the second vehicle 
  3254. 	if (coop_is_active() == false) then 
  3255. 		vehicle_hide(courtesy_vehicle_group.vehicles[2]) 
  3256. 	end 
  3257. end 
  3258.  
  3259. -- Function to setup a player's courtesy vehicle by teleporting the player(s) and homies into the vehicle seats 
  3260. function m22_setup_player_courtesy_vehicle(courtesy_vehicle_group) 
  3261. 	-- Put the players into the vehicle 
  3262. 	local seat_idx = 0 
  3263. 	vehicle_enter_teleport(LOCAL_PLAYER, courtesy_vehicle_group.vehicles[1], seat_idx, true) 
  3264. 	seat_idx = seat_idx + 1	-- increment to the next seat 
  3265. 	if (coop_is_active() == true) then 
  3266. 		vehicle_enter_teleport(REMOTE_PLAYER, courtesy_vehicle_group.vehicles[1], seat_idx, true) 
  3267. 		seat_idx = seat_idx + 1	-- increment to the next seat 
  3268. 	end 
  3269. 	 
  3270. 	-- Put the homies into the vehicle 
  3271. 	vehicle_enter_teleport(M22_characters.Pierce, courtesy_vehicle_group.vehicles[1], seat_idx, true) 
  3272. 	vehicle_enter_teleport(M22_characters.Oleg, courtesy_vehicle_group.vehicles[1], 5, true) -- force Oleg into his "special" seat in the back 
  3273. end 
  3274.  
  3275. -- Simple function that enables/disables notoriety spawning of brutes.  The ordering matters when enableing/disabling 
  3276. -- 
  3277. -- enable:			(bool) true - turns brutes on, false - turns brutes off 
  3278. function m22_brute_enable(enable) 
  3279. 	if enable then 
  3280. 		-- Enable brutes 
  3281. 		disable_specific_notoriety_group("luchadores", 4, "G_Luchadore_Brute_M", false) 
  3282. 		disable_specific_notoriety_group("luchadores", 4, "G_Luchadore_Brute_F", false) 
  3283. 		disable_specific_notoriety_group("luchadores", 4, "G_Luchadore_Brute_G", false) 
  3284. 		disable_specific_notoriety_group("luchadores", 5, "G_Luchadore_Brute_M", false) 
  3285. 		disable_specific_notoriety_group("luchadores", 5, "G_Luchadore_Brute_F", false) 
  3286. 		disable_specific_notoriety_group("luchadores", 5, "G_Luchadore_Brute_G", false)			 
  3287. 	else 
  3288. 		-- Disable brutes 
  3289. 		disable_specific_notoriety_group("luchadores", 4, "G_Luchadore_Brute_M", true) 
  3290. 		disable_specific_notoriety_group("luchadores", 4, "G_Luchadore_Brute_F", true) 
  3291. 		disable_specific_notoriety_group("luchadores", 4, "G_Luchadore_Brute_G", true) 
  3292. 		disable_specific_notoriety_group("luchadores", 5, "G_Luchadore_Brute_M", true) 
  3293. 		disable_specific_notoriety_group("luchadores", 5, "G_Luchadore_Brute_F", true) 
  3294. 		disable_specific_notoriety_group("luchadores", 5, "G_Luchadore_Brute_G", true) 
  3295. 	end 
  3296. end 
  3297.  
  3298. -- Function that sets Stag and Syndacite min/max notorieties to a specific level. 
  3299. -- 
  3300. -- level:	(int) level to set notoriety to 
  3301. function m22_set_stag_synd_notoriety(level) 
  3302. 	notoriety_set_min_and_max("police", level, level) 
  3303. 	notoriety_set("police", level) 
  3304. 	notoriety_set_min_and_max("luchadores", level, level) 
  3305. 	notoriety_set("luchadores", level) 
  3306. end 
  3307.  
  3308. -- Gives the sonic gun and farts in jars to both players. 
  3309. -- 
  3310. function m22_give_temp_weapons_for_save_saints() 
  3311. 	inv_weapon_add_temporary(LOCAL_PLAYER, KIA_TEMPORARY_WEAPON, 1, false, false, false, true) 
  3312. 	-- Remove any normal flashbangs and replace them with farts in jars. 
  3313. 	inv_item_remove(KIA_TEMPORARY_GRENADE, LOCAL_PLAYER) 
  3314. 	inv_weapon_add_temporary(LOCAL_PLAYER, KIA_TEMPORARY_GRENADE, 2, false, false, false, true, WEAPON_LEVEL4) 
  3315. 	if coop_is_active() then 
  3316. 		inv_weapon_add_temporary(REMOTE_PLAYER, KIA_TEMPORARY_WEAPON, 1, false, false, false, true) 
  3317. 		-- Remove any normal flashbangs and replace them with farts in jars. 
  3318. 		inv_item_remove(KIA_TEMPORARY_GRENADE, REMOTE_PLAYER) 
  3319. 		inv_weapon_add_temporary(REMOTE_PLAYER, KIA_TEMPORARY_GRENADE, 2, false, false, false, true, WEAPON_LEVEL4) 
  3320. 	end 
  3321. end 
  3322.  
  3323. -- Removes the temporary sonic gun and farts in jars from both players. 
  3324. -- 
  3325. function m22_remove_temp_weapons_for_save_saints() 
  3326. 	inv_weapon_remove_temporary(LOCAL_PLAYER, KIA_TEMPORARY_WEAPON) 
  3327. 	inv_weapon_remove_temporary(LOCAL_PLAYER, KIA_TEMPORARY_GRENADE) 
  3328. 	if (coop_is_active() == true) then 
  3329. 		inv_weapon_remove_temporary(REMOTE_PLAYER, KIA_TEMPORARY_WEAPON) 
  3330. 		inv_weapon_remove_temporary(REMOTE_PLAYER, KIA_TEMPORARY_GRENADE) 
  3331. 	end 
  3332. end 
  3333.  
  3334. -- Equips the sonic gun on both players when entering the statue. 
  3335. -- 
  3336. function m22_equip_temp_weapons_for_save_saints() 
  3337. 	inv_item_equip(KIA_TEMPORARY_WEAPON, LOCAL_PLAYER) 
  3338. 	if coop_is_active() then 
  3339. 		inv_item_equip(KIA_TEMPORARY_WEAPON, REMOTE_PLAYER) 
  3340. 	end 
  3341. end 
  3342.  
  3343. -- *************************************************** 
  3344. -- m22_initialize Helper Functions 
  3345. -- *************************************************** 
  3346.  
  3347. -- Handle any common initialization 
  3348. -- 
  3349. function m22_initialize_common()	 
  3350. 	Completed_m23 = mission_is_complete("m23") 
  3351. 	Completed_m24 = mission_is_complete("m24") 
  3352. 	 
  3353. 	city_zone_swap("burn", ENABLE) 
  3354. 	 
  3355. 	-- If the player is replaying this mission, and the statue got blown 
  3356. 	-- up previously, undo that for the duration of the mission. 
  3357. 	city_zone_swap("rubble", false) 
  3358. 	 
  3359. 	-- Let people buy stuff even though there's notoriety. 
  3360. 	shop_ignore_clerk(true) 
  3361. 	 
  3362. 	--notoriety_force_no_spawn("police", true) 
  3363. 	flashpoints_enable(DISABLE) -- no flashpoints for this mission 
  3364. 	set_stag_active(ENABLE) 
  3365. 	 
  3366. 	disable_specific_notoriety_group("stag", 2, "G_STAG_CopCar", true) 
  3367. 	disable_specific_notoriety_group("stag", 3, "G_STAG_CopCar", true) 
  3368. 	disable_specific_notoriety_group("stag", 4, "G_STAG_CopCar", true) 
  3369. 	disable_specific_notoriety_group("stag", 5, "G_STAG_CopCar", true) 
  3370. 	disable_specific_notoriety_group("stag", 2, "G_STAG_BikeCop", true) 
  3371. 	disable_specific_notoriety_group("stag", 3, "G_STAG_BikeCop", true) 
  3372. 	 
  3373. 	notoriety_set_can_decay(DISABLE) 
  3374. 	 
  3375. 	notoriety_force_no_spawn_group("stag_tank", true) 
  3376. 	notoriety_force_no_spawn_group("stag_attack_heli", true) 
  3377. 	notoriety_force_no_spawn_group("stag_heli", true) 
  3378. 	notoriety_force_no_spawn_group("stag_riot", true) 
  3379. 	 
  3380. 	roadblocks_ambient_traffic_enable(false) 
  3381. 	 
  3382. 	-- Show Fake Notoriety 
  3383. 	hud_set_fake_notoriety("police", true, 5) 
  3384. 	hud_set_fake_notoriety("luchadores", true, 5) 
  3385.  
  3386. 	set_civilians_flee(ENABLE, ENABLE, LOCAL_PLAYER) 
  3387. 	 
  3388. 	-- Create the roadblocks around the city 
  3389. 	for i, roadblock in pairs(M22_roadblocks) do 
  3390. 		roadblock.handle = roadblock_create(roadblock.layout, roadblock.navpoint) 
  3391. 	end 
  3392. 	 
  3393. 	-- Hide alll the C4 at the statue until it's time for that objective 
  3394. 	for i, mover in pairs(M22_movers.c4) do 
  3395. 		mesh_mover_hide(mover) 
  3396. 	end 
  3397. 	for i, mover in pairs(M22_movers.first_floor) do 
  3398. 		mesh_mover_hide(mover) 
  3399. 	end 
  3400. 	 
  3401. 	-- Load up kinzie's persona 
  3402. 	M22_personas.kinzie.persona_id = audio_persona_load_2d(M22_personas.kinzie.name) 
  3403. 	M22_personas.kia.persona_id = audio_persona_load_2d(M22_personas.kia.name) 
  3404. 	M22_personas.angel.persona_id = audio_persona_load_2d(M22_personas.angel.name) 
  3405. 	 
  3406. 	-- Spawn fewer parked cars so we have room for all the vehicles at the battle zones. 
  3407. 	parking_spot_set_max(4) 
  3408. end 
  3409.  
  3410. -- Check if the given checkpoint name is a battle zone checkpoint 
  3411. -- 
  3412. -- checkpoint_name:				Name of the checkpoint 
  3413. --  
  3414. -- returns: 
  3415. --		is_battle_zone:			True if the checkpoint is for a battle zone 
  3416. --		last_zone_completed:	Last battle zone that was completed 
  3417. --		second_zone_complted:	The second battle zone that was completed (or nil if only one battle zone has been completed) 
  3418. function m22_checkpoint_is_battle_zone(checkpoint_name) 
  3419. 	if (checkpoint_name == M22_checkpoints.BATTLE_ZONE_1) then 
  3420. 		return true, 1 
  3421. 	elseif (checkpoint_name == M22_checkpoints.BATTLE_ZONE_2) then 
  3422. 		return true, 2 
  3423. 	elseif (checkpoint_name == M22_checkpoints.BATTLE_ZONE_3) then 
  3424. 		return true, 3 
  3425. 	end 
  3426. 	 
  3427. 	return false 
  3428. end 
  3429.  
  3430. -- Check if the given checkpoint name is an armory checkpoint 
  3431. -- 
  3432. -- checkpoint_name:				Name of the checkpoint 
  3433. --  
  3434. -- returns: 
  3435. --		is_armory_checkpoint:	True if the checkpoint is for a battle zone 
  3436. --		last_zone_completed:	Last battle zone that was completed 
  3437. function m22_checkpoint_is_get_to_armory(checkpoint_name) 
  3438. 	if (checkpoint_name == M22_checkpoints.GOTO_ARMORY1) then 
  3439. 		return true, 1 
  3440. 	elseif (checkpoint_name == M22_checkpoints.GOTO_ARMORY2) then 
  3441. 		return true, 2 
  3442. 	elseif (checkpoint_name == M22_checkpoints.GOTO_ARMORY3) then 
  3443. 		return true, 3 
  3444. 	end 
  3445. 	 
  3446. 	return false 
  3447. end 
  3448.  
  3449. -- Checkpoint specific initialization 
  3450. -- 
  3451. -- checkpoint:		The checkpoint to be initialized 
  3452. function m22_initialize_checkpoint(checkpoint) 
  3453. 	if (checkpoint == M22_checkpoints.CHECKPOINT_START) then 
  3454. 		Number_of_zones_cleared = 0 
  3455. 		Latest_zone_cleared = 0 
  3456. 		 
  3457. 		m22_create_player_courtesy_vehicle(M22_groups.Start_Vehicle) 
  3458. 		m22_setup_oleg_and_pierce() 
  3459. 		 
  3460. 		teleport_coop(M22_navpoints.local_start, M22_navpoints.remote_start, true) 
  3461. 		 
  3462. 		-- Setup the courtesy vehicle 
  3463. 		m22_setup_player_courtesy_vehicle(M22_groups.Start_Vehicle) 
  3464. 		 
  3465. 		m22_brute_enable(DISABLE) -- turn off notoriety brute spawning 
  3466. 		m22_set_stag_synd_notoriety(2) 
  3467. 		 
  3468. 	end 
  3469. 	 
  3470. 	local is_battle_zone, zone1, zone2 = m22_checkpoint_is_battle_zone(checkpoint) 
  3471. 	if (is_battle_zone == true) then 
  3472. 		Latest_zone_cleared = zone1 
  3473. 		Battle_Zone_Groups[zone1].cleared = true 
  3474. 		 
  3475. 		if (zone2 == nil) then 
  3476. 			Number_of_zones_cleared = 1 
  3477. 		else 
  3478. 			Number_of_zones_cleared = 2 
  3479. 			Battle_Zone_Groups[zone2].cleared = true 
  3480. 		end 
  3481. 		 
  3482. 		m22_setup_oleg_and_pierce() 
  3483. 		m22_brute_enable(DISABLE) -- turn off notoriety brute spawning 
  3484. 		m22_set_stag_synd_notoriety(2) 
  3485. 		 
  3486. 		-- Create the courtesy vehicles 
  3487. 		m22_create_player_courtesy_vehicle(Battle_Zone_Groups[Latest_zone_cleared].courtesy_vehicles) 
  3488. 		 
  3489. 		-- Create the Saints groups 
  3490. 		group_create(Battle_Zone_Groups[Latest_zone_cleared].saints_group.name, true) 
  3491. 		 
  3492. 		teleport_coop(Battle_Zone_Groups[Latest_zone_cleared].player_starts[1], Battle_Zone_Groups[Latest_zone_cleared].player_starts[2], true) 
  3493.  
  3494. 		-- Setup the courtesy vehicle 
  3495. 		m22_setup_player_courtesy_vehicle(Battle_Zone_Groups[Latest_zone_cleared].courtesy_vehicles) 
  3496. 	end 
  3497. 	 
  3498. 	local is_go_to_armory, last_zone = m22_checkpoint_is_get_to_armory(checkpoint) 
  3499. 	if (is_go_to_armory == true) then 
  3500. 		Latest_zone_cleared = last_zone 
  3501. 		Number_of_zones_cleared = 2 
  3502. 	 
  3503. 		m22_setup_oleg_and_pierce() 
  3504. 		m22_brute_enable(DISABLE) -- turn off notoriety brute spawning 
  3505. 		m22_set_stag_synd_notoriety(4) 
  3506. 		 
  3507. 		-- Create the courtesy vehicles 
  3508. 		m22_create_player_courtesy_vehicle(Battle_Zone_Groups[Latest_zone_cleared].courtesy_vehicles) 
  3509. 		 
  3510. 		teleport_coop(Battle_Zone_Groups[Latest_zone_cleared].player_starts[1], Battle_Zone_Groups[Latest_zone_cleared].player_starts[2], true) 
  3511. 		 
  3512. 		-- Setup the courtesy vehicle 
  3513. 		m22_setup_player_courtesy_vehicle(Battle_Zone_Groups[Latest_zone_cleared].courtesy_vehicles) 
  3514. 	end 
  3515.  
  3516. 	if (checkpoint == M22_checkpoints.ARMORY_FIGHT) then 
  3517. 		Number_of_zones_cleared = 3 
  3518. 	 
  3519. 		m22_setup_oleg_and_pierce() 
  3520. 		 
  3521. 		Local_player_zone = ZONE_ACTIVE 
  3522. 		Remote_player_zone = ZONE_ACTIVE 
  3523. 		 
  3524. 		teleport_coop(Armory_battle_zone.player_starts[1], Armory_battle_zone.player_starts[2], true) 
  3525. 		Armory_reached = true 
  3526. 		m22_brute_enable(DISABLE) -- turn off notoriety brute spawning 
  3527. 	end 
  3528. 	 
  3529. 	if (checkpoint == M22_checkpoints.DEBUG_AIRPORT_CHOICE or checkpoint == M22_checkpoints.DEBUG_STATUE_CHOICE) then 
  3530. 		-- NOTHING TO DO 
  3531. 	end 
  3532. 	 
  3533. 	if (checkpoint == M22_checkpoints.MAKE_YOUR_CHOICE) then 
  3534. 		-- Spawn courtesy vehicle 
  3535. 		m22_create_player_courtesy_vehicle(Armory_battle_zone.courtesy_vehicles) 
  3536. 		teleport_coop(Armory_battle_zone.player_starts[1], Armory_battle_zone.player_starts[2], true)		 
  3537. 	end 
  3538. 	 
  3539. 	if (checkpoint == M22_checkpoints.STOP_KILLBANE) then 
  3540. 		group_create(M22_groups.Angel.name, true) 
  3541. 		group_create(M22_groups.Angels_Attackers.name, true)		 
  3542. 		 
  3543. 		teleport_coop(M22_navpoints.player_angel_start[1], M22_navpoints.player_angel_start[2], true) 
  3544. 		-- Play some music where we left off 
  3545. 		audio_object_post_event(M22_audio_events.music_start_checkpoint, nil, nil, LOCAL_PLAYER) 
  3546. 	end 
  3547. 	 
  3548. 	if (checkpoint == M22_checkpoints.KILL_KILLBANE) then 
  3549. 		m22_setup_kill_killbane() 
  3550. 	end 
  3551. 	 
  3552. 	if (checkpoint == M22_checkpoints.GOTO_SAINTS or checkpoint == M22_checkpoints.DEBUG_STATUE_CTE) then 
  3553. 		-- Create the courtesy vehicles 
  3554. 		m22_setup_statue_courtesy_boats()	 
  3555. 		 
  3556. 		teleport_coop(M22_navpoints.player_dock_start[1], M22_navpoints.player_dock_start[2]) 
  3557. 		 
  3558. 		-- Play some music where we left off 
  3559. 		audio_object_post_event(M22_audio_events.music_start_checkpoint, nil, nil, LOCAL_PLAYER)		 
  3560. 	end	 
  3561.  
  3562. 	if (checkpoint == M22_checkpoints.SAVE_SAINTS) then 
  3563. 		 
  3564. 		m22_setup_save_the_saints() 
  3565. 		 
  3566. 		-- Give the player the sonic gun and farts in jars. 
  3567. 		m22_give_temp_weapons_for_save_saints() 
  3568. 		-- Equip the sonic gun. 
  3569. 		m22_equip_temp_weapons_for_save_saints() 
  3570. 		 
  3571. 		teleport_coop(M22_navpoints.statue_obs_deck, M22_navpoints.statue_obs_deck) 
  3572. 		 
  3573. 		-- Play some music where we left off 
  3574. 		audio_object_post_event(M22_audio_events.music_start_checkpoint, nil, nil, LOCAL_PLAYER)		 
  3575. 	end 
  3576. 	 
  3577. 	if (checkpoint == M22_checkpoints.KILL_KIA) then 
  3578. 		m22_setup_kill_kia() 
  3579. 		 
  3580. 		-- Give the player the sonic gun and farts in jars. 
  3581. 		m22_give_temp_weapons_for_save_saints() 
  3582. 		 
  3583. 		teleport_coop(M22_navpoints.player_kia_fight_start[1] , M22_navpoints.player_kia_fight_start[2]) 
  3584. 	end 
  3585.  
  3586. end 
  3587.  
  3588.  
  3589. -- *************************************************** 
  3590. -- Miscellaneous m22 Helper Funcrtions 
  3591. -- *************************************************** 
  3592.  
  3593. -- Create Oleg and Pierce and assigns them as homies 
  3594. function m22_setup_oleg_and_pierce() 
  3595. 	group_create(M22_groups.Oleg_and_Pierce.name, true) 
  3596. 	party_add(M22_characters.Pierce, LOCAL_PLAYER) 
  3597. 	 
  3598. 	if in_coop then 
  3599. 		party_add(M22_characters.Oleg, REMOTE_PLAYER) 
  3600. 	else 
  3601. 		party_add(M22_characters.Oleg, LOCAL_PLAYER) 
  3602. 	end 
  3603. 	 
  3604. 	party_set_dismissable(false) 
  3605. 	on_death("m22_oleg_died_cb", M22_characters.Oleg) 
  3606. 	on_death("m22_pierce_died_cb", M22_characters.Pierce) 
  3607. 	on_dismiss("m22_pierce_abandoned_cb", M22_characters.Pierce) 
  3608. 	follower_set_can_abandon(M22_characters.Pierce, ENABLE) 
  3609. end 
  3610.  
  3611. -- Resets callbacks and disables a given trigger 
  3612. -- 
  3613. -- trigger_name:		(string) name of the trigger to clean up 
  3614. -- 
  3615. function m22_cleanup_trigger(trigger_name) 
  3616. 	on_trigger("", trigger_name) 
  3617. 	on_trigger_exit("", trigger_name) 
  3618. 	trigger_enable(trigger_name, false) 
  3619. 	marker_remove_trigger(trigger_name) 
  3620. end 
  3621.  
  3622. -- Cleans up all triggers 
  3623. -- 
  3624. function m22_cleanup_triggers(trigger_group) 
  3625. 	for i, trigger in pairs(trigger_group) do 
  3626. 		if (type(trigger) == "table") then 
  3627. 			m22_cleanup_triggers(trigger) 
  3628. 		else		 
  3629. 			m22_cleanup_trigger(trigger) 
  3630. 		end 
  3631. 	end 
  3632. end 
  3633.  
  3634. --  Cleans up all threads 
  3635. -- 
  3636. function m22_cleanup_threads(thread_group) 
  3637. 	for i, thread in pairs(thread_group) do 
  3638. 		if (type(thread) == "table") then 
  3639. 			m22_cleanup_threads(thread) 
  3640. 		else		 
  3641. 			if thread ~= INVALID_THREAD_HANDLE then 
  3642. 				thread_kill(thread) 
  3643. 				thread = INVALID_THREAD_HANDLE 
  3644. 			end 
  3645. 		end 
  3646. 	end 
  3647. end 
  3648.  
  3649. -- Resets the on_mover_destroyed callback for all movers 
  3650. -- 
  3651. function m22_cleanup_movers(mover_group) 
  3652. 	for i, mover in pairs(mover_group) do 
  3653. 		if (type(mover) == "table") then 
  3654. 			m22_cleanup_movers(mover) 
  3655. 		else		 
  3656. 			on_mover_destroyed("", mover) 
  3657. 			on_take_damage("", mover) 
  3658. 			on_mover_enter_water("", mover) 
  3659. 		end 
  3660. 	end 
  3661. end 
  3662.  
  3663. -- Stops any active conversation and restores the handle to invalid 
  3664. function m22_cleanup_conversations() 
  3665. 	-- If we have a conversation thread active, kill it 
  3666. 	if M22_threads.convo_handle ~= INVALID_THREAD_HANDLE then 
  3667. 		if Active_conversation.convo_table ~= nil then 
  3668. 			audio_conversation_end(Active_conversation.convo_table.handle) 
  3669. 			Active_conversation.convo_table.handle = INVALID_CONVERSATION_HANDLE 
  3670. 			Active_conversation.convo_table = nil 
  3671. 		end 
  3672. 		thread_kill(M22_threads.convo_handle) 
  3673. 		M22_threads.convo_handle = INVALID_CONVERSATION_HANDLE 
  3674. 	end 
  3675. 	 
  3676. 	audio_remove_mission_cellphone(M22_cur_cell_call_name) 
  3677. 	M22_cur_cell_call_name = "" 
  3678. end 
  3679.  
  3680. -- Unloads any 2d personas used in the mission 
  3681. function m22_cleanup_personas() 
  3682. 	for i, persona in pairs(M22_personas) do 
  3683. 		if persona.persona_id ~= INVALID_PERSONA_HANDLE then 
  3684. 			audio_persona_remove_2d(persona.persona_id) 
  3685. 			persona.persona_id = INVALID_PERSONA_HANDLE 
  3686. 		end 
  3687. 	end 
  3688. end 
  3689. -- ************************* 
  3690. -- 
  3691. -- Callback functions 
  3692. -- 
  3693. -- ************************* 
  3694.  
  3695. function m22_oleg_died_cb() 
  3696. 	mission_end_failure("m22", "m22_failure_oleg_died") 
  3697. end 
  3698.  
  3699. function m22_pierce_died_cb() 
  3700. 	mission_end_failure("m22", "m22_failure_pierce_died") 
  3701. end 
  3702.  
  3703. function m22_pierce_abandoned_cb() 
  3704. 	mission_end_failure("m22", "m22_failure_pierce_abandoned") 
  3705. end 
  3706.  
  3707. -- On killed callback for all humanoids within a battle zone. Increments the player's kill count. 
  3708. -- 
  3709. -- team:		(string) Team that this particular humanoid belongs to 
  3710. -- killer:	(string) The name of the character/player that killed them 
  3711. function m22_battle_zone_initial_died_cb(team, killer) 
  3712.  
  3713. 	if (team == "Civilian") then 
  3714. 		return 
  3715. 	end 
  3716. 	 
  3717. 	if (team == "Saints") then 
  3718. 		return 
  3719. 	end 
  3720.  
  3721. 	if (killer == LOCAL_PLAYER or killer == REMOTE_PLAYER) then 
  3722. 		if killer ~= nil then 
  3723. 			if object_is_in_trigger(Current_bz.zone.trigger, killer) then 
  3724. 				Current_bz.kills = Current_bz.kills + 1 
  3725. 				m22_helper_update_battle_zone_hud() 
  3726. 			end 
  3727. 		end 
  3728. 	end 
  3729. end 
  3730.  
  3731. -- Callback for a initial stag spawn within a battle zone.  This function, will update kill credit and 
  3732. -- spawn numbers, and then spawn reinforcements as necessary. 
  3733. -- 
  3734. -- npc:		(string) name of the npc who died 
  3735. -- killer:	(string) name of the character that killed them 
  3736. function m22_battle_zone_stag_initial_died_cb(npc, killer) 
  3737. 	-- MLG (07/06/11): We're running out of animation memory, so we need to be stricter with how we clean-up guys. 
  3738. 	--					Don't release these NPCs into the world, since we're going to destroy their group before the next 
  3739. 	--					battle location spawns 
  3740. 	-- WillA (9/5/2011): We need to release some of these guys to free up NPC slots for notoriety, so we'll release the first 
  3741. 	--                     NUM_ZONE_ENEMIES_TO_RELEASE guys that die. 
  3742. 	-- character is dead, release it if we need to 
  3743. 	if Current_bz.num_enemies_released < NUM_ZONE_ENEMIES_TO_RELEASE then 
  3744. 		Current_bz.num_enemies_released = Current_bz.num_enemies_released + 1 
  3745. 		if not character_is_released(npc) then 
  3746. 			release_to_world(npc) 
  3747. 			thread_yield() 
  3748. 		end 
  3749. 	end 
  3750. 	 
  3751. 	Current_bz.num_initial_stag_alive = Current_bz.num_initial_stag_alive - 1	 
  3752.  
  3753. 	-- Spawn the backup waves based on how many of the initial spawn remain. 
  3754. 	if (Current_bz.num_initial_stag_alive <= 10) then 
  3755.  
  3756. 		local level = 3 
  3757. 		if (Number_of_zones_cleared == 2) then 
  3758. 			level = 4 
  3759. 		end 
  3760. 		 
  3761. 		m22_set_stag_synd_notoriety(level) 
  3762. 	 
  3763. 		notoriety_force_no_spawn("stag", false) 
  3764. 		--notoriety_force_no_spawn("luchadores", false) 
  3765. 		 
  3766. 		local stag_navpoint_name = Current_bz.zone.center_pos 
  3767. 		--local luchadore_navpoint_name = Current_bz.zone.center_pos 
  3768. 		 
  3769. 		notoriety_spawn_group_set_destination("stag", stag_navpoint_name) 
  3770. 		--notoriety_spawn_group_set_destination("luchadores", luchadore_navpoint_name) 
  3771. 	end 
  3772. end 
  3773.  
  3774. -- Callback for a initial synd spawn within a battle zone.  This function, will update kill credit and 
  3775. -- spawn numbers, and then spawn reinforcements as necessary. 
  3776. -- 
  3777. -- npc:		(string) name of the npc who died 
  3778. -- killer:	(string) name of the character that killed them 
  3779. function m22_battle_zone_synd_initial_died_cb(npc, killer) 
  3780. 	-- MLG (07/06/11): We're running out of animation memory, so we need to be stricter with how we clean-up guys. 
  3781. 	--					Don't release these NPCs into the world, since we're going to destroy their group before the next 
  3782. 	--					battle location spawns	 
  3783. 	-- WillA (9/5/2011): We need to release some of these guys to free up NPC slots for notoriety, so we'll release the first 
  3784. 	--                     NUM_ZONE_ENEMIES_TO_RELEASE guys that die. 
  3785. 	-- character is dead, release it if we need to 
  3786. 	if Current_bz.num_enemies_released < NUM_ZONE_ENEMIES_TO_RELEASE then 
  3787. 		Current_bz.num_enemies_released = Current_bz.num_enemies_released + 1 
  3788. 		if not character_is_released(npc) then 
  3789. 			release_to_world(npc) 
  3790. 			thread_yield() 
  3791. 		end 
  3792. 	end 
  3793. 	 
  3794. 	Current_bz.num_initial_synd_alive = Current_bz.num_initial_synd_alive - 1			 
  3795. 	 
  3796. 	-- Spawn the backup waves based on how many of the initial spawn remain. 
  3797. 	if (Current_bz.num_initial_synd_alive <= 10) then 
  3798. 		local level = 3 
  3799. 		if (Number_of_zones_cleared == 2) then 
  3800. 			level = 4 
  3801. 		end 
  3802. 	 
  3803. 		m22_set_stag_synd_notoriety(level) 
  3804. 		 
  3805. 		--notoriety_force_no_spawn("stag", false) 
  3806. 		notoriety_force_no_spawn("luchadores", false) 
  3807. 		 
  3808. 		--local stag_navpoint_name = Current_bz.zone.center_pos 
  3809. 		local luchadore_navpoint_name = Current_bz.zone.center_pos 
  3810. 		 
  3811. 		--notoriety_spawn_group_set_destination("stag", stag_navpoint_name) 
  3812. 		notoriety_spawn_group_set_destination("luchadores", luchadore_navpoint_name) 
  3813. 	end 
  3814. end 
  3815.  
  3816. -- On_trigger callback for battle zone triggers.  Figures out which zone was triggered, associates the player 
  3817. -- with that zone, spawns it if it hasn't already started, and then sets up the on_trigger_exit callback. 
  3818. -- 
  3819. -- player:			(string) name of the player who triggered the zone 
  3820. -- trigger_name:	(string) name of the trigger 
  3821. -- 
  3822. function m22_zone_triggered_cb(player, trigger_name) 
  3823. 	-- Find out which zone was triggered 
  3824. 	local battle_zone = m22_helper_battle_zone_from_trigger(trigger_name) 
  3825. 	 
  3826. 	-- We don't care if the battlezone is already cleared 
  3827. 	if (battle_zone.cleared == true) then 
  3828. 		return 
  3829. 	end 
  3830. 	 
  3831. 	-- If there's already a battle zone active, we only care if the player is entering that zone 
  3832. 	if (Current_bz.zone ~= NO_ZONE and Current_bz.zone ~= battle_zone) then 
  3833. 		return 
  3834. 	end 
  3835. 	 
  3836. 	-- Remove all the trigger markers 
  3837. 	for i, battle_zone in pairs(Battle_Zone_Groups) do 
  3838. 		marker_remove_trigger(battle_zone.trigger, SYNC_ALL) 
  3839. 	end 
  3840. 	 
  3841. 	-- Check to see if this is a new zone that needs to go active 
  3842. 	if Current_bz.zone == NO_ZONE then 
  3843. 		Current_bz.zone = battle_zone 
  3844.  
  3845. 		-- Enable the battle area trigger 
  3846. 		on_trigger("m22_battle_area_triggered_cb", Current_bz.zone.battle_area) 
  3847. 		on_trigger_exit("m22_battle_area_exited_cb", Current_bz.zone.battle_area) 
  3848. 		trigger_enable(Current_bz.zone.battle_area, true)		 
  3849. 	end 
  3850. 	m22_set_players_zone(player) 
  3851. 	 
  3852. 	local other_player_in_zone = m22_other_player_in_zone(player) 
  3853. 	local hud_bar_size = Current_bz.zone.required_kills + Battle_zone_boss_hud_bar_factor * #Battle_Zone_Finales[Number_of_zones_cleared + 1] 
  3854.  
  3855. 	if player == LOCAL_PLAYER then 
  3856. 		objective_text_clear(0) 
  3857. 		hud_bar_on(0, "Health", "m22_obj_clear_battlezone", hud_bar_size, SYNC_LOCAL, OI_ASSET_KILL) 
  3858. 		 
  3859. 		-- Add the battle area radius, and a marker to the center of the battle area 
  3860. 		minimap_icon_add_radius(Current_bz.zone.center_pos, trigger_get_radius(Current_bz.zone.battle_area), SYNC_LOCAL) 
  3861. 		marker_add(Current_bz.zone.center_pos, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_LOCAL) 
  3862. 	 
  3863. 		if m22_other_player_in_zone(player) ~= ZONE_ACTIVE then 
  3864. 			-- remote player isnt in a zone 
  3865. 			marker_add_trigger(trigger_name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_REMOTE) 
  3866. 		end 
  3867. 	elseif player == REMOTE_PLAYER then 
  3868. 		objective_text_clear(1) 
  3869. 		hud_bar_on(1, "Health", "m22_obj_clear_battlezone", hud_bar_size, SYNC_REMOTE, OI_ASSET_KILL) 
  3870. 		 
  3871. 		-- Add the battle area radius, and a marker to the center of the battle area 
  3872. 		minimap_icon_add_radius(Current_bz.zone.center_pos, trigger_get_radius(Current_bz.zone.battle_area), SYNC_REMOTE) 
  3873. 		marker_add(Current_bz.zone.center_pos, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_REMOTE) 
  3874.  
  3875. 		if m22_other_player_in_zone(player) ~= ZONE_ACTIVE then 
  3876. 			-- host player isnt in a zone 
  3877. 			marker_add_trigger(trigger_name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_LOCAL) 
  3878. 		end 
  3879. 	end 
  3880. end 
  3881.  
  3882. -- On_trigger_exit callback used for when a player exits a zone.  Will shut down the battle zone if the player 
  3883. -- is the last one to leave the zone 
  3884. -- 
  3885. -- player:			(string) name of the player who triggered the zone 
  3886. -- trigger_name:	(string) name of the trigger 
  3887. -- 
  3888. function m22_zone_exited_cb(player, trigger_name) 
  3889. 	local other_player_zone = m22_other_player_in_zone(player) 
  3890. 	 
  3891. 	-- Don't care if there is no active zone 
  3892. 	if (Current_bz.zone == NO_ZONE) then 
  3893. 		return 
  3894. 	end 
  3895. 	 
  3896. 	--Check to see if the other player is still in the zone 
  3897. 	if other_player_zone ~= ZONE_ACTIVE then 
  3898. 		-- Kill the thread processing the battle zone 
  3899. 		thread_kill(M22_threads.battle_zone_instance) 
  3900. 		 
  3901. 		m22_cleanup_battle_zone_kill_enemies() 
  3902. 		 
  3903. 		-- Destroy the guys we spawned 
  3904. 		if (group_is_loaded(Current_bz.zone.initial_spawn.name) == true) then 
  3905. 			group_destroy(Current_bz.zone.initial_spawn.name) 
  3906. 		end 
  3907. 		 
  3908. 		-- Release the courtesy vehicle to the world and destroy the group 
  3909. 		if group_is_loaded(Current_bz.zone.courtesy_vehicles.name) then 
  3910. 			release_to_world(Current_bz.zone.courtesy_vehicles.name) 
  3911. 			group_destroy(Current_bz.zone.courtesy_vehicles.name) 
  3912. 		end		 
  3913. 		 
  3914. 		m22_cleanup_battle_zone_saint_reinforcements() 
  3915. 	else  
  3916. 		-- We're in coop, and this player left the zone before their partner 
  3917. 		if (Current_bz.zone.cleared == false) then 
  3918. 			-- Was the zone cleared? If not, give them the icon to get back in to help their friend 
  3919. 			marker_add_trigger(trigger_name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, sync_from_player(player)) 
  3920. 		end 
  3921. 	end 
  3922. 	 
  3923. 	if LOCAL_PLAYER == player then 
  3924. 		Local_player_zone = NO_ZONE 
  3925. 		hud_bar_off(0) 
  3926. 		objective_text( 0, "m22_obj_goto_battlezone", "", "", SYNC_LOCAL , OI_ASSET_LOCATION) 
  3927. 		 
  3928. 		minimap_icon_remove_radius(Current_bz.zone.center_pos, SYNC_LOCAL) 
  3929. 		marker_remove(Current_bz.zone.center_pos, SYNC_LOCAL) 
  3930. 	else 
  3931. 		Remote_player_zone = NO_ZONE 
  3932. 		hud_bar_off(1) 
  3933. 		objective_text( 1, "m22_obj_goto_battlezone", "", "", SYNC_REMOTE , OI_ASSET_LOCATION) 
  3934. 		 
  3935. 		minimap_icon_remove_radius(Current_bz.zone.center_pos, SYNC_REMOTE) 
  3936. 		marker_remove(Current_bz.zone.center_pos, SYNC_REMOTE) 
  3937. 	end 
  3938. end 
  3939.  
  3940. -- Get a battle zone table from a trigger name (used for callbacks) 
  3941. -- 
  3942. -- trigger_name:	Name of the trigger  
  3943. function m22_helper_battle_zone_from_trigger(trigger_name) 
  3944. 	-- Find out which zone was triggered 
  3945. 	for i, battle_zone in pairs(Battle_Zone_Groups) do 
  3946. 		if (battle_zone.trigger == trigger_name or battle_zone.battle_area == trigger_name) then 
  3947. 			return battle_zone 
  3948. 		end 
  3949. 	end 
  3950.  
  3951. 	if (Armory_battle_zone.trigger == trigger_name or Armory_battle_zone.battle_area == trigger_name) then 
  3952. 		return Armory_battle_zone 
  3953. 	end 
  3954. 	 
  3955. 	return NO_ZONE 
  3956. end 
  3957.  
  3958. -- Callback when the player enters the battle area for a batttle zone 
  3959. function m22_battle_area_triggered_cb(player, trigger_name) 
  3960. 	-- If a battle zone isn't active or this isn't the battle area for that zone, just return 
  3961. 	local battle_zone = m22_helper_battle_zone_from_trigger(trigger_name) 
  3962. 	if (Current_bz.zone == NO_ZONE or Current_bz.zone ~= battle_zone) then 
  3963. 		return 
  3964. 	end 
  3965. 	 
  3966. 	-- Remove the marker leading the player to the battle area 
  3967. 	if LOCAL_PLAYER == player then 
  3968. 		marker_remove(battle_zone.center_pos, SYNC_LOCAL) 
  3969. 	else 
  3970. 		marker_remove(battle_zone.center_pos, SYNC_REMOTE) 
  3971. 	end 
  3972. end 
  3973.  
  3974. -- Callback when the players leaves the battle area for a battle zone 
  3975. function m22_battle_area_exited_cb(player, trigger_name) 
  3976. 	-- If a battle zone isn't active or this isn't the battle area for that zone, just return 
  3977. 	local battle_zone = m22_helper_battle_zone_from_trigger(trigger_name) 
  3978. 	if (Current_bz.zone == NO_ZONE or  Current_bz.zone ~= battle_zone) then 
  3979. 		return 
  3980. 	end 
  3981.  
  3982. 	-- Add the marker leading the player to the battle area 
  3983. 	if LOCAL_PLAYER == player then 
  3984. 		marker_add(battle_zone.center_pos, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_LOCAL) 
  3985. 	else 
  3986. 		marker_add(battle_zone.center_pos, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_REMOTE) 
  3987. 	end	 
  3988. end 
  3989.  
  3990. -- On_trigger callback used to determine when a player reaches the armory 
  3991. -- 
  3992. -- player:			(string) name of the player that entered the trigger 
  3993. -- trigger_name:	(string) name of the trigger entered 
  3994. -- 
  3995. function m22_armory_reached_cb(player, trigger_name) 
  3996. 	m22_set_players_zone(LOCAL_PLAYER) 
  3997. 	if (coop_is_active() == true) then 
  3998. 		m22_set_players_zone(REMOTE_PLAYER) 
  3999. 	end 
  4000.  
  4001. 	Armory_reached = true 
  4002. 	mission_waypoint_remove() 
  4003. 	m22_cleanup_trigger(trigger_name) 
  4004. end 
  4005.  
  4006. -- On_trigger callback used to determine which area the player went to 
  4007. -- 
  4008. -- player:			(string) name of the player that entered the trigger 
  4009. -- trigger_name:	(string) name of the trigger entered 
  4010. -- 
  4011. function m22_player_choice_cb(player, trigger_name) 
  4012. 	if trigger_name == M22_triggers.kill_killbane then 
  4013. 		Player_choice = "killbane" 
  4014. 	elseif trigger_name == M22_triggers.save_saints then 
  4015. 		Player_choice = "shaundi" 
  4016. 	end 
  4017. 	 
  4018. 	-- Cleanup the triggers 
  4019. 	m22_cleanup_trigger(M22_triggers.kill_killbane_perimeter) 
  4020. 	m22_cleanup_trigger(M22_triggers.save_saints_perimeter) 
  4021. 	m22_cleanup_trigger(M22_triggers.kill_killbane) 
  4022. 	m22_cleanup_trigger(M22_triggers.save_saints) 
  4023. end 
  4024.  
  4025. -- On_vehicle_enter callback used to determine when a player has entered a vehicle capable of reaching the statue 
  4026. function m22_player_entered_vehicle_cb(player, vehicle_name) 
  4027. 	local veh_type = get_vehicle_type(vehicle_name) 
  4028. 	if (veh_type == VT_AIRPLANE or veh_type == VT_HELICOPTER or veh_type == VT_VTOL or veh_type == VT_WATERCRAFT) then 
  4029. 		marker_remove(M22_navpoints.statue_boat_loc) 
  4030. 		marker_add_trigger(M22_triggers.save_saints, MINIMAP_ICON_PROTECT_ACQUIRE, INGAME_EFFECT_CHECKPOINT, OI_ASSET_DEFEND, OI_FLAGS_LOCATION, SYNC_ALL) 
  4031. 	end 
  4032. end 
  4033.  
  4034. -- On_projectile_hit callback that is used to monitor Killbanes plane for RPG hits 
  4035. -- 
  4036. -- object_hit_type:		(string) type of object that was hit by a projectile 
  4037. -- object_hit_name:		(string) name of the object that was hit 
  4038. -- weapon:				(string) name of the weapon type from which the projectile originated 
  4039. -- 
  4040. function m22_projectile_hit_cb(object_hit_type, object_hit_name, weapon) 
  4041. 	if object_hit_type == "vehicle" and object_hit_name == M22_vehicles.Killbanes_Plane then 
  4042. 		Num_plane_hits = Num_plane_hits + 1 
  4043. 		if Num_plane_hits == NUM_HITS_TO_STOP_PLANE then 
  4044. 			on_projectile_hit("") 
  4045. 			 
  4046. 			-- Clean up the pathing threads 
  4047. 			thread_kill(M22_threads.killbane_path_handle) 
  4048. 			thread_kill(M22_threads.player_path_handle) 
  4049. 			thread_kill(M22_threads.player_car_speed_handle) 
  4050. 			M22_threads.killbane_path_handle = INVALID_THREAD_HANDLE 
  4051. 			M22_threads.player_path_handle = INVALID_THREAD_HANDLE 
  4052. 			M22_threads.player_car_speed_handle = INVALID_THREAD_HANDLE 
  4053. 			 
  4054. 			-- Destroy the Airplane 
  4055. 			turn_vulnerable(M22_vehicles.Killbanes_Plane) 
  4056. 			vehicle_detonate(M22_vehicles.Killbanes_Plane) 
  4057. 			marker_remove(M22_vehicles.Killbanes_Plane) 
  4058. 			vehicle_stop(M22_vehicles.Angels_Car) 
  4059.  
  4060. 		else 
  4061. 			-- Reduce the HP of the plan  
  4062. 			local max = get_max_hit_points(M22_vehicles.Killbanes_Plane) 
  4063. 			set_current_hit_points(M22_vehicles.Killbanes_Plane, max * ((NUM_HITS_TO_STOP_PLANE - Num_plane_hits) / NUM_HITS_TO_STOP_PLANE)) 
  4064. 		end		 
  4065. 	end 
  4066.  
  4067. end 
  4068.  
  4069. -- On_trigger callback that spawns and moves the first roadblock of the Killbane chase sequence 
  4070. -- 
  4071. -- player:			(string) name of the player that triggered the trigger 
  4072. -- trigger_name:	(string) name of the trigger 
  4073. -- 
  4074. function m22_spawn_first_roadblock_cb(player, trigger_name) 
  4075. 	m22_cleanup_trigger(trigger_name) 
  4076. 	m22_spawn_and_move_roadblock(M22_groups.Airport_Roadblock_one, M22_navpoints.roadblock_one_move_tos) 
  4077. end 
  4078.  
  4079. -- On_trigger callback that spawns and moves the second roadblock of the Killbane chase sequence 
  4080. -- 
  4081. -- player:			(string) name of the player that triggered the trigger 
  4082. -- trigger_name:	(string) name of the trigger 
  4083. -- 
  4084. function m22_spawn_second_roadblock_cb(player, trigger_name) 
  4085. 	m22_cleanup_trigger(trigger_name) 
  4086. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.angel_shoot_plane, 5.0) 
  4087. 	m22_spawn_and_move_roadblock(M22_groups.Airport_Roadblock_two, M22_navpoints.roadblock_two_move_tos) 
  4088. end 
  4089.  
  4090. -- On_trigger callback that spawns and moves the third roadblock of the Killbane chase sequence 
  4091. -- 
  4092. -- player:			(string) name of the player that triggered the trigger 
  4093. -- trigger_name:	(string) name of the trigger 
  4094. -- 
  4095. function m22_spawn_third_roadblock_cb(player, trigger_name) 
  4096. 	group_destroy(M22_groups.Airport_Roadblock_one) -- cleanup the first roadblock 
  4097. 	m22_cleanup_trigger(trigger_name) 
  4098. 	m22_spawn_and_move_roadblock(M22_groups.Airport_Roadblock_three, M22_navpoints.roadblock_three_move_tos) 
  4099. end 
  4100.  
  4101. -- On_trigger callback that spawns and moves the third roadblock of the Killbane chase sequence 
  4102. -- 
  4103. -- player:			(string) name of the player that triggered the trigger 
  4104. -- trigger_name:	(string) name of the trigger 
  4105. -- 
  4106. function m22_spawn_fourth_roadblock_cb(player, trigger_name) 
  4107. 	group_destroy(M22_groups.Airport_Roadblock_two) -- cleanup the second roadblock 
  4108. 	m22_cleanup_trigger(trigger_name) 
  4109. 	m22_spawn_and_move_roadblock(M22_groups.Airport_Roadblock_four, M22_navpoints.roadblock_four_move_tos) 
  4110. end 
  4111.  
  4112. -- On_mover_destroyed callback used to keep track of the C4 
  4113. -- 
  4114. -- mover_name:		(string) name of the script mover 
  4115. -- attacker:		(string) name of the character that destroyed the mover 
  4116. -- 
  4117. function m22_c4_destroyed_cb(mover_name, attacker) 
  4118. 	on_take_damage("", mover_name) 
  4119. 	on_mover_destroyed("", mover_name) 
  4120. 	on_mover_enter_water("", mover_name) 
  4121.  
  4122. 	if object_is_in_trigger(M22_triggers.statue_explosion_region, mover_name) then 
  4123. 		-- Bomb blew up on the statue. 
  4124. 		character_kill(LOCAL_PLAYER) 
  4125. 		 
  4126. 		if in_coop then 
  4127. 			character_kill(REMOTE_PLAYER) 
  4128. 		end 
  4129. 		mission_end_failure("m22", "m22_failure_statue_blown_up")	 
  4130. 		 
  4131. 		for i, mover in pairs(M22_movers.c4) do 
  4132. 			mesh_mover_kill (mover, LOCAL_PLAYER) 
  4133. 		end 
  4134. 	else 
  4135. 		Num_c4_left_to_destroy = Num_c4_left_to_destroy - 1  
  4136. 		marker_remove(mover_name) 
  4137.  
  4138. 		objective_text( 0, "m22_obj_remove_bombs", Total_c4_to_destroy - Num_c4_left_to_destroy, Total_c4_to_destroy .. " ", SYNC_ALL, OI_ASSET_USE ) 
  4139. 	end 
  4140. end 
  4141. -- On_mover_destroyed callback used to keep track of the C4 on the first floor 
  4142. -- 
  4143. -- mover_name:		(string) name of the script mover 
  4144. -- attacker:		(string) name of the character that destroyed the mover 
  4145. -- 
  4146. function m22_c41_destroyed_cb(mover_name, attacker) 
  4147. 	on_take_damage("", mover_name) 
  4148. 	on_mover_destroyed("", mover_name) 
  4149. 	on_mover_enter_water("", mover_name) 
  4150.  
  4151. 	if object_is_in_trigger(M22_triggers.statue_explosion_region, mover_name) then 
  4152. 		-- Bomb blew up on the statue. 
  4153. 		character_kill(LOCAL_PLAYER) 
  4154. 		 
  4155. 		if in_coop then 
  4156. 			character_kill(REMOTE_PLAYER) 
  4157. 		end 
  4158. 		mission_end_failure("m22", "m22_failure_statue_blown_up")	 
  4159. 		 
  4160. 		for i, mover in pairs(M22_movers.c4) do 
  4161. 			mesh_mover_kill (mover, LOCAL_PLAYER) 
  4162. 		end 
  4163. 	else 
  4164. 		Num_c4_left_to_destroy = Num_c4_left_to_destroy - 1 
  4165. 		Num_c4_left_first_floor = Num_c4_left_first_floor - 1 
  4166. 		marker_remove(mover_name) 
  4167.  
  4168. 		objective_text( 0, "m22_obj_remove_bombs", Total_c4_to_destroy - Num_c4_left_to_destroy, Total_c4_to_destroy .. " ", SYNC_ALL, OI_ASSET_USE ) 
  4169. 	end 
  4170. end 
  4171. -- Callback for when a C4 mover is damaged 
  4172. -- 
  4173. -- mover_name:		(string) name of the script mover 
  4174. -- attacker:		(string) name of the character that damaged the mover 
  4175. -- hitpoint_pct:	(float) percent of hitpoints remaining 
  4176. -- from_exp:		(bool) true if the mover was damaged from an explosion 
  4177. -- from_melee:		(bool) true if the mover was damaged from melee 
  4178. -- from_sonic:		(bool) true if the mover was damaged from a sonic gun 
  4179. -- 
  4180. function m22_c4_damaged_cb(mover_name, attacker, hitpoint_pct, from_exp, from_melee, from_sonic) 
  4181. 	if (from_sonic == false) then 
  4182. 		if (object_is_in_trigger(M22_triggers.statue_explosion_region, mover_name) == false) then 
  4183. 			on_take_damage("", mover_name)			 
  4184. 			thread_yield() 
  4185. 			mesh_mover_kill(mover_name, LOCAL_PLAYER) 
  4186. 		end 
  4187. 	end 
  4188. end 
  4189.  
  4190. -- on_mover_enter_water callback used to keep track of the C4 
  4191. -- 
  4192. -- mover_name:		(string) name of the script mover 
  4193. -- 
  4194. function m22_c41_entered_water_cb(mover_name) 
  4195. 	Num_c4_left_to_destroy = Num_c4_left_to_destroy - 1 
  4196. 	Num_c4_left_first_floor = Num_c4_left_first_floor - 1 
  4197. 	marker_remove(mover_name) 
  4198. 	 
  4199. 	on_mover_enter_water("", mover_name) 
  4200. 	on_mover_destroyed("", mover_name) 
  4201. 	on_take_damage("", mover_name) 
  4202. 	 
  4203. 	mesh_mover_kill(mover_name, LOCAL_PLAYER) 
  4204.  
  4205. 	objective_text_clear(0) 
  4206. 	objective_text( 0, "m22_obj_remove_bombs", Total_c4_to_destroy - Num_c4_left_to_destroy, Total_c4_to_destroy .. " ", SYNC_ALL, OI_ASSET_USE ) 
  4207. end 
  4208. -- on_mover_enter_water callback used to keep track of the C4 on the first floor 
  4209. -- 
  4210. -- mover_name:		(string) name of the script mover 
  4211. -- 
  4212. function m22_c4_entered_water_cb(mover_name) 
  4213. 	Num_c4_left_to_destroy = Num_c4_left_to_destroy - 1  
  4214. 	marker_remove(mover_name) 
  4215. 	 
  4216. 	on_mover_enter_water("", mover_name) 
  4217. 	on_mover_destroyed("", mover_name) 
  4218. 	on_take_damage("", mover_name) 
  4219. 	 
  4220. 	mesh_mover_kill(mover_name, LOCAL_PLAYER) 
  4221.  
  4222. 	objective_text_clear(0) 
  4223. 	objective_text( 0, "m22_obj_remove_bombs", Total_c4_to_destroy - Num_c4_left_to_destroy, Total_c4_to_destroy .. " ", SYNC_ALL, OI_ASSET_USE ) 
  4224. end 
  4225. -- on_trigger_exit callback used to kill humans leaving the statue 
  4226. function m22_human_left_statue_cb(character_name, trigger_name) 
  4227. 	--if character_name ~= LOCAL_PLAYER and character_name ~= REMOTE_PLAYER then 
  4228. 	if character_name ~= nil then 
  4229. 		character_ragdoll(character_name) 
  4230. 		character_kill(character_name, true) 
  4231. 	end 
  4232. 	--end 
  4233. end 
  4234.  
  4235. -- Callback for when the player takes the elevator up the statue 
  4236. -- 
  4237. -- char_name:		(string) name of the player that triggered the trigger 
  4238. -- trigger_name:	(string) name of the trigger 
  4239. -- 
  4240. function m22_player_used_elevator_cb(char_name, trigger_name) 
  4241. 	Player_used_elevator = true 
  4242. 	m22_cleanup_trigger(trigger_name) 
  4243. end 
  4244. -- Callback for when the player reaches the breadcrumb 
  4245. -- 
  4246. -- char_name:		(string) name of the player that triggered the trigger 
  4247. -- trigger_name:	(string) name of the trigger 
  4248. -- 
  4249. function m22_player_reached_breadcrumb_cb(char_name, trigger_name) 
  4250. 	Player_reached_breadcrumb = true 
  4251. 	m22_cleanup_trigger(trigger_name) 
  4252. end 
  4253. -- Callback for when the player reaches the top of the statue 
  4254. -- 
  4255. -- char_name:		(string) name of the player that triggered the trigger 
  4256. -- trigger_name:	(string) name of the trigger 
  4257. -- 
  4258. function m22_player_reached_top_cb(char_name, trigger_name) 
  4259. 	Player_reached_top = true 
  4260. 	m22_cleanup_trigger(trigger_name) 
  4261. end 
  4262.  
  4263. -- Callback for when the player unties a saint 
  4264. -- 
  4265. -- char_name:		(string) name of the player that triggered the trigger 
  4266. -- trigger_name:	(string) name of the trigger 
  4267. -- 
  4268. function m22_saint_untied_cb(char_name, trigger_name) 
  4269. 	m22_cleanup_trigger(trigger_name) 
  4270.  
  4271. 	 
  4272. 	for i, trigger in pairs(M22_triggers.untie) do 
  4273. 		if trigger == trigger_name then 
  4274. 			set_script_animation_state(M22_groups.Statue.saints[i], nil) 
  4275. 			 
  4276. 			action_play_synced(char_name, M22_groups.Statue.saints[i], "Hostage Release") 
  4277. 			turn_vulnerable(M22_groups.Statue.saints[i]) 
  4278. 					 
  4279. 			-- Clear their hostage state 
  4280. 			if (character_is_dead(M22_groups.Statue.saints[i]) == false) then 
  4281. 				set_ignore_ai_flag(M22_groups.Statue.saints[i], false) 
  4282. 				set_dont_attack_me_on_sight_flag(M22_groups.Statue.saints[i], false) 
  4283. 				character_allow_ragdoll(M22_groups.Statue.saints[i], ENABLE) 
  4284. 				character_prevent_flinching(M22_groups.Statue.saints[i], DISABLE) 
  4285. 				character_prevent_bumping(M22_groups.Statue.saints[i], DISABLE) 
  4286. 				 
  4287. 				party_add(M22_groups.Statue.saints[i]) 
  4288. 			end 
  4289. 			 
  4290. 			break 
  4291. 		end 
  4292. 	end 
  4293. end 
  4294.  
  4295. -- Callback called when a tied up saint is killed.  Cleans up trigger and character callbacks. 
  4296. -- 
  4297. -- char_name:		(string) name of the saint that died 
  4298. -- attacker_name:	(string) name of the person that killed the saint or nil 
  4299. -- 
  4300. function m22_saint_died_cb(char_name, attacker_name) 
  4301. 	on_death("", char_name) 
  4302. 	 
  4303. 	for i, saint in pairs(M22_groups.Statue.saints) do 
  4304. 		if saint == char_name then 
  4305. 			m22_cleanup_trigger(M22_triggers.untie[i]) 
  4306. 			break 
  4307. 		end 
  4308. 	end 
  4309. end 
  4310.  
  4311. -- Callback called when the player runs out of time during the statue sequence. 
  4312. function m22_statue_times_up_cb() 
  4313. 	-- Bomb blew up on the statue. 
  4314. 	character_kill(LOCAL_PLAYER) 
  4315. 	 
  4316. 	if in_coop then 
  4317. 		character_kill(REMOTE_PLAYER) 
  4318. 	end 
  4319.  
  4320. 	mission_end_failure("m22", "m22_failure_statue_blown_up")	 
  4321. end 
  4322.  
  4323. -- Callback for when Kia is damaged 
  4324. function m22_kia_damaged_cb(victim, attacker, hitpoints, from_explosion, from_melee, causes_vomit) 
  4325. 	-- Only care about the damage if it should cause her to vomit 
  4326. 	if (causes_vomit == true) then 
  4327. 		-- If we're not already processing a vomit, then kick off a new thread 
  4328. 		if (thread_check_done(M22_threads.kia_vomit_handle) == true) then 
  4329. 			M22_threads.kia_vomit_handle = thread_new("m22_kia_process_vomit_thread") 
  4330. 		end 
  4331. 	end 
  4332. end 
  4333.  
  4334. -- Callback when the Mayor Burt is damaged 
  4335. function m22_burt_damaged_cb(victim, attacker, hitpoints, from_explosion, from_melee, causes_vomit) 
  4336. 	if (M22_burt_can_play_damage_line == true) then 
  4337. 		-- Play a situational line 
  4338. 		if (causes_vomit == true) then 
  4339. 			audio_play_persona_line(M22_characters.Mayor, M22_dialog_lines.burt_fiaj[rand_int(1, #M22_dialog_lines.burt_fiaj)]) 
  4340. 		else 
  4341. 			audio_play_persona_line(M22_characters.Mayor, M22_dialog_lines.burt_damaged[rand_int(1, #M22_dialog_lines.burt_damaged)]) 
  4342. 		end 
  4343. 		 
  4344. 		M22_burt_can_play_damage_line = false 
  4345. 		delay(5.0) 
  4346. 		M22_burt_can_play_damage_line = true 
  4347. 	end 
  4348. end 
  4349.  
  4350. -- Callback when Shaundi is killed 
  4351. function m22_shaundi_killed_cb() 
  4352. 	mission_end_failure("m22", "m22_failure_shaundi_died")	 
  4353. end 
  4354.  
  4355. -- Callback for when a player enters a trigger to get Fart in a Jar ammo 
  4356. -- 
  4357. -- triggerer:		Name of the player that entered the trigger region 
  4358. -- trigger:			Name of the trigger region that was entered 
  4359. function m22_give_fart_in_jar_ammo_cb(triggerer, trigger) 
  4360. 	-- Figure out which trigger volume was triggered 
  4361. 	for i, fart_jar_trigger in pairs(M22_triggers.fart_jars) do 
  4362. 		if (fart_jar_trigger == trigger) then 
  4363. 			-- Disable the trigger, and hide the item 
  4364. 			trigger_enable(trigger, false) 
  4365. 			item_hide(M22_groups.Kia_battle_props.fart_jars[i]) 
  4366. 			marker_remove_trigger(trigger, SYNC_ALL) 
  4367. 	 
  4368. 			-- Give them a FIAJ 
  4369. 			if (inv_item_get_weapon_upgrades(KIA_TEMPORARY_GRENADE, triggerer) ~= WEAPON_LEVEL4) then 
  4370. 				-- If the player doesn't already have the FIAJ flashbang upgrade then give it to them 
  4371. 				inv_weapon_add_temporary(triggerer, KIA_TEMPORARY_GRENADE, 0, false, false, false, true, WEAPON_LEVEL4) 
  4372. 			else 
  4373. 				-- Otherwise just give them some ammo 
  4374. 				inv_item_add_ammo(triggerer, KIA_TEMPORARY_GRENADE, 1) 
  4375. 			end 
  4376.  
  4377. 			Player_got_fiaj = true 
  4378. 			 
  4379. 			-- Delay until the respawn time has elapsed 
  4380. 			delay(FART_IN_JAR_RESPAWN_TIME) 
  4381. 			 
  4382. 			-- Re-enable the trigger, and show the item 
  4383. 			trigger_enable(trigger, true) 
  4384. 			item_show(M22_groups.Kia_battle_props.fart_jars[i])	 
  4385. 			marker_add_trigger(trigger, MINIMAP_ICON_USE, nil, OI_ASSET_USE, OI_FLAGS_DEFAULT, SYNC_ALL) 
  4386. 			 
  4387. 			break 
  4388. 		end 
  4389. 	end 
  4390. end 
  4391. -- Callback for when a battle zone boss dies 
  4392. -- 
  4393. -- group_name:		Name of the continuous spawn group that was killed 
  4394. function m22_bz_boss_killed_cb(group_name) 
  4395. 	Current_bz.bosses_killed = Current_bz.bosses_killed + 1 
  4396. 	m22_helper_update_battle_zone_hud() 
  4397. end 
  4398.  
  4399. -- Callback for when the player reaches the first floor breadcrumb on the statue 
  4400. -- 
  4401. -- char_name:		(string) name of the player that triggered the trigger 
  4402. -- trigger_name:	(string) name of the trigger 
  4403. function m22_first_floor_cb(char_name, trigger_name) 
  4404. 	m22_cleanup_trigger(trigger_name) 
  4405.  
  4406. 	-- Set up trigger for the second floor 
  4407. 	on_trigger("m22_second_floor_cb", M22_triggers.Second_Floor) 
  4408. 	trigger_enable(M22_triggers.Second_Floor, true) 
  4409. 	marker_add_trigger(M22_triggers.Second_Floor, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  4410.  
  4411. end 
  4412. -- Callback for when the player reaches the second floor breadcrumb on the statue 
  4413. -- 
  4414. -- char_name:		(string) name of the player that triggered the trigger 
  4415. -- trigger_name:	(string) name of the trigger 
  4416. function m22_second_floor_cb(char_name, trigger_name) 
  4417. 	Second_floor_reached = true 
  4418. 	m22_cleanup_trigger(trigger_name) 
  4419.  
  4420. 	for i, mover in pairs(M22_movers.c4) do 
  4421. 		if not (mesh_mover_destroyed(mover))then 
  4422. 			marker_add(mover, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_DEFAULT, SYNC_ALL) 
  4423. 		end 
  4424. 	end 
  4425. end 
  4426.  
  4427.  
  4428. -- ************************* 
  4429. -- 
  4430. -- Thread functions 
  4431. -- 
  4432. -- ************************* 
  4433.  
  4434. -- Failsafe thread that will re-enable notoriety after a certain amount of 
  4435. -- time during the "kill some dudes" section of a battle zone. 
  4436. -- 
  4437. function m22_thread_notoriety_failsafe() 
  4438. 	delay(NOTORIETY_FAILSAFE_TIME) 
  4439.  
  4440. 	local level = 3 
  4441. 	if (Number_of_zones_cleared == 2) then 
  4442. 		level = 4 
  4443. 	end 
  4444. 	 
  4445. 	m22_set_stag_synd_notoriety(level) 
  4446. 	 
  4447. 	notoriety_force_no_spawn("stag", false) 
  4448. 	notoriety_force_no_spawn("luchadores", false) 
  4449. 	 
  4450. 	--notoriety_spawn_group_clear_destination("stag") 
  4451. 	--notoriety_spawn_group_clear_destination("luchadores") 
  4452. end 
  4453.  
  4454. function m22_thread_neareast_battlezone_gps() 
  4455. 	while true do 
  4456. 		m22_gps_path_to_nearest_battle() 
  4457. 		delay(1.0) 
  4458. 	end 
  4459. end 
  4460.  
  4461. function m22_helper_play_conversation(conversation_table, delay_time) 
  4462. 	if Active_conversation.convo_table ~= nil then 
  4463. 		-- currently playing a conversation, kill it 
  4464. 		audio_conversation_end(Active_conversation.convo_table.handle) 
  4465. 		Active_conversation.convo_table.handle = INVALID_CONVERSATION_HANDLE 
  4466. 		Active_conversation.convo_table = nil 
  4467. 	end 
  4468.  
  4469. 	-- Load the conversation 
  4470. 	if conversation_table.direct  then 
  4471. 		conversation_table.handle = audio_conversation_load_direct(conversation_table.name) 
  4472. 	else 
  4473. 		conversation_table.handle = audio_conversation_load(conversation_table.name) 
  4474. 	end 
  4475. 	 
  4476. 	Active_conversation.convo_table = conversation_table 
  4477. 	 
  4478. 	delay(delay_time) 
  4479. 	 
  4480. 	-- Wait for anything else that was using the failsafe thread handle to finish. 
  4481. 	while M22_threads.audio_failsafe ~= INVALID_THREAD_HANDLE do 
  4482. 		thread_yield() 
  4483. 	end 
  4484. 	 
  4485. 	M22_threads.audio_failsafe = thread_new("delay", 120.0) 
  4486. 	 
  4487. 	conversation_table.played = true 
  4488. 	 
  4489. 	-- Play the conversation and wait for it to end or for the maximum wait time to elapse. 
  4490. 	audio_conversation_play(conversation_table.handle) 
  4491. 	 
  4492. 	while audio_conversation_playing(conversation_table.handle) and thread_check_done(M22_threads.audio_failsafe) == false do 
  4493. 		thread_yield() 
  4494. 	end 
  4495. 	audio_conversation_end(conversation_table.handle) 
  4496. 	 
  4497. 	thread_kill(M22_threads.audio_failsafe) 
  4498. 	M22_threads.audio_failsafe = INVALID_THREAD_HANDLE 
  4499. 	 
  4500. 	conversation_table.handle = INVALID_CONVERSATION_HANDLE 
  4501. 	Active_conversation.convo_table = nil 
  4502. 	M22_threads.convo_handle = INVALID_THREAD_HANDLE 
  4503. end 
  4504.  
  4505. -- Thread function responsible for controling Killbanes plane 
  4506. function m22_airport_killbane_path_thread() 
  4507. 	-- Stop notoriety spawning during the take off sequence. 
  4508. 	notoriety_force_no_spawn("stag", true) 
  4509. 	notoriety_force_no_spawn("luchadores", true) 
  4510. 	 
  4511. 	delay(10) 
  4512. 	vehicle_max_speed(M22_vehicles.Killbanes_Plane, 35)  -- AC: Previously 20 turned it up to 30 
  4513. 	vehicle_pathfind_to(M22_vehicles.Killbanes_Plane, Airport_Killbane_Path1, true, false) 
  4514. 	vehicle_max_speed(M22_vehicles.Killbanes_Plane, 45) 
  4515. 	vehicle_pathfind_to(M22_vehicles.Killbanes_Plane, Airport_Killbane_Path2, true, false) 
  4516. 	vehicle_max_speed(M22_vehicles.Killbanes_Plane, 45) 
  4517. 	vehicle_pathfind_to(M22_vehicles.Killbanes_Plane, Airport_Killbane_Path3, true, false) 
  4518. 	vehicle_max_speed(M22_vehicles.Killbanes_Plane, 30) 
  4519. 	vehicle_pathfind_to(M22_vehicles.Killbanes_Plane, Airport_Killbane_Path4, true, false) 
  4520. 	--vehicle_max_speed(M22_vehicles.Killbanes_Plane, 35)	 
  4521. 	 
  4522. 	 
  4523. 	vehicle_max_speed(M22_vehicles.Killbanes_Plane, 55) 
  4524. 	vehicle_pathfind_to(M22_vehicles.Killbanes_Plane, Airport_Killbane_Path5, true, false) 
  4525. 	--airplane_takeoff(M22_vehicles.Killbanes_Plane) 
  4526. 	mission_end_failure("m22", "m22_failure_killbane_escaped") 
  4527. end 
  4528.  
  4529. -- Thread function responsible for controling Angels car 
  4530. function m22_angel_car_path_thread() 
  4531. 	for i, segment_name in pairs(Airport_player_path) do 
  4532. 		vehicle_pathfind_to(M22_vehicles.Angels_Car, segment_name, true, false) 
  4533. 	end 
  4534. 	mission_end_failure("m22", "m22_failure_killbane_escaped") 
  4535. end 
  4536.  
  4537. -- Thread function that will drive to a specific spot, used for roadblocks in the airplane chase sequence 
  4538. -- 
  4539. -- driver_name:			(string) name of the driver 
  4540. -- car_name:			(string) name of the car 
  4541. -- nav_point_name:		(string) name of the destination navpoint 
  4542. -- thread_index:		(int) index into M22_threads.roadblock_drive_to_handles, to clean up when this thread ends 
  4543. -- 
  4544. function m22_roadblock_drive_to_thread(driver_name, car_name, nav_point_name, thread_index) 
  4545. 	vehicle_max_speed(car_name, 65) -- AC: Test 
  4546. 	vehicle_pathfind_to(car_name, nav_point_name, true, true) 
  4547. 	vehicle_exit_group( { driver_name } ) 
  4548. 	-- Get the drivers to attack the player 
  4549. 	npc_combat_enable(driver_name, true) 
  4550. 	ai_add_enemy_target(driver_name, M22_groups.Angel.members[1], ATTACK_NOW, true) 
  4551. 	 
  4552. 	M22_threads.roadblock_driveto_handles[thread_index] = INVALID_THREAD_HANDLE 
  4553. end 
  4554.  
  4555. -- Thread to process one of the attack VTOLs as it circles around the statue 
  4556. -- 
  4557. -- vtol_table:		Lua table defining the VTOL objects 
  4558. function m22_process_kia_vtol_circling(vtol_table) 
  4559. 	vehicle_max_speed(vtol_table.vtol, vtol_table.loop_speed) 
  4560. 	helicopter_set_path_orientation(vtol_table.vtol, HELI_PF_PATH_PITCH) 
  4561. 	helicopter_fly_to_direct_dont_stop(vtol_table.vtol, vtol_table.loop_speed, vtol_table.path_intro) 
  4562. 	 
  4563. 	while(vehicle_is_destroyed(vtol_table.vtol) == false) do 
  4564. 		-- MLG: This would have been nice, but the minimum follow distance is 20m, which is way to far to keep these VTOLs in formation 
  4565. 		--[[ 
  4566. 		-- Find a potential follow target 
  4567. 		local follow_target = nil 
  4568. 		for i, vtol in pairs(M22_groups.Kia_Vtol1.vtols) do 
  4569. 			if (vtol == vtol_table) then 
  4570. 				-- We didn't find any VTOLs in front of us in the list, so break without a VTOL follow target 
  4571. 				break 
  4572. 			elseif (thread_check_done(vtol.thread_id) == false) then 
  4573. 				-- The VTOL still has a looping thread, so it hasn't broken off yet.  Follow this guy 
  4574. 				follow_target = vtol.vtol 
  4575. 				break 
  4576. 			end 
  4577. 		end 
  4578. 		--]] 
  4579. 	 
  4580. 	--[[ 
  4581. 		if (follow_target ~= nil) then 
  4582. 			helicopter_fly_to_follow_dont_stop(vtol_table.vtol, 150.0, follow_target, vtol_table.path_looping, 20.0, false) 
  4583. 		else 
  4584. 		--]] 
  4585. 			helicopter_fly_to_direct_dont_stop(vtol_table.vtol, vtol_table.loop_speed, vtol_table.path_looping) 
  4586. 			--[[ 
  4587. 		end 
  4588. 		--]] 
  4589. 		thread_yield() 
  4590. 	end 
  4591. end 
  4592.  
  4593. -- Thread to process the attack VTOLs that circle the status and attack the player during the Kia Boss Battle 
  4594. function m22_process_kia_vtols_thread() 
  4595. 	-- Loop forever 
  4596. 	while (true) do 
  4597. 		-- Create the script group for the VTOLs 
  4598. 		group_create_hidden(M22_groups.Kia_Vtol1.name, true) 
  4599. 		group_show(M22_groups.Kia_Vtol1.name) 
  4600. 		 
  4601. 		-- Setup each VTOL in the group, and set them on the intor paths 
  4602. 		for i, vtol in pairs(M22_groups.Kia_Vtol1.vtols) do 
  4603. 			vehicle_enter_group_teleport(vtol.members, vtol.vtol) 
  4604. 			vehicle_suppress_npc_exit(vtol.vtol) 
  4605. 			vtol.thread_id = thread_new("m22_process_kia_vtol_circling", vtol) 
  4606. 		end 
  4607. 		 
  4608. 		-- Start a loop to break one VTOL off at a time and attack the player 
  4609. 		while(true) do 
  4610. 			-- Find the first VTOL that is still alive (search this last backwards, since we want to break of the following plane's first) 
  4611. 			local attack_vtol_table = nil 
  4612. 			for i=(#M22_groups.Kia_Vtol1.vtols), 1, -1 do 
  4613. 				if (vehicle_is_destroyed(M22_groups.Kia_Vtol1.vtols[i].vtol) == false) then 
  4614. 					attack_vtol_table = M22_groups.Kia_Vtol1.vtols[i] 
  4615. 					break 
  4616. 				end 
  4617. 			end 
  4618. 			 
  4619. 			-- If we didn't find an attack VTOL, they must all have died, break out of this loop so we can create another wave 
  4620. 			if (attack_vtol_table == nil) then 
  4621. 				break 
  4622. 			end 
  4623. 			 
  4624. 			-- Kill the circling path thread 
  4625. 			thread_kill(attack_vtol_table.thread_id) 
  4626. 			 
  4627. 			-- Wait until the attack VTOL has finished the current loop it's on 
  4628. 			while(vehicle_pathfind_check_done(attack_vtol_table.vtol) == 0) do 
  4629. 				thread_yield() 
  4630. 			end 
  4631. 			 
  4632. 			-- Fly the break-off path 
  4633. 			helicopter_fly_to_direct(attack_vtol_table.vtol, -1, M22_groups.Kia_Vtol1.path_break_off) 
  4634. 			 
  4635. 			-- Process this VTOL attacking until it dies 
  4636. 			Kia_boss_ai.attack_vtol_side = "east" 
  4637. 			local attack_navs = M22_navpoints.kia_vtol_east_attack 
  4638. 			while(vehicle_is_destroyed(attack_vtol_table.vtol) == false) do 
  4639. 				-- Move the VTOL to the idle attack position, and wait 
  4640. 				helicopter_set_path_orientation(attack_vtol_table.vtol, HELI_PF_FACE_TARGET, LOCAL_PLAYER) 
  4641. 				helicopter_fly_to_direct(attack_vtol_table.vtol, -1, attack_navs[1])				 
  4642. 				delay(KIA_ATTACK_VTOL_IDLE_TIME) 
  4643. 				 
  4644. 				-- Start the attack, and move down to the attack navpoint 
  4645. 				Kia_boss_ai.attack_vtol_attacking = true 
  4646. 				delay(1.0) -- sneak a little delay in here, so Kia has time to get into cover 
  4647. 				helicopter_fly_to_direct(attack_vtol_table.vtol, -1, attack_navs[2]) 
  4648. 				 
  4649. 				-- Fire on the player 
  4650. 				set_ignore_ai_flag(attack_vtol_table.members[1], true) -- ignore AI so we don't fire while at the idle location 
  4651. 				delay(KIA_ATTACK_VTOL_PRE_ATTACK_TIME) 
  4652. 				set_ignore_ai_flag(attack_vtol_table.members[1], false) -- turn AI back on 
  4653. 				helicopter_shoot_human(attack_vtol_table.vtol, LOCAL_PLAYER) 
  4654. 				delay(KIA_ATTACK_VTOL_POST_ATTACK_TIME) 
  4655. 				 
  4656. 				-- Stop attacking 
  4657. 				Kia_boss_ai.attack_vtol_attacking = false 
  4658. 				 
  4659. 				-- Select a random side to attack from next 
  4660. 				local prev_attack_side = Kia_boss_ai.attack_vtol_side 
  4661. 				if (rand_int(1, 2) == 1) then 
  4662. 					Kia_boss_ai.attack_vtol_side = "east" 
  4663. 					attack_navs = M22_navpoints.kia_vtol_east_attack 
  4664. 				else 
  4665. 					Kia_boss_ai.attack_vtol_side = "west" 
  4666. 					attack_navs = M22_navpoints.kia_vtol_west_attack 
  4667. 				end 
  4668. 				 
  4669. 				-- Check if we're switching sides 
  4670. 				if (Kia_boss_ai.attack_vtol_side ~= prev_attack_side) then 
  4671. 					-- Switching sides, so do a transition pathfind depending on which side we're going to 
  4672. 					helicopter_set_path_orientation(attack_vtol_table.vtol, HELI_PF_PATH_PITCH) 
  4673. 					if (Kia_boss_ai.attack_vtol_side == "east") then 
  4674. 						helicopter_fly_to_direct(attack_vtol_table.vtol, -1, M22_groups.Kia_Vtol1.path_west_east) 
  4675. 					else 
  4676. 						helicopter_fly_to_direct(attack_vtol_table.vtol, -1, M22_groups.Kia_Vtol1.path_east_west) 
  4677. 					end 
  4678. 				end 
  4679. 			end 
  4680. 		end 
  4681. 		 
  4682. 		-- Release the now dead group to the world and destroy the group, so we can recreate them 
  4683. 		release_to_world(M22_groups.Kia_Vtol1.name) 
  4684. 		group_destroy(M22_groups.Kia_Vtol1.name) 
  4685. 		 
  4686. 		delay(KIA_ATTACK_VTOL_RESAPWN_TIME) 
  4687. 	end 
  4688. end 
  4689.  
  4690. -- Thread to process Kia's AI during the boss battle 
  4691. function m22_kia_boss_ai_thread() 
  4692. 	-- Make Kia grab Shaundi 
  4693. 	character_take_human_shield(M22_characters.Kia, M22_characters.Shaundi, true) -- bypass AI to take the human shield immediately 
  4694. 	 
  4695. 	npc_leash_remove(M22_characters.Kia) 
  4696. 	 
  4697. 	-- Register both players as enemy targets 
  4698. 	ai_add_enemy_target(M22_characters.Kia, LOCAL_PLAYER, ATTACK_NOW_NEVER_LOSE) 
  4699. 	if (coop_is_active() == true) then 
  4700. 		ai_add_enemy_target(M22_characters.Kia, REMOTE_PLAYER, ATTACK_NOW_NEVER_LOSE) 
  4701. 	end 
  4702. 	 
  4703. 	-- Do per-frame AI processing until Kia has died 
  4704. 	while(character_is_dead(M22_characters.Kia) == false) do 
  4705. 		-- Evaluate if Kia should move to a new position 
  4706. 		m22_kia_boss_ai_evaluate_move() 
  4707. 		 
  4708. 		thread_yield() 
  4709. 	end 
  4710. end 
  4711.  
  4712. function m22_kia_boss_ai_evaluate_move() 
  4713. 	-- Don't process move to AI if Kia is vomiting 
  4714. 	if (thread_check_done(M22_threads.kia_vomit_handle) == false) then 
  4715. 		return 
  4716. 	end 
  4717. 	 
  4718. 	-- Don't process move to AI if Kia doesn't have Shaundi as a human shield 
  4719. 	if (character_has_human_shield(M22_characters.Kia) == false) then 
  4720. 		return 
  4721. 	end 
  4722. 	 
  4723. 	if (Kia_boss_ai.attack_vtol_attacking == true) then 
  4724. 		-- Attack VTOL is about to attack, take cover 
  4725. 		m22_kia_do_take_cover_from_vtol() 
  4726. 	else 
  4727. 		-- No immediate thread, so just try and keep away from the player(s) 
  4728. 		m22_kia_do_move_away_from_player() 
  4729. 	end 
  4730. end 
  4731.  
  4732. -- Per frame processing for Kia to try and take cover from an attack VTOL 
  4733. function m22_kia_do_take_cover_from_vtol() 
  4734. 	-- Figure out which group of cover nodes to search through, based on which side the VTOL is attacking from 
  4735. 	local search_navs = nil 
  4736. 	if (Kia_boss_ai.attack_vtol_side == "east") then 
  4737. 		-- VTOL is attacking from the east, so look for cover on the west 
  4738. 		search_navs = M22_navpoints.kia_defence_west_navs 
  4739. 	else 
  4740. 		-- VTOL is attacking from the west, so look for cover on the east 
  4741. 		search_navs = M22_navpoints.kia_defence_east_navs 
  4742. 	end 
  4743. 	 
  4744. 	-- Find the closest cover navpoint 
  4745. 	local closest_nav_dist = 100000 -- big number 
  4746. 	local closest_nav = nil 
  4747. 	for i, nav in pairs(search_navs) do 
  4748. 		local distance = get_dist(nav, M22_characters.Kia) 
  4749. 		if (distance < closest_nav_dist) then 
  4750. 			-- We have a new closest navpoint 
  4751. 			closest_nav = nav 
  4752. 			closest_nav_dist = distance 
  4753. 		end 
  4754. 	end 
  4755. 	 
  4756. 	-- If this navpoint is different than Kia's current navpoint, then move there 
  4757. 	if (closest_nav ~= Kia_boss_ai.current_navpoint) then 
  4758. 		npc_leash_remove(M22_characters.Kia) 
  4759. 		npc_leash_to_object(M22_characters.Kia, closest_nav, KIA_DEFENSIVE_POSITION_LEASH_RADIUS) 
  4760. 		 
  4761. 		Kia_boss_ai.current_navpoint = closest_nav 
  4762. 	end 
  4763. end 
  4764.  
  4765. -- Per frame processing for Kia to try and maintain a safe distance from the player 
  4766. function m22_kia_do_move_away_from_player() 
  4767. 	local dist_to_player, closest_player = get_dist_closest_player_to_object(M22_characters.Kia) 
  4768. 	if (dist_to_player <= KIA_DESIRED_PLAYER_KEEP_DISTANCE) then 
  4769. 		-- We're too close to a player, see if we should consider a new attack position 
  4770. 		 
  4771. 		-- First, check to see if our destination position is too close to a player 
  4772. 		if (Kia_boss_ai.current_navpoint ~= nil) then 
  4773. 			local dest_dist_to_player, dest_closest_player = get_dist_closest_player_to_object(Kia_boss_ai.current_navpoint) 
  4774. 			if (dest_dist_to_player >= KIA_DESIRED_PLAYER_KEEP_DISTANCE) then 
  4775. 				-- Our current destination is far enough away, just stay the course 
  4776. 				return 
  4777. 			end 
  4778. 		end 
  4779. 		 
  4780. 		-- See if any of the other navpoints are a better pick 
  4781. 		local best_nav = nil 
  4782. 		local closest_nav_dist = 100000 -- big number 
  4783. 		local furthest_from_player_dist = 0 
  4784. 		local furthest_from_player_nav = nil 
  4785. 		for i, nav in pairs(M22_navpoints.kia_attack_navs) do 
  4786. 			local nav_dist_to_player = get_dist_closest_player_to_object(nav) 
  4787. 			local dist_to_nav = get_dist(M22_characters.Kia, nav) 
  4788. 			 
  4789. 			if (nav_dist_to_player > KIA_DESIRED_PLAYER_KEEP_DISTANCE) then 
  4790. 				-- If the nav is outside of the desired keep distance, compare how close it is to other navs outside of the keep distance 
  4791. 				if (dist_to_nav < closest_nav_dist) then 
  4792. 					best_nav = nav 
  4793. 					closest_nav_dist = dist_to_nav 
  4794. 				end 
  4795. 			else 
  4796. 				-- Track the furthest navpoint away from the player that falls within the keep distance 
  4797. 				if (nav_dist_to_player > furthest_from_player_dist) then 
  4798. 					furthest_from_player_nav = nav 
  4799. 					furthest_from_player_dist = nav_dist_to_player 
  4800. 				end 
  4801. 			end 
  4802. 		end 
  4803. 		 
  4804. 		-- If there was no suitable navpoint outside of the keep radius, then check if we should consider the furthest navpoint inside the keep radius 
  4805. 		if (best_nav == nil and furthest_from_player_nav ~= nil) then 
  4806. 			-- Is this at least 10% further away from the closest player? 
  4807. 			if (furthest_from_player_dist > (dist_to_player * 1.1)) then 
  4808. 				best_nav = furthest_from_player_nav 
  4809. 			end 
  4810. 		end 
  4811. 		 
  4812. 		-- If there's a better navpoint, then move there 
  4813. 		if (best_nav ~= nil) then 
  4814. 			npc_leash_remove(M22_characters.Kia) 
  4815. 			npc_leash_to_object(M22_characters.Kia, best_nav, KIA_ATTACK_POSITION_LEASH_RADIUS) 
  4816. 			 
  4817. 			Kia_boss_ai.current_navpoint = best_nav 
  4818. 		end 
  4819. 	end 
  4820. end 
  4821.  
  4822. -- Thread to process character's custom FIAJ reaction for Mission22 
  4823. -- 
  4824. -- character_name:		Name of the character 
  4825. -- loop:				TRUE if the FIAJ should loop indefinitely, FALSE if it should play only once 
  4826. function m22_do_character_fiaj_thread(character_name, loop) 
  4827. 	repeat 
  4828. 		-- Pick a random fiaj reaction 
  4829. 		local fiaj_reaction = M22_anims.fiaj_reactions[rand_int(1, #M22_anims.fiaj_reactions)] 
  4830.  
  4831. 		-- Play the FIAJ reaction animations 
  4832. 		action_play(character_name, fiaj_reaction.intro) 
  4833. 		action_play(character_name, fiaj_reaction.outro) 
  4834. 	until (loop == false) 
  4835. end 
  4836.  
  4837. -- Process Kia vomitting 
  4838. function m22_kia_process_vomit_thread() 
  4839. 	-- Release Shaundi 
  4840. 	--[[ 
  4841. 	character_release_human_shield(M22_characters.Kia) 
  4842. 	while(character_has_human_shield(M22_characters.Kia) == true) do 
  4843. 		thread_yield() 
  4844. 	end 
  4845. 	--]] 
  4846. 	 
  4847. 	-- Apply the vomiting damage multiplier to Kia, and disable AI (so she won't attack the player between vomits - it looks bad) 
  4848. 	character_set_damage_multiplier(M22_characters.Kia, KIA_DAMAGE_MULTIPLIER_VOMITING) 
  4849. 	set_ignore_ai_flag(M22_characters.Kia, true) 
  4850. 	set_ignore_ai_flag(M22_characters.Shaundi, true) 
  4851. 	 
  4852. 	action_play_synced(M22_characters.Kia, M22_characters.Shaundi, KIA_FIAJ_REACTION_SYNCED_ANIM) 
  4853. 	 
  4854. 	--[[ 
  4855. 	local shaundi_reaction_thread = thread_new("m22_do_character_fiaj_thread", M22_characters.Shaundi, true) 
  4856. 	m22_do_character_fiaj_thread(M22_characters.Kia, false) 
  4857. 	--]] 
  4858. 	 
  4859. 	-- Apply the normal damage multiplyer on Kia, and re-enable AI processing 
  4860. 	character_set_damage_multiplier(M22_characters.Kia, KIA_DAMAGE_MULTIPLIER_HUMAN_SHIELD) 
  4861. 	set_ignore_ai_flag(M22_characters.Kia, false) 
  4862. 	 
  4863. 	--[[ 
  4864. 	while character_is_ready(M22_characters.Kia) == false do 
  4865. 		thread_yield() 
  4866. 	end 
  4867.  
  4868. 	-- Grab Shaundi again 
  4869. 	character_take_human_shield(M22_characters.Kia, M22_characters.Shaundi, true) 
  4870. 	 
  4871. 	while(character_has_human_shield(M22_characters.Kia) == false) do 
  4872. 		thread_yield() 
  4873. 	end 
  4874. 	--]] 
  4875. 	 
  4876. 	set_ignore_ai_flag(M22_characters.Shaundi, false) 
  4877. 	 
  4878. 	--thread_kill(shaundi_reaction_thread) 
  4879. 	 
  4880. 	-- Continue moving to the destination navpoint, if there is one 
  4881. 	if (Kia_boss_ai.current_navpoint ~= nil) then 
  4882. 		npc_leash_remove(M22_characters.Kia) 
  4883. 		npc_leash_to_object(M22_characters.Kia, Kia_boss_ai.current_navpoint, KIA_ATTACK_POSITION_LEASH_RADIUS) 
  4884. 	end 
  4885. end 
  4886.  
  4887. -- Thread function that spawns continuous heli reinforcements during the Kia boss battle  
  4888. function m22_kia_coop_reinforcements_thread() 
  4889. 	while true do 
  4890. 		group_create(M22_groups.vtol_coop_reinforcement) 
  4891. 		m22_setup_stag_transport(M22_groups.vtol_coop_reinforcement) 
  4892. 		helicopter_fly_to_direct(M22_groups.vtol_coop_reinforcement.vtol, -1, M22_groups.vtol_coop_reinforcement.drop_offs.path) 
  4893. 		 
  4894. 		-- Tell the soldiers to exit the transport VTOL 
  4895. 		for i, soldier in pairs(M22_groups.vtol_coop_reinforcement.drop_offs.soldiers) do 
  4896. 			teleport(soldier, "nav_vtol_dropoff_coop", true) 
  4897. 		end 
  4898. 		 
  4899. 		delay(1) 
  4900. 		helicopter_fly_to_direct(M22_groups.vtol_coop_reinforcement.vtol, -1, "nav_vtol_dropoff_flee_coop") 
  4901. 		helicopter_enter_retreat(M22_groups.vtol_coop_reinforcement.vtol) 
  4902. 		release_to_world(M22_groups.vtol_coop_reinforcement.name) 
  4903. 		delay(KIA_COOP_REINFORCEMENTS_TIME) 
  4904. 	end 
  4905. end 
  4906.  
  4907. -- Thread function that maintains a certain speed on the player's vehicle based on it's distance from Killbane's plane 
  4908. function m22_manage_players_car_speed_thread() 
  4909. 	local distance_from_killbane 
  4910. 	while true do 
  4911. 		distance_from_killbane = get_dist(M22_vehicles.Angels_Car, M22_vehicles.Killbanes_Plane) 
  4912. 		 
  4913. 		if distance_from_killbane < 30 then 
  4914. 			vehicle_max_speed(M22_vehicles.Angels_Car, 35) 
  4915. 		else  
  4916. 			if distance_from_killbane < 100 then 
  4917. 				vehicle_max_speed(M22_vehicles.Angels_Car, 75) 
  4918. 			else 
  4919. 				vehicle_max_speed(M22_vehicles.Angels_Car, 100) 
  4920. 			end 
  4921. 		end 
  4922. 		 
  4923. 		delay(3) 
  4924. 	end 
  4925. end 
  4926.  
  4927. -- Function to process when to trigger a driving conversation between battlezones 
  4928. function m22_thread_process_drive_convo(convo_table) 
  4929. 	if (Number_of_zones_cleared > 1) then 
  4930. 		-- Wait until the player gets into a car 
  4931. 		while(character_is_in_vehicle(LOCAL_PLAYER) == false) do 
  4932. 			thread_yield() 
  4933. 		end 
  4934. 	 
  4935. 		audio_play_persona_line(M22_characters.Pierce, M22_dialog_lines.pierce_leave_oleg[Number_of_zones_cleared]) 
  4936. 	end 
  4937.  
  4938. 	-- If the driving convo has already played, then just return 
  4939. 	if (M22_conversations.drive_convos[Number_of_zones_cleared + 1].played == true) then 
  4940. 		return 
  4941. 	end 
  4942.  
  4943. 	delay(10) 
  4944. 	while(thread_check_done(M22_threads.convo_handle) == false or character_is_in_vehicle(LOCAL_PLAYER) == false) do 
  4945. 		thread_yield() 
  4946. 	end 
  4947. 	 
  4948. 	M22_threads.convo_handle = thread_new("m22_helper_play_conversation", M22_conversations.drive_convos[Number_of_zones_cleared + 1], 0.0) 
  4949. end 
  4950.