./m21.lua

  1. --[[ 
  2. 	m21.lua 
  3. 	SR3 Mission Script 
  4. 	DATE: 4-19-10 
  5. 	AUTHOR:	John Karczewski 
  6. ]]-- 
  7.  
  8.  
  9. -- Debug flags -- 
  10.  
  11. -- Tweakable Parameters -- 
  12.  
  13. 	ANGEL_HEALTH_MULTIPLIER				= .50 -- temp value for tweaking angel's health 
  14.  
  15. 	-- Phase 1: Defend Angel - Angel vs Killbane -- 
  16. 	TIME_BETWEEN_WAVES					= 6 -- in seconds 
  17. 	TIME_BETWEEN_HARASSER_TO_DISTRACTOR = 6 
  18. 	TIME_BETWEEN_KILLBANE_ANGEL_ACTIONS = 2 
  19. 	TIME_BETWEEN_KILLBANE_ANGEL_CHEATS 	= 2 
  20. 	 
  21. 		-- Temp phase 1 angel dmg 
  22. 	CHEAPSHOT_INTERVAL 					= 1 -- in seconds 
  23. 	CHEAPSHOT_DAMAGE					= 35 
  24. 	ANGEL_DAMAGE_FROM_KILLBANE_PER_SEC	= 10 -- damage per second 
  25. 	 
  26. 	-- Phase 2: Defend Angel - Chainsaw -- 
  27. 	ANGEL_DAMAGE_FROM_STOMPER_PER_SEC	= 5 
  28. 	NUM_STOMPERS_TO_MAINTAIN			= 4 
  29. 	 
  30. 	-- Phase 3: Killbane Fight -- 
  31. 	LUCHADORE_RAGDOLL_TIME				= 3000 	-- in ms 
  32. 	NUM_WEAPON_HITS_FOR_FINISHER		= 4 
  33. 	NUM_KILLBANE_WAVES_TO_WIN 			= 3 
  34. 	KILLBANE_RIDE_MAX_TIME				= 20.0	-- in seconds 
  35.  
  36. 	 
  37. -- Groups -- 
  38. 	M21_groups = { 
  39. 		crowd_props = { 
  40. 			name = "Crowd_props_group", 
  41. 		}, 
  42. 	 
  43. 		angel = { 
  44. 			name = "Angel_Group", 
  45. 			members = { "M21_Angel" }, 
  46. 			angel = "M21_Angel" 
  47. 		}, 
  48. 		 
  49. 		killbane = { 
  50. 			name = "Killbane_Group", 
  51. 			members = { "M21_Killbane" }, 
  52. 			killbane = "M21_Killbane" 
  53. 		}, 
  54. 		 
  55. 		ref = { 
  56. 			name = "Ref_Group", 
  57. 			members = { "Ref" }, 
  58. 			ref = "Ref" 
  59. 		}, 
  60. 		 
  61. 		fight_club_phase_reinforcements = { 
  62. 			name = "Fight_Club_Phase_Group", 
  63. 			members = { "Fight_club_phase_npc 001", "Fight_club_phase_npc 002", "Fight_club_phase_npc 003", "Fight_club_phase_npc 004" } 
  64. 		}, 
  65. 		 
  66. 		wave1 = { 
  67. 			name = "Wave1_Group", 
  68. 			members = { "Distractor_NPC 001", 
  69. 							"Harasser_Npc 001", "Harasser_Npc 002", "Harasser_Npc 002a", "Harasser_Npc 002b", "Harasser_Npc 002c", "Harasser_Npc 002d", "Harasser_Npc 002e"}, 
  70. 			harassers = { "Harasser_Npc 001", "Harasser_Npc 002", "Harasser_Npc 002a", "Harasser_Npc 002b", "Harasser_Npc 002c", "Harasser_Npc 002d", "Harasser_Npc 002e" }, 
  71. 			distractors = { "Distractor_NPC 001" }, 
  72. 			effect_navpoints = { "Tunnel_effect 001", "Tunnel_effect 002"} 
  73. 		}, 
  74. 		 
  75. 		wave2 = { 
  76. 			name = "Wave2_Group", 
  77. 			members = { "Distractor_NPC 002", "Distractor_NPC 003", 
  78. 							"Harasser_Npc 004", "Harasser_Npc 005", "Harasser_Npc 006", "Harasser_Npc 007", 
  79. 							"Harasser_Npc 008", "Harasser_Npc 009" }, 
  80. 			harassers = { "Harasser_Npc 004", "Harasser_Npc 005", "Harasser_Npc 006", "Harasser_Npc 007", 
  81. 								 "Harasser_Npc 008", "Harasser_Npc 009" }, 
  82. 			distractors = { "Distractor_NPC 002", "Distractor_NPC 003" }, 
  83. 			effect_navpoints = { "Tunnel_effect 001", "Tunnel_effect 002", "Tunnel_effect 003", "Tunnel_effect 004"} 
  84. 		}, 
  85. 		 
  86. 		wave3 = { 
  87. 			name = "Wave3_Group", 
  88. 			members = { "Distractor_NPC 004", "Distractor_NPC 005", 
  89. 							"Harasser_Npc 010", "Harasser_Npc 011", "Harasser_Npc 012", "Harasser_Npc 013", 
  90. 							"Harasser_Npc 014", "Harasser_Npc 015"  }, 
  91. 			harassers = { "Harasser_Npc 010", "Harasser_Npc 011", "Harasser_Npc 012", "Harasser_Npc 013", 
  92. 								 "Harasser_Npc 014", "Harasser_Npc 015" }, 
  93. 			distractors = { "Distractor_NPC 004", "Distractor_NPC 005" }, 
  94. 			effect_navpoints = { "Tunnel_effect 001", "Tunnel_effect 002", "Tunnel_effect 003", "Tunnel_effect 004" } 
  95. 		}, 
  96. 		 
  97. 		wave4 = { 
  98. 			name = "Wave4_Group", 
  99. 			members = { "Distractor_NPC 007", "Distractor_NPC 008", "Distractor_NPC 009", "Distractor_NPC 010",  
  100. 							"Harasser_Npc 016", "Harasser_Npc 017", "Harasser_Npc 018", "Harasser_Npc 019", 
  101. 							"Harasser_Npc 020", "Harasser_Npc 021", "Harasser_Npc 022", "Harasser_Npc 023", 
  102. 							"Harasser_Npc 024" }, 
  103. 			harassers = { "Harasser_Npc 016", "Harasser_Npc 017", "Harasser_Npc 018", "Harasser_Npc 019", 
  104. 								 "Harasser_Npc 020", "Harasser_Npc 021", "Harasser_Npc 022", "Harasser_Npc 023", 
  105. 								 "Harasser_Npc 024"}, 
  106. 			distractors = { "Distractor_NPC 007", "Distractor_NPC 008", "Distractor_NPC 009", "Distractor_NPC 010" }, 
  107. 			effect_navpoints  = { "Tunnel_effect 001", "Tunnel_effect 002", "Tunnel_effect 003", "Tunnel_effect 004", 
  108. 								 "Tunnel_effect 005", "Tunnel_effect 006", "Tunnel_effect 007", "Tunnel_effect 008" } 
  109. 		}, 
  110. 		 
  111. 		angel_stompers = { 
  112. 			name = "Angel_Stomper", 
  113. 			members = { "npc_angel_stomper_001", "npc_angel_stomper_002", "npc_angel_stomper_003", "npc_angel_stomper_004" }, 
  114. 		}, 
  115. 		 
  116. 		chainsaw_wave_01 = { 
  117. 			name = "Chainsaw_Wave1_Group", 
  118. 			members = { "Chainsaw_sequence_npc 001", "Chainsaw_sequence_npc 002", "Chainsaw_sequence_npc 003", "Chainsaw_sequence_npc 004", 
  119. 						"Chainsaw_sequence_npc 005", "Chainsaw_sequence_npc 006", "Chainsaw_sequence_npc 007", "Chainsaw_sequence_npc 008" }, 
  120. 		}, 
  121. 		 
  122. 		chainsaw_wave_02 = { 
  123. 			name = "Chainsaw_Wave2_Group", 
  124. 			members = { "Chainsaw_sequence_npc 009", "Chainsaw_sequence_npc 010", "Chainsaw_sequence_npc 011", "Chainsaw_sequence_npc 012", 
  125. 						"Chainsaw_sequence_npc 013", "Chainsaw_sequence_npc 014", "Chainsaw_sequence_npc 015", "Chainsaw_sequence_npc 016" }, 
  126. 		}, 
  127. 		 
  128. 		chainsaw_wave_03 = { 
  129. 			name = "Chainsaw_Wave3_Group", 
  130. 			members = { "Chainsaw_sequence_npc 017", "Chainsaw_sequence_npc 018", "Chainsaw_sequence_npc 019", "Chainsaw_sequence_npc 020", 
  131. 						"Chainsaw_sequence_npc 021", "Chainsaw_sequence_npc 022", "Chainsaw_sequence_npc 023", "Chainsaw_sequence_npc 024" }, 
  132. 		}, 
  133. 		 
  134. 		chainsaw_wave_04 = { 
  135. 			name = "Chainsaw_Wave4_Group", 
  136. 			members = { "Chainsaw_sequence_npc 025", "Chainsaw_sequence_npc 026", "Chainsaw_sequence_npc 027", "Chainsaw_sequence_npc 028", 
  137. 						"Chainsaw_sequence_npc 029", "Chainsaw_sequence_npc 030", "Chainsaw_sequence_npc 031", "Chainsaw_sequence_npc 032" }, 
  138. 		}, 
  139. 		 
  140. 		coop_cont_spawn_01 = { 
  141. 			name = "Coop_cont_spawn_01", 
  142. 		}, 
  143. 		 
  144. 		coop_cont_spawn_02 = { 
  145. 			name = "Coop_cont_spawn_02", 
  146. 		},			 
  147. 		 
  148. 		cte_luch_group = { 
  149. 			name = "m21_cte_luch_group_01", 
  150. 		}, 
  151. 		 
  152. 		M21_cte = { 
  153. 			name = "m21_cte_01", 
  154. 		} 
  155. 	}	 
  156. 	 
  157. -- Navpoints -- 
  158.  
  159. 	M21_navpoints = { 
  160. 	 
  161. 		player_mission_start				= { "Player_Mission_Start_Navpoint", "Coop_Mission_Start_Navpoint" }, 
  162. 		player_defend_angel_start			= { "nav_player_start_chk_02_ 001", "nav_player_start_chk_02_ 002" }, 
  163. 		player_fight_start					= { "Player_Fight_Start_Navpoint", "Coop_Fight_Start_Navpoint" }, 
  164. 		player_fight_start_alt				= { "Player_Fight_Start_Navpoint_Alt", "Coop_Fight_Start_Navpoint_Alt" }, 
  165. 		player_mission_end					= { "M21_Local_Player_Exit", "M21_Remote_Player_Exit" }, 
  166. 		 
  167. 		killbane_corner						= "Killbane_Start_Navpoint", 
  168. 		angel_landing_position				= "Angel_Landing_Position", 
  169. 		player_reacherd_angel				= "nav_player_reached_angel 001", 
  170. 		lookat_angel						= "nav_player_angel_lookat 001", 
  171. 		 
  172. 		killswitch_ring_taunt				= "nav_ring_center", 
  173. 		 
  174. 		player_enter_ring					= "Player_enter_ring_start", 
  175. 		player_enter_ring_dest				= "Player_enter_ring_apron_dest", 
  176. 		player_over_ropes_dest				= "Player_over_ropes_dest", 
  177. 		player_outside_ring					= "Player_tag_in_navpoint", 
  178. 		player_outside_ring_dest			= "Player_tag_in_navpoint_dest", 
  179. 		player_inside_ring_dest				= "Player_tag_out_navpoint_dest", 
  180. 		player_inside_ring					= "Player_tag_out_navpoint", 
  181. 		 
  182. 		npc_outside_arena_tele_points		= { "hallway_spawn_point 001", "hallway_spawn_point 002", "hallway_spawn_point 003", "hallway_spawn_point 004" }, 
  183. 		killbane_pace_end					= "Killbane_Pace_Navpoint 003", 
  184. 		killbane_pace_end_tele				= "Killbane_Pace_Navpoint_Start", 
  185. 		killbane_beatup_trigger_points		= { "beatup_trigger_navpoint 001", "beatup_trigger_navpoint 002", "beatup_trigger_navpoint 003", 
  186. 												"beatup_trigger_navpoint 004"}, 
  187. 		killbane_enter_ring					= { "Killbane_enter_ring_nav 001", "Killbane_enter_ring_nav 002", "Killbane_enter_ring_nav 003", "Killbane_enter_ring_nav 004" }, 
  188. 												 
  189. 		ref_points							= { "Ref_Navpoint 001", "Ref_Navpoint 002", "Ref_Navpoint 003", "Ref_Navpoint 004" }, 
  190. 		ref_standing_point					= "Ref_standing_point 001", 
  191. 		--Points where npcs can harass the fight 
  192. 		npc_harass_points					= { "Npc_Harass_Point 001", "Npc_Harass_Point 002", "Npc_Harass_Point 003", "Npc_Harass_Point 004" }, 
  193. 		npc_harass_dest_points				= { "Npc_Harass_Point_Dest 001", "Npc_Harass_Point_Dest 002", "Npc_Harass_Point_Dest 003", "Npc_Harass_Point_Dest 004" }, 
  194. 		npc_harass_points_out_ring			= { "Npc_Harass_Point_02 001", "Npc_Harass_Point_02 002", "Npc_Harass_Point_02 003", "Npc_Harass_Point_02 004" }, 
  195. 		npc_harass_points_in_ring			= { "Npc_Harass_Point_In_Ring 001", "Npc_Harass_Point_In_Ring 002", "Npc_Harass_Point_In_Ring 003", "Npc_Harass_Point_In_Ring 004" }, 
  196. 		 
  197. 		firework_navs						= { "Tunnel_effect 001", "Tunnel_effect 002", "Tunnel_effect 003", "Tunnel_effect 004", "Tunnel_effect 005", "Tunnel_effect 006", "Tunnel_effect 007", "Tunnel_effect 008" }, 
  198. 		camera_flash_navs					= { "vfx_camera_flashes 001", "vfx_camera_flashes 002", "vfx_camera_flashes 003", "vfx_camera_flashes 004", "vfx_camera_flashes 005" }, 
  199. 	} 
  200. -- Paths -- 
  201.  
  202. -- Triggers -- 
  203. 	M21_triggers = { 
  204. 		beatup_killbane				= { "beatup_killbane_trigger 001", "beatup_killbane_trigger 002", "beatup_killbane_trigger 003", 
  205. 										"beatup_killbane_trigger 004" },										 
  206. 		player_enter_ring			= "Player_Enter_Ring_Trigger 001", 
  207. 		player_reached_angel		= "Player_Reached_Angel_Trigger 001", 
  208. 		tag_trigger_outside			= "Player_tag_team_outside_trigger", 
  209. 		tag_trigger_inside			= "Player_tag_team_inside_trigger", 
  210. 		 
  211. 		ring_trigger				= "Ring_Trigger", 
  212. 	} 
  213.  
  214. -- Spawn Groups -- 
  215. 	M21_spawn_groups = { 
  216. 		luch2_group1 			= "m21_luch2_group 001", 
  217. 		luch2_group2 			= "m21_luch2_group 002", 
  218. 		luch2_group3 			= "m21_luch2_group 003", 
  219. 		luch2_group4 			= "m21_luch2_group 004", 
  220. 		luch2_group5 			= "m21_luch2_group 005", 
  221. 		luch2_group6 			= "m21_luch2_group 006" 
  222. 	} 
  223. 	 
  224. -- Characters -- 
  225. 	M21_characters = { 
  226. 		angel = M21_groups.angel.angel, 
  227. 		killbane = M21_groups.killbane.killbane, 
  228. 		ref = M21_groups.ref.ref 
  229. 	} 
  230.  
  231. -- Vehicles -- 
  232.  
  233. -- Mesh Movers -- 
  234.  
  235. -- Text -- 
  236.  
  237. -- Threads -- 
  238.  
  239. 	M21_threads = { 
  240. 		process_dialog							= INVALID_THREAD_HANDLE, 
  241. 		Killbane_angel_fight_anim_handle		= INVALID_THREAD_HANDLE, 
  242. 		Killbane_angel_damage_handle			= INVALID_THREAD_HANDLE, 
  243. 		Ref_distractor_handles					= { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE }, 
  244. 		Ref_handle								= INVALID_THREAD_HANDLE, 
  245. 		Process_defend_the_ring_handle			= INVALID_THREAD_HANDLE, 
  246. 		Harasser_processing_handle				= INVALID_THREAD_HANDLE, 
  247. 		angel_stompers_handle 					= INVALID_THREAD_HANDLE, 
  248. 		Killbane_pacing_handle 					= INVALID_THREAD_HANDLE, 
  249. 		Killbane_mounted_processing				= INVALID_THREAD_HANDLE, 
  250. 		Killbane_reinforcements_handles			= { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE }, 
  251. 		enforce_character_locations				= INVALID_THREAD_HANDLE, 
  252. 	} 
  253. -- Checkpoints -- 
  254. 	M21_checkpoints = { 
  255. 		start							= MISSION_START_CHECKPOINT,			-- defined in ug_lib.lua 
  256. 		defend_angel 					= "m21_checkpoint_defend_angel", 
  257. 		fight_killbane 					= "m21_checkpoint_fight_killbane", 
  258. 		fight_killbane_remote			= "m21_checkpoint_fight_killbane_02", 
  259. 	} 
  260. 	 
  261. -- Cutscenes -- 
  262. 	M21_cutscenes = { 
  263. 		mission_intro 	= "21_in", 
  264. 		angle_thrown_out = "21_Z01", 
  265. 		unmask_threat = "21_Z02", 
  266. 		remove_mask = "21_Z03", 
  267. 		release_killbane = "21_Z04", 
  268. 		mission_outro = "21_out", 
  269. 	} 
  270. 	 
  271. -- Persona Handles -- 
  272. 	M21_personas = { 
  273. 		bobby = { 
  274. 			name = "Bobby", 
  275. 			persona_id = INVALID_PERSONA_HANDLE, 
  276. 		}, 
  277. 		 
  278. 		zach = { 
  279. 			name = "Zach", 
  280. 			persona_id = INVALID_PERSONA_HANDLE, 
  281. 		}, 
  282. 	} 
  283. 		 
  284. 	 
  285. -- Conversations -- 
  286. 	M21_conversations = { 
  287. 		pickup_dildo = { name = "M21_Pick_Up_Dildo_Bat", load_direct = true }, 
  288. 		angel_beat_down = { name = "M21_Defend_Angel", load_direct = true }, 
  289. 		talk_to_angel = { name = "M21_Convo_4", load_direct = false }, 
  290. 		player_killbane_fight = { name = "M21_Convo_5", load_direct = true }, 
  291. 		player_killbane_banter = { name = "M21_Main_Event_Start", load_direct = false }, 
  292. 		killbane_player_taunt = { name = "M21_Taunting_Player", load_direct = false }, 
  293. 		killswitch_blocked_01 = { name = "M21_1st_Killswitch_Blocked", load_direct = true }, 
  294. 		killswitch_blocked_02 = { name = "M21_2nd_Killswitch_Blocked", load_direct = true }, 
  295. 		killswitch_blocked_03 = { name = "M21_3rd_Killswitch_Blocked", load_direct = true }, 
  296. 		killbane_out_of_ring_01 = { name = "M21_1st_Killbane_Out_Of_Ring", load_direct = true }, 
  297. 		killbane_out_of_ring_02 = { name = "M21_2nd_Killbane_Out_Of_Ring", load_direct = true }, 
  298. 	} 
  299. 	 
  300. 	M21_dialog_lines = { 
  301. 		angel_killbane_commentary = { 
  302. 			{ name = "M21_Mission_Start_01", persona = LOCAL_PLAYER, can_interrupt = false }, 
  303. 			{ name = "M21_Mission_Start_02", persona = "Zach", can_interrupt = false }, 
  304. 			--{ name = "M21_Mission_Start_03", persona = "Bobby", can_interrupt = false }, 
  305. 			{ name = "M21_Mission_Start_04", persona = "Zach", can_interrupt = true }, 
  306. 			{ name = "M21_Call_Out_Prop_05", persona = "Bobby", can_interrupt = true }, 
  307. 			{ name = "M21_Mission_Start_05", persona = "Bobby", can_interrupt = true }, 
  308. 			{ name = "M21_Taunting_Angel_01", persona = M21_characters.killbane, can_interrupt = false }, 
  309. 			{ name = "M21_Taunting_Angel_02", persona = M21_characters.angel, can_interrupt = false }, 
  310. 			{ name = "M21_Taunting_Angel_03", persona = M21_characters.killbane, can_interrupt = false }, 
  311. 			{ name = "M21_Taunting_Angel_04", persona = M21_characters.angel, can_interrupt = false }, 
  312. 			{ name = "M21_Match_Commentary_01_01", persona = "Zach", can_interrupt = true }, 
  313. 			{ name = "M21_Match_Commentary_01_02", persona = "Bobby", can_interrupt = true }, 
  314. 			{ name = "M21_Match_Commentary_01_03", persona = "Zach", can_interrupt = true }, 
  315. 			{ name = "M21_Match_Commentary_01_04", persona = "Bobby", can_interrupt = true }, 
  316. 			{ name = "M21_Match_Commentary_01_05", persona = "Zach", can_interrupt = true }, 
  317. 			{ name = "M21_Match_Commentary_01_06", persona = "Bobby", can_interrupt = true }, 
  318. 			{ name = "M21_Match_Commentary_01_07", persona = "Zach", can_interrupt = true }, 
  319. 			{ name = "M21_Match_Commentary_01_08", persona = "Bobby", can_interrupt = true }, 
  320. 			{ name = "M21_Match_Commentary_01_09", persona = "Zach", can_interrupt = true }, 
  321. 			{ name = "M21_Match_Commentary_01_10", persona = "Bobby", can_interrupt = true }, 
  322. 			{ name = "M21_Match_Commentary_01_11", persona = "Zach", can_interrupt = true }, 
  323. 			{ name = "M21_Match_Commentary_01_12", persona = "Bobby", can_interrupt = true }, 
  324. 			{ name = "M21_Match_Commentary_01_13", persona = "Zach", can_interrupt = true }, 
  325. 			{ name = "M21_Match_Commentary_01_14", persona = "Bobby", can_interrupt = true }, 
  326. 			{ name = "M21_Match_Commentary_01_15", persona = "Zach", can_interrupt = true }, 
  327. 			{ name = "M21_Match_Commentary_01_16", persona = "Bobby", can_interrupt = true }, 
  328. 			{ name = "M21_Match_Commentary_01_17", persona = "Zach", can_interrupt = true }, 
  329. 		}, 
  330. 		 
  331. 		ref_distracted = { 
  332. 			{ name = "M21_Ref_Distracted_01", persona = "Bobby", can_interrupt = false }, 
  333. 			--{ name = "M21_Ref_Distracted_02", persona = "Zach", can_interrupt = false }, 
  334. 			{ name = "M21_Ref_Distracted_03", persona = "Bobby", can_interrupt = false }, 
  335. 			{ name = "M21_Ref_Distracted_04", persona = "Zach", can_interrupt = false }, 
  336. 			{ name = "M21_Ref_Distracted_06", persona = "Zach", can_interrupt = false }, 
  337. 		}, 
  338. 		 
  339. 		chainsaw_commentary = { 
  340. 			{ name = "M21_Defend_Angel_01", persona = "Zach", can_interrupt = false }, 
  341. 			{ name = "M21_Defend_Angel_02", persona = "Bobby", can_interrupt = false }, 
  342. 			{ name = "M21_Defend_Angel_03", persona = "Zach", can_interrupt = false }, 
  343. 			{ name = "M21_Defend_Angel_04", persona = "Bobby", can_interrupt = false }, 
  344. 		}, 
  345. 		 
  346. 		chainsaw_kills = { 
  347. 			{ name = "M21_Chainsaw_01", persona = "Zach", can_interrupt = false }, 
  348. 			--{ name = "M21_Chainsaw_02", persona = "Bobby", can_interrupt = false }, 
  349. 			--{ name = "M21_Chainsaw_03", persona = "Zach", can_interrupt = false }, 
  350. 			{ name = "M21_Chainsaw_04", persona = "Bobby", can_interrupt = false }, 
  351. 			{ name = "M21_Chainsaw_05", persona = "Zach", can_interrupt = false }, 
  352. 			{ name = "M21_Chainsaw_06", persona = "Bobby", can_interrupt = false }, 
  353. 		}, 
  354. 		 
  355. 		exclamation = { 
  356. 			{ name = "M21_Chainsaw_02", persona = "Bobby", can_interrupt = false }, 
  357. 			{ name = "M21_Chainsaw_03", persona = "Zach", can_interrupt = false }, 
  358. 			{ name = "M21_Killswitch_Coming_04", persona = "Bobby", can_interrupt = false }, 
  359. 			{ name = "M21_Break_Out_Of_Commentary_03", persona = "Zach", can_interrupt = false }, 
  360. 			{ name = "M21_Ref_Distracted_05", persona = "Bobby", can_interrupt = false }, 
  361. 		}, 
  362. 		 
  363. 		player_killbane_start = { 
  364. 			{ name = "M21_Fight_Killbane_01", persona = "Zach", can_interrupt = true }, 
  365. 			{ name = "M21_Fight_Killbane_02", persona = "Bobby", can_interrupt = true }, 
  366. 		}, 
  367. 		 
  368. 		player_killbane_commentary = { 
  369. 			{ name = "M21_Main_Event_Fight_01", persona = "Zach", can_interrupt = true }, 
  370. 			{ name = "M21_Main_Event_Fight_02", persona = "Bobby", can_interrupt = true }, 
  371. 			{ name = "M21_Main_Event_Fight_03", persona = "Zach", can_interrupt = true }, 
  372. 			{ name = "M21_Main_Event_Fight_04", persona = "Bobby", can_interrupt = true }, 
  373. 			{ name = "M21_Main_Event_Fight_05", persona = "Zach", can_interrupt = true }, 
  374. 			{ name = "M21_Main_Event_Fight_06", persona = "Bobby", can_interrupt = true }, 
  375. 		}, 
  376. 		 
  377. 		killswitch_tell = { 
  378. 			{ name = "M21_Killswitch_Coming_01", persona = "Bobby", can_interrupt = false }, 
  379. 			{ name = "M21_Killswitch_Coming_02", persona = "Bobby", can_interrupt = false }, 
  380. 			{ name = "M21_Killswitch_Coming_03", persona = "Bobby", can_interrupt = false }, 
  381. 			{ name = "M21_Killswitch_Coming_04", persona = "Bobby", can_interrupt = false }, 
  382. 			{ name = "M21_Killswitch_Coming_05", persona = "Bobby", can_interrupt = false }, 
  383. 			{ name = "M21_Killswitch_Coming_06", persona = "Bobby", can_interrupt = false }, 
  384. 		}, 
  385. 		 
  386. 		qte_failed = { 
  387. 			{ name = "M21_Failed_QTE_01", persona = "Bobby", can_interrupt = false }, 
  388. 			{ name = "M21_Failed_QTE_02", persona = "Bobby", can_interrupt = false }, 
  389. 			{ name = "M21_Failed_QTE_03", persona = "Bobby", can_interrupt = false }, 
  390. 			{ name = "M21_Failed_QTE_04", persona = "Bobby", can_interrupt = false }, 
  391. 			{ name = "M21_Failed_QTE_05", persona = "Bobby", can_interrupt = false }, 
  392. 			{ name = "M21_Failed_QTE_06", persona = "Bobby", can_interrupt = false }, 
  393. 			{ name = "M21_Failed_QTE_07", persona = "Bobby", can_interrupt = false }, 
  394. 			{ name = "M21_Failed_QTE_08", persona = "Bobby", can_interrupt = false }, 
  395. 			{ name = "M21_Failed_QTE_09", persona = "Bobby", can_interrupt = false }, 
  396. 			{ name = "M21_Failed_QTE_10", persona = "Bobby", can_interrupt = false }, 
  397. 		}, 
  398. 		 
  399. 		killbane_out_of_ring_01 = { 
  400. 			{ name = "M21_First_Killbane_Out_Of_Ring_01", persona = "Zach", can_interrupt = false }, 
  401. 		}, 
  402. 		 
  403. 		killbane_back_in_ring_01 = { 
  404. 			{ name = "M21_First_Killbane_Out_Of_Ring_02", persona = "Bobby", can_interrupt = false }, 
  405. 			{ name = "M21_First_Killbane_Out_Of_Ring_03", persona = "Zach", can_interrupt = false }, 
  406. 			{ name = "M21_First_Killbane_Out_Of_Ring_04", persona = "Bobby", can_interrupt = false }, 
  407. 		}, 
  408. 		 
  409. 		killbane_posturing = { 
  410. 			{ name = "M21_Killbane_Plays_To_Crowd_01", persona = "Zach", can_interrupt = false }, 
  411. 			{ name = "M21_Killbane_Plays_To_Crowd_02", persona = "Zach", can_interrupt = false }, 
  412. 			{ name = "M21_Killbane_Plays_To_Crowd_03", persona = "Zach", can_interrupt = false }, 
  413. 			{ name = "M21_Killbane_Plays_To_Crowd_04", persona = "Zach", can_interrupt = false }, 
  414. 			{ name = "M21_Killbane_Plays_To_Crowd_05", persona = "Zach", can_interrupt = false }, 
  415. 			{ name = "M21_Killbane_Plays_To_Crowd_06", persona = "Zach", can_interrupt = false }, 
  416. 		}, 
  417. 		 
  418. 		commentater_break_out = { 
  419. 			{ name = "M21_Break_Out_Of_Commentary_01", persona = "Zach", can_interrupt = false }, 
  420. 			{ name = "M21_Break_Out_Of_Commentary_02", persona = "Bobby", can_interrupt = false }, 
  421. 			{ name = "M21_Break_Out_Of_Commentary_03", persona = "Zach", can_interrupt = false }, 
  422. 			{ name = "M21_Break_Out_Of_Commentary_04", persona = "Bobby", can_interrupt = false }, 
  423. 			{ name = "M21_Break_Out_Of_Commentary_05", persona = "Zach", can_interrupt = false }, 
  424. 			{ name = "M21_Break_Out_Of_Commentary_06", persona = "Bobby", can_interrupt = false }, 
  425. 			{ name = "M21_Break_Out_Of_Commentary_07", persona = "Zach", can_interrupt = false }, 
  426. 			{ name = "M21_Break_Out_Of_Commentary_08", persona = "Bobby", can_interrupt = false }, 
  427. 			{ name = "M21_Break_Out_Of_Commentary_09", persona = "Zach", can_interrupt = false }, 
  428. 			{ name = "M21_Break_Out_Of_Commentary_10", persona = "Bobby", can_interrupt = false }, 
  429. 		}, 
  430. 		 
  431. 		commentater_break_in = { 
  432. 			{ name = "M21_Break_Into_Commentary_01", persona = "Bobby", can_interrupt = false },			 
  433. 			{ name = "M21_Break_Into_Commentary_02", persona = "Bobby", can_interrupt = false }, 
  434. 			{ name = "M21_Break_Into_Commentary_03", persona = "Zach", can_interrupt = false },	 
  435. 			{ name = "M21_Break_Into_Commentary_04", persona = "Zach", can_interrupt = false },					 
  436. 		}, 
  437. 		 
  438. 		prop_call_out = { 
  439. 			{ name = "M21_Call_Out_Prop_01", persona = "Bobby", can_interrupt = false }, 
  440. 			{ name = "M21_Call_Out_Prop_02", persona = "Zach", can_interrupt = false }, 
  441. 			{ name = "M21_Call_Out_Prop_03", persona = "Bobby", can_interrupt = false }, 
  442. 			{ name = "M21_Call_Out_Prop_04", persona = "Zach", can_interrupt = false }, 
  443. 			{ name = "M21_Call_Out_Prop_06", persona = "Zach", can_interrupt = false }, 
  444. 		}, 
  445. 		 
  446. 		prop_in_ring = { 
  447. 			{ name = "M21_Call_Out_Prop_In_Ring_01", persona = "Bobby", can_interrupt = false }, 
  448. 			{ name = "M21_Call_Out_Prop_In_Ring_02", persona = "Zach", can_interrupt = false }, 
  449. 			{ name = "M21_Call_Out_Prop_In_Ring_03", persona = "Bobby", can_interrupt = false }, 
  450. 			{ name = "M21_Call_Out_Prop_In_Ring_04", persona = "Zach", can_interrupt = false }, 
  451. 			{ name = "M21_Call_Out_Prop_In_Ring_05", persona = "Bobby", can_interrupt = false }, 
  452. 			{ name = "M21_Call_Out_Prop_In_Ring_06", persona = "Zach", can_interrupt = false }, 
  453. 		}, 
  454. 	} 
  455. 	 
  456. 	M21_audio_events = { 
  457. 		crowd_against = "M21_crowd_bed_against", 
  458. 		crowd_with = "M21_crowd_bed_with", 
  459. 	 
  460. 		music_your_the_best = "M21_mus_youre_the_best", 
  461. 		music_your_the_best_stop = "M21_mus_youre_the_best_STOP", 
  462. 		 
  463. 		-- Chants 
  464. 		angel_long = "M21_chant_angel_long", 
  465. 		angel_short = "M21_chant_angel_three", 
  466. 		killbane_long = "M21_chant_killbane_long", 
  467. 		killbane_short = "M21_chant_killbane_three", 
  468. 		dildo = "M21_chant_dildo_long", 
  469. 		we_want_blood = "M21_chant_we_want_blood", 
  470. 		murderbrawl = "M21_chant_murderbrawl", 
  471. 		 
  472. 		-- Cheers 
  473. 		crowd_cheer_low = "m21_crowd_cheer_low", 
  474. 		crowd_cheer_mid = "m21_crowd_cheer_mid", 
  475. 		crowd_cheer_high = "m21_crowd_cheer_high", 
  476. 		boo_killbane = "m21_crowd_boo_killbane", 
  477. 		boo_short = "m21_crowd_boo_short", 
  478. 		crowd_count_cheer = "m21_crowd_count_cheer", 
  479. 		crowd_disappoint = "m21_crowd_disappoint", 
  480. 		crowd_chainsaw = "m21_crowd_get_chainsaw", 
  481. 		 
  482. 		-- Crowd count 
  483. 		crowd_count = { 
  484. 			"m21_crowd_count_01", 
  485. 			"m21_crowd_count_02", 
  486. 			"m21_crowd_count_03", 
  487. 			"m21_crowd_count_04", 
  488. 			"m21_crowd_count_05", 
  489. 			"m21_crowd_count_06", 
  490. 			"m21_crowd_count_07", 
  491. 			"m21_crowd_count_08", 
  492. 			"m21_crowd_count_09", 
  493. 			"m21_crowd_count_10", 
  494. 		}, 
  495. 		 
  496. 		-- Riding Killbane 
  497. 		ride_killbane_start = "m21_crowd_killbane_ride", 
  498. 		ride_killbane_stop = "m21_crowd_killbane_ride_STOP", 
  499. 		 
  500. 		-- Misc 
  501. 		crowd_shocked = "m21_crowd_ohh_shocked", 
  502. 		 
  503. 		-- Zscenes 
  504. 		z01 = "m21_Z01_crowds", 
  505. 		z02 = "m21_Z02_crowds", 
  506. 		z03 = "m21_Z03_crowds", 
  507. 		z04 = "m21_Z04_crowds", 
  508. 	} 
  509. 	 
  510. 	M22_audio_emitters = { 
  511. 		room_tone = "M21_amb_int_murderbrawl_arena", 
  512. 	} 
  513. 	 
  514. -- Animations -- 
  515. 	M21_animations = { 
  516. 		luchadore_jump_on_ring = "Lucha Enter Apron", 
  517. 		luchadore_jump_over_ropes = "Lucha Enter Ring", 
  518. 		luchadore_enter_ring = "Enter Ring From Floor", 
  519. 		 
  520. 		player_jump_on_ring	= "Lucha Enter Apron", 
  521. 		player_jump_over_ropes = "Lucha Enter Ring", 
  522. 		 
  523. 		player_tag_in = "m21_plym_tagTeam_swapA", 
  524. 		player_tag_out = "m21_plym_tagTeam_swapB", 
  525. 		 
  526. 		killbane_angel_grapple = "Wrestling Grapple", 
  527. 		killbane_angel_fight = { "Wrestling Seq 1", "Wrestling Seq 2", "Wrestling Seq 3", "Wrestling Seq 4", "Wrestling Seq 5" }, 
  528. 		killbane_angel_cheats = {  
  529. 			{  
  530. 				intro = "Wrestling to Cheat 1",  
  531. 				state = "Cheat 1", 
  532. 				outro = "Cheat to Wrestling 1", 
  533. 			}, 
  534. 			{  
  535. 				intro = "Wrestling to Cheat 2",  
  536. 				state = "Cheat 2", 
  537. 				outro = "Cheat to Wrestling 2" 
  538. 			}, 
  539. 		}, 
  540. 		 
  541. 		killbane_flinches = { "base flinch chest front a", "base flinch chest front b" }, 
  542. 		killbane_pacing = "KillBane Pacing", 
  543. 		killbane_enter_ring = "Enter Ring", 
  544. 		 
  545. 			 
  546. 		--KILLBANE_WRESTLE 				= "killbane_wrestle" 
  547. 		--ANGEL_WRESTLE					= "angel_wrestle" 
  548. 	} 
  549. 	 
  550. -- Animation States -- 
  551. 	M21_animation_state = { 
  552. 		luchadore_ring_stand 			= "Lucha Apron distract", 
  553. 		ref_watch 						= "Ref Watch", 
  554. 		ref_distracted 					= "Ref Distracted", 
  555. 	} 
  556.  
  557.  
  558. -- Other -- 
  559. 	dialog_queue = { 
  560. 		playing  = { 
  561. 			thread_id = INVALID_THREAD_HANDLE, 
  562. 			dialog_handle = INVALID_CONVERSATION_HANDLE, 
  563. 			dialog_table = nil, 
  564. 		}, 
  565. 		list = {}, 
  566. 		size = 0, 
  567. 	} 
  568. 		 
  569. 	active_conversation = { 
  570. 		dialog_table = nil, 
  571. 	} 
  572. 	 
  573. 	M21_hud_states = { 
  574. 		hide_hud = -1, 
  575. 	} 
  576. 	 
  577. 	M21_spawn_regions = { 
  578. 		"spawn_region_coop 001", 
  579. 		"spawn_region_coop 002", 
  580. 		"spawn_region_coop 003", 
  581. 		"spawn_region_coop 004", 
  582. 	} 
  583. 	 
  584. 	M21_defend_angel_waves = { M21_groups.wave1, M21_groups.wave2, M21_groups.wave3, M21_groups.wave4 } 
  585. 	 
  586. 	M21_angel_stomper_locations = { 
  587. 		{ nav = "nav_angel_stomper_pos 001", anim = "M21 angel beat down b", occupant = "", thread_id = INVALID_THREAD_HANDLE }, 
  588. 		{ nav = "nav_angel_stomper_pos 002", anim = "M21 angel beat down c", occupant = "", thread_id = INVALID_THREAD_HANDLE }, 
  589. 		{ nav = "nav_angel_stomper_pos 003", anim = "M21 angel beat down d", occupant = "", thread_id = INVALID_THREAD_HANDLE }, 
  590. 		{ nav = "nav_angel_stomper_pos 004", anim = "M21 angel beat down e", occupant = "", thread_id = INVALID_THREAD_HANDLE }, 
  591. 	} 
  592. 	 
  593. 	M21_pontential_stomper_list = { } 
  594. 	 
  595. 	PHASE_DEFEND_RING = 1 
  596. 	PHASE_FIGHT_KILLBANE = 2 
  597. 	 
  598. 	player_win = false 
  599. 	player_unmasked_killbane = false 
  600.  
  601. 	ENABLE = true 
  602. 	DISABLE = false 
  603. 	 
  604. 	in_coop = false 
  605. 	 
  606. 	enabled_trigger_index = 0 
  607. 	 
  608. 	local_melee_weapon = "none" 
  609. 	remote_melee_weapon = "none" 
  610. 	 
  611. 	-- Angel harasser variables (m21 part 1) 
  612. 	NUM_TOTAL_ANGEL_HARASSERS 					= 8 
  613. 	player_completed_phase_one					= false 
  614. 	num_distractors_on_ring 					= 0  
  615. 	distractors_on_ring							= { "", "", "", "" } 
  616. 	ref_target									= "" 
  617. 	ref_location_idx							= 0 
  618. 	 
  619. 	-- Defend Angel variables (m21 part 2) 
  620. 	Chainsaw_luchadors_alive = 0 
  621. 	Player_entered_ring = false 
  622. 	player_reached_angel = false 
  623. 	 
  624. 	-- Fight harasser variables (m21 part 3) 
  625. 	num_times_killbane_hit_by_weapon 		= 0 
  626. 	killbane_wave 							= 1 
  627. 	killbane_thug_enemies_to_kill 			= 0 
  628. 	killbane_thug_enemies_living			= 0 
  629. 	Killbane_should_be_in_ring				= true 
  630. 	 
  631. 	player_in_ring							= LOCAL_PLAYER 
  632. 	player_outside_ring						= REMOTE_PLAYER 
  633. 	player_ready_to_tag_in					= false 
  634. 	 
  635. 	M21_prop_called_out						= false 
  636. 	fight_club_phase 						= false 
  637. 	M21_killbane_ride_success				= false 
  638. 	M21_corner_qte_cb_count						= 1 
  639. 	Play_choice_selection					= -1 
  640. 	 
  641. 	-- HUD indices 
  642. 	GSI_OBJECTIVE_INDEX				= 0 
  643. 	GSI_ANGEL_HEALTH_INDEX 			= 1 
  644.  
  645. 	-- Conversation enums 
  646. 	M21_CONVO_PLAY_LAST = 0 
  647. 	M21_CONVO_PLAY_NEXT = 1 
  648. 	M21_CONVO_PLAY_IMMEDIATE = 2 
  649. -- ************************* 
  650. -- 
  651. -- Standard functions 
  652. -- 
  653. -- ************************* 
  654.  
  655. -- This is the primary entry point for the mission, and is responsible for starting up the mission 
  656. -- at the specified checkpoint. 
  657. -- CALLED FROM CODE 
  658. -- 
  659. -- m21_checkpoint:	The checkpoint the mission should begin at 
  660. -- is_restart:					TRUE if the mission is restarting, FALSE otherwise 
  661. -- 
  662. function m21_start(m21_checkpoint, is_restart) 
  663. 	in_coop = coop_is_active() 
  664. 	 
  665. 	mission_start_fade_out() 
  666. 	 
  667. 	city_zone_swap("m21", true) 
  668. 	 
  669. 	-- Handle mission initialization for the current checkpoint 
  670. 	m21_initialize(m21_checkpoint) 
  671.  
  672. 	-- Check if this mission starting from the beginning 
  673. 	if (m21_checkpoint == M21_checkpoints.start) then 
  674. 		if (is_restart == false) then 
  675. 			-- First time playing mission 
  676. 			 
  677. 			-- Play an intro cutscene??? 
  678. 			if (M21_cutscenes.mission_intro ~= "") then 
  679. 				cutscene_play(M21_cutscenes.mission_intro, nil, M21_navpoints.player_mission_start, false) 
  680. 				--bink_play(M21_cutscenes.mission_intro)				 
  681. 			end 
  682. 		end 
  683. 	end 
  684. 	 
  685. 	mission_start_fade_in() 
  686. 	 
  687. 	-- Run the mission from the current checkpoint 
  688. 	m21_run(m21_checkpoint) 
  689. end 
  690.  
  691. -- This is the primary function responsible for cleaning up the entire mission 
  692. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  693. -- 
  694. function m21_cleanup() 
  695. 	city_zone_swap("m21", false) 
  696.  
  697. 	player_can_sprint(true) -- allow sprinting once again 
  698. 	party_use_melee_weapons_only(false) 
  699. 	 
  700. 	m21_cleanup_defend_the_ring() 
  701. 	m21_cleanup_defend_angel() 
  702. 	m21_cleanup_goto_angel() 
  703. 	m21_cleanup_enter_the_ring() 
  704. 	 
  705. 	-- end any conversations 
  706. 	m21_cleanup_conversations() 
  707. 	persona_suppress_ambient_lines(DISABLE) 
  708. 	 
  709. 	-- Cleanup callbacks 
  710. 	on_mount("", M21_characters.killbane)  
  711. 	on_dismount("", M21_characters.killbane) 
  712. 	on_take_damage("", M21_characters.killbane) 
  713. 	on_revived("", M21_characters.killbane) 
  714. 	on_death("", M21_characters.angel) 
  715. 	on_qte_animation_trigger("") 
  716. 	 
  717. 	on_take_damage("", LOCAL_PLAYER) 
  718. 	on_weapon_pickup("", LOCAL_PLAYER) 
  719. 	if (coop_is_active() == true) then 
  720. 		on_take_damage("", REMOTE_PLAYER) 
  721. 		on_weapon_pickup("", REMOTE_PLAYER) 
  722. 	end 
  723. 	 
  724. 	for i, enemy in pairs(M21_groups.fight_club_phase_reinforcements.members) do 
  725. 		-- Assign enemy callbacks, add markers 
  726. 		if (character_exists(enemy)) then 
  727. 			on_death("", enemy) 
  728. 		end 
  729. 		 
  730. 	end 
  731. 	 
  732. 	-- cleanup groups 
  733. 	m21_cleanup_groups(M21_groups) 
  734. 	 
  735. 	hud_bar_off(GSI_ANGEL_HEALTH_INDEX) 
  736. 	objective_text_clear(GSI_OBJECTIVE_INDEX) 
  737. 	m21_helper_hide_hud(false) 
  738. 	 
  739. 	-- Kill all alive threads 
  740. 	m21_cleanup_threads(M21_threads) 
  741. 	 
  742. 	-- clean up triggers 
  743. 	m21_cleanup_triggers(M21_triggers) 
  744.  
  745. 	qte_cleanup() 
  746. 	boss_battle_kb_enable(DISABLE) 
  747. 	boss_battle_kb_enable_crowd_props(DISABLE) 
  748. 	 
  749. 	-- Stop all the audio emitters 
  750. 	for i, emitter in pairs(M22_audio_emitters) do 
  751. 		audio_ambient_emitter_stop(emitter) 
  752. 	end 
  753. 	 
  754. 	--customization_item_revert() 
  755. 	customization_item_revert() 
  756. 	 
  757. 	-- Restore the HUD 
  758. 	for i, hud_state in pairs(M21_hud_states) do 
  759. 		if (hud_state ~= -1) then 
  760. 			hud_display_remove_state(hud_state) 
  761. 			hud_state = -1 
  762. 		end 
  763. 	end 
  764. 	 
  765. 	-- Remove always combat ready flag for Luchadores 
  766. 	set_force_combat_ready_team("") 
  767. 	 
  768. 	--Clean-up stuff for the players 
  769. 	character_set_always_combat_ready(LOCAL_PLAYER, false) 
  770. 	hud_prompt_clear(LOCAL_PLAYER) 
  771. 	 
  772. 	human_riding_trigger_end(LOCAL_PLAYER) 
  773. 	 
  774. 	player_movement_enable(LOCAL_PLAYER) 
  775. 	player_actions_enable(LOCAL_PLAYER)	 
  776. 	 
  777. 	inv_item_remove_in_slot("single_use", LOCAL_PLAYER) 
  778. 	 
  779. 	-- Add back any permenant melee weapons 
  780. 	if local_melee_weapon ~= "none" then 
  781. 		inv_item_add(local_melee_weapon, 1, LOCAL_PLAYER) 
  782. 	end 
  783. 	inv_weapon_remove_temporary(LOCAL_PLAYER, "chainsaw") -- Remove temp chainsaw 
  784. 	set_players_can_be_downed(LOCAL_PLAYER, ENABLE) 
  785. 	clear_animation_state(LOCAL_PLAYER) 
  786. 	character_disable_human_downed_interactions(LOCAL_PLAYER, false) 
  787. 	 
  788. 	if (coop_is_active() == true) then 
  789. 		character_set_always_combat_ready(REMOTE_PLAYER, false) 
  790. 		hud_prompt_clear(REMOTE_PLAYER) 
  791. 		 
  792. 		human_riding_trigger_end(REMOTE_PLAYER) 
  793. 		 
  794. 		player_movement_enable(REMOTE_PLAYER) 
  795. 		player_actions_enable(REMOTE_PLAYER)	 
  796. 		 
  797. 		inv_item_remove_in_slot("single_use", REMOTE_PLAYER) 
  798.  
  799. 		-- Add back any permenant melee weapons 
  800. 		if remote_melee_weapon ~= "none" then 
  801. 			inv_item_add(remote_melee_weapon, 1, REMOTE_PLAYER) 
  802. 		end 
  803. 		inv_weapon_remove_temporary(REMOTE_PLAYER, "chainsaw") 
  804. 		set_players_can_be_downed(REMOTE_PLAYER, ENABLE)		 
  805. 		clear_animation_state(REMOTE_PLAYER) 
  806. 		character_disable_human_downed_interactions(REMOTE_PLAYER, false) 
  807. 	end	 
  808.  
  809. 	-- Clean-up any continuous spawning 
  810. 	continuous_spawn_stop(M21_groups.coop_cont_spawn_01.name, true) 
  811. 	continuous_spawn_stop(M21_groups.coop_cont_spawn_02.name, true) 
  812. 	 
  813. 	npc_drop_grenades(true) 
  814. 	 
  815. 	-- Turn peds, vehicles, and action nodes back on 
  816. 	spawning_pedestrians(true) 
  817. 	spawning_vehicles(true) 
  818. 	action_nodes_enable(true) 
  819. 	 
  820. 	-- Remove the callback for the player choice sequence 
  821. 	on_m21_player_choice("") 
  822. end 
  823.  
  824. -- Called when the mission has ended with success 
  825. -- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++) 
  826. -- 
  827. function m21_success() 
  828. 	--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]-- 
  829. 	if (player_unmasked_killbane == true) then 
  830. 		game_choice_set_state( MISSION_21_CHOICE, M21_CHOICE_KILLBANE_UNMASKED ) 
  831. 	else 
  832. 		game_choice_set_state( MISSION_21_CHOICE, M21_CHOICE_KILLBANE_NOT_UNMASKED ) 
  833. 	end 
  834. end 
  835.  
  836.  
  837. -- ************************* 
  838. -- 
  839. -- Local functions 
  840. -- 
  841. -- ************************* 
  842.  
  843. -- Initialize the mission for the specified checkpoint 
  844. -- 
  845. -- checkpoint:		Checkpoint to initialize the mission to 
  846. -- 
  847. function m21_initialize(checkpoint) 
  848. 	-- Set the mission author 
  849. 	set_mission_author("John Karczewski") 
  850.  
  851. 	-- Common initialization 
  852. 	m21_initialize_common() 
  853.  
  854. 	-- Checkpoint specific initialization 
  855. 	m21_initialize_checkpoint(checkpoint) 
  856. end 
  857.  
  858. -- Handle any common initialization 
  859. -- 
  860. function m21_initialize_common() 
  861. 	-- Turn on the audio emitter to adjust the room tone 
  862. 	audio_ambient_emitter_start(M22_audio_emitters.room_tone) 
  863.  
  864. 	-- Dismiss the players' party 
  865. 	party_dismiss_all() 
  866.  
  867. 	-- Put the players' wrestling costumes on 
  868. 	if (character_get_gender(LOCAL_PLAYER) == GENDER_TYPE_MALE) then 
  869. 		customization_outfit_wear("Murderbrawl Wrestling Male", 0, SYNC_LOCAL) 
  870. 	else 
  871. 		customization_outfit_wear("Murderbrawl Wrestling Female", 0, SYNC_LOCAL) 
  872. 	end 
  873. 	if (coop_is_active() == true) then 
  874. 		if (character_get_gender(REMOTE_PLAYER) == GENDER_TYPE_MALE) then 
  875. 			customization_outfit_wear("Murderbrawl Wrestling Male", 0, SYNC_REMOTE) 
  876. 		else 
  877. 			customization_outfit_wear("Murderbrawl Wrestling Female", 0, SYNC_REMOTE) 
  878. 		end 
  879. 	end 
  880. 	 
  881. 	-- Initialize the dialog lines 
  882. 	for i, convo in pairs(M21_conversations) do 
  883. 		convo.is_convo = true 
  884. 		convo.queued = false 
  885. 		convo.started = false 
  886. 		convo.completed = false 
  887. 		convo.ended = false 
  888. 	end 
  889. 	for i, line_group in pairs(M21_dialog_lines) do 
  890. 		for j, line in pairs(line_group) do 
  891. 			line.is_convo = false 
  892. 			line.queued = false 
  893. 			line.started = false 
  894. 			line.completed = false 
  895. 			line.ended = false 
  896. 		end 
  897. 	end 
  898.  
  899. 	-- Spawn Killbane 
  900. 	group_create(M21_groups.killbane.name, true) 
  901. 	set_behavior_set(M21_characters.killbane, "Killbane") 
  902. 	set_ignore_ai_flag(M21_characters.killbane, true) 
  903. 	character_allow_ragdoll(M21_characters.killbane, false) -- Killbane should never ragdoll 
  904. 	 
  905. 	-- Spawn Angel 
  906. 	group_create(M21_groups.angel.name, true) 
  907. 	set_ignore_ai_flag(M21_characters.angel, true) 
  908. 	inv_item_remove_all(M21_characters.angel) -- Make sure Angel has nothing 
  909. 	character_prevent_flinching(M21_characters.angel, true) 
  910. 	character_prevent_bumping(M21_characters.angel, true) 
  911. 	character_allow_ragdoll(M21_characters.angel, false) 
  912. 	set_max_hit_points(M21_characters.angel, get_max_hit_points(M21_characters.angel) * ANGEL_HEALTH_MULTIPLIER, true) 
  913. 	set_dont_attack_me_on_sight_flag(M21_characters.angel, true) 
  914. 	 
  915. 	-- Create the crowd props group 
  916. 	group_create(M21_groups.crowd_props.name, true) 
  917.  
  918. 	-- Do not allow the player to use any weapons but melee 
  919. 	party_use_melee_weapons_only(true) 
  920. 	local_melee_weapon = inv_item_in_slot(LOCAL_PLAYER, "melee") -- if the player has a melee weapon, remove it for the mission 
  921. 	if local_melee_weapon ~= nil then 
  922. 		inv_item_remove(local_melee_weapon, LOCAL_PLAYER) 
  923. 	end 
  924. 	inv_item_equip_slot("unarmed", LOCAL_PLAYER) 
  925. 	 
  926. 	if in_coop then 
  927. 		remote_melee_weapon = inv_item_in_slot(REMOTE_PLAYER, "melee") 
  928. 		if remote_melee_weapon ~= nil then 
  929. 			inv_item_remove(remote_melee_weapon, REMOTE_PLAYER) 
  930. 		end 
  931. 		inv_item_equip_slot("unarmed", REMOTE_PLAYER) 
  932. 	end 
  933. 	 
  934. 	boss_battle_kb_enable(ENABLE) -- Initializes everything, and forces the murderbrawl camera mode 
  935. 	 
  936. 	-- Load the 2d personas 
  937. 	M21_personas.bobby.persona_id = audio_persona_load_2d(M21_personas.bobby.name) 
  938. 	M21_personas.zach.persona_id = audio_persona_load_2d(M21_personas.zach.name) 
  939. 	 
  940. 	persona_suppress_ambient_lines(ENABLE) 
  941. 	 
  942. 	-- Set the cancel mission warp locations 
  943. 	mission_set_cancel_warp_location(M21_navpoints.player_mission_end[1], M21_navpoints.player_mission_end[2]) 
  944. 	 
  945. 	-- Start the conversation thread 
  946. 	M21_threads.process_dialog = thread_new("m21_thread_process_dialog") 
  947. 	 
  948. 	-- Set the Luchadores always combat ready 
  949. 	set_force_combat_ready_team("Luchadores") 
  950. 	 
  951. 	-- Set the player's always combat  
  952. 	character_set_always_combat_ready(LOCAL_PLAYER, true) 
  953. 	if (coop_is_active() == true) then 
  954. 		character_set_always_combat_ready(REMOTE_PLAYER, true) 
  955. 	end 
  956. 	 
  957. 	-- Turn peds, vehicles, and action nodes back on 
  958. 	spawning_pedestrians(false) 
  959. 	spawning_vehicles(false) 
  960. 	action_nodes_enable(false)	 
  961. 	 
  962. 	-- NPCs shouldn't drop grenades 
  963. 	npc_drop_grenades(false) 
  964. end 
  965.  
  966. -- Checkpoint specific initialization 
  967. -- 
  968. -- checkpoint:		The checkpoint to be initialized 
  969. function m21_initialize_checkpoint(checkpoint) 
  970. 	if (checkpoint == M21_checkpoints.start) then 
  971. 		m21_initialize_defend_the_ring() 
  972. 	end 
  973. 	 
  974. 	if checkpoint == M21_checkpoints.defend_angel then 
  975. 		group_create(M21_groups.angel_stompers.name, true) 
  976. 		group_create(M21_groups.chainsaw_wave_01.name, true) 
  977. 	 
  978. 		-- Set up the players at their positions 
  979. 		teleport_coop(M21_navpoints.player_defend_angel_start[1], M21_navpoints.player_defend_angel_start[1], true) 
  980. 		turn_to("#PLAYER1#", M21_navpoints.player_defend_angel_start[1], true) 
  981. 		if (in_coop) then 
  982. 			turn_to("#PLAYER2#", M21_navpoints.player_defend_angel_start[2], true) 
  983. 		end		 
  984. 		 
  985. 		m21_setup_defend_angel(false) 
  986. 	end 
  987. 	 
  988. 	if checkpoint == M21_checkpoints.fight_killbane then 
  989. 		player_in_ring = LOCAL_PLAYER 
  990. 		player_outside_ring = REMOTE_PLAYER 
  991. 	 
  992. 		-- Set up the players at their positions 
  993. 		teleport_coop(M21_navpoints.player_fight_start[1], M21_navpoints.player_fight_start[2], true) 
  994. 		turn_to(LOCAL_PLAYER, M21_navpoints.player_fight_start[1], true) 
  995. 		if (in_coop) then 
  996. 			turn_to(REMOTE_PLAYER, M21_navpoints.player_fight_start[2], true) 
  997. 		end	 
  998. 		 
  999. 		-- Teleport Angel and Killane to their correct locations 
  1000. 		teleport(M21_characters.angel, M21_navpoints.angel_landing_position) 
  1001. 		teleport(M21_characters.killbane, M21_navpoints.killbane_corner) 
  1002. 		thread_yield() 
  1003. 		 
  1004. 		-- The crowd is now with the player, so switch the audio 
  1005. 		audio_object_post_event(M21_audio_events.crowd_with, nil, nil, LOCAL_PLAYER)		 
  1006. 		 
  1007. 		m21_setup_fight_killbane() 
  1008. 	end 
  1009. 	 
  1010. 	if checkpoint == M21_checkpoints.fight_killbane_remote then 
  1011. 		player_in_ring = REMOTE_PLAYER 
  1012. 		player_outside_ring = LOCAL_PLAYER	 
  1013. 	 
  1014. 		-- Set up the players at their positions 
  1015. 		teleport_coop(M21_navpoints.player_fight_start[2], M21_navpoints.player_fight_start[1], true) 
  1016. 		turn_to(LOCAL_PLAYER, M21_navpoints.player_fight_start[2], true) 
  1017. 		if (in_coop) then 
  1018. 			turn_to(REMOTE_PLAYER, M21_navpoints.player_fight_start[1], true) 
  1019. 		end 
  1020. 		 
  1021. 		-- Teleport Angel and Killane to their correct locations 
  1022. 		teleport(M21_characters.angel, M21_navpoints.angel_landing_position) 
  1023. 		teleport(M21_characters.killbane, M21_navpoints.killbane_corner) 
  1024. 		thread_yield() 
  1025. 		 
  1026. 		-- The crowd is now with the player, so switch the audio 
  1027. 		audio_object_post_event(M21_audio_events.crowd_with, nil, nil, LOCAL_PLAYER)		 
  1028. 		 
  1029. 		m21_setup_fight_killbane()		 
  1030. 	end 
  1031. end 
  1032.  
  1033. -- This is the primary function responsible for running the entire mission from start to finish. 
  1034. -- 
  1035. -- first_checkpoint:	The first checkpoint to begin running the mission at 
  1036. -- 
  1037. function m21_run(first_checkpoint) 
  1038. 	local current_checkpoint = first_checkpoint 
  1039.  
  1040. 	-- Run the mission from the beginning 
  1041. 	if (current_checkpoint == M21_checkpoints.start) then 
  1042. 		m21_run_defend_the_ring() 
  1043. 		m21_run_angel_throw_out() 
  1044. 		 
  1045. 		current_checkpoint = M21_checkpoints.defend_angel 
  1046. 		mission_set_checkpoint(current_checkpoint, true) -- ignore vehicles 
  1047. 	end 
  1048. 	 
  1049. 	if (current_checkpoint == M21_checkpoints.defend_angel) then 
  1050. 		m21_run_defend_angel() 
  1051. 		m21_run_goto_angel() 
  1052. 		m21_run_enter_the_ring() 
  1053. 		 
  1054. 		m21_setup_fight_killbane() 
  1055.  
  1056. 		if (player_in_ring == LOCAL_PLAYER) then 
  1057. 			current_checkpoint = M21_checkpoints.fight_killbane 
  1058. 		else 
  1059. 			current_checkpoint = M21_checkpoints.fight_killbane_remote 
  1060. 		end 
  1061. 		mission_set_checkpoint(current_checkpoint, true) -- ignore vehicles 
  1062. 	end 
  1063. 	 
  1064. 	if (current_checkpoint == M21_checkpoints.fight_killbane or current_checkpoint == M21_checkpoints.fight_killbane_remote) then 
  1065. 		m21_fight_killbane() 
  1066. 		m21_killbane_unmask_threat() 
  1067. 		m21_player_choice_sequence() 
  1068. 		 
  1069. 		-- Set the play choice game-size.  We need to do this here in addition to m21_success(), since the  
  1070. 		-- final cinematic needs to know the choice and that gets called before m21_success() 
  1071. 		if (player_unmasked_killbane == true) then 
  1072. 			game_choice_set_state( MISSION_21_CHOICE, M21_CHOICE_KILLBANE_UNMASKED ) 
  1073. 		else 
  1074. 			game_choice_set_state( MISSION_21_CHOICE, M21_CHOICE_KILLBANE_NOT_UNMASKED ) 
  1075. 		end 
  1076. 		 
  1077. 		 -- Play the Z-scene depending on the player's choice 
  1078. 		if(player_unmasked_killbane) then 
  1079. 			mission_set_excluded_reward("M21_Weapon_Killbanes_Gloves") 
  1080. 			m21_player_unmasked_killbane() 
  1081. 		else 
  1082. 			mission_set_excluded_reward("M21_Clothing_Killbanes_Mask") 
  1083. 			m21_player_didnt_unmask_killbane() 
  1084. 		end 
  1085. 	end 
  1086.  
  1087. 	mission_end_success("m21", M21_cutscenes.mission_outro, M21_navpoints.player_mission_end) 
  1088. end 
  1089.  
  1090. function m21_initialize_defend_the_ring() 
  1091. 	-- Load the Ref and set his animation state 
  1092. 	group_create(M21_groups.ref.name, true) 
  1093. 	set_script_animation_state(M21_characters.ref, M21_animation_state.ref_watch) 
  1094. 	npc_combat_enable(M21_characters.ref, false) 
  1095. 	 
  1096. 	-- Load the first set of enemies 
  1097. 	if (coop_is_active() == false) then 
  1098. 		group_create_hidden(M21_groups.wave1.name, true) 
  1099. 	else 
  1100. 		group_create_hidden(M21_groups.wave3.name, true) 
  1101. 	end 
  1102.  
  1103. 	-- Set up the players at their positions 
  1104. 	teleport_coop(M21_navpoints.player_mission_start[1], M21_navpoints.player_mission_start[2], true) 
  1105. 	 
  1106. 	-- Setup Angel 
  1107. 	marker_add(M21_characters.angel, MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND, OI_FLAGS_FULL)  
  1108. 	on_death("m21_angel_died_1", M21_characters.angel)	 
  1109. 	 
  1110. 	-- Start up a thread for processing the Killbane/Angel fight 
  1111. 	M21_threads.Killbane_angel_fight_anim_handle = thread_new("m21_manage_killbane_angel_fight_thread") 
  1112. 	 
  1113. 	-- Start up the threads for processing the Ref AI 
  1114. 	M21_threads.Process_defend_the_ring_handle = thread_new("m21_process_ref_ai_thread")	 
  1115. end 
  1116.  
  1117. -- Main function for the defense of the ring portion of the mission 
  1118. -- 
  1119. function m21_run_defend_the_ring() 
  1120. 	objective_text( GSI_OBJECTIVE_INDEX, "m21_obj_defend_the_ring", "", "", SYNC_ALL, OI_ASSET_DEFEND ) 
  1121. 	hud_bar_on(GSI_ANGEL_HEALTH_INDEX, "health", "", get_max_hit_points(M21_characters.angel), SYNC_ALL) 
  1122. 	hud_bar_set_value(GSI_ANGEL_HEALTH_INDEX, get_current_hit_points(M21_characters.angel)) 
  1123. 	 
  1124. 	-- Start the crowd up 
  1125. 	audio_object_post_event(M21_audio_events.crowd_against, nil, nil, LOCAL_PLAYER) 
  1126. 	 
  1127. 	-- Start a Murderbrawl chant 
  1128. 	audio_object_post_event(M21_audio_events.murderbrawl, nil, nil, LOCAL_PLAYER) 
  1129. 	 
  1130. 	-- Register callbacks so that we know when one of the players' wieldable props is destroyed 
  1131. 	on_wieldable_prop_destroy("m21_player_prop_destroyed_cb", LOCAL_PLAYER) 
  1132. 	if (coop_is_active() == true) then 
  1133. 		on_wieldable_prop_destroy("m21_player_prop_destroyed_cb", REMOTE_PLAYER) 
  1134. 	end 
  1135. 	 
  1136. 	-- Queue up some dialog 
  1137. 	for i, line in pairs(M21_dialog_lines.angel_killbane_commentary) do 
  1138. 		m21_helper_dialog_play(line, M21_CONVO_PLAY_LAST, 0.0) 
  1139. 	end 
  1140. 	 
  1141. 	-- Register a callback so we know when the player picks up a prop 
  1142. 	on_weapon_pickup("m21_player_picked_up_weapon_cb", LOCAL_PLAYER) 
  1143. 	if (coop_is_active() == true) then 
  1144. 		on_weapon_pickup("m21_player_picked_up_weapon_cb", REMOTE_PLAYER) 
  1145. 	end 
  1146. 	 
  1147. 	-- Start prepping the Z-scene we're going to play after this objective 
  1148. 	zscene_prep(M21_cutscenes.angle_thrown_out) 
  1149. 	 
  1150. 	delay(5.0)	-- Wait for the dialog to catch up 
  1151. 	 
  1152. 	-- Start a thread to process Angel's Health 
  1153. 	M21_threads.Killbane_angel_damage_handle = thread_new("m21_manage_killbane_angel_damage_thread", ANGEL_DAMAGE_FROM_KILLBANE_PER_SEC) 
  1154. 	 
  1155. 	-- Start the props 
  1156. 	boss_battle_kb_enable_crowd_props(ENABLE, PHASE_DEFEND_RING)	 
  1157. 	 
  1158. 	-- Process the enemey Luchador waves 
  1159. 	if (coop_is_active() == false) then 
  1160. 		-- Start loading the next wave of enemies 
  1161. 		group_create_hidden(M21_groups.wave2.name) 
  1162. 	 
  1163. 		-- Process the first wave (were already created) 
  1164. 		m21_helper_process_phase1_wave(M21_groups.wave1) 
  1165. 		delay(TIME_BETWEEN_WAVES) 
  1166. 		 
  1167. 		-- Make sure the second wave is ready to go 
  1168. 		while(group_is_loaded(M21_groups.wave2.name) == false) do 
  1169. 			thread_yield() 
  1170. 		end 
  1171. 		 
  1172. 		-- Process the second wave 
  1173. 		m21_helper_process_phase1_wave(M21_groups.wave2) 
  1174. 	else 
  1175. 		-- Start loading the next wave of enemies 
  1176. 		group_create_hidden(M21_groups.wave4.name) 
  1177. 		 
  1178. 		-- Process the first wave (were already created) 
  1179. 		m21_helper_process_phase1_wave(M21_groups.wave3) 
  1180. 		delay(TIME_BETWEEN_WAVES) 
  1181. 		 
  1182. 		-- Make sure the second wave is ready to go 
  1183. 		while(group_is_loaded(M21_groups.wave4.name) == false) do 
  1184. 			thread_yield() 
  1185. 		end 
  1186. 		 
  1187. 		-- Process the second wave 
  1188. 		m21_helper_process_phase1_wave(M21_groups.wave4)		 
  1189. 	end 
  1190. 	 
  1191. 	-- Wait for the current dialog line to finish (up to a max of 12 seconds) 
  1192. 	local elapsed_time = 0.0 
  1193. 	while(thread_check_done(dialog_queue.playing.thread_id) == false) do 
  1194. 		thread_yield() 
  1195. 		elapsed_time = elapsed_time + get_frame_time() 
  1196. 		if (elapsed_time > 12.0) then 
  1197. 			break 
  1198. 		end 
  1199. 	end 
  1200. end 
  1201.  
  1202. -- Clean up the sequence where you defend the ring from guys trying to run and jump in it 
  1203. -- 
  1204. function m21_cleanup_defend_the_ring()	 
  1205. 	thread_kill(M21_threads.Process_defend_the_ring_handle) 
  1206. 	M21_threads.Process_defend_the_ring_handle = INVALID_THREAD_HANDLE 
  1207. 	 
  1208. 	thread_kill(M21_threads.Killbane_angel_fight_anim_handle) 
  1209. 	M21_threads.KILLBANE_ANDLE_FIGHT_ANIM_HANDLE = INVALID_THREAD_HANDLE 
  1210. 	 
  1211. 	thread_kill(M21_threads.Killbane_angel_damage_handle) 
  1212. 	M21_threads.Killbane_angel_damage_handle = INVALID_THREAD_HANDLE 
  1213.  
  1214. 	action_stop_synced_state(M21_characters.angel) 
  1215. 	action_stop_synced_state(M21_characters.killbane) 
  1216. 	 
  1217. 	group_destroy(M21_groups.ref.name) 
  1218. 	 
  1219. 	boss_battle_kb_enable_crowd_props(DISABLE) 
  1220. 	 
  1221. 	-- Remove the weapon pickup callback on the player's 
  1222. 	on_weapon_pickup("", LOCAL_PLAYER) 
  1223. 	if (coop_is_active() == true) then 
  1224. 		on_weapon_pickup("", REMOTE_PLAYER) 
  1225. 	end 
  1226. 	 
  1227. 	-- Remove callbacks for when the players' wieldable prop is destroyed 
  1228. 	on_wieldable_prop_destroy("", LOCAL_PLAYER) 
  1229. 	if (coop_is_active() == true) then 
  1230. 		on_wieldable_prop_destroy("", REMOTE_PLAYER) 
  1231. 	end	 
  1232. 	 
  1233. 	-- Clean-up the waves of enemies 
  1234. 	for i, group in pairs(M21_defend_angel_waves) do 
  1235. 		if (group_is_loaded(group.name) == true) then 
  1236. 			for j, member in pairs(group.members) do 
  1237. 				on_take_damage("", member) 
  1238. 			end 
  1239. 			release_to_world(group.name) 
  1240. 			group_destroy(group.name) 
  1241. 		end 
  1242. 	end 
  1243. end 
  1244.  
  1245. -- Callback for when one of the players' wieldable props is destroyed 
  1246. function m21_player_picked_up_weapon_cb() 
  1247. 	-- Play a crowd boo 
  1248. 	audio_object_post_event(M21_audio_events.boo_short, nil, nil, LOCAL_PLAYER) 
  1249. end 
  1250.  
  1251. -- Handles setting up and processing of one wave during phase 1 
  1252. -- 
  1253. -- group_table 	(string) name of the group for the current wavef 
  1254. function m21_helper_process_phase1_wave(group_table) 
  1255. 	group_show(group_table.name) 
  1256. 	 
  1257. 	-- Setup the distractors 
  1258. 	for i, npc in pairs(group_table.distractors) do 
  1259. 		set_suppress_synced_attacks_flag(npc) 
  1260. 		M21_threads.Ref_distractor_handles[i] = thread_new("m21_manage_distractor_thread", npc, i) 
  1261. 	end 
  1262. 	 
  1263. 	-- Setup the harassers 
  1264. 	for i, npc in pairs(group_table.harassers) do 
  1265. 		set_suppress_synced_attacks_flag(npc) 
  1266. 		ai_add_enemy_target(npc, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE) 
  1267. 	end 
  1268. 	 
  1269. 	-- Start up a thread for making player harassers into ref distractors 
  1270. 	M21_threads.Harasser_processing_handle = thread_new("m21_harasser_processing_thread", group_table) 
  1271. 	 
  1272. 	delay(3.0) 
  1273. 	 
  1274. 	-- Play the effects 
  1275. 	m21_play_arena_entrance_fireworks(group_table) 
  1276. 	 
  1277. 	m21_process_enemy_set(group_table.members) 
  1278. 	 
  1279. 	-- all npcs are dead, clean up threads used to move them in this wave 
  1280. 	for i, npc in pairs(group_table.distractors) do	 
  1281. 		thread_kill(M21_threads.Ref_distractor_handles[i]) 
  1282. 		M21_threads.Ref_distractor_handles[i] = INVALID_THREAD_HANDLE 
  1283. 	end 
  1284. 	 
  1285. 	thread_kill(M21_threads.Harasser_processing_handle) 
  1286. 	M21_threads.Harasser_processing_handle = INVALID_THREAD_HANDLE 
  1287. end 
  1288.  
  1289. -- Directs a single npc to the side of, then onto the ring 
  1290. -- npc_name:		(string) name of the npc directed to distract the ref 
  1291. -- location_number: (int) number designating the location to run to 
  1292.  
  1293. function m21_manage_distractor_thread(npc_name, location_number) 
  1294. 	if (location_number < 1 or location_number > #M21_navpoints.npc_harass_points) then 
  1295. 		return 
  1296. 	end 
  1297. 	 
  1298. 	distractors_on_ring[location_number] = npc_name 
  1299. 	on_take_damage("m21_distractor_hit", npc_name)		 
  1300.  
  1301. 	set_attack_player_flag(npc_name, false) 
  1302. 	character_prevent_bumping(npc_name, true) 
  1303. 	character_prevent_flinching(npc_name, true) 
  1304. 	npc_combat_enable(npc_name, false) 
  1305. 	 
  1306. 	-- Move them to the ring 
  1307. 	local start_nav = M21_navpoints.npc_harass_points[location_number] 
  1308. 	local dest_nav = M21_navpoints.npc_harass_dest_points[location_number] 
  1309. 	ai_do_scripted_move(npc_name, start_nav, true) 
  1310. 	while(ai_scripted_action_is_processing(npc_name) and get_dist(npc_name, start_nav) > 1.25) do 
  1311. 		thread_yield() 
  1312. 	end 
  1313. 	 
  1314. 	if (character_is_dead(npc_name)) then 
  1315. 		distractors_on_ring[location_number] = "" 
  1316. 		return 
  1317. 	end 
  1318. 	if (get_dist(npc_name, start_nav) > 1.5) then 
  1319. 		on_take_damage("", npc_name)			 
  1320. 		set_attack_player_flag(npc_name, true) 
  1321. 		character_prevent_bumping(npc_name, true) 
  1322. 		character_prevent_flinching(npc_name, true) 
  1323. 		npc_combat_enable(npc_name, false)		 
  1324. 		 
  1325. 		distractors_on_ring[location_number] = "" 
  1326. 		return 
  1327. 	end 
  1328. 	 
  1329. 	-- They ignore all AI from here on out 
  1330. 	set_ignore_ai_flag(npc_name, ENABLE)		 
  1331. 	 
  1332. 	-- Turn them to face their target 
  1333. 	inv_item_remove_all(npc_name) 
  1334. 	turn_to(npc_name, start_nav, true) 
  1335.  
  1336. 	-- Play the animation to get up onto the ring - need to disable gravity to prevent fall animation from playing 
  1337. 	human_gravity_enable(npc_name, false) 
  1338. 	character_collision_enable(npc_name, false) 
  1339. 	action_play(npc_name, M21_animations.luchadore_jump_on_ring, "", false, 0.75, true, true, start_nav, dest_nav)  
  1340. 	character_collision_enable(npc_name, true) 
  1341. 	human_gravity_enable(npc_name, true) 
  1342. 	 
  1343. 	if (character_is_dead(npc_name) == false) then 
  1344. 		-- Play the looping distracting animation 
  1345. 		set_script_animation_state(npc_name, M21_animation_state.luchadore_ring_stand) 
  1346. 	 
  1347. 		-- Replace the small object indicator with the full kill indicator 
  1348. 		marker_remove(npc_name) 
  1349. 		marker_add(npc_name, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL) 
  1350. 	end 
  1351. end 
  1352.  
  1353. -- Function to continuously apply damage to Killbane while fighting Angel 
  1354. function m21_manage_killbane_angel_damage_thread(dmg_per_sec) 
  1355. 	while (true) do 
  1356. 		character_damage(M21_characters.angel, dmg_per_sec * get_frame_time()) 
  1357. 		hud_bar_set_value(GSI_ANGEL_HEALTH_INDEX, get_current_hit_points(M21_characters.angel)) 
  1358. 		thread_yield() 
  1359. 	end 
  1360. end 
  1361.  
  1362. -- Continuously plays the fight between killbane and angel 
  1363. function m21_manage_killbane_angel_fight_thread() 
  1364. 	action_play_synced_state(M21_characters.killbane, M21_characters.angel, M21_animations.killbane_angel_grapple) 
  1365. 	 
  1366. 	local wrestling_move_idx = 1 
  1367. 	local cheat_move_idx = 1 
  1368. 	while(true) do 
  1369. 		delay(TIME_BETWEEN_KILLBANE_ANGEL_ACTIONS) 
  1370.  
  1371. 		if (ref_target ~= "") then 
  1372. 			-- Switch to the looping cheating state 
  1373. 			action_play_synced_state(M21_characters.killbane, M21_characters.angel, M21_animations.killbane_angel_cheats[cheat_move_idx].state) 
  1374. 			 
  1375. 			-- Play some dialog telling the player that Killbane is cheating 
  1376. 			m21_helper_play_interrupting_commentary_line(M21_dialog_lines.ref_distracted, true, true, true, 0.0, true) -- allow repeats 
  1377.  
  1378. 			-- Play the setup action to get to the cheating state 
  1379. 			action_play_synced(M21_characters.killbane, M21_characters.angel, M21_animations.killbane_angel_cheats[cheat_move_idx].intro) 
  1380. 			 
  1381. 			-- Loop in the cheating animation state and apply damage until the ref is no longer distracted 
  1382. 			delay(2.0)	-- stay in the cheating state for a minimum of 2 seconds 
  1383. 			while(ref_target ~= "") do 
  1384. 				character_damage(M21_characters.angel, CHEAPSHOT_DAMAGE) 
  1385. 				delay(CHEAPSHOT_INTERVAL) 
  1386. 			end 
  1387. 			 
  1388. 			-- Switch back to the wrestling grabble state 
  1389. 			action_play_synced_state(M21_characters.killbane, M21_characters.angel, M21_animations.killbane_angel_grapple) 
  1390. 			 
  1391. 			-- Play thr outro action to return to the grapple state 
  1392. 			action_play_synced(M21_characters.killbane, M21_characters.angel, M21_animations.killbane_angel_cheats[cheat_move_idx].outro) 
  1393. 			 
  1394. 			-- Move to the next cheat 
  1395. 			cheat_move_idx = cheat_move_idx + 1 
  1396. 			if (cheat_move_idx > #M21_animations.killbane_angel_cheats) then 
  1397. 				cheat_move_idx = 1 
  1398. 			end 
  1399. 		else 
  1400. 			action_play_synced(M21_characters.killbane, M21_characters.angel, M21_animations.killbane_angel_fight[wrestling_move_idx]) 
  1401. 			 
  1402. 			-- Move to the next wrestling move 
  1403. 			wrestling_move_idx = wrestling_move_idx + 1 
  1404. 			if (wrestling_move_idx > #M21_animations.killbane_angel_fight) then 
  1405. 				wrestling_move_idx = 1 
  1406. 			end 
  1407. 		end 
  1408. 	end 
  1409. end 
  1410.  
  1411. function m21_harasser_processing_thread(group_name) 
  1412. 	while true do 
  1413. 		delay(TIME_BETWEEN_HARASSER_TO_DISTRACTOR) -- wait before checking the status of the ring 
  1414. 		 
  1415. 		-- Count the number of active distractors 
  1416. 		local num_distractors = 0 
  1417. 		for i, distractor in pairs(distractors_on_ring) do 
  1418. 			if (distractor ~= "") then 
  1419. 				num_distractors = num_distractors + 1 
  1420. 			end 
  1421. 		end 
  1422. 		 
  1423. 		-- If theres no distractors on the ring, try to send a harasser to the nearest spot on the ring 
  1424. 		if (num_distractors < 2) then 
  1425. 			-- See if there's any guys to promote 
  1426. 			for i, npc_name in pairs(group_name.harassers) do 
  1427. 				if not character_is_dead(npc_name) and character_is_ready(npc_name) then 
  1428. 					-- Make sure they're not already distracting 
  1429. 					local already_distracting = false 
  1430. 					for i, distractor in pairs(distractors_on_ring) do 
  1431. 						if (distractor == npc_name) then 
  1432. 							already_distracting = true 
  1433. 							break 
  1434. 						end 
  1435. 					end 
  1436. 					 
  1437. 					if (already_distracting == false) then 
  1438. 						-- Find the closest distract point 
  1439. 						local closest_idx = m21_closest_distract_point(npc_name) 
  1440. 						if (closest_idx ~= 0) then 
  1441. 						 
  1442. 							-- Clean-up the old thread 
  1443. 							if (thread_check_done(M21_threads.Ref_distractor_handles[closest_idx]) == false) then 
  1444. 								thread_kill(M21_threads.Ref_distractor_handles[closest_idx]) 
  1445. 							end				 
  1446. 						 
  1447. 							set_suppress_synced_attacks_flag(npc_name) 
  1448. 							set_attack_player_flag(npc_name, false) 
  1449. 							M21_threads.Ref_distractor_handles[closest_idx] = thread_new("m21_manage_distractor_thread", npc_name, closest_idx) 
  1450. 							break 
  1451. 						end 
  1452. 					end 
  1453. 				end 
  1454. 			end 
  1455. 		end 
  1456. 	end 
  1457. end 
  1458.  
  1459. -- Plays the Z-Scene of Angel getting thrown out of the ring 
  1460. function m21_run_angel_throw_out() 
  1461. 	zscene_prep(M21_cutscenes.angle_thrown_out) 
  1462. 	while(zscene_is_loaded(M21_cutscenes.angle_thrown_out) == false) do 
  1463. 		thread_yield() 
  1464. 	end 
  1465. 	thread_yield() 
  1466. 	 
  1467. 	audio_object_post_event(M21_audio_events.z02, nil, nil, LOCAL_PLAYER) 
  1468. 	m21_helper_dialog_kill_all() 
  1469. 	cutscene_play(M21_cutscenes.angle_thrown_out, nil, M21_navpoints.player_defend_angel_start, false) 
  1470.  
  1471. 	m21_cleanup_defend_the_ring() 
  1472. 	m21_setup_defend_angel(true) 
  1473. 	mission_start_fade_in() 
  1474. end 
  1475.  
  1476. -- Set up the sequence where you defend Angel from the 40+ guys 
  1477. -- 
  1478. function m21_setup_defend_angel(create_groups) 
  1479. 	if (create_groups == true) then 
  1480. 		group_create(M21_groups.angel_stompers.name, true) 
  1481. 		group_create(M21_groups.chainsaw_wave_01.name, true) 
  1482. 	end 
  1483. 	 
  1484. 	inv_weapon_disable_slot(WEAPON_SLOT_UNARMED, true) 
  1485. 	inv_weapon_add_temporary(LOCAL_PLAYER, "chainsaw", 1, true, true) 
  1486. 	if (in_coop) then 
  1487. 		inv_weapon_add_temporary(REMOTE_PLAYER, "chainsaw", 1, true, true) 
  1488. 	end 
  1489. 	 
  1490. 	-- Teleport Angel and Killbane 
  1491. 	teleport(M21_characters.angel, M21_navpoints.angel_landing_position, true, true, 0.0, 0.0, 0.0, false) 
  1492. 	teleport(M21_characters.killbane, M21_navpoints.killswitch_ring_taunt) 
  1493. 	 
  1494. 	-- Play some appropriate crowd cheers 
  1495. 	audio_object_post_event(M21_audio_events.crowd_chainsaw, nil, nil, LOCAL_PLAYER) 
  1496. 	 
  1497. 	-- The crowd is now with the player, so switch the audio 
  1498. 	audio_object_post_event(M21_audio_events.crowd_with, nil, nil, LOCAL_PLAYER) 
  1499.  
  1500. 	-- Setup Angel 
  1501. 	on_death("m21_angel_died_2", M21_characters.angel) 
  1502. 	marker_add(M21_characters.angel, MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND, OI_FLAGS_FULL)  
  1503. 	npc_leash_to_nav(M21_characters.angel, M21_navpoints.angel_landing_position, 5) 
  1504. 	set_script_animation_state(M21_characters.angel, "M21 angel beat down a") 
  1505. 	set_current_hit_points(M21_characters.angel, get_max_hit_points(M21_characters.angel)) 
  1506. 	set_suppress_synced_attacks_flag(M21_characters.angel, true) 
  1507. 	 
  1508. 	-- Make Angel invulnerable 
  1509. 	turn_invulnerable(M21_characters.angel) 
  1510. 	 
  1511. 	-- Setup Killbane 
  1512. 	set_script_animation_state(M21_characters.killbane, "KillBane Pacing") 
  1513. 	 
  1514. 	thread_yield() 
  1515. 	 
  1516. 	-- Setup the initial stompers 
  1517. 	Chainsaw_luchadors_alive = 0 
  1518. 	m21_helper_setup_chainsaw_group(M21_groups.angel_stompers) 
  1519. 	for i, member in pairs(M21_groups.angel_stompers.members) do 
  1520. 		-- Teleport to the nav (exit vehicle, reset camera, 0.0 X-offset, 0.0 Y-offset, 0.0 Z-offset, don't check for obstacles) 
  1521. 		teleport(member, M21_angel_stomper_locations[i].nav, true, true, 0.0, 0.0, 0.0, false) 
  1522. 		set_suppress_synced_attacks_flag(member) 
  1523. 	 
  1524. 		M21_angel_stomper_locations[i].thread_id = thread_new("m21_process_angel_stomper_thread", member, M21_angel_stomper_locations[i]) 
  1525. 	end	 
  1526. 	 
  1527. 	-- Start up a thread to process the HUD for Angel's health 
  1528. 	M21_threads.Killbane_angel_damage_handle = thread_new("m21_manage_killbane_angel_damage_thread", 0.0) 
  1529. 	 
  1530. 	-- Start up a thread to process the Angel stompers 
  1531. 	M21_threads.angel_stompers_handle = thread_new("m21_process_angel_stompers_thread") 
  1532. 	 
  1533. 	-- Setup the first wave of guys 
  1534. 	m21_helper_setup_chainsaw_group(M21_groups.chainsaw_wave_01)	 
  1535. end 
  1536.  
  1537. -- Main function for the defend angel sequence of the fight 
  1538. -- 
  1539. function m21_run_defend_angel() 
  1540. 	-- Update the objective text 
  1541. 	objective_text( GSI_OBJECTIVE_INDEX, "m21_obj_protect_angel", "", "", SYNC_ALL, OI_ASSET_DEFEND ) 
  1542. 	hud_bar_on(GSI_ANGEL_HEALTH_INDEX, "health", "", get_max_hit_points(M21_characters.angel), SYNC_ALL) 
  1543. 	 
  1544. 	-- Wait a sec, then play some music 
  1545. 	delay(1.0) 
  1546. 	audio_object_post_event(M21_audio_events.music_your_the_best, nil, nil, LOCAL_PLAYER) 
  1547. 	 
  1548. 	-- Queue up some dialog 
  1549. 	delay(1.5) 
  1550. 	for i=#M21_dialog_lines.chainsaw_commentary, 1, -1 do 
  1551. 		m21_helper_dialog_play(M21_dialog_lines.chainsaw_commentary[i], M21_CONVO_PLAY_NEXT, 0.0) 
  1552. 	end 
  1553. 	 
  1554. 	-- Do some fireworks 
  1555. 	m21_play_arena_entrance_fireworks() 
  1556. 	 
  1557. 	-- Wait until all there are only 5 guys remaining 
  1558. 	while (Chainsaw_luchadors_alive > 5) do 
  1559. 		thread_yield() 
  1560. 	end	 
  1561. 	 
  1562. 	-- Spawn the second wave of guys 
  1563. 	group_create(M21_groups.chainsaw_wave_02.name) 
  1564. 	m21_helper_setup_chainsaw_group(M21_groups.chainsaw_wave_02) 
  1565. 	 
  1566. 	-- Do some fireworks 
  1567. 	delay(3.0) 
  1568. 	m21_play_arena_entrance_fireworks() 
  1569. 	 
  1570. 	-- Wait until all there are only 5 guys remaining 
  1571. 	while (Chainsaw_luchadors_alive > 7) do 
  1572. 		thread_yield() 
  1573. 	end	 
  1574. 	 
  1575. 	-- Spawn the third wave of guys 
  1576. 	group_create(M21_groups.chainsaw_wave_03.name) 
  1577. 	m21_helper_setup_chainsaw_group(M21_groups.chainsaw_wave_03) 
  1578. 	 
  1579. 	-- Do some fireworks 
  1580. 	delay(3.0) 
  1581. 	m21_play_arena_entrance_fireworks()	 
  1582. 	 
  1583. 	-- Wait until all there are only 5 guys remaining 
  1584. 	while (Chainsaw_luchadors_alive > 5) do 
  1585. 		thread_yield() 
  1586. 	end	 
  1587. 	 
  1588. 	-- Spawn the fourth wave of guys 
  1589. 	group_create(M21_groups.chainsaw_wave_04.name) 
  1590. 	m21_helper_setup_chainsaw_group(M21_groups.chainsaw_wave_04) 
  1591. 	 
  1592. 	-- Do some fireworks 
  1593. 	delay(3.0) 
  1594. 	m21_play_arena_entrance_fireworks()	 
  1595. 	 
  1596. 	-- Wait until everyone has been killed 
  1597. 	while (Chainsaw_luchadors_alive > 0) do 
  1598. 		thread_yield() 
  1599. 	end 
  1600.  
  1601. 	-- MLG (07/13/11): Design wants the "You're the best" music to play out 
  1602. 	--[[ 
  1603. 	-- Wait a sec and the stop the music (if it's still playing) 
  1604. 	delay(1.5) 
  1605. 	audio_object_post_event(M21_audio_events.music_your_the_best_stop, nil, nil, LOCAL_PLAYER) 
  1606. 	--]] 
  1607.  
  1608. 	m21_cleanup_defend_angel() 
  1609. end 
  1610.  
  1611. function m21_cleanup_defend_angel() 
  1612. 	hud_bar_off(GSI_ANGEL_HEALTH_INDEX) 
  1613. 	marker_remove(M21_characters.angel) 
  1614. 	 
  1615. 	inv_weapon_disable_slot(WEAPON_SLOT_UNARMED, false) 
  1616. 	 
  1617. 	for i, member in pairs(M21_groups.angel_stompers.members) do 
  1618. 		on_death("", member) 
  1619. 		on_detection("", member) 
  1620. 	end 
  1621. 	for i, member in pairs(M21_groups.chainsaw_wave_01.members) do 
  1622. 		on_death("", member) 
  1623. 	end 
  1624. 	for i, member in pairs(M21_groups.chainsaw_wave_02.members) do 
  1625. 		on_death("", member) 
  1626. 	end 
  1627. 	 
  1628. 	release_to_world(M21_groups.angel_stompers.name) 
  1629. 	release_to_world(M21_groups.chainsaw_wave_01.name) 
  1630. 	release_to_world(M21_groups.chainsaw_wave_02.name) 
  1631. 	group_destroy(M21_groups.angel_stompers.name) 
  1632. 	group_destroy(M21_groups.chainsaw_wave_01.name) 
  1633. 	group_destroy(M21_groups.chainsaw_wave_02.name) 
  1634. 	 
  1635. 	thread_kill(M21_threads.angel_stompers_handle) 
  1636. 	M21_threads.angel_stompers_handle = INVALID_THREAD_HANDLE 
  1637. 	 
  1638. 	for i, stomp_location in pairs(M21_angel_stomper_locations) do 
  1639. 		if (stomp_location.occupant ~= "") then 
  1640. 			set_script_animation_state(stomp_location.occupant, nil) 
  1641. 		end 
  1642. 		thread_kill(stomp_location.thread_id) 
  1643. 		stomp_location.thread_id = INVALID_THREAD_HANDLE 
  1644. 	end 
  1645. 	 
  1646. 	m21_helper_cleanup_chainsaw_group(M21_groups.chainsaw_wave_01) 
  1647. 	m21_helper_cleanup_chainsaw_group(M21_groups.chainsaw_wave_02) 
  1648. 	m21_helper_cleanup_chainsaw_group(M21_groups.chainsaw_wave_03) 
  1649. 	m21_helper_cleanup_chainsaw_group(M21_groups.chainsaw_wave_04) 
  1650. end 
  1651.  
  1652. function m21_helper_setup_chainsaw_group(group_table) 
  1653. 	group_show(group_table.name) 
  1654. 	for i, member in pairs(group_table.members) do 
  1655. 		on_death("m21_chainsaw_luchador_killed_cb", member) 
  1656. 		marker_add(member, MINIMAP_ICON_KILL, OI_ASSET_KILL) 
  1657. 		set_suppress_synced_attacks_flag(member) 
  1658. 		ai_add_enemy_target(member, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true) 
  1659. 		 
  1660. 		M21_pontential_stomper_list[#M21_pontential_stomper_list + 1] = member 
  1661. 		Chainsaw_luchadors_alive = Chainsaw_luchadors_alive + 1 
  1662. 	end 
  1663. end 
  1664.  
  1665. function m21_helper_cleanup_chainsaw_group(group_table) 
  1666. 	for i, member in pairs(group_table.members) do 
  1667. 		on_death("", member) 
  1668. 	end 
  1669. end 
  1670.  
  1671. -- Thread to process a Luchador running over to stomp on Angel some 
  1672. -- 
  1673. -- human_name:		Name of the Luchador 
  1674. -- location_table:	Lua table defining the stomp location 
  1675. function m21_process_angel_stomper_thread(human_name, location_table) 
  1676. 	set_ignore_ai_flag(human_name, true) 
  1677. 	 
  1678. 	-- Remove this guy from the potential stomper list 
  1679. 	for i, member in pairs(M21_pontential_stomper_list) do 
  1680. 		if (member == human_name) then 
  1681. 			M21_pontential_stomper_list[i] = "" 
  1682. 			break 
  1683. 		end 
  1684. 	end 
  1685. 	 
  1686. 	-- Store the occupant with this human 
  1687. 	location_table.occupant = human_name 
  1688. 	 
  1689. 	-- Move to the navpoint 
  1690. 	if (m21_move_script_npc_to(human_name, location_table.nav, true, false) == false) then 
  1691. 		set_ignore_ai_flag(human_name, false) 
  1692. 		location_table.occupant = "" 
  1693. 		return 
  1694. 	end 
  1695. 	 
  1696. 	-- They made it, turn off bumping and flinching 
  1697. 	character_prevent_bumping(human_name, true) 
  1698. 	character_prevent_flinching(human_name, true) 
  1699. 	turn_to(human_name, location_table.nav, true) -- use the navpoints orientation 
  1700.  
  1701. 	-- Play the animation		 
  1702. 	set_script_animation_state(human_name, location_table.anim) 
  1703. 	 
  1704. 	-- Spin until the character has died or has moved away from the navpoint 
  1705. 	while(true) do 
  1706. 		local is_dead = character_is_dead(human_name) 
  1707. 		if (is_dead == true or get_dist(human_name, location_table.nav) > 0.5) then 
  1708. 			set_ignore_ai_flag(human_name, false) 
  1709. 			set_script_animation_state(human_name, nil) 
  1710. 			character_prevent_bumping(human_name, false) 
  1711. 			character_prevent_flinching(human_name, false) 
  1712. 			location_table.occupant = "" 
  1713. 			 
  1714. 			if (is_dead == false) then 
  1715. 				-- Try again 
  1716. 				location_table.occupant = human_name 
  1717. 				location_table.thread_id = thread_new("m21_process_angel_stomper_thread", human_name, location_table) 
  1718. 			end			 
  1719. 			 
  1720. 			return 
  1721. 		end 
  1722.  
  1723. 		thread_yield() 
  1724. 	end 
  1725. end 
  1726.  
  1727. -- Process the Luchador Angel stompers 
  1728. function m21_process_angel_stompers_thread() 
  1729. 	-- Loop forever (we'll be killed when it's time to stop) 
  1730. 	while(true) do 
  1731. 		-- Determine how many Luchadors are stomping on Angel 
  1732. 		local num_stompers = 0 
  1733. 		local num_active_stompers = 0 
  1734. 		local free_stomp_locations = { } 
  1735. 		for i, stomp_location in pairs(M21_angel_stomper_locations) do 
  1736. 			if (stomp_location.occupant ~= "") then 
  1737. 				num_stompers = num_stompers + 1 
  1738. 				if (check_script_animation_state(stomp_location.occupant, stomp_location.anim) == true) then 
  1739. 					num_active_stompers = num_active_stompers + 1 
  1740. 				end 
  1741. 			else  
  1742. 				free_stomp_locations[#free_stomp_locations + 1] = stomp_location 
  1743. 			end 
  1744. 		end 
  1745. 		 
  1746. 		-- Do we need to recruit a new stomper? 
  1747. 		if (num_stompers < NUM_STOMPERS_TO_MAINTAIN) then 
  1748. 			-- Find the best chainsaw guy that is alive to recruit for some stompin 
  1749. 			local best_guy = nil 
  1750. 			local best_dist = 1000000 
  1751. 			for i, member in pairs(M21_pontential_stomper_list) do 
  1752. 				if (member ~= "" and character_is_dead(member) == false) then 
  1753. 					local dist = get_dist(member, M21_characters.angel) 
  1754. 					if (dist < best_dist) then 
  1755. 						best_guy = member 
  1756. 						best_dist = dist 
  1757. 					end 
  1758. 				end 
  1759. 			end 
  1760. 			 
  1761. 			-- If we found a guy, recruit him 
  1762. 			if (best_guy ~= nil) then 
  1763. 				local stomp_location = free_stomp_locations[rand_int(1, #free_stomp_locations)] 
  1764. 				stomp_location.thread_id = thread_new("m21_process_angel_stomper_thread", best_guy, stomp_location) 
  1765. 			end 
  1766. 		end 
  1767. 		 
  1768. 		if (num_active_stompers > 0) then 
  1769. 			if (check_script_animation_state(M21_characters.angel, "M21 angel beat down a") == false) then 
  1770. 				set_script_animation_state(M21_characters.angel, "M21 angel beat down a") 
  1771. 			end 
  1772. 		else 
  1773. 			if (check_script_animation_state(M21_characters.angel, "M24 Suffering") == false) then 
  1774. 				set_script_animation_state(M21_characters.angel, "M24 Suffering") 
  1775. 			end 
  1776. 		end 
  1777. 			 
  1778. 		 
  1779. 		-- Apply damage to Angel based on how many stompers are still stomping 
  1780. 		local damage_to_apply = num_active_stompers * ANGEL_DAMAGE_FROM_STOMPER_PER_SEC * get_frame_time() 
  1781. 		character_damage(M21_characters.angel, damage_to_apply) 
  1782. 		 
  1783. 		thread_yield() 
  1784. 	end 
  1785. end 
  1786.  
  1787.  
  1788. -- Callback when one of the Luchadors stomping on angle is killed 
  1789. -- 
  1790. -- victim:		Name of the Luchador that was killed 
  1791. -- attacker:	Name of the person that attacked the luchador 
  1792. function m21_chainsaw_luchador_killed_cb(victim, attacker) 
  1793. 	-- Remove the makrer and on-death callback 
  1794. 	marker_remove(victim) 
  1795. 	on_death("", victim) 
  1796.  
  1797. 	-- Maybe play some commentary 
  1798. 	if (rand_int(1, 3) == 1) then 
  1799. 		m21_helper_play_interrupting_commentary_line(M21_dialog_lines.chainsaw_kills, false) -- don't repeat lines 
  1800. 	end 
  1801. 	 
  1802. 	-- Remove this guy from the stomper list 
  1803. 	for i, member in pairs(M21_pontential_stomper_list) do 
  1804. 		if (member == victim) then 
  1805. 			M21_pontential_stomper_list[i] = "" 
  1806. 			break 
  1807. 		end 
  1808. 	end 
  1809. 	 
  1810. 	-- Update the number of chainsaw luchadors still alive 
  1811. 	Chainsaw_luchadors_alive = Chainsaw_luchadors_alive - 1 
  1812. end 
  1813.  
  1814. -- Callback when one of the Luchadors stomping on angel detects a player 
  1815. -- 
  1816. -- enemy:		Name of the Luchador that detected the player 
  1817. -- player:		Name of the player that was detected 
  1818. function m21_luchador_stomper_detect_player_cb(enemy, player) 
  1819. 	-- Register the player as an Enemy 
  1820. 	ai_add_enemy_target(enemy, player, ATTACK_NOW_NEVER_LOSE) 
  1821.  
  1822. 	-- Remove the callback 
  1823. 	on_detection("", enemy) 
  1824. end 
  1825.  
  1826.  
  1827. -- Player needs to goto angel and check up on him 
  1828. function m21_run_goto_angel() 
  1829. 	-- Update the objective text 
  1830. 	objective_text(GSI_OBJECTIVE_INDEX, "m21_obj_go_to_angel", "", "", SYNC_ALL, OI_ASSET_LOCATION) 
  1831. 	 
  1832. 	on_death("m21_angel_died_1", M21_characters.angel) 
  1833.  
  1834. 	-- Set up trigger and marker for player to goto angel to talk 
  1835. 	marker_add_trigger(M21_triggers.player_reached_angel, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  1836. 	 
  1837. 	-- Add a small delay, since the player is likely already standing right next to angel 
  1838. 	delay(2.0) 
  1839. 	 
  1840. 	-- Enable the trigger 
  1841. 	on_trigger("m21_player_reached_angel", M21_triggers.player_reached_angel) 
  1842. 	trigger_enable(M21_triggers.player_reached_angel, ENABLE) 
  1843. 	 
  1844. 	-- Wait for the player to reach Angel 
  1845. 	player_reached_angel = false 
  1846. 	while(not player_reached_angel) do 
  1847. 		thread_yield() 
  1848. 	end 
  1849. 	 
  1850. 	-- Play the main event starting conversation, followed by the commentary 
  1851. 	m21_helper_dialog_kill_all() 
  1852. 	m21_helper_dialog_play(M21_conversations.player_killbane_fight, M21_CONVO_PLAY_IMMEDIATE, 0.0) 
  1853.  
  1854. 	-- Wait for the announcers to finish talking (up to 25 seconds) 
  1855. 	local elapsed_time = 0.0 
  1856. 	while(m21_helper_dialog_check_done(M21_conversations.player_killbane_fight) == false) do 
  1857. 		thread_yield() 
  1858. 		elapsed_time = elapsed_time + get_frame_time() 
  1859. 		if (elapsed_time > 12.0) then 
  1860. 			break 
  1861. 		end 
  1862. 	end 
  1863. 	 
  1864. 	m21_cleanup_goto_angel() 
  1865. end 
  1866.  
  1867. -- Cleanup goto angel objective 
  1868. function m21_cleanup_goto_angel() 
  1869. 	marker_remove_trigger(M21_triggers.player_reached_angel) 
  1870.  
  1871. 	inv_weapon_remove_temporary("#player1#", "chainsaw") 
  1872. 	if (in_coop) then 
  1873. 		inv_weapon_remove_temporary("#player2#", "chainsaw") 
  1874. 	end 
  1875. 	 
  1876. 	camera_end_look_through(false)	 
  1877. end 
  1878.  
  1879. -- Do what needs to be done to get the player into the ring and 
  1880. -- ready to fight Killbane 
  1881. --  
  1882. function m21_run_enter_the_ring() 
  1883. 	-- Update the objective text 
  1884. 	objective_text(GSI_OBJECTIVE_INDEX, "m21_obj_enter_the_ring", "", "", SYNC_ALL, OI_ASSET_LOCATION) 
  1885. 	 
  1886. 	-- Stop throwing the props  
  1887. 	boss_battle_kb_enable_crowd_props(DISABLE, PHASE_FIGHT_KILLBANE)	 
  1888.  
  1889. 	-- Enable the trigger to enter the ring 
  1890. 	trigger_enable(M21_triggers.player_enter_ring, ENABLE) 
  1891. 	on_trigger("m21_player_enter_ring", M21_triggers.player_enter_ring) 
  1892. 	marker_add_trigger(M21_triggers.player_enter_ring, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL) 
  1893. 	 
  1894. 	-- Wait until the player has entered the ring 
  1895. 	while(Player_entered_ring == false) do 
  1896. 		thread_yield() 
  1897. 	end 
  1898. 	 
  1899. 	-- Set a safe respawn point if the player can't get up from a ragdoll (so they don't spawn on the wrong side of the ropes) 
  1900. 	character_ragdoll_set_last_valid_position(LOCAL_PLAYER, M21_navpoints.player_fight_start[1], true) 
  1901. 	character_ragdoll_set_last_valid_position(LOCAL_PLAYER, M21_navpoints.player_fight_start_alt[1], false) 
  1902. 	if (coop_is_active() == true) then 
  1903. 		character_ragdoll_set_last_valid_position(REMOTE_PLAYER, M21_navpoints.player_fight_start[2]) 
  1904. 		character_ragdoll_set_last_valid_position(REMOTE_PLAYER, M21_navpoints.player_fight_start_alt[2], false) 
  1905. 	end	 
  1906. 	 
  1907. 	-- Turn Killbane to face the player 
  1908. 	set_script_animation_state(M21_characters.killbane, nil) 
  1909. 	thread_yield() 
  1910. 	thread_yield() 
  1911. 	turn_to_do(M21_characters.killbane, player_in_ring) 
  1912.  
  1913. 	-- Hide the HUD 
  1914. 	m21_helper_hide_hud(true) 
  1915. 	 
  1916. 	-- Move the player into the ring 
  1917. 	player_movement_disable(player_in_ring) 
  1918. 	player_actions_disable(player_in_ring) 
  1919. 	 
  1920. 	inv_item_remove_in_slot("single_use", player_in_ring) 
  1921. 	 
  1922. 	move_to(player_in_ring, M21_navpoints.player_enter_ring, 1) 
  1923. 	turn_to_do(player_in_ring, M21_navpoints.player_enter_ring, true) -- turn to face angle 
  1924. 	 
  1925. 	-- Start some dialog 
  1926. 	m21_helper_dialog_kill_all() 
  1927. 	m21_helper_dialog_play(M21_conversations.player_killbane_banter, M21_CONVO_PLAY_IMMEDIATE, 0.0, player_in_ring) 
  1928.  
  1929. 	-- Play the enter animation 
  1930. 	human_gravity_enable(player_in_ring, false) 
  1931. 	character_collision_enable(player_in_ring, false) 
  1932. 	action_play(player_in_ring, M21_animations.luchadore_enter_ring, "", false, 0.6, true, true, M21_navpoints.player_enter_ring, M21_navpoints.player_over_ropes_dest) 
  1933. 	human_gravity_enable(player_in_ring, true) 
  1934. 	character_collision_enable(player_in_ring, true) 
  1935. 	 
  1936. 	player_movement_enable(player_in_ring) 
  1937. 	player_actions_enable(player_in_ring) 
  1938. 	 
  1939. 	-- Re-enable the HUD 
  1940. 	m21_helper_hide_hud(false) 
  1941. 	 
  1942. 	m21_cleanup_enter_the_ring() 
  1943. end 
  1944.  
  1945. -- Cleanup entering the ring 
  1946. function m21_cleanup_enter_the_ring() 
  1947. 	-- NOTHING TO DO HERE YET 
  1948. end 
  1949.  
  1950. -- All the required setup before the boss fight starts 
  1951. function m21_setup_fight_killbane() 
  1952. 	-- Set a safe respawn point if the player can't get up from a ragdoll (so they don't spawn on the wrong side of the ropes) 
  1953. 	character_ragdoll_set_last_valid_position(LOCAL_PLAYER, M21_navpoints.player_fight_start[1], true) 
  1954. 	character_ragdoll_set_last_valid_position(LOCAL_PLAYER, M21_navpoints.player_fight_start_alt[1], false) 
  1955. 	if (coop_is_active() == true) then 
  1956. 		character_ragdoll_set_last_valid_position(REMOTE_PLAYER, M21_navpoints.player_fight_start[2], true) 
  1957. 		character_ragdoll_set_last_valid_position(REMOTE_PLAYER, M21_navpoints.player_fight_start_alt[2], false) 
  1958. 	end 
  1959.  
  1960. 	-- Set Angel into his animation state 
  1961. 	npc_leash_to_nav(M21_characters.angel, M21_navpoints.angel_landing_position, 5) 
  1962. 	set_script_animation_state(M21_characters.angel, "M24 Suffering")		 
  1963.  
  1964. 	-- Setup Killbane 
  1965. 	set_ignore_ai_flag(M21_characters.killbane, false) 
  1966. 	set_attack_player_flag(M21_characters.killbane, true) 
  1967. end 
  1968.  
  1969. -- Main function for the Killbane battle 
  1970. -- The Killswitch, additional reinforcements, and success are handled here 
  1971. -- 
  1972. function m21_fight_killbane() 
  1973. 	-- Update the objective text 
  1974. 	objective_text( GSI_OBJECTIVE_INDEX, "m21_obj_fight_killbane", "", "", SYNC_ALL, OI_ASSET_KILL ) 
  1975. 	 
  1976. 	-- Kick off a thread to process mission critical characters and enforce they are where the out to be 
  1977. 	Killbane_should_be_in_ring = true 
  1978. 	M21_threads.enforce_character_locations = thread_new("m21_thread_enforce_character_locations") 
  1979. 	 
  1980. 	-- Make Angel invulnerable 
  1981. 	turn_invulnerable(M21_characters.angel) 
  1982. 	 
  1983. 	-- Hide the HUD 
  1984. 	m21_helper_hide_hud(true) 
  1985. 	 
  1986. 	-- Player can't sprint 
  1987. 	player_can_sprint(false) 
  1988. 	 
  1989. 	-- Setup for coop 
  1990. 	if in_coop then 
  1991. 		-- Players can't be downed in coop 
  1992. 		set_players_can_be_downed(LOCAL_PLAYER, DISABLE) 
  1993. 		set_players_can_be_downed(REMOTE_PLAYER, DISABLE) 
  1994. 		 
  1995. 		continuous_spawn_start(M21_groups.coop_cont_spawn_01.name, 0, 5.0) 
  1996. 		continuous_spawn_start(M21_groups.coop_cont_spawn_02.name, 0, 5.0) 
  1997. 		 
  1998. 		character_disable_human_downed_interactions(player_outside_ring, true) 
  1999. 	end 
  2000.  
  2001. 	-- Initialize the turnbuckle triggers to the correct callback 
  2002. 	for i, trigger in pairs(M21_triggers.beatup_killbane) do 
  2003. 		on_trigger("m21_killbane_beatup_callback", trigger) 
  2004. 	end 
  2005. 	 
  2006. 	m21_helper_setup_killbane_ring_fighting() 
  2007.  
  2008. 	-- Register callbacks for when Killbane is mounted and dismounter 
  2009. 	on_mount("m21_killbane_mounted_callback", M21_characters.killbane)  
  2010. 	on_dismount("m21_killbane_dismounted_callback", M21_characters.killbane) 
  2011. 	 
  2012. 	-- Register a callback for when the player is damaged 
  2013. 	on_take_damage("m21_player_damaged_in_ring_cb", player_in_ring) 
  2014. 	on_weapon_pickup("m21_player_got_prop_in_ring_cb", player_in_ring) 
  2015. 	 
  2016. 	on_trigger("m21_cb_tag_partner_inside_ring", M21_triggers.tag_trigger_inside) 
  2017. 	on_trigger("m21_cb_tag_partner_outside_ring", M21_triggers.tag_trigger_outside) 
  2018. 	m21_enable_coop_tag_triggers(ENABLE) 
  2019. 	 
  2020. 	-- Play the main event starting conversation, followed by the commentary 
  2021. 	for i, line in pairs(M21_dialog_lines.player_killbane_commentary) do 
  2022. 		m21_helper_dialog_play(line, M21_CONVO_PLAY_LAST, 0.0) 
  2023. 	end 
  2024. 	 
  2025. 	-- Start prepping the next Z-scene 
  2026. 	zscene_prep(M21_cutscenes.unmask_threat) 
  2027. 	 
  2028. 	-- Start throwing the props 
  2029. 	if (M21_conversations.player_killbane_banter.started == true) then 
  2030. 		while(m21_helper_dialog_check_done(M21_conversations.player_killbane_banter) == false) do 
  2031. 			thread_yield() 
  2032. 		end 
  2033. 	else 
  2034. 		delay(3.0) 
  2035. 	end 
  2036. 	 
  2037. 	boss_battle_kb_enable_crowd_props(ENABLE, PHASE_FIGHT_KILLBANE) 
  2038. 	 
  2039. 	-- Process the killbane fight 
  2040. 	killbane_wave = 1 
  2041. 	while (not player_win) do	 
  2042. 		if (not fight_club_phase) then 
  2043. 			if (num_times_killbane_hit_by_weapon >= NUM_WEAPON_HITS_FOR_FINISHER) then 
  2044. 				on_take_damage("", M21_characters.killbane) -- turn of the callback for the QTE, or it will count 
  2045. 				 
  2046. 				-- Crowd cheers 
  2047. 				--audio_object_post_event(M21_audio_events.crowd_cheer_low, nil, nil, LOCAL_PLAYER) 
  2048. 				 
  2049. 				if (killbane_wave == 3) then 
  2050. 					-- If this is the final Killswitch, kill the Killbane/player taunt 
  2051. 					if (dialog_queue.playing.dialog_table.name == M21_conversations.killbane_player_taunt.name) then 
  2052. 						m21_helper_dialog_cleanup_playing() 
  2053. 					end 
  2054. 				end 
  2055. 				 
  2056. 				-- Play some dialog for Killbane's tell for the incoming Killswitch 
  2057. 				m21_helper_play_interrupting_commentary_line(M21_dialog_lines.killswitch_tell, true, false, false, 10.0, true) -- allow repeat lines for this 
  2058. 				 
  2059. 				--delay(1.0) 
  2060. 				 
  2061. 				-- Drop all their weapons 
  2062. 				inv_item_remove_in_slot( "single_use", player_in_ring ) 
  2063. 				 
  2064. 				-- Register a callback so we know when to play the commentary lines 
  2065. 				on_qte_animation_trigger("m21_killswitch_intermediary_cb") 
  2066. 				 
  2067. 				-- Do the Killswitch 
  2068. 				perform_killswitch(M21_characters.killbane, player_in_ring) 
  2069. 				num_times_killbane_hit_by_weapon = 0 
  2070. 			end 
  2071. 			 
  2072. 			if (in_coop) then  
  2073. 			end 
  2074. 		end 
  2075. 		thread_yield() 
  2076. 	end 
  2077. 	 
  2078. 	-- Stop the props 
  2079. 	boss_battle_kb_enable_crowd_props(DISABLE) 
  2080. end 
  2081.  
  2082. -- Cutscene that happens after the player chokes out Killbane in which the  
  2083. -- player threatens to demask him 
  2084. -- 
  2085. function m21_killbane_unmask_threat() 
  2086. 	--m21_helper_set_player_headlock_anim(player_in_ring) 
  2087. 	 
  2088. 	-- Kill the thread enforcing everybody is where they need to be (don't want it messing with the cutscenes) 
  2089. 	if (thread_check_done(M21_threads.enforce_character_locations) == false) then 
  2090. 		thread_kill(M21_threads.enforce_character_locations) 
  2091. 	end 
  2092. 	 
  2093. 	-- Clear the HUD prompts for both players 
  2094. 	hud_prompt_clear(LOCAL_PLAYER) 
  2095. 	if (coop_is_active() == true) then 
  2096. 		hud_prompt_clear(REMOTE_PLAYER) 
  2097. 	end 
  2098. 	 
  2099. 	-- Remove the callbacks for the tag in/out triggers 
  2100. 	on_trigger("", M21_triggers.tag_trigger_inside) 
  2101. 	on_trigger("", M21_triggers.tag_trigger_outside)	 
  2102.  
  2103. 	zscene_prep(M21_cutscenes.unmask_threat) 
  2104. 	while(zscene_is_loaded(M21_cutscenes.unmask_threat) == false) do 
  2105. 		thread_yield() 
  2106. 	end 
  2107. 	thread_yield() 
  2108. 	 
  2109. 	local teleport_navs = { } 
  2110. 	if (player_in_ring == LOCAL_PLAYER) then 
  2111. 		teleport_navs[1] = M21_navpoints.killswitch_ring_taunt 
  2112. 		teleport_navs[2] = M21_navpoints.player_outside_ring 
  2113. 	else 
  2114. 		teleport_navs[1] = M21_navpoints.player_outside_ring 
  2115. 		teleport_navs[2] = M21_navpoints.killswitch_ring_taunt 
  2116. 	end 
  2117. 	 
  2118. 	cutscene_play(M21_cutscenes.unmask_threat, nil, teleport_navs, false) 
  2119. 	thread_yield() 
  2120. 	 
  2121. 	teleport(M21_characters.killbane, M21_navpoints.killswitch_ring_taunt) 
  2122. 	 
  2123. 	set_ignore_ai_flag(M21_characters.killbane, true) 
  2124. 	character_allow_ragdoll(M21_characters.killbane, false) -- Killbane should never ragdoll 
  2125. 	 
  2126. 	player_movement_disable(player_in_ring) 
  2127. 	player_actions_disable(player_in_ring) 
  2128. 	 
  2129. 	m21_helper_hide_hud(true) 
  2130. 	 
  2131. 	m21_helper_set_player_headlock_anim(player_in_ring) 
  2132. 	delay(0.2) 
  2133. 	 
  2134. 	fade_in(0.1) 
  2135. 	fade_in_block() 
  2136. end 
  2137.  
  2138. -- Blocking function which waits for the choice callback to let us know the  
  2139. -- player made a choice 
  2140. -- 
  2141. function m21_player_choice_sequence() 
  2142. 	-- Start a Murderbrawl chant 
  2143. 	audio_object_post_event(M21_audio_events.we_want_blood, nil, nil, LOCAL_PLAYER) 
  2144.  
  2145. 	delay(1.0) -- minor delay 
  2146. 	 
  2147. 	-- Push the selection screen 
  2148. 	Play_choice_selection = -1 
  2149. 	on_m21_player_choice("m21_player_made_choice_cb") 
  2150. 	hud_push_screen("msn_killbane", sync_from_player(player_in_ring)) 
  2151. 	thread_yield() 
  2152. 	 
  2153. 	while(Play_choice_selection == -1) do 
  2154. 		thread_yield() 
  2155. 	end 
  2156. 	 
  2157. 	player_movement_enable(player_in_ring) 
  2158. 	player_actions_enable(player_in_ring) 
  2159. 	 
  2160. 	-- Set the player's choice 
  2161. 	player_unmasked_killbane = false 
  2162. 	if (Play_choice_selection == 1) then 
  2163. 		player_unmasked_killbane = true 
  2164. 	end 
  2165. end 
  2166.  
  2167. -- Callback when a player has made their decision 
  2168. -- 
  2169. -- selection:	(integer) The player choice (0 = unmask Killbane, 1 = leave Killbane's mask) 
  2170. function m21_player_made_choice_cb(selection) 
  2171. 	Play_choice_selection = selection 
  2172. end 
  2173.  
  2174. -- Plays the cutscene where the player unmasked killbane 
  2175. -- 
  2176. function m21_player_unmasked_killbane() 
  2177. 	zscene_prep(M21_cutscenes.remove_mask) 
  2178. 	while(zscene_is_loaded(M21_cutscenes.remove_mask) == false) do 
  2179. 		thread_yield() 
  2180. 	end 
  2181. 	thread_yield() 
  2182.  
  2183. 	audio_object_post_event(M21_audio_events.z03, nil, nil, LOCAL_PLAYER) 
  2184. 	cutscene_play(M21_cutscenes.remove_mask, nil, nil, false) 
  2185. end 
  2186.  
  2187. -- Plays the cutscene where the player didnt unmask killbane 
  2188. -- 
  2189. function m21_player_didnt_unmask_killbane() 
  2190. 	zscene_prep(M21_cutscenes.release_killbane) 
  2191. 	while(zscene_is_loaded(M21_cutscenes.release_killbane) == false) do 
  2192. 		thread_yield() 
  2193. 	end 
  2194. 	thread_yield() 
  2195.  
  2196. 	audio_object_post_event(M21_audio_events.z04, nil, nil, LOCAL_PLAYER) 
  2197. 	cutscene_play(M21_cutscenes.release_killbane, nil, nil, false) 
  2198. end 
  2199.  
  2200. -- *************************************************** 
  2201. -- m21_run Helper Functions 
  2202. -- *************************************************** 
  2203.  
  2204. -- *************************************************** 
  2205. -- m21_initialize Helper Functions 
  2206. -- *************************************************** 
  2207.  
  2208.  
  2209. -- This callback gets called when Killbane first gets ridden. 
  2210. -- It finds the appropriate turnbuckle trigger region and turns it on. 
  2211. function m21_set_killbane_beatup_trigger() 
  2212.  
  2213. 	-- Find the trigger furthest away from the player 
  2214. 	local largest_distance_found = 0 
  2215. 	local furthest_trigger = 0 
  2216.  
  2217. 	for i, trigger in pairs(M21_triggers.beatup_killbane) do 
  2218. 		local distance = get_dist(player_in_ring, trigger) 
  2219. 		if (distance > largest_distance_found) then 
  2220. 			largest_distance_found = distance 
  2221. 			furthest_trigger = i 
  2222. 		end 
  2223. 	end 
  2224. 	 
  2225. 	-- Now we have the furthest trigger, enable it 
  2226. 	enabled_trigger_index = furthest_trigger 
  2227. 	trigger_enable(M21_triggers.beatup_killbane[enabled_trigger_index], ENABLE) 
  2228. 	 
  2229. 	marker_add_trigger(M21_triggers.beatup_killbane[enabled_trigger_index], MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, sync_from_player(player_in_ring)) 
  2230. end 
  2231.  
  2232. -- Remove and clean up the trigger used to tell if the player has reached the corner 
  2233. -- 
  2234. function m21_remove_killbane_beatup_trigger() 
  2235. 	trigger_enable(M21_triggers.beatup_killbane[enabled_trigger_index], DISABLE) 
  2236. 	marker_remove_trigger(M21_triggers.beatup_killbane[enabled_trigger_index], sync_from_player(player_in_ring)) 
  2237. end 
  2238.  
  2239. -- Turns on/off the coop tag triggers, used during riding.. etc 
  2240. function m21_enable_coop_tag_triggers(enable) 
  2241. 	if in_coop then 
  2242. 		if enable then 
  2243. 			if (player_ready_to_tag_in == false) then 
  2244. 				trigger_enable(M21_triggers.tag_trigger_outside, ENABLE) 
  2245. 				ingame_effect_add_trigger(M21_triggers.tag_trigger_outside, INGAME_EFFECT_LOCATION, sync_from_player(player_outside_ring)) 
  2246. 			else 
  2247. 				trigger_enable(M21_triggers.tag_trigger_inside, ENABLE) 
  2248. 				ingame_effect_add_trigger(M21_triggers.tag_trigger_inside, INGAME_EFFECT_LOCATION, sync_from_player(player_in_ring)) 
  2249. 			end 
  2250.  
  2251. 		else 
  2252. 			trigger_enable(M21_triggers.tag_trigger_outside, DISABLE) 
  2253. 			ingame_effect_remove_trigger(M21_triggers.tag_trigger_outside, SYNC_ALL) 
  2254. 			trigger_enable(M21_triggers.tag_trigger_inside, DISABLE) 
  2255. 			ingame_effect_remove_trigger(M21_triggers.tag_trigger_inside, SYNC_ALL) 
  2256. 		end 
  2257. 	end 
  2258. end 
  2259.  
  2260. --  This is called after Killbane has been beat up.  It will spawn the fight club phase npcs and  
  2261. --  have them run into the ring. 
  2262. function m21_spawn_fight_club_phase_npcs() 
  2263. 	objective_text( GSI_OBJECTIVE_INDEX, "m21_obj_kill_luchadores", "", "", SYNC_ALL, OI_ASSET_KILL ) 
  2264. 	group_create( M21_groups.fight_club_phase_reinforcements.name, true ) 
  2265. 	killbane_thug_enemies_to_kill = 0 
  2266. 	for side, enemy in pairs(M21_groups.fight_club_phase_reinforcements.members) do 
  2267. 		if (not character_is_dead(enemy)) then 
  2268. 			-- Assign enemy callbacks, add markers 
  2269. 			on_death("m21_killbane_thug_enemy_killed", enemy) 
  2270. 			set_attack_player_flag(enemy, true) 
  2271. 			set_attack_enemies_flag(enemy, false)  
  2272. 			set_suppress_synced_attacks_flag(enemy) 
  2273. 			M21_threads.Killbane_reinforcements_handles[side] = thread_new("m21_killbane_reinforcements_thread", enemy, side) 
  2274. 			killbane_thug_enemies_to_kill = killbane_thug_enemies_to_kill + 1 
  2275. 		end 
  2276. 	end 
  2277. 	killbane_thug_enemies_living = killbane_thug_enemies_to_kill 
  2278. 	fight_club_phase = true 
  2279. 	 
  2280. 	if (coop_is_active()) then 
  2281. 	end 
  2282. 	 
  2283. 	M21_threads.Killbane_pacing_handle = thread_new("m21_killbane_pacing_thread") 
  2284. 	 
  2285. 	-- Wait a second and play some boos from the crowd 
  2286. 	delay(2.0) 
  2287. 	audio_object_post_event(M21_audio_events.boo_killbane, nil, nil, LOCAL_PLAYER) 
  2288. 	 
  2289. 	-- Do some fireworks 
  2290. 	delay(1.0) 
  2291. 	m21_play_arena_entrance_fireworks()	 
  2292. end 
  2293.  
  2294. -- Cleans up the thugs that join the right after Killbane leaves the ring 
  2295. function m21_cleanup_fight_club_phase_npcs() 
  2296. 	for side, enemy in pairs(M21_groups.fight_club_phase_reinforcements.members) do 
  2297. 		-- Assign enemy callbacks, add markers 
  2298. 		if (character_exists(enemy)) then 
  2299. 			on_death("", enemy) 
  2300. 			release_to_world(enemy) 
  2301. 		end 
  2302. 		 
  2303. 		if (M21_threads.Killbane_reinforcements_handles[side] ~= INVALID_THREAD_HANDLE) then 
  2304. 			thread_kill(M21_threads.Killbane_reinforcements_handles[side]) 
  2305. 			M21_threads.Killbane_reinforcements_handles[side] = INVALID_THREAD_HANDLE 
  2306. 		end 
  2307. 	end 
  2308. 	group_destroy(M21_groups.fight_club_phase_reinforcements.name) 
  2309. end 
  2310.  
  2311. function m21_find_closest_killbane_enter_ring_nav() 
  2312. 	-- Find the closest navpoint 
  2313. 	local closest_nav = M21_navpoints.killbane_enter_ring[1] 
  2314. 	local closest_dist = 9999999 
  2315. 	for i, nav in pairs(M21_navpoints.killbane_enter_ring) do 
  2316. 		local dist = get_dist(nav, M21_characters.killbane) 
  2317. 		if (dist < closest_dist) then 
  2318. 			closest_nav = nav 
  2319. 			closest_dist = dist 
  2320. 		end 
  2321. 	end 
  2322. 	 
  2323. 	return closest_nav 
  2324. end 
  2325.  
  2326. -- Thread to process Killbane getting back into the ring 
  2327. function m21_killbane_back_into_ring_thread() 
  2328. 	ai_clear_scripted_action(M21_characters.killbane) 
  2329. 	set_ignore_ai_flag(M21_characters.killbane, false)	 
  2330. 	 
  2331. 	-- Find the closest navpoint 
  2332. 	local closest_nav = m21_find_closest_killbane_enter_ring_nav() 
  2333. 	 
  2334. 	-- Move into position 
  2335. 	m21_move_script_npc_to(M21_characters.killbane, closest_nav, false, false) 
  2336. 	turn_to(M21_characters.killbane, closest_nav, true) 
  2337. 	 
  2338. 	-- Play the enter animation 
  2339. 	human_gravity_enable(M21_characters.killbane, false) 
  2340. 	character_collision_enable(M21_characters.killbane, false) 
  2341. 	action_play(M21_characters.killbane, M21_animations.killbane_enter_ring, M21_animations.killbane_enter_ring, false, 0.8, false, true, closest_nav)  
  2342. 	human_gravity_enable(M21_characters.killbane, true) 
  2343. 	character_collision_enable(M21_characters.killbane, true) 
  2344. 	 
  2345. 	Killbane_should_be_in_ring = true 
  2346. 	 
  2347. 	-- Setup Killbane now that he's back in the ring 
  2348. 	m21_helper_setup_killbane_ring_fighting() 
  2349. end 
  2350.  
  2351. -- Checks the number of thugs remaining in the fight club phase and handles the transition for when they die 
  2352. function m21_check_for_remaining_thugs() 
  2353. 	if (killbane_thug_enemies_living <= 0) then 
  2354. 		if (fight_club_phase) then 
  2355. 			-- thugs were just killed, bring in killbane and port out player if needed 
  2356. 			fight_club_phase = false 
  2357. 			 
  2358. 			objective_text( GSI_OBJECTIVE_INDEX, "m21_obj_fight_killbane", "", "", SYNC_ALL, OI_ASSET_KILL ) 
  2359. 			 
  2360. 			thread_kill(M21_threads.Killbane_pacing_handle) 
  2361. 			M21_threads.Killbane_pacing_handle = thread_new("m21_killbane_back_into_ring_thread") 
  2362. 			 
  2363. 			-- Stop the pacing animation 
  2364. 			set_script_animation_state(M21_characters.killbane, nil) 
  2365.  
  2366. 			-- Play another conversation 
  2367. 			m21_helper_dialog_play(M21_conversations.killbane_player_taunt, M21_CONVO_PLAY_NEXT, 0.0, player_in_ring) 
  2368. 		end 
  2369. 	end 
  2370. end 
  2371.  
  2372. -- Helper function to move and block until an npc gets to a destination 
  2373. -- 
  2374. -- npc:				(string) name of the npc 
  2375. -- dest:			(string) name of the destination 
  2376. -- run:				(bool, optional) should the npc run? 
  2377. -- move_and_fire:   (bool, optional) should the npc move and fire? 
  2378. -- 
  2379. function m21_move_script_npc_to(npc, dest, run, move_and_fire) 
  2380. 	-- Do the scripted move 
  2381. 	if (ai_do_scripted_move(npc, dest, run, move_and_fire) == false) then 
  2382. 		-- Scripted move failed 
  2383. 		return false 
  2384. 	end 
  2385. 	 
  2386. 	-- Wait for the scripted pathfind to finish process 
  2387. 	while(ai_scripted_action_is_processing(npc) == true) do 
  2388. 		thread_yield() 
  2389. 	end 
  2390. 	 
  2391. 	-- Return if the scripted pathfind succeeded 
  2392. 	return ai_scripted_action_is_complete(npc) 
  2393. end 
  2394.  
  2395. -- Player finished the QTE beatup, start the transition 
  2396. -- 
  2397. function m21_killbane_qte_beatup_finished() 
  2398. 	killbane_wave = killbane_wave + 1 
  2399. 	if (killbane_wave > NUM_KILLBANE_WAVES_TO_WIN) then 
  2400. 		player_win = true 
  2401. 		--m21_helper_set_player_headlock_anim(player_in_ring) 
  2402. 	elseif (killbane_wave == 3) then 
  2403. 		m21_cleanup_fight_club_phase_npcs() -- clean up any previously spawned npcs 
  2404. 		m21_spawn_fight_club_phase_npcs() 
  2405. 	else	 
  2406. 		M21_threads.Killbane_pacing_handle = thread_new("m21_killbane_back_into_ring_thread") 
  2407. 	end 
  2408. end 
  2409.  
  2410. -- *************************************************** 
  2411. -- Miscellaneous m21 Helper Functions 
  2412. -- *************************************************** 
  2413.  
  2414. -- Cleanup all the threads 
  2415. -- 
  2416. function m21_cleanup_threads() 
  2417. 	cleanup_threads(M21_threads) 
  2418. end 
  2419.  
  2420. -- Cleanup all the groups of characters and vehicles 
  2421. --  
  2422.  
  2423. function m21_cleanup_groups() 
  2424. 	cleanup_groups(M21_groups) 
  2425. end 
  2426.  
  2427. function m21_cleanup_triggers(trigger_group) 
  2428. 	for i, trigger in pairs(trigger_group) do 
  2429. 		if (type(trigger) == "table") then 
  2430. 			m21_cleanup_triggers(trigger) 
  2431. 		else		 
  2432. 			m21_clear_trigger(trigger) 
  2433. 		end 
  2434. 	end 
  2435. end 
  2436.  
  2437. function m21_cleanup_conversations() 
  2438. 	-- Kill the conversation thread 
  2439. 	m21_helper_dialog_kill_all() 
  2440. 	if (thread_check_done(M21_threads.process_dialog) == false) then 
  2441. 		thread_kill(M21_threads.process_dialog) 
  2442. 		M21_threads.process_dialog = INVALID_THREAD_HANDLE 
  2443. 	end 
  2444. 	 
  2445. 	audio_persona_remove_2d(M21_personas.bobby.persona_id) 
  2446. 	M21_personas.bobby.persona_id = INVALID_PERSONA_HANDLE 
  2447. 		 
  2448. 	audio_persona_remove_2d(M21_personas.zach.persona_id) 
  2449. 	M21_personas.zach.persona_id = INVALID_PERSONA_HANDLE 
  2450. 	 
  2451. end 
  2452.  
  2453. -- Disable trigger 
  2454. -- 
  2455. -- trigger:			(string) Name of the trigger 
  2456. -- 
  2457. function m21_clear_trigger(trigger) 
  2458. 	on_trigger("", trigger) 
  2459. 	trigger_enable(trigger, false) 
  2460. 	marker_remove_trigger(trigger, SYNC_ALL) 
  2461. end 
  2462.  
  2463. -- Disables a characters callbacks and releases them to the world 
  2464. -- 
  2465. -- npc_name:		(string) name of the character 
  2466. -- 
  2467. function m21_release_harasser_to_world(npc_name) 
  2468. 	on_death("", npc_name) 
  2469. 	on_take_damage("", npc_name) 
  2470. 	if(character_exists(npc_name)) then 
  2471. 		release_to_world(npc_name) 
  2472. 	end 
  2473. end 
  2474.  
  2475. function m21_process_enemy_set(enemy_table) 
  2476. 	enemy_set_setup(enemy_table, false) 
  2477. 	 
  2478. 	while (not Process_enemy_set_cleared) do 
  2479. 		thread_yield() 
  2480. 	end 
  2481. 	 
  2482. 	-- make sure everything is cleaned up 
  2483. 	enemy_set_cleanup(enemy_table) 
  2484. end 
  2485.  
  2486.  
  2487.  
  2488. -- Determines which distracting navpoint the given npc is closest to 
  2489. -- 
  2490. -- npc_name:  (string) name of the npc 
  2491. -- 
  2492. -- returns:		index of the closest distract navpoint 
  2493. function m21_closest_distract_point(npc_name) 
  2494. 	local cur_lowest_dist = 99999999 
  2495. 	local best_navpoint_number = 0 
  2496. 	for i, navpoint in pairs(M21_navpoints.npc_harass_points) do 
  2497. 		if (distractors_on_ring[i] == "") then 
  2498. 			local dist = get_dist(navpoint, npc_name) 
  2499. 			if dist < cur_lowest_dist then 
  2500. 				cur_lowest_dist = dist 
  2501. 				best_navpoint_number = i 
  2502. 			end 
  2503. 		end 
  2504. 	end 
  2505.  
  2506. 	return best_navpoint_number 
  2507. end 
  2508.  
  2509. -- Check if a particular conversation is done (Originally written by Matt Gawalek for Mission 02) 
  2510. -- 
  2511. -- dialog_table:		Conversation Lua table (see M21_conversations) 
  2512. function m21_helper_dialog_check_done(dialog_table) 
  2513. 	if (dialog_table.queued == false and dialog_table.started == false) then 
  2514. 		return true 
  2515. 	else 
  2516. 		return dialog_table.ended 
  2517. 	end 
  2518. end 
  2519.  
  2520. -- Helper to play conversations, by adding them to the cue (Originally written by Matt Gawalek for Mission 02) 
  2521. -- 
  2522. -- dialog_table:	Conversation Lua table (see M21_conversations) 
  2523. -- priority:		Desired priority for the conversation 
  2524. -- delay:			Amonut of time to dalya after this conversation before playing the next conversation (in seconds) 
  2525. -- player:			Player to play the line on if in coop (if player speaks in dialog), or nil to play on the HOST (defaults to nil) 
  2526. function m21_helper_dialog_play(dialog_table, priority, delay, player) 
  2527. 	dialog_table.queued = true 
  2528. 	dialog_table.delay = delay 
  2529. 	dialog_table.player = player 
  2530. 	 
  2531. 	if (priority == M21_CONVO_PLAY_LAST) then 
  2532. 		-- Insert this entry at the end of hte lsit 
  2533. 		dialog_queue.list[dialog_queue.size] = dialog_table 
  2534. 		dialog_queue.size = dialog_queue.size + 1 
  2535. 	elseif (priority == M21_CONVO_PLAY_NEXT) then 
  2536. 		-- Shift the list to the right 
  2537. 		for i = dialog_queue.size - 1, 0, -1 do 
  2538. 			dialog_queue.list[i + 1] = dialog_queue.list[i] 
  2539. 		end 
  2540. 		dialog_queue.list[0] = dialog_table 
  2541. 		dialog_queue.size = dialog_queue.size + 1 
  2542. 	elseif (priority == M21_CONVO_PLAY_IMMEDIATE) then 
  2543. 		-- Stop any actively playing conversations, and start this one immediatly 
  2544. 		m21_helper_dialog_cleanup_playing() 
  2545. 		dialog_queue.playing.thread_id = thread_new("m21_thread_play_dialog", dialog_table) 
  2546. 	end 
  2547. end 
  2548.  
  2549. -- Kill any active dialog, and clear out the dialog queue (Originally written by Matt Gawalek for Mission 02) 
  2550. function m21_helper_dialog_kill_all() 
  2551. 	-- Stop any active conversation 
  2552. 	m21_helper_dialog_cleanup_playing() 
  2553. 	 
  2554. 	-- Clear out the queue 
  2555. 	for i = 0, dialog_queue.size - 1 do 
  2556. 		dialog_queue.list[i].ended = true 
  2557. 	end 
  2558. 	dialog_queue.size = 0 
  2559. end 
  2560.  
  2561. -- Cleanup any playing dialog (Originally written by Matt Gawalek for Mission 02) 
  2562. function m21_helper_dialog_cleanup_playing() 
  2563. 	-- Stop the thread processing a playing dialog 
  2564. 	if (dialog_queue.playing.thread_id ~= INVALID_THREAD_HANDLE) then 
  2565. 		thread_kill(dialog_queue.playing.thread_id) 
  2566. 		dialog_queue.playing.thread_id = INVALID_THREAD_HANDLE 
  2567. 	end 
  2568. 	-- Cleanup any dialog data for a playing dialog 
  2569. 	if (dialog_queue.playing.dialog_handle ~= INVALID_CONVERSATION_HANDLE) then 
  2570. 		if (dialog_queue.playing.dialog_table.is_convo == true) then 
  2571. 			audio_conversation_end(dialog_queue.playing.dialog_handle) 
  2572. 		else 
  2573. 			audio_stop(dialog_queue.playing.dialog_handle) 
  2574. 		end 
  2575. 		dialog_queue.playing.dialog_handle = INVALID_CONVERSATION_HANDLE 
  2576. 	end 
  2577. 	-- Mark the playing dialog as ended 
  2578. 	if (dialog_queue.playing.dialog_table ~= nil) then 
  2579. 		dialog_queue.playing.dialog_table.ended = true 
  2580. 	end 
  2581. end 
  2582.  
  2583. -- Thread to process playing a single converation or dialog line (Originally written by Matt Gawalek for Mission 02) 
  2584. function m21_thread_play_dialog(dialog_table) 
  2585. 	-- Add this conversatin to the playing dialog data 
  2586. 	dialog_queue.playing.dialog_table = dialog_table 
  2587. 	 
  2588. 	dialog_table.started = true	-- it has now started 
  2589. 	dialog_table.queued = false 
  2590. 	 
  2591. 	-- Play the dialog 
  2592. 	if (dialog_table.is_convo == true) then 
  2593. 		-- Load the conversation data 
  2594. 		if (dialog_table.load_direct == false) then 
  2595. 			if (dialog_table.player ~= nil) then 
  2596. 				dialog_queue.playing.dialog_handle = audio_conversation_load_player(dialog_table.name, dialog_table.player) 
  2597. 			else 
  2598. 				dialog_queue.playing.dialog_handle = audio_conversation_load(dialog_table.name) 
  2599. 			end 
  2600. 		else 
  2601. 			dialog_queue.playing.dialog_handle = audio_conversation_load_direct(dialog_table.name) 
  2602. 		end 
  2603. 	 
  2604. 		-- Play the conversation and wait for it to end 
  2605. 		audio_conversation_play(dialog_queue.playing.dialog_handle) 
  2606. 		audio_conversation_wait_for_end(dialog_queue.playing.dialog_handle) 
  2607. 		audio_conversation_end(dialog_queue.playing.dialog_handle) 
  2608. 		 
  2609. 		dialog_queue.playing.dialog_handle = INVALID_CONVERSATION_HANDLE 
  2610. 	else 
  2611. 		-- Find the persona ID for this line 
  2612. 		local persona_id = INVALID_PERSONA_HANDLE 
  2613. 		for i, persona in pairs (M21_personas) do 
  2614. 			if (persona.name == dialog_table.persona) then 
  2615. 				persona_id = persona.persona_id 
  2616. 				break 
  2617. 			end 
  2618. 		end 
  2619.  
  2620. 		if (persona_id ~= INVALID_PERSONA_HANDLE) then 
  2621. 			-- Play the line 
  2622. 			dialog_queue.playing.dialog_handle = audio_play_persona_line_2d(persona_id, dialog_table.name) 
  2623. 		else 
  2624. 			-- Assume the persona listed is an actual character 
  2625. 			dialog_queue.playing.dialog_handle = audio_play_persona_line(dialog_table.persona, dialog_table.name) 
  2626. 		end 
  2627.  
  2628. 		-- Wait for the line to end 
  2629. 		while(audio_is_playing(dialog_queue.playing.dialog_handle) == true) do 
  2630. 			thread_yield() 
  2631. 		end		 
  2632. 	end 
  2633. 	 
  2634. 	delay(0.1) 
  2635. 	delay(dialog_table.delay) 
  2636. 	 
  2637. 	-- Do some book-keeping 
  2638. 	dialog_queue.playing.dialog_handle = INVALID_CONVERSATION_HANDLE 
  2639. 	dialog_table.completed = true 
  2640. 	dialog_table.ended = true 
  2641. end 
  2642.  
  2643. -- Process the dialog queue (should be running the duration of the mission) (Originally written by Matt Gawalek for Mission 02) 
  2644. function m21_thread_process_dialog() 
  2645. 	-- Loop forever 
  2646. 	while(true) do 
  2647. 		-- Wait until something is added to the queue 
  2648. 		while(dialog_queue.size == 0 or thread_check_done(dialog_queue.playing.thread_id) == false) do 
  2649. 			thread_yield() 
  2650. 		end 
  2651. 		 
  2652. 		-- Play the first dialog from the queue, and then remove it from the qeue 
  2653. 		dialog_queue.playing.thread_id = thread_new("m21_thread_play_dialog", dialog_queue.list[0]) 
  2654. 		for i = 1, dialog_queue.size do 
  2655. 			dialog_queue.list[i - 1] = dialog_queue.list[i] 
  2656. 		end 
  2657. 		dialog_queue.size = dialog_queue.size - 1 
  2658. 		 
  2659. 		-- Wait for the active dialog thread to end 
  2660. 		while(thread_check_done(dialog_queue.playing.thread_id) == false) do 
  2661. 			thread_yield() 
  2662. 		end 
  2663. 		dialog_queue.playing.thread_id = INVALID_THREAD_HANDLE 
  2664. 		 
  2665. 		delay(0.2) 
  2666. 	end 
  2667. end 
  2668.  
  2669. function m21_helper_find_commentary_line_variant(dialog_line_group, desired_speaker, allow_repeat) 
  2670. 	local best_line = nil 
  2671. 	local index = rand_int(1, #(dialog_line_group)) 
  2672.  
  2673. 	-- Start looking for a suitable line 
  2674. 	for i=1,#(dialog_line_group) do 
  2675. 		-- Only look at lines that aren't currently queued 
  2676. 		if (dialog_line_group[index].queued == false) then 
  2677. 			-- Look for lines that haven't been played before first 
  2678. 			if (dialog_line_group[index].started == false) then 
  2679. 				best_line = dialog_line_group[index] 
  2680. 				 
  2681. 				-- If this matches the desired speaker, this is as good as it gets 
  2682. 				if (desired_speaker == nil or dialog_line_group[index].persona == desired_speaker) then	 
  2683. 					break 
  2684. 				end 
  2685. 			elseif (allow_repeat == true) then 
  2686. 				-- This is better than no line 
  2687. 				if (best_line == nil) then 
  2688. 					best_line = dialog_line_group[index] 
  2689. 				else 
  2690. 					-- If the previous line has already been played also, check if we match the speaker 
  2691. 					if (best_line.started == true and dialog_line_group[index].persona == desired_speaker) then 
  2692. 						best_line = dialog_line_group[index] 
  2693. 					end 
  2694. 				end 
  2695. 			end 
  2696. 		end 
  2697. 		 
  2698. 		-- Increment the index 
  2699. 		index = index + 1 
  2700. 		if (index > #(dialog_line_group)) then 
  2701. 			index = 1 
  2702. 		end 
  2703. 	end 
  2704. 	 
  2705. 	return best_line 
  2706. end 
  2707.  
  2708. function m21_helper_play_interrupting_commentary_line(dialog_line_group, allow_repeat, break_out, break_in, delay, play_immediate) 
  2709. 	if (allow_repeat == nil) then 
  2710. 		allow_repeat = false 
  2711. 	end 
  2712. 	if (break_out == nil) then 
  2713. 		break_out = true 
  2714. 	end 
  2715. 	if (break_in == nil) then 
  2716. 		break_in = true 
  2717. 	end 
  2718. 	if (delay == nil) then 
  2719. 		delay = 0.0 
  2720. 	end 
  2721. 	if (play_immediate == nil) then 
  2722. 		play_immediate = false 
  2723. 	end 
  2724.  
  2725. 	-- Find a line variant to play 
  2726. 	local line_variant = nil 
  2727. 	local break_out_line = nil 
  2728. 	local break_in_line = nil 
  2729.  
  2730. 	-- Check if there is any dialog currently playing 
  2731. 	if (thread_check_done(dialog_queue.playing.thread_id) == false) then 
  2732. 		-- If the line is part of a conversation or cannot be interrupted, then just return without playing this line 
  2733. 		if (dialog_queue.playing.dialog_table.is_convo == true or dialog_queue.playing.dialog_table.can_interrupt == false) then 
  2734. 			return 
  2735. 		end 
  2736. 		 
  2737. 		-- If we're not playing immediatly, check to see if we can interrupt the next dialog on the queue (this keeps interrupts from piling up) 
  2738. 		if (play_immediate == false and dialog_queue.size ~= 0 and (dialog_queue.list[0].is_convo == true or dialog_queue.list[0].can_interrupt == false)) then 
  2739. 			return 
  2740. 		end 
  2741. 		 
  2742. 		-- We want to play the line on whoever isn't talking 
  2743. 		local speaker_order = { } 
  2744. 		if (dialog_queue.playing.dialog_table.persona == "Zach") then 
  2745. 			-- Try Bobby first, and then Zach 
  2746. 			speaker_order = { "Bobby", "Zach" } 
  2747. 		else 
  2748. 			-- Try Zach first, and then Bobby 
  2749. 			speaker_order = { "Zach", "Bobby" } 
  2750. 		end 
  2751. 		 
  2752. 		-- Try to find some lines to play 
  2753. 		for i, speaker in pairs(speaker_order) do 
  2754. 			-- Try to find lines for Bobby first 
  2755. 			line_variant = m21_helper_find_commentary_line_variant(dialog_line_group, speaker, allow_repeat) 
  2756. 			 
  2757. 			if (break_out == true) then 
  2758. 				break_out_line = m21_helper_find_commentary_line_variant(M21_dialog_lines.commentater_break_out, speaker, true) 
  2759. 			end 
  2760. 			if (break_in == true) then 
  2761. 				break_in_line = m21_helper_find_commentary_line_variant(M21_dialog_lines.commentater_break_in, speaker, true) 
  2762. 			end 
  2763. 			 
  2764. 			-- If we found two suitable lines, then stop looking 
  2765. 			if (line_variant ~= nil and (break_out == false or break_out_line ~= nil) and (break_in == false or break_in_line ~= nil)) then 
  2766. 				break 
  2767. 			end 
  2768. 			 
  2769. 			line_variant = nil 
  2770. 			break_out_line = nil 
  2771. 			break_in_line = nil			 
  2772. 		end 
  2773. 		 
  2774. 		-- If we couldn't find suitable lines, then just return 
  2775. 		if (line_variant == nil or (break_out == true and break_out_line == nil) or (break_in == true and break_in_line == nil)) then 
  2776. 			return 
  2777. 		end 
  2778. 	else 
  2779. 		-- Don't need to worry about interrupting a line, just find a variant to play 
  2780. 		line_variant = m21_helper_find_commentary_line_variant(dialog_line_group, nil, allow_repeat) 
  2781. 	end 
  2782. 	 
  2783. 	if (play_immediate == true) then 
  2784. 		-- Play the break out line if we have one 
  2785. 		if (break_out_line ~= nil) then 
  2786. 			m21_helper_dialog_play(break_out_line, M21_CONVO_PLAY_IMMEDIATE, 0.0) 
  2787. 		end 
  2788. 		 
  2789. 		-- Play the break in line if we have one  
  2790. 		-- (this goes before the actual line varient, since playing next is pushing the line at the front of the queue) 
  2791. 		if (break_in_line ~= nil) then 
  2792. 			m21_helper_dialog_play(break_in_line, M21_CONVO_PLAY_NEXT, delay) 
  2793. 			delay = 0.0 
  2794. 		end 
  2795.  
  2796. 		-- Play the line variant if we have one 
  2797. 		if (line_variant ~= nil) then 
  2798. 			if (break_out == true) then 
  2799. 				m21_helper_dialog_play(line_variant, M21_CONVO_PLAY_NEXT, delay) 
  2800. 			else 
  2801. 				m21_helper_dialog_play(line_variant, M21_CONVO_PLAY_IMMEDIATE, delay) 
  2802. 			end 
  2803. 		end 
  2804. 	else 
  2805. 		-- Play the break in line if we have one  
  2806. 		-- (this goes before the actual line varient, since playing next is pushing the line at the front of the queue) 
  2807. 		if (break_in_line ~= nil) then 
  2808. 			m21_helper_dialog_play(break_in_line, M21_CONVO_PLAY_NEXT, delay) 
  2809. 			delay = 0.0 
  2810. 		end 
  2811.  
  2812. 		-- Play the line variant if we have one 
  2813. 		if (line_variant ~= nil) then 
  2814. 			m21_helper_dialog_play(line_variant, M21_CONVO_PLAY_NEXT, delay) 
  2815. 		end 
  2816. 		 
  2817. 		-- Play the break out line if we have one 
  2818. 		if (break_out_line ~= nil) then 
  2819. 			m21_helper_dialog_play(break_out_line, M21_CONVO_PLAY_NEXT, 0.0) 
  2820. 		end 
  2821. 	end 
  2822. end 
  2823.  
  2824. -- Hide or unhide the hud 
  2825. -- 
  2826. -- hide:	TRUE to hide the HUD, FALSE to unhide it 
  2827. function m21_helper_hide_hud(hide) 
  2828. 	if (hide == true) then 
  2829. 		if (M21_hud_states.hide_hud == -1) then 
  2830. 			M21_hud_states.hide_hud = hud_display_create_state() 
  2831. 			hud_display_set_element(M21_hud_states.hide_hud, HUD_ELEM_MINIMAP, HUD_FADE_HIDDEN) 
  2832. 			hud_display_set_element(M21_hud_states.hide_hud, HUD_ELEM_WEAPONS, HUD_FADE_HIDDEN) 
  2833. 			hud_display_commit_state(M21_hud_states.hide_hud) 
  2834. 		end 
  2835. 	else 
  2836. 		if (M21_hud_states.hide_hud ~= -1) then 
  2837. 			hud_display_remove_state(M21_hud_states.hide_hud) 
  2838. 			M21_hud_states.hide_hud = -1 
  2839. 		end 
  2840. 	end 
  2841. end 
  2842.  
  2843. -- Helper to restore Killbane back to his fighting state in the ring 
  2844. function m21_helper_setup_killbane_ring_fighting() 
  2845. 	ai_clear_scripted_action(M21_characters.killbane) 
  2846. 	set_ignore_ai_flag(M21_characters.killbane, false)	 
  2847. 	ai_add_enemy_target(M21_characters.killbane, player_in_ring, ATTACK_NOW_NEVER_LOSE, true) 
  2848.  
  2849. 	-- Register a callback for when Killbane is damaged 
  2850. 	on_take_damage("m21_killbane_damaged", M21_characters.killbane)	 
  2851. 	on_revived("m21_killbane_revived", M21_characters.killbane) 
  2852. end 
  2853.  
  2854. -- Helper function to set the correct synced animation between the player and Killbane 
  2855. function m21_helper_set_player_headlock_anim(player) 
  2856. 	if (character_get_gender(LOCAL_PLAYER) == GENDER_TYPE_MALE) then 
  2857. 		action_play_synced_state(player_in_ring, M21_characters.killbane, "MB HeadLock") 
  2858. 	else 
  2859. 		action_play_synced_state(player_in_ring, M21_characters.killbane, "MB HeadLock Female") 
  2860. 	end 
  2861. end 
  2862.  
  2863. -- Play the firework VFX at the end of the entry tunnels to the arena 
  2864. function m21_play_arena_entrance_fireworks(group_table) 
  2865. 	if (group_table ~= nil) then 
  2866. 		for i, navpoint in pairs(group_table.effect_navpoints) do 
  2867. 			effect_play(navpoint) 
  2868. 		end 
  2869. 	else  
  2870. 		for i, navpoint in pairs(M21_navpoints.firework_navs) do 
  2871. 			effect_play(navpoint) 
  2872. 		end		 
  2873. 	end 
  2874. end 
  2875.  
  2876. -- ************************* 
  2877. -- 
  2878. -- Callback functions 
  2879. -- 
  2880. -- ************************* 
  2881.  
  2882. -- Thug has died, update the count and check for remaing thugs 
  2883. -- 
  2884. -- enemy:			(string) name of the npc to move 
  2885. -- 
  2886. function m21_killbane_thug_enemy_killed(npc) 
  2887. 	-- Make sure to stop the npc's thread. 
  2888. 	for side, enemy in pairs(M21_groups.fight_club_phase_reinforcements.members) do 
  2889. 		if (npc == enemy) then 
  2890. 			thread_kill(M21_threads.Killbane_reinforcements_handles[side]) 
  2891. 			M21_threads.Killbane_reinforcements_handles[side] = INVALID_THREAD_HANDLE 
  2892. 		end 
  2893. 	end 
  2894.  
  2895. 	killbane_thug_enemies_living = killbane_thug_enemies_living - 1 
  2896. 	m21_check_for_remaining_thugs() 
  2897. end 
  2898.  
  2899. -- Player successfully brought Killbane to a corner 
  2900. -- 
  2901. -- char_name:			(string) name of the player that hit the trigger 
  2902. -- trigger_name:		(string) name of the trigger hit 
  2903. -- 
  2904. function m21_killbane_beatup_callback(char_name, trigger_name) 
  2905. 	if (char_name == player_in_ring) then 
  2906. 		-- Disable the trigger 
  2907. 		m21_remove_killbane_beatup_trigger() 
  2908. 		 
  2909. 		-- Kill the thread processing the player mounted on Killbane 
  2910. 		if (thread_check_done(M21_threads.Killbane_mounted_processing) == false) then 
  2911. 			thread_kill(M21_threads.Killbane_mounted_processing) 
  2912. 			M21_threads.Killbane_mounted_processing = INVALID_THREAD_HANDLE 
  2913. 		end	 
  2914. 		 
  2915. 		-- Move the player and killbane into player 
  2916. 		--player_controls_disable(player_in_ring) 
  2917. 		--move_to(player_in_ring, M21_navpoints.killbane_beatup_trigger_points[enabled_trigger_index], 1, true) 
  2918. 		--player_controls_enable(player_in_ring) 
  2919. 		 
  2920. 		-- Mark the ride as a success, and dismount the player 
  2921. 		M21_killbane_ride_success = true 
  2922. 		human_riding_trigger_end(player_in_ring) 
  2923. 		 
  2924. 		-- Initialize the player and Killbane for the QTE 
  2925. 		character_set_never_fall(player_in_ring, true) 
  2926. 		character_allow_ragdoll(player_in_ring, false) 
  2927. 		character_set_never_fall(M21_characters.killbane, true) 
  2928. 		 
  2929. 		-- Register a callback so we know when to play the commentary lines 
  2930. 		M21_corner_qte_cb_count = 1	-- reset the crowd counting index 
  2931. 		on_qte_animation_trigger("m21_corner_qte_intermediary_cb")		 
  2932. 		 
  2933. 		-- Start the QTE 
  2934. 		Killbane_should_be_in_ring = false	-- disable this now, so we don't try to teleport Killbane back into the ring as he flies out 
  2935. 		local qte_name 
  2936. 		if (killbane_wave == 1) then 
  2937. 			qte_name = "Mission21_CORNERQTE1" 
  2938. 		elseif (killbane_wave == 2) then 
  2939. 			qte_name = "Mission21_CORNERQTE2" 
  2940. 		else 
  2941. 			qte_name = "Mission21_CORNERQTE3" 
  2942. 		end 
  2943. 		qte_start(player_in_ring, qte_name, "m21_corner_qte_complete_cb", M21_characters.killbane, false, M21_navpoints.killbane_beatup_trigger_points[enabled_trigger_index]) 
  2944. 	end 
  2945. end 
  2946.  
  2947. -- Player mounted killbane, enable the corresponding corner trigger 
  2948. -- 
  2949. function m21_killbane_mounted_callback() 
  2950. 	m21_enable_coop_tag_triggers(DISABLE) 
  2951. 	m21_set_killbane_beatup_trigger() 
  2952. 	set_attack_player_flag(M21_characters.killbane, false) 
  2953. 	 
  2954. 	-- Reset the successful ride flag 
  2955. 	M21_killbane_ride_success = false	 
  2956. 	 
  2957. 	-- Start a thread to process the player mounted on Killbane 
  2958. 	M21_threads.Killbane_mounted_processing = thread_new("m21_killbane_mounter_process_thread") 
  2959. 	 
  2960. 	-- Start the crowd cheers for the player riding Killbane 
  2961. 	audio_object_post_event(M21_audio_events.ride_killbane_start, nil, nil, LOCAL_PLAYER) 
  2962. end 
  2963.  
  2964. -- Player was dismounted from Killbane, check to see if they were dismounted early 
  2965. -- 
  2966. function m21_killbane_dismounted_callback() 
  2967. 	-- Kill the thread processing the player mounted on Killbane 
  2968. 	if (thread_check_done(M21_threads.Killbane_mounted_processing) == false) then 
  2969. 		thread_kill(M21_threads.Killbane_mounted_processing) 
  2970. 		M21_threads.Killbane_mounted_processing = INVALID_THREAD_HANDLE 
  2971. 	end 
  2972. 	 
  2973. 	-- Clean-up the corner trigger 
  2974. 	if (M21_killbane_ride_success == false) then 
  2975. 		m21_remove_killbane_beatup_trigger() 
  2976. 	end 
  2977. 	enabled_trigger_index = 0	 
  2978. 	 
  2979. 	-- Stop the crowd cheers for the player riding Killbane 
  2980. 	audio_object_post_event(M21_audio_events.ride_killbane_stop, nil, nil, LOCAL_PLAYER) 
  2981.  
  2982. 	delay(1) -- let the animations blend out 
  2983.  
  2984. 	m21_helper_setup_killbane_ring_fighting() 
  2985. 	 
  2986. 	if (M21_killbane_ride_success == false) then 
  2987. 		-- Play some dissapointed cheers 
  2988. 		audio_object_post_event(M21_audio_events.crowd_disappoint, nil, nil, LOCAL_PLAYER) 
  2989. 	end 
  2990. end 
  2991.  
  2992. -- The player entered the trigger region needed to enter the ring to fight Killbane 
  2993. -- 
  2994. function m21_player_enter_ring(player) 
  2995. 	-- Disable the trigger 
  2996. 	trigger_enable(M21_triggers.player_enter_ring, DISABLE)	 
  2997. 	on_trigger("", M21_triggers.player_enter_ring) 
  2998. 	marker_remove_trigger(M21_triggers.player_enter_ring, SYNC_ALL) 
  2999. 		 
  3000. 	if (player == REMOTE_PLAYER) then 
  3001. 		player_in_ring = REMOTE_PLAYER 
  3002. 		player_outside_ring = LOCAL_PLAYER 
  3003. 	end 
  3004. 	 
  3005. 	Player_entered_ring = true 
  3006. end 
  3007.  
  3008. -- Callback for the ref distractor on_take_damage.  These npcs need to ragdoll and reduce the count of distractors on the ring.  
  3009. -- 
  3010. -- npc_name:		(string) name of the ref distractor that was hit by a player 
  3011. -- 
  3012. function m21_distractor_hit(npc_name) 
  3013. 	on_take_damage("", npc_name) 
  3014. 	 
  3015. 	for i, npc in pairs(distractors_on_ring) do 
  3016. 		if (npc == npc_name) then 
  3017. 			distractors_on_ring[i] = "" 
  3018. 		end 
  3019. 	end 
  3020.  
  3021. 	-- The crowd boos  
  3022. 	audio_object_post_event(M21_audio_events.boo_short, nil, nil, LOCAL_PLAYER)	 
  3023.  
  3024. 	set_script_animation_state(npc_name, nil) 
  3025. 	character_ragdoll(npc_name) 
  3026. 	character_kill(npc_name) 
  3027. end 
  3028.  
  3029. -- Callback for the reinforcements that come in during the Killbane fight 
  3030. -- This allows the player to knock the npcs off while they climb onto the ring 
  3031. -- 
  3032. -- npc_name:	name of the reinforcement 
  3033. -- 
  3034. function m21_killbane_reinforcement_hit(npc_name) 
  3035. 	character_ragdoll(npc_name, LUCHADORE_RAGDOLL_TIME, 5.0) 
  3036. 	human_gravity_enable(npc_name, true) 
  3037. 	character_collision_enable(npc_name, true) 
  3038. 	character_kill(npc_name) 
  3039. 	on_take_damage("",npc_name) 
  3040. end 
  3041.  
  3042. -- Callback for when the player reaches Angel 
  3043. -- 
  3044. function m21_player_reached_angel(player) 
  3045. 	on_trigger("", M21_triggers.player_reached_angel) 
  3046. 	trigger_enable(M21_triggers.player_reached_angel, DISABLE) 
  3047. 	marker_remove(M21_characters.angel) 
  3048. 	 
  3049. 	-- Move the player into position 
  3050. 	player_movement_disable(player) 
  3051. 	player_actions_disable(player) 
  3052. 	 
  3053. 	-- Disable always combat ready and remove the chainsaw 
  3054. 	character_set_always_combat_ready(player, false) 
  3055. 	inv_weapon_remove_temporary(player, "chainsaw")	 
  3056. 	 
  3057. 	--[[ 
  3058. 	move_to(player, M21_navpoints.player_reacherd_angel, 1) 
  3059. 	 
  3060. 	-- Check if they're ready (checks that they aren't dead, ragdolled 
  3061. 	local ready = false 
  3062. 	while(ready == false) do 
  3063. 		thread_yield() 
  3064. 	 
  3065. 		ready = true 
  3066. 		if (character_is_ready(player) == false) then 
  3067. 			ready = false 
  3068. 		end 
  3069. 		if (character_playing_combat_move(player) == true) then 
  3070. 			ready = false 
  3071. 		end 
  3072. 		if (character_is_jumping(player) == true) then 
  3073. 			ready = false 
  3074. 		end	 
  3075. 	end 
  3076.  
  3077. 	-- Change the camera to look at the PC and Angel 
  3078. 	camera_look_through(M21_navpoints.lookat_angel, 0.6) 
  3079.  
  3080. 	crouch_start(player, true)	-- set as scripted crouch 
  3081.  
  3082. 	action_play(player, "crouch", "", false, 0.5, true, true, M21_navpoints.player_reacherd_angel) 
  3083. 	--]] 
  3084.  
  3085. 	-- The crowd starts cheering Angel's name 
  3086. 	audio_object_post_event(M21_audio_events.angel_long, nil, nil, LOCAL_PLAYER) 
  3087. 	 
  3088. 	-- Play the conversation and block until it is complete 
  3089. 	m21_helper_dialog_play(M21_conversations.talk_to_angel, M21_CONVO_PLAY_IMMEDIATE, 0.0, player) 
  3090. 	 
  3091. 	-- Wait for end of the angel conversation 
  3092. 	while (m21_helper_dialog_check_done(M21_conversations.talk_to_angel) == false) do 
  3093. 		thread_yield() 
  3094. 	end 
  3095. 	 
  3096. 	-- Stand the player up and re-enable their controls 
  3097. 	--crouch_stop(player) 
  3098. 	player_movement_enable(player) 
  3099. 	player_actions_enable(player) 
  3100. 	 
  3101. 	-- Return the camera to the player 
  3102. 	camera_end_look_through(false) 
  3103. 	 
  3104. 	-- Make the player always combat ready again 
  3105. 	character_set_always_combat_ready(player, true) 
  3106. 	 
  3107. 	player_reached_angel = true 
  3108. end 
  3109.  
  3110. -- Callback for angel's death during the "defend the ring" portion of the fight 
  3111. -- 
  3112. function m21_angel_died_1() 
  3113. 	m21_cleanup_defend_the_ring() 
  3114. 	mission_end_failure("m21", "m21_obj_angel_died") 
  3115. end 
  3116.  
  3117. -- Callback for angel's death during the "defend angel" portion of the fight 
  3118. -- 
  3119. function m21_angel_died_2() 
  3120. 	m21_cleanup_defend_angel() 
  3121. 	mission_end_failure("m21", "m21_obj_angel_died") 
  3122. end 
  3123.  
  3124. -- Callback when a player picks up a weapon 
  3125. -- 
  3126. function m21_player_picked_up_weapon_cb(player, weapon) 
  3127. 	-- If this is the dildo bat, then play some commentary 
  3128. 	if (weapon == "WP_baseball_bat") then 
  3129. 		m21_helper_dialog_play(M21_conversations.pickup_dildo, M21_CONVO_PLAY_IMMEDIATE, 0.0, player) 
  3130. 	end 
  3131. 	 
  3132. 	-- Remove the weapon pickup callback 
  3133. 	on_weapon_pickup("", LOCAL_PLAYER) 
  3134. 	if (coop_is_active() == true) then 
  3135. 		on_weapon_pickup("", REMOTE_PLAYER) 
  3136. 	end 
  3137. end 
  3138.  
  3139. -- Callback when one of the intermediary triggers is triggered from a QTE animation 
  3140. -- 
  3141. -- node_idx:	Index of the current QTE node 
  3142. function m21_killswitch_intermediary_cb(node_idx) 
  3143. 	if (node_idx == 1) then 
  3144. 		-- The player failed... the Killswitch landed 
  3145. 		local idx = rand_int(1, #M21_dialog_lines.qte_failed) 
  3146. 		m21_helper_dialog_play(M21_dialog_lines.qte_failed[idx], M21_CONVO_PLAY_IMMEDIATE, 0.0) 
  3147. 		--m21_helper_play_interrupting_commentary_line(M21_dialog_lines.qte_failed, true, false, true, 0.0, true) 
  3148. 	elseif (node_idx == 2) then 
  3149. 		-- The player successfully dodged the Killswitch, play some success dialog 
  3150. 		if (M21_conversations.killswitch_blocked_01.started == false) then 
  3151. 			m21_helper_dialog_play(M21_conversations.killswitch_blocked_01, M21_CONVO_PLAY_IMMEDIATE, 0.0) 
  3152. 		elseif (M21_conversations.killswitch_blocked_02.started == false) then 
  3153. 			m21_helper_dialog_play(M21_conversations.killswitch_blocked_02, M21_CONVO_PLAY_IMMEDIATE, 0.0) 
  3154. 		elseif (M21_conversations.killswitch_blocked_03.started == false) then 
  3155. 			m21_helper_dialog_play(M21_conversations.killswitch_blocked_03, M21_CONVO_PLAY_IMMEDIATE, 0.0) 
  3156. 			 
  3157. 			thread_yield() 
  3158. 			M21_conversations.killswitch_blocked_01.started = false 
  3159. 			M21_conversations.killswitch_blocked_02.started = false 
  3160. 			M21_conversations.killswitch_blocked_03.started = false 
  3161. 		end 
  3162. 	end 
  3163. end 
  3164.  
  3165. function m21_killswitch_qte_complete_cb(success) 
  3166. 	-- Remove the callback 
  3167. 	on_qte_animation_trigger("") 
  3168.  
  3169. 	if success then 
  3170. 		-- NOTHING TO DO HERE 
  3171. 	else 
  3172. 		m21_helper_setup_killbane_ring_fighting() 
  3173. 	end 
  3174. end 
  3175.  
  3176. -- Callback when one of the intermediary triggers is triggered from a QTE animation 
  3177. -- 
  3178. -- node_idx:	Index of the current QTE node 
  3179. function m21_corner_qte_intermediary_cb(node_idx) 
  3180. 	-- Play some dialog 
  3181. 	if (killbane_wave == 1) then 
  3182. 		if (node_idx == 0) then 
  3183. 			-- Crowd counts 
  3184. 			audio_object_post_event(M21_audio_events.crowd_count[M21_corner_qte_cb_count], nil, nil, LOCAL_PLAYER) 
  3185. 		elseif (node_idx == 1) then 
  3186. 			if (M21_corner_qte_cb_count == 11) then 
  3187. 				-- Play some success commentary 
  3188. 				for i=#M21_dialog_lines.killbane_back_in_ring_01, 1, -1 do 
  3189. 					m21_helper_dialog_play(M21_dialog_lines.killbane_back_in_ring_01[i], M21_CONVO_PLAY_NEXT, 0.0) 
  3190. 				end			 
  3191. 				m21_helper_dialog_play(M21_dialog_lines.killbane_out_of_ring_01[1], M21_CONVO_PLAY_NEXT, 5.0) 
  3192. 				m21_helper_dialog_play(M21_dialog_lines.commentater_break_out[1], M21_CONVO_PLAY_IMMEDIATE) 
  3193. 			elseif (M21_corner_qte_cb_count == 12) then 
  3194. 				-- Do some fireworks 
  3195. 				m21_play_arena_entrance_fireworks() 
  3196. 			end 
  3197. 		elseif (node_idx == 2) then 
  3198. 			-- Play a failure line 
  3199. 			local idx = rand_int(1, #M21_dialog_lines.qte_failed) 
  3200. 			m21_helper_dialog_play(M21_dialog_lines.qte_failed[idx], M21_CONVO_PLAY_IMMEDIATE, 0.0) 
  3201. 		end 
  3202. 	elseif (killbane_wave == 2) then 
  3203. 		if (node_idx == 1) then 
  3204. 			if (M21_corner_qte_cb_count == 1) then 
  3205. 				-- Player kicked killbane in the nuts 
  3206. 				m21_helper_dialog_play(M21_dialog_lines.exclamation[2], M21_CONVO_PLAY_IMMEDIATE) 
  3207. 			else 
  3208. 				-- Player's getting ready to drop a flying elbow 
  3209. 				m21_helper_dialog_play(M21_dialog_lines.exclamation[3], M21_CONVO_PLAY_IMMEDIATE, 2.0) 
  3210. 			end 
  3211. 		elseif (node_idx == 2) then 
  3212. 			-- Play a failure line 
  3213. 			local idx = rand_int(1, #M21_dialog_lines.qte_failed) 
  3214. 			m21_helper_dialog_play(M21_dialog_lines.qte_failed[idx], M21_CONVO_PLAY_IMMEDIATE, 0.0)	 
  3215. 		elseif (node_idx == 3) then 
  3216. 			if (M21_corner_qte_cb_count == 3) then 
  3217. 				m21_helper_dialog_play(M21_dialog_lines.exclamation[4], M21_CONVO_PLAY_IMMEDIATE, 2.0)						 
  3218. 				m21_helper_dialog_play(M21_dialog_lines.exclamation[5], M21_CONVO_PLAY_NEXT)	 
  3219. 			elseif (M21_corner_qte_cb_count == 4) then 
  3220. 				-- Play some success commentary 
  3221. 				m21_helper_dialog_play(M21_conversations.killbane_out_of_ring_02, M21_CONVO_PLAY_IMMEDIATE) 
  3222. 			else 
  3223. 				-- Do some fireworks 
  3224. 				m21_play_arena_entrance_fireworks() 
  3225. 			end 
  3226. 		end 
  3227. 	elseif (killbane_wave == 3) then 
  3228. 		if (node_idx == 0) then 
  3229. 			-- Crowd counts 
  3230. 			audio_object_post_event(M21_audio_events.crowd_count[M21_corner_qte_cb_count], nil, nil, LOCAL_PLAYER) 
  3231. 		elseif (node_idx == 3) then 
  3232. 			if (M21_corner_qte_cb_count == 5) then 
  3233. 				-- Play some camera flashes 
  3234. 				for i, nav in pairs(M21_navpoints.camera_flash_navs) do 
  3235. 					effect_play(nav) 
  3236. 				end 
  3237. 			elseif (M21_corner_qte_cb_count == 6) then 
  3238. 				-- Do some fireworks 
  3239. 				m21_play_arena_entrance_fireworks() 
  3240. 			else 
  3241. 				-- Player lands the elbow 
  3242. 				m21_helper_dialog_play(M21_dialog_lines.exclamation[1], M21_CONVO_PLAY_IMMEDIATE) 
  3243. 			end 
  3244. 		elseif (node_idx == 2) then 
  3245. 			-- Play a failure line 
  3246. 			m21_helper_play_interrupting_commentary_line(M21_dialog_lines.qte_failed, true) 
  3247. 		end 
  3248. 	end 
  3249. 	 
  3250. 	M21_corner_qte_cb_count = M21_corner_qte_cb_count + 1	 
  3251. end 
  3252.  
  3253. -- Callback for the corner qtes 
  3254. -- 
  3255. -- success:		(bool) true - if the player was successful, false - if they failed 
  3256. function m21_corner_qte_complete_cb(success) 
  3257. 	-- Remove the callback 
  3258. 	on_qte_animation_trigger("") 
  3259. 	 
  3260. 	-- Clear a bunch of flags we set 
  3261. 	character_set_never_fall(player_in_ring, false) 
  3262. 	character_allow_ragdoll(player_in_ring, true) 
  3263. 	character_set_never_fall(M21_characters.killbane, false)	 
  3264.  
  3265. 	if success then 
  3266. 		m21_killbane_qte_beatup_finished() 
  3267. 	else 
  3268. 		 -- Killbane won, set everything back up 
  3269. 		m21_helper_setup_killbane_ring_fighting() 
  3270. 	end 
  3271. 	m21_enable_coop_tag_triggers(ENABLE) 
  3272. end 
  3273.  
  3274. -- Killbane damaged callback 
  3275. -- When Killbane takes damage, figure out what caused it, and restore his hit points 
  3276. -- 
  3277. -- killbane_name:		(string) name of killbane 
  3278. -- attacker_name:		(string) name of the attacker 
  3279. -- percent_health:		(float)  what the attack left killbane at 
  3280. -- explosion:			(bool)	 explosion? 
  3281. -- melee:				(bool) 	 melee attack? 
  3282. -- 
  3283. function m21_killbane_damaged(killbane_name, attacker_name, percent_health, explosion, melee) 
  3284. 	local killbane_hit = false	 
  3285. 	 
  3286. 	if (attacker_name ~= nil) then 	 
  3287. 		if(not melee) then 
  3288. 			-- thrown wieldable prop 
  3289. 			--audio_object_post_event(M21_audio_events.crowd_cheer_mid, nil, nil, LOCAL_PLAYER) 
  3290. 			 
  3291. 			killbane_hit = true 
  3292. 		else 
  3293. 			-- melee weapon hit 
  3294. 			local weapon_name = inv_item_get_equipped_item(attacker_name) 
  3295. 			if (weapon_name ~= nil) then 
  3296. 				killbane_hit = true 
  3297. 			end 
  3298. 		end 
  3299. 	end 
  3300. 	 
  3301. 	if (killbane_hit == true) then 
  3302. 		-- Play a random Killbane flinch animation 
  3303. 		action_play_do(M21_characters.killbane, M21_animations.killbane_flinches[rand_int(1, #M21_animations.killbane_flinches)]) 
  3304. 	 
  3305. 		-- Increment the times hit count 
  3306. 		num_times_killbane_hit_by_weapon = num_times_killbane_hit_by_weapon + 1 
  3307. 	else 
  3308. 		-- If Killbane blocked it, the crowd is shocked 
  3309. 		--audio_object_post_event(M21_audio_events.crowd_shocked, nil, nil, LOCAL_PLAYER) 
  3310. 	end 
  3311. 	 
  3312. 	-- Killbane can't die, refill his hp 
  3313. 	set_current_hit_points(M21_characters.killbane, get_max_hit_points(M21_characters.killbane))  
  3314. end 
  3315.  
  3316. -- Callback when Killbane is revived from the downed state 
  3317. function m21_killbane_revived() 
  3318. 	m21_helper_setup_killbane_ring_fighting() 
  3319. 	turn_invulnerable(M21_characters.killbane) 
  3320. end 
  3321.  
  3322. -- Callback for when the player takes damage while in the ring 
  3323. -- 
  3324. -- player_name:		(string) name of the player damaged 
  3325. -- attacker:		(string) name of the attacker 
  3326. -- damage_amt:		(float) amount of hp remaining after attack 
  3327. -- from_expo:		(boolean) damage came from an explosion 
  3328. -- from_melee:		(boolean) damage came from a melee attack 
  3329. -- 
  3330. function m21_player_damaged_in_ring_cb(player_name, attacker, damage_amt, from_exp, from_melee) 
  3331. 	if (attacker == M21_characters.killbane and from_melee == true) then 
  3332. 		audio_object_post_event(M21_audio_events.boo_short, nil, nil, LOCAL_PLAYER) 
  3333. 	end 
  3334. end 
  3335.  
  3336. -- Callback for when the player picks up a weapon (prop) while in the ring 
  3337. -- 
  3338. -- player_name:		(string) name of the player that picked up the prop 
  3339. function m21_player_got_prop_in_ring_cb(player_name) 
  3340. 	audio_object_post_event(M21_audio_events.crowd_cheer_low, nil, nil, LOCAL_PLAYER) 
  3341. end 
  3342.  
  3343. -- Callback for when a wieldable prop is created 
  3344. -- 
  3345. -- defend_ring:		TRUE if the prop was created outside the ring, FALSE if it was created for inside the ring 
  3346. function m21_wieldable_prop_created_cb(outside_ring) 
  3347. 	if (outside_ring == true) then 
  3348. 		--[[ 
  3349. 		if (rand_int(1, 4) ~= 1) then 
  3350. 			return 
  3351. 		end 
  3352. 	 
  3353. 		m21_helper_play_interrupting_commentary_line(M21_dialog_lines.prop_call_out, false, true, true) 
  3354. 		--]] 
  3355. 	else 
  3356. 		if (--[[M21_prop_called_out == false or --]](thread_check_done(dialog_queue.playing.thread_id) and dialog_queue.size == 0)) then  
  3357. 			M21_prop_called_out = true 
  3358. 			 
  3359. 			m21_helper_play_interrupting_commentary_line(M21_dialog_lines.prop_in_ring, true, true, true, 0.0, true) 
  3360.  
  3361. 			--delay(2.0) 
  3362. 			--audio_play_persona_line(LOCAL_PLAYER, "M21_Should_Pick_Up_Prop") 
  3363. 		end 
  3364. 	end 
  3365. end 
  3366.  
  3367. -- Callback for when the player's prop is destroyed 
  3368. -- 
  3369. -- player_name:		(string) name of the player who's prop was destroyed 
  3370. function m21_player_prop_destroyed_cb(player_name) 
  3371. 	-- Play some dissapointed cheers 
  3372. 	audio_object_post_event(M21_audio_events.crowd_disappoint, nil, nil, LOCAL_PLAYER) 
  3373. end 
  3374.  
  3375. function m21_cb_tag_partner_outside_ring(triggerer, trigger_name) 
  3376. 	if (triggerer == player_outside_ring) then 
  3377. 		-- Disable the trigger 
  3378. 		trigger_enable(M21_triggers.tag_trigger_outside, DISABLE) 
  3379. 		ingame_effect_remove_trigger(M21_triggers.tag_trigger_outside, SYNC_ALL) 
  3380. 		 
  3381. 		-- Clear their inventory 
  3382. 		inv_item_remove_in_slot( "single_use", player_outside_ring ) 
  3383.  
  3384. 		-- Move to the correct place 
  3385. 		player_movement_disable(player_outside_ring) 
  3386. 		player_actions_disable(player_outside_ring) 
  3387. 		turn_to(player_outside_ring, M21_navpoints.player_outside_ring, true) -- turn to face ring 
  3388.  
  3389. 		-- Play the animation to get up onto the ring 
  3390. 		human_gravity_enable(player_outside_ring, false) 
  3391. 		character_collision_enable(player_outside_ring, false) 
  3392. 		set_animation_state(player_outside_ring, "m21_plym_tageTeam_rope_idle") 
  3393. 		action_play(player_outside_ring, M21_animations.player_jump_on_ring, "", false, 0.6, true, true, M21_navpoints.player_outside_ring, M21_navpoints.player_inside_ring_dest)  
  3394. 		 
  3395. 		-- The player is now on the ring 
  3396. 		player_ready_to_tag_in = true 
  3397. 		trigger_enable(M21_triggers.tag_trigger_inside, ENABLE) 
  3398. 		ingame_effect_add_trigger(M21_triggers.tag_trigger_inside, INGAME_EFFECT_LOCATION, sync_from_player(player_in_ring)) 
  3399. 		 
  3400. 		message("M21_HELP_TEXT_WATING_TO_TAG", 5.0, true, sync_from_player(player_outside_ring)) 
  3401. 		hud_prompt(player_outside_ring, "M21_USE_TEXT_LEAVE_RING_SIDE", "m21_cb_player_leaving_ring_side") 
  3402. 	end 
  3403. end 
  3404.  
  3405. -- On_trigger call back for the trigger inside the ring, this will cause a swap of the host and remote players 
  3406. function m21_cb_tag_partner_inside_ring(triggerer, trigger_name) 
  3407. 	if (triggerer == player_in_ring) then 
  3408. 		-- Disable the trigger 
  3409. 		trigger_enable(M21_triggers.tag_trigger_inside, DISABLE) 
  3410. 		ingame_effect_remove_trigger(M21_triggers.tag_trigger_inside, SYNC_ALL) 
  3411. 		 
  3412. 		-- Remove the HUD prompt 
  3413. 		hud_prompt_clear(player_outside_ring) 
  3414. 	 
  3415. 		-- Clear their inventory 
  3416. 		inv_item_remove_in_slot( "single_use", player_in_ring ) 
  3417. 		 
  3418. 		-- Make Killbane not attack the player's 
  3419. 		set_attack_player_flag(M21_characters.killbane, false) 
  3420.  
  3421. 		-- Disable the player's movement in the ring and move them into position 
  3422. 		player_actions_disable(player_in_ring) 
  3423. 		player_movement_disable(player_in_ring) 
  3424. 		 
  3425. 		-- Player that was inside the ring no cannot interact with downed humans 
  3426. 		character_disable_human_downed_interactions(player_in_ring, true) 
  3427.  
  3428. 		turn_to(player_in_ring, M21_navpoints.player_inside_ring, true) -- turn to face outside of the ring 
  3429. 		 
  3430. 		audio_play_persona_line(player_in_ring, "M21_Tag_In_Partner") 
  3431. 		 
  3432. 		-- Disable gravity and collision on the player's so we can force them through the ropes		 
  3433. 		human_gravity_enable(player_outside_ring, false) 
  3434. 		human_gravity_enable(player_in_ring, false) 
  3435. 		character_collision_enable(player_outside_ring, false) 
  3436. 		character_collision_enable(player_in_ring, false) 
  3437. 		character_prevent_bumping(player_outside_ring, true) 
  3438. 		character_prevent_bumping(player_in_ring, true) 
  3439. 		 
  3440. 		delay(0.3) 
  3441. 		 
  3442. 		-- Play the synced tag animation (well not synced really... since they're both players)		 
  3443. 		action_play_non_blocking(player_outside_ring, M21_animations.player_tag_in, "", false, true, true, M21_navpoints.player_inside_ring_dest, M21_navpoints.player_outside_ring_dest) 
  3444. 		action_play_non_blocking(player_in_ring, M21_animations.player_tag_out, "", false, true, true, M21_navpoints.player_inside_ring, M21_navpoints.player_inside_ring_dest) 
  3445. 		 
  3446. 		-- Wait for the animations to finish 
  3447. 		delay(0.5) 
  3448. 		clear_animation_state(player_outside_ring) 
  3449. 		set_animation_state(player_in_ring, "m21_plym_tageTeam_rope_idle")		 
  3450. 		while(action_play_is_finished(REMOTE_PLAYER) == false) do 
  3451. 			thread_yield() 
  3452. 		end 
  3453. 		while(action_play_is_finished(LOCAL_PLAYER) == false) do 
  3454. 			thread_yield() 
  3455. 		end 
  3456. 		 
  3457. 		-- Turn gravity and collision back on 
  3458. 		character_collision_enable(player_outside_ring, true) 
  3459. 		human_gravity_enable(player_outside_ring, true) 
  3460. 		character_prevent_bumping(player_outside_ring, false) 
  3461. 		 
  3462. 		-- Check to make sure the player that was outside the ring made it into the ring correctly 
  3463. 		if (object_is_in_trigger(M21_triggers.ring_trigger, player_outside_ring) == false) then 
  3464. 			teleport(player_outside_ring, M21_navpoints.player_outside_ring_dest) 
  3465. 		end 
  3466. 		if (object_is_in_trigger(M21_triggers.ring_trigger, player_in_ring) == true) then 
  3467. 			teleport(player_in_ring, M21_navpoints.player_inside_ring_dest) 
  3468. 		end 
  3469.  
  3470. 		-- Re-enable the control for the player that was outside the ring 
  3471. 		player_actions_enable(player_outside_ring) 
  3472. 		player_movement_enable(player_outside_ring) 
  3473. 		 
  3474. 		-- Player that was outside of the ring can now interact with downed humans 
  3475. 		character_disable_human_downed_interactions(player_outside_ring, false) 
  3476. 	 
  3477. 		-- Update the callbacks for the player in the ring 
  3478. 		on_take_damage("", player_in_ring) 
  3479. 		on_weapon_pickup("", player_in_ring) 
  3480. 		on_take_damage("m21_player_damaged_in_ring_cb", player_outside_ring) 
  3481. 		on_weapon_pickup("m21_player_got_prop_in_ring_cb", player_outside_ring) 
  3482.  
  3483. 		-- Do the swap 
  3484. 		local swap_buffer = player_outside_ring 
  3485. 		player_outside_ring = player_in_ring 
  3486. 		player_in_ring = swap_buffer 
  3487. 		 
  3488. 		-- Killbane can attack the player in the ring now 
  3489. 		set_attack_player_flag(M21_characters.killbane, true) 
  3490. 		ai_add_enemy_target(M21_characters.killbane, player_in_ring, ATTACK_NOW_NEVER_LOSE, true) 
  3491. 	 
  3492. 		-- Enable the trigger again 
  3493. 		trigger_enable(M21_triggers.tag_trigger_inside, ENABLE) 
  3494. 		ingame_effect_add_trigger(M21_triggers.tag_trigger_inside, INGAME_EFFECT_LOCATION, sync_from_player(player_in_ring)) 
  3495. 		 
  3496. 		-- Tell the player that's now outside the ring what's up 
  3497. 		message("M21_HELP_TEXT_WATING_TO_TAG", 5.0, true, sync_from_player(player_outside_ring)) 
  3498. 		hud_prompt(player_outside_ring, "M21_USE_TEXT_LEAVE_RING_SIDE", "m21_cb_player_leaving_ring_side") 
  3499. 	end 
  3500. end 
  3501.  
  3502. function m21_cb_player_leaving_ring_side() 
  3503. 	-- Remove the HUD prompt 
  3504. 	hud_prompt_clear(player_outside_ring) 
  3505. 	 
  3506. 	-- Disable the trigger inside the ring 
  3507. 	trigger_enable(M21_triggers.tag_trigger_inside, DISABLE) 
  3508. 	ingame_effect_remove_trigger(M21_triggers.tag_trigger_inside, SYNC_ALL)	 
  3509. 	 
  3510. 	-- Clear their animation state 
  3511. 	clear_animation_state(player_outside_ring) 
  3512.  
  3513. 	-- Move off the ring 
  3514. 	--move_to(player_outside_ring, M21_navpoints.player_outside_ring, 1, true) 
  3515.  
  3516. 	-- Turn on gravity and collision gain 
  3517. 	character_collision_enable(player_outside_ring, true) 
  3518. 	human_gravity_enable(player_outside_ring, true) 
  3519.  
  3520. 	-- Re-enable the control for the player outside the ring 
  3521. 	player_actions_enable(player_outside_ring) 
  3522. 	player_movement_enable(player_outside_ring) 
  3523. 	 
  3524. 	-- Enable the trigger outside the ring 
  3525. 	trigger_enable(M21_triggers.tag_trigger_outside, ENABLE) 
  3526. 	ingame_effect_add_trigger(M21_triggers.tag_trigger_outside, INGAME_EFFECT_LOCATION, sync_from_player(player_outside_ring))	 
  3527. end 
  3528.  
  3529. -- ************************* 
  3530. -- 
  3531. -- Thread functions 
  3532. -- 
  3533. -- ************************* 
  3534.  
  3535. -- Direct an npc from a starting entrance into the ring 
  3536. -- 
  3537. -- npc:			(string) name of the npc to move 
  3538. -- side:		(int) 	 which side to enter from, determins which navpoints to use 
  3539. -- 
  3540. function m21_killbane_reinforcements_thread(npc, side) 
  3541. 	set_ignore_ai_flag(npc, true) 
  3542. 	 
  3543. 	-- Move into position 
  3544. 	if (m21_move_script_npc_to(npc, M21_navpoints.npc_harass_points_out_ring[side], true, false) == false) then 
  3545. 		character_kill(npc) 
  3546. 		return 
  3547. 	end 
  3548. 	character_prevent_bumping(npc, true) 
  3549. 	character_prevent_flinching(npc, true) 
  3550.  
  3551. 	-- Don't start entering the ring if the player will block our destination (causes the NPCs to get stuck in the ropes, and other undesirable behaviors) 
  3552. 	local elapsed_time = 0 
  3553. 	while(get_dist(player_in_ring, M21_navpoints.npc_harass_points_in_ring[side]) < 1.0) do 
  3554. 		elapsed_time = elapsed_time + get_frame_time() 
  3555. 		if (elapsed_time > 7.0) then 
  3556. 			break 
  3557. 		end 
  3558. 		thread_yield() 
  3559. 	end 
  3560. 	 
  3561. 	-- Set their last valid ragdoll position to inside the ring 
  3562. 	character_ragdoll_set_last_valid_position(npc, M21_navpoints.npc_harass_points_in_ring[side], true) -- clear out the queue	 
  3563. 	 
  3564. 	-- Start the enter animation 
  3565. 	human_gravity_enable(npc, false) 
  3566. 	character_collision_enable(npc, false) 
  3567. 	action_play(npc, M21_animations.luchadore_enter_ring, M21_animations.luchadore_enter_ring, false, 0.52, true, true, M21_navpoints.npc_harass_points_out_ring[side], M21_navpoints.npc_harass_points_in_ring[side]) 
  3568. 	 
  3569. 	if (get_dist(player_in_ring, M21_navpoints.npc_harass_points_in_ring[side]) < 1.0) then 
  3570. 		character_ragdoll(player_in_ring, 750) 
  3571. 		thread_yield() 
  3572. 	end 
  3573.  
  3574. 	-- Turn gravity and collision back on, and register a callback to kill the player until they are safely in the ring 
  3575. 	on_take_damage("m21_killbane_reinforcement_hit", npc) 
  3576. 	character_collision_enable(npc, true) 
  3577. 	human_gravity_enable(npc, true) 
  3578.  
  3579. 	-- Wait until the animation is far enough along that they are safely within the ring 
  3580. 	while(action_play_is_finished(npc, 0.75) == false) do 
  3581. 		thread_yield() 
  3582. 	end 
  3583. 	 
  3584. 	-- Remove our callback that was forcefully killing the guy 
  3585. 	on_take_damage("", npc)	 
  3586. 	 
  3587. 	delay(0.25) 
  3588. 	 
  3589. 	-- Do a safety check to ensure that the NPC actually made it into the ring 
  3590. 	if (character_is_dead(npc) == false and object_is_in_trigger(M21_triggers.ring_trigger, npc) == false) then 
  3591. 		-- Just teleport them into the ring to make sure that we don't soft lock the mission 
  3592. 		teleport(npc, M21_navpoints.npc_harass_points_in_ring[side]) 
  3593. 		thread_yield() 
  3594. 	end 
  3595. 	 
  3596. 	set_ignore_ai_flag(npc, false) 
  3597. 	character_prevent_flinching(npc, false) 
  3598. 	ai_add_enemy_target(npc, player_in_ring, 2) 
  3599.  
  3600. 	-- Make sure the Luchadore stays in the ring - if they leave kill them to prevent a soft crash 
  3601. 	while(true) do 
  3602. 		if (character_is_dead(npc) == true) then 
  3603. 			return 
  3604. 		elseif (object_is_in_trigger(M21_triggers.ring_trigger, npc) == false) then 
  3605. 			character_kill(npc) 
  3606. 		end 
  3607. 		 
  3608. 		thread_yield() 
  3609. 	end 
  3610. end 
  3611.  
  3612. -- Thread that will move Killbane to different points outside of the ring 
  3613. -- 
  3614. function m21_killbane_pacing_thread() 
  3615. 	local closest_nav = m21_find_closest_killbane_enter_ring_nav() 
  3616.  
  3617. 	-- Move into position 
  3618. 	m21_move_script_npc_to(M21_characters.killbane, closest_nav, false, false)	 
  3619.  
  3620. 	-- Turn off AI, and set Killbane's animation state 
  3621. 	set_ignore_ai_flag(M21_characters.killbane, true) -- turned back off when the thread is killed 
  3622. 	set_script_animation_state(M21_characters.killbane, M21_animations.killbane_pacing) 
  3623. 	 
  3624. 	delay(4.0) 
  3625. 	m21_helper_play_interrupting_commentary_line(M21_dialog_lines.killbane_posturing, true, false, true) 
  3626. end 
  3627.  
  3628. -- Process the ref's AI 
  3629. function m21_process_ref_ai_thread() 
  3630. 	while(true) do 
  3631. 		delay(0.1) 
  3632. 	 
  3633. 		if (ref_target == "") then 
  3634. 			-- Ref doesn't have a target, see if he should 
  3635. 			local distractor_idx = 0 
  3636. 			for i, distractor in pairs(distractors_on_ring) do 
  3637. 				if (distractor ~= "" and character_is_dead(distractor) == false and check_script_animation_state(distractor, M21_animation_state.luchadore_ring_stand)) then 
  3638. 					ref_target = distractor 
  3639. 					distractor_idx = i 
  3640. 					break 
  3641. 				end 
  3642. 			end 
  3643. 			 
  3644. 			-- Do we still not have a taget? 
  3645. 			if (ref_target ~= "") then 
  3646. 				-- Check if the ref needs to move to an intermediary point to avoid running through the fight 
  3647. 				local intermediary_point = 0 
  3648. 				if (ref_location_idx == 1) then 
  3649. 					if (distractor_idx == 2) then 
  3650. 						intermediary_point = 4 
  3651. 					end 
  3652. 				elseif (ref_location_idx == 2) then 
  3653. 					if (distractor_idx == 1) then 
  3654. 						intermediary_point = 3 
  3655. 					end 
  3656. 				elseif (ref_location_idx == 3 or ref_location_idx == 0) then 
  3657. 					if (distractor_idx == 4) then 
  3658. 						intermediary_point = 1 
  3659. 					end					 
  3660. 				elseif (ref_location_idx == 4) then 
  3661. 					if (distractor_idx == 3) then 
  3662. 						intermediary_point = 1 
  3663. 					end 
  3664. 				end 
  3665. 				ref_location_idx = distractor_idx 
  3666. 				 
  3667. 				-- Clear the ref's animation state 
  3668. 				set_script_animation_state(M21_characters.ref, nil) 
  3669.  
  3670. 				-- Move to an intermediary target if necessary 
  3671. 				if (intermediary_point ~= 0 ) then 
  3672. 					-- Move towards the intermediary point 
  3673. 					ai_do_scripted_move(M21_characters.ref, M21_navpoints.ref_points[intermediary_point], true) 
  3674. 					 
  3675. 					while(ai_scripted_action_is_processing(M21_characters.ref) == true and get_dist(M21_characters.ref, M21_navpoints.ref_points[intermediary_point]) > 3.0) do 
  3676. 						thread_yield() 
  3677. 					end 
  3678. 				end 
  3679. 			 
  3680. 				-- Move to go yell at the target 
  3681. 				m21_move_script_npc_to(M21_characters.ref, M21_navpoints.ref_points[distractor_idx], true, true) 
  3682.  
  3683. 				turn_to(M21_characters.ref, M21_navpoints.ref_points[distractor_idx], true)		 
  3684. 				set_script_animation_state(M21_characters.ref, M21_animation_state.ref_distracted) 
  3685. 			else 
  3686. 				if (ref_location_idx ~= 0) then 
  3687. 					set_script_animation_state(M21_characters.ref, nil)	 
  3688.  
  3689. 					if (ref_location_idx == 4) then 
  3690. 						-- Move towards the intermediary point 
  3691. 						ai_do_scripted_move(M21_characters.ref, M21_navpoints.ref_points[2], true) 
  3692. 						while(ai_scripted_action_is_processing(M21_characters.ref) == true and get_dist(M21_characters.ref, M21_navpoints.ref_points[2]) > 3.0) do 
  3693. 							thread_yield() 
  3694. 						end 
  3695. 					end 
  3696. 					 
  3697. 					ref_location_idx = 0 
  3698. 					 
  3699. 					m21_move_script_npc_to(M21_characters.ref, M21_navpoints.ref_standing_point, true, false) 
  3700. 					 
  3701. 					turn_to(M21_characters.ref, M21_characters.killbane) 
  3702. 				end 
  3703. 				set_script_animation_state(M21_characters.ref, M21_animation_state.ref_watch)										 
  3704. 			end 
  3705. 		else 
  3706. 			-- Check to make sure out target is still valid	 
  3707. 			local found = false 
  3708. 			for i, distractor in pairs(distractors_on_ring) do 
  3709. 				if (distractor == ref_target) then 
  3710. 					found = true 
  3711. 				end 
  3712. 			end 
  3713.  
  3714. 			if (found == false) then 
  3715. 				ref_target = "" 
  3716. 			end 
  3717. 		end 
  3718. 	end 
  3719. end 
  3720.  
  3721. function m21_killbane_mounter_process_thread() 
  3722. 	delay(KILLBANE_RIDE_MAX_TIME) 
  3723. 	 
  3724. 	human_riding_trigger_end(player_in_ring) 
  3725. end 
  3726.  
  3727. function m21_thread_enforce_character_locations() 
  3728. 	while(true) do 
  3729. 		-- Make sure the player in the ring is ACTUALLY in the ring 
  3730. 		if (action_play_is_finished(player_in_ring, 1.0) and object_is_in_trigger(M21_triggers.ring_trigger, player_in_ring) == false) then 
  3731. 			-- They got out of the ring somehow, teleport them back in 
  3732. 			teleport(player_in_ring, M21_navpoints.player_fight_start[1]) 
  3733. 			repeat thread_yield() until teleport_check_done(player_in_ring) 
  3734. 		end 
  3735. 		 
  3736. 		-- If coop is active, we need to make sure the player outside of the ring is ACTUALLY outside of the ring 
  3737. 		if (coop_is_active() == true) then 
  3738. 			if (action_play_is_finished(player_outside_ring, 1.0) and object_is_in_trigger(M21_triggers.ring_trigger, player_outside_ring) == true) then 
  3739. 				-- They got into the ring somehow, teleport them back out 
  3740. 				teleport(player_outside_ring, M21_navpoints.player_fight_start[2]) 
  3741. 				repeat thread_yield() until teleport_check_done(player_outside_ring) 
  3742. 			end 
  3743. 		end 
  3744. 		 
  3745. 		-- If Killbane should be in the ring, make sure he's ACTUALLY inside the ring 
  3746. 		if (Killbane_should_be_in_ring == true) then 
  3747. 			if (action_play_is_finished(M21_characters.killbane, 1.0) and object_is_in_trigger(M21_triggers.ring_trigger, M21_characters.killbane) == false) then 
  3748. 				teleport(M21_characters.killbane, M21_navpoints.killbane_corner) 
  3749. 			end 
  3750. 		end 
  3751. 		 
  3752. 		thread_yield() 
  3753. 	end 
  3754. end 
  3755.  
  3756.  
  3757.