sr2lua/bh04.lua

  1. -- bh04.lua 
  2. -- SR2 mission script 
  3. -- 3/28/07 
  4.  
  5. -- Groups -- 
  6. 	GROUP_COURTESY_CAR =			"bh04_$courtesy_car" 
  7. 	GROUP_COURTESY_CAR_COOP =	"bh04_$courtesy_car_coop" 
  8. 	GROUP_RAGDOLL =				"bh04_$ragdoll" 
  9. 	GROUP_DONNIE =					"bh04_$donnie" 
  10. 	GROUP_DONNIE_CAR =			"bh04_$donnie_car" 
  11. 	GROUP_DONNIE_COOP	=			"bh04_$donnie_coop" 
  12.  
  13. -- Navpoints -- 
  14. 	NAV_LOCAL_START =		"bh04_$n047" 
  15. 	NAV_REMOTE_START =	"bh04_$n049" 
  16. 	NAV_MECHANIC_CAR =	"bh04_$n000" 
  17. 	NAV_DONNIE_FLEE =		{"bh04_$n045", "bh04_$n046", "bh04_$n048"} 
  18. 	NAV_DRAG_ROUTE =		 
  19. 		{	{"bh04_$n001", "bh04_$n002", "bh04_$n003", "bh04_$n004"}, 
  20. 			{"bh04_$n005", "bh04_$n006", "bh04_$n007", "bh04_$n008"}, 
  21. 			{"bh04_$n009", "bh04_$n010", "bh04_$n011", "bh04_$n012"}, 
  22. 			{"bh04_$n013", "bh04_$n014", "bh04_$n015", "bh04_$n016"}, 
  23. 			{"bh04_$n017", "bh04_$n018", "bh04_$n019", "bh04_$n020"}, 
  24. 			{"bh04_$n021", "bh04_$n022", "bh04_$n023", "bh04_$n024"}, 
  25. 			{"bh04_$n025", "bh04_$n026", "bh04_$n027", "bh04_$n028"}, 
  26. 			{"bh04_$n029", "bh04_$n030", "bh04_$n031", "bh04_$n032"}, 
  27. 			{"bh04_$n033", "bh04_$n034", "bh04_$n035", "bh04_$n036"}, 
  28. 			{"bh04_$n037", "bh04_$n038", "bh04_$n039", "bh04_$n040"}, 
  29. 			{"bh04_$n041", "bh04_$n042", "bh04_$n043", "bh04_$n044"}, 
  30. 		} 
  31. 	NAV_GARAGE_LOCATION = "bh04_$Ngarage_location" 
  32.  
  33. -- Triggers -- 
  34.  
  35. -- Characters -- 
  36. 	CHAR_DRIVER =			"bh04_$c000" 
  37. 	CHAR_PASSENGERS =		{"bh04_$c000", "bh04_$c008", "bh04_$c011"} 
  38. 	CHAR_CARLOS =			"bh04_$c001" 
  39. 	CHAR_DONNIE =			"bh04_$c002" 
  40. 	CHAR_GUARDS =			{"bh04_$c003", "bh04_$c004", "bh04_$c005", "bh04_$c006"} 
  41.  
  42. -- Vehicles -- 
  43. 	BERGEN =					"bh04_$v000" 
  44. 	MECHANIC_CAR =			"bh04_$v001" 
  45.  
  46. -- Mesh Movers -- 
  47. 	DOOR_1 =					"bh04_Door01b0" 
  48. 	DOOR_2 =					"bh04_Door010" 
  49. 	BOX_1 =					"bh04_boxCardBoardA07_21020" 
  50. 	BOX_2 =					"bh04_boxCardBoardA07_21050" 
  51. 	TRASHCAN =				"bh04_trashCanC01_20310" 
  52. 	--WIELDABLE_MOVERS =	{BOX_1, BOX_2, TRASHCAN} 
  53. 	WIELD_LOCATIONS =  
  54. 		{	"bh04_$n048", "bh04_$n050", "bh04_$n051", "bh04_$n052", "bh04_$n053",  
  55. 			"bh04_$n054", "bh04_$n055", "bh04_$n056"			 
  56. 		} 
  57. 	WIELDABLE_MOVERS =	 
  58. 		{	"bh04_$MM_donnie_weapon_1", "bh04_$MM_donnie_weapon_2", "bh04_$MM_donnie_weapon_3", 
  59. 			"bh04_$MM_donnie_weapon_4", "bh04_$MM_donnie_weapon_5", "bh04_$MM_donnie_weapon_6", 
  60. 			"bh04_$MM_donnie_weapon_7", "bh04_$MM_donnie_weapon_8", "bh04_$MM_donnie_weapon_9", 
  61. 			"bh04_$MM_donnie_weapon_10" 
  62. 		} 
  63. 	UNLIKELY_WIELDABLE_MOVERS =  
  64. 		{	"bh04_$MM_donnie_unlikely_weapon_1", "bh04_$MM_donnie_unlikely_weapon_2", "bh04_$MM_donnie_unlikely_weapon_3" 
  65. 		} 
  66.  
  67. -- Text -- 
  68. 	TEXT_TALK_TO_DONNIE =	"bh04_talk_to_donnie" 
  69. 	TEXT_PUSH_DONNIE =		"bh04_push_donnie" 
  70. 	TEXT_STOP_TRUCK =			"bh04_stop_truck" 
  71. 	TEXT_DAMAGE_TRUCK =		"bh04_damage_truck" 
  72. 	TEXT_CARLOS_HEALTH =		"bh04_carlos_health" 
  73. 	TEXT_HURRY =				"bh04_hurry" 
  74. 	TEXT_DONNIE_DIED =		"bh04_donnie_died" 
  75. 	TEXT_CARLOS_DIED =		"bh04_carlos_died" 
  76. 	TEXT_HELP_CARLOS =		"bh04_help_carlos" 
  77.  
  78. -- Threads -- 
  79. 	THREAD_RAGDOLL =				-1 
  80. 	THREAD_CARLOS_TIMER =		-1 
  81. 	THREAD_FLEE =					-1 
  82. 	THREAD_NO_SHIELD =			-1 
  83. 	THREAD_NOTORIETY =			-1 
  84. 	THREAD_COLLISION_PENALTY = -1 
  85.  
  86. -- Checkpoints -- 
  87. 	CHECKPOINT_START	=		MISSION_START_CHECKPOINT			-- defined in ug_lib.lua 
  88. 	CHECKPOINT_DONNIE =		"bh04_checkpoint_donnie" 
  89.  
  90. -- Cutscenes -- 
  91. 	CUTSCENE_IN =						"br04-1.bik" 
  92. 	CUTSCENE_OUT =						"br04-2.bik" 
  93.  
  94. -- Other -- 
  95. 	IN_COOP =						false 
  96. 	Carlos_health_pct =			75.0 
  97. 	Bh04_donnie_initial_hp =	-1 
  98. 	DONNIE_HEALTH_MULTIPLIER = 8 
  99. 	MAX_BH_NOTORIETY =			2 
  100. 	BERGEN_STOPPED_SPEED =		10 
  101. 	BERGEN_STOPPED_TIME =		5 
  102. 	CARLOS_DEATH_SPEED =			0.2166666666 
  103. 	STATE_WORK_ON_CAR =			"crouch plant bomb" 
  104. 	BERGEN_SPEED =	65 
  105. 	BERGEN_HEALTH_MULTIPLIER =	1.3 
  106. 	DONNIE_REACT_DISTANCE =		40 
  107. 	Carlos_being_dragged =		false 
  108. 	MAX_WIELD_DIST = 1.5 
  109.  
  110. 	local INTERROGATION_CONVERSATIONS =  
  111. 	{	 
  112. 		{ 
  113. 			.96, 
  114. 			{ 
  115. 				{ "BR04_SHOVED_L1", CHAR_DONNIE, 1 }, 
  116. 			}, 
  117. 		}, 
  118. 		{ 
  119. 			.92, 
  120. 			{ 
  121. 				{ "PLAYER_BR04_SHOVED_L2", LOCAL_PLAYER, 0 }, 
  122. 				{ "BR04_SHOVED_L3", CHAR_DONNIE, 0.5 }, 
  123. 			}, 
  124. 		}, 
  125. 		{ 
  126. 			.86, 
  127. 			{ 
  128. 				{ "PLAYER_BR04_SHOVED_L4", LOCAL_PLAYER, 0 }, 
  129. 				{ "BR04_SHOVED_L5", CHAR_DONNIE, 1 }, 
  130. 			}, 
  131. 		}, 
  132. 		{ 
  133. 			.82, 
  134. 			{ 
  135. 				{ "PLAYER_BR04_SHOVED_L6", LOCAL_PLAYER, 0 }, 
  136. 				{ "BR04_SHOVED_L7", CHAR_DONNIE, 1 }, 
  137. 			}, 
  138. 		}, 
  139. 		{ 
  140. 			.78, 
  141. 			{ 
  142. 				{ "PLAYER_BR04_SHOVED_L8", LOCAL_PLAYER, 0 }, 
  143. 				{ "BR04_SHOVED_L9", CHAR_DONNIE, 1 }, 
  144. 			}, 
  145. 		}, 
  146. 		{ 
  147. 			.75, 
  148. 			{ 
  149. 				{ "PLAYER_BR04_SHOVED_L10", LOCAL_PLAYER, 0 }, 
  150. 				{ "BR04_SHOVED_L11", CHAR_DONNIE, 1 }, 
  151. 			}, 
  152. 		}, 
  153. 		{ 
  154. 			.72, 
  155. 			{ 
  156. 				{ "PLAYER_BR04_SHOVED_L12", LOCAL_PLAYER, 0 }, 
  157. 				{ "BR04_SHOVED_L13", CHAR_DONNIE, 1 }, 
  158. 			}, 
  159. 		}, 
  160. 		{ 
  161. 			.68, 
  162. 			{ 
  163. 				{ "PLAYER_BR04_SHOVED_L14", LOCAL_PLAYER, 0 }, 
  164. 				{ "BR04_SHOVED_L15", CHAR_DONNIE, 1 }, 
  165. 			}, 
  166. 		}, 
  167. 	} 
  168.  
  169. 	PLAYER_SYNC = {[LOCAL_PLAYER] = SYNC_LOCAL, [REMOTE_PLAYER] = SYNC_ALL} 
  170.  
  171. 	BH04_BROTHERHOOD_ATTACK_PERSONAS = { 
  172. 		["HM_Bro1"]	=	"HMBRO1", 
  173. 		["HM_Bro2"]	=	"HMBRO2", 
  174. 		["HM_Bro3"]	=	"HMBRO3", 
  175.  
  176. 		["HF_Bro2"]	=	"HFBRO2", 
  177.  
  178. 		["WM_Bro3"]	=	"WMBRO3", 
  179.  
  180. 		["WF_Bro1"]	=	"WFBRO1", 
  181. 		["WF_Bro2"]	=	"WFBRO2", 
  182. 	} 
  183.  
  184. function bh04_start(bh04_checkpoint, is_restart) 
  185.  
  186. 	if (bh04_checkpoint == CHECKPOINT_START) then 
  187. 		if (not is_restart) then 
  188. 			cutscene_play("br04-01") 
  189. 		end 
  190. 		fade_out(0) 
  191. 	end 
  192.  
  193. 	bh04_initialize(bh04_checkpoint) 
  194.  
  195. 	if bh04_checkpoint == CHECKPOINT_DONNIE then 
  196. 		bh04_save_carlos() 
  197. 	else 
  198. 		bh04_get_to_mechanic_shop() 
  199. 	end 
  200. end 
  201.  
  202. function bh04_initialize(checkpoint) 
  203.  
  204. 	mission_start_fade_out(0.0) 
  205.  
  206. 	-- Start trigger is hit...the activate button was hit 
  207. 	set_mission_author("Phillip Alexander and Aaron Hanson (aka Father Zucosos)") 
  208.  
  209. 	bh04_initialize_common() 
  210.  
  211. 	bh04_initialize_checkpoint(checkpoint) 
  212.  
  213. 	mission_start_fade_in() 
  214.  
  215. end 
  216.  
  217. -- Initialization code shared by all checkpoints. 
  218. function bh04_initialize_common() 
  219.  
  220. 	notoriety_set_max("Brotherhood", MAX_BH_NOTORIETY) 
  221.  
  222. 	if coop_is_active() then 
  223. 		IN_COOP = true 
  224. 	end 
  225.  
  226. 	set_weather(4,false) 
  227.  
  228. 	bh04_start_persona_overrides() 
  229.  
  230. end 
  231.  
  232. -- Initialization code specific to the checkpoint. 
  233. function bh04_initialize_checkpoint(checkpoint) 
  234.  
  235. 	bh04_door_open(DOOR_2, true) 
  236.  
  237. 	if (checkpoint == CHECKPOINT_DONNIE) then 
  238. 		group_create(GROUP_DONNIE_CAR, true) 
  239. 		teleport_vehicle(MECHANIC_CAR, NAV_MECHANIC_CAR) 
  240. 		bh04_door_open(DOOR_1, false) 
  241. 		delay(1.0) 
  242. 	else 
  243. 		 
  244. 		group_create(GROUP_COURTESY_CAR, true) 
  245. 		if (IN_COOP) then 
  246. 			group_create(GROUP_COURTESY_CAR_COOP, true) 
  247. 		end 
  248.  
  249. 		teleport_coop(NAV_LOCAL_START, NAV_REMOTE_START) 
  250.  
  251. 	end 
  252.  
  253. end 
  254.  
  255. function bh04_start_persona_overrides() 
  256. 	persona_override_group_start(BH04_BROTHERHOOD_ATTACK_PERSONAS, POT_SITUATIONS[POT_ATTACK], "BR04_ATTACK") 
  257. end 
  258.  
  259. function bh04_stop_persona_overrides() 
  260. 	persona_override_group_stop(BROTHERHOOD_PERSONAS, POT_SITUATIONS[POT_ATTACK]) 
  261. end 
  262.  
  263. function bh04_get_to_mechanic_shop() 
  264. 	group_create(GROUP_DONNIE, true) 
  265. 	turn_invulnerable(CHAR_DONNIE) 
  266. 	group_create(GROUP_DONNIE_CAR, true) 
  267. 	if IN_COOP then 
  268. 		group_create(GROUP_DONNIE_COOP, true) 
  269. 	end 
  270. 	Bh04_donnie_initial_hp = get_current_hit_points(CHAR_DONNIE) 
  271. 	Bh04_donnie_initial_hp = Bh04_donnie_initial_hp * DONNIE_HEALTH_MULTIPLIER 
  272. 	set_max_hit_points(CHAR_DONNIE, Bh04_donnie_initial_hp) 
  273. 	set_current_hit_points(CHAR_DONNIE, Bh04_donnie_initial_hp) 
  274. 	inv_item_equip("tire_iron", CHAR_DONNIE) 
  275. 	crouch_start(CHAR_DONNIE) 
  276. 	set_animation_state(CHAR_DONNIE, STATE_WORK_ON_CAR) 
  277. 	set_ignore_ai_flag(CHAR_DONNIE, true) 
  278.  
  279. 	thread_new("bh04_donnie_truck_audio") 
  280.  
  281. 	for i, npc in pairs(CHAR_GUARDS) do 
  282. 		set_attack_player_flag(npc, true) 
  283. 	end 
  284.  
  285. 	mission_help_table(TEXT_TALK_TO_DONNIE) 
  286.  
  287. 	marker_add_navpoint(NAV_GARAGE_LOCATION, MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_LOCATION, SYNC_ALL) 
  288. 	mission_waypoint_add(CHAR_DONNIE) 
  289.  
  290. 	teleport_vehicle(MECHANIC_CAR, NAV_MECHANIC_CAR) 
  291.  
  292. 	on_death("bh04_failure_donnie_died", CHAR_DONNIE) 
  293. 	on_take_damage("bh04_donnie_damaged", CHAR_DONNIE) 
  294. 	on_take_damage("bh04_car_damaged", MECHANIC_CAR) 
  295.  
  296. 	local local_far_away = get_dist_char_to_char(LOCAL_PLAYER, CHAR_DONNIE) > DONNIE_REACT_DISTANCE 
  297. 	local remote_far_away = ( (not IN_COOP) or (IN_COOP and get_dist_char_to_char(REMOTE_PLAYER, CHAR_DONNIE) > DONNIE_REACT_DISTANCE) ) 
  298.  
  299. 	while (local_far_away and remote_far_away and Bh04_donnie_healthy and Bh04_car_healthy) do 
  300. 		local_far_away = get_dist_char_to_char(LOCAL_PLAYER, CHAR_DONNIE) > DONNIE_REACT_DISTANCE 
  301. 		remote_far_away = ( (not IN_COOP) or (IN_COOP and get_dist_char_to_char(REMOTE_PLAYER, CHAR_DONNIE) > DONNIE_REACT_DISTANCE) ) 
  302. 		thread_yield() 
  303. 	end 
  304. 	marker_remove_navpoint(NAV_GARAGE_LOCATION, SYNC_ALL) 
  305.  
  306. 	bh04_interrogate_donnie() 
  307. end 
  308.  
  309. Bh04_donnie_healthy = true 
  310. function bh04_donnie_damaged(donnie, attacker, damage_percent) 
  311. 	Bh04_donnie_healthy = false 
  312. end 
  313.  
  314. Bh04_car_healthy = true 
  315. function bh04_car_damaged(donnie, attacker, damage_percent) 
  316.  
  317. 	if (damage_percent < .60) then 
  318. 		Bh04_car_healthy = false 
  319. 	end 
  320. 	 
  321. end 
  322.  
  323.  
  324. function bh04_donnie_truck_audio() 
  325. 	while (get_dist_char_to_char(LOCAL_PLAYER, CHAR_DONNIE) > 90)	 
  326. 			and ((not IN_COOP) or (IN_COOP and get_dist_char_to_char(REMOTE_PLAYER, CHAR_DONNIE) > 90)) do 
  327. 		thread_yield() 
  328. 	end 
  329.  
  330. 	local audio_truck_work = audio_play_for_character("SFX_DONNIE_TRUCK_WORK", CHAR_DONNIE) 
  331.  
  332. 	while (get_dist_char_to_char(LOCAL_PLAYER, CHAR_DONNIE) > DONNIE_REACT_DISTANCE)	 
  333. 			and ((not IN_COOP) or (IN_COOP and get_dist_char_to_char(REMOTE_PLAYER, CHAR_DONNIE) > DONNIE_REACT_DISTANCE)) do 
  334. 		thread_yield() 
  335. 	end 
  336.  
  337. 	audio_stop(audio_truck_work) 
  338. 	delay(1) 
  339. 	audio_play_for_character("DONNIE_BR04_SEEPLAYER", CHAR_DONNIE, "voice") 
  340. end 
  341.  
  342. Bh04_interrogation_started = false 
  343. function bh04_interrogate_donnie() 
  344.  
  345. 	if (Bh04_interrogation_started) then 
  346. 		return 
  347. 	end 
  348.  
  349. 	marker_add_npc(CHAR_DONNIE, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL)	 
  350.  
  351. 	Bh04_interrogation_started = true 
  352. 	mission_waypoint_remove(SYNC_ALL) 
  353.  
  354. 	clear_animation_state(CHAR_DONNIE) 
  355. 	npc_weapon_pickup_override(CHAR_DONNIE, false) 
  356. 	set_dont_attack_me_on_sight_flag(CHAR_DONNIE, true) 
  357. 	set_attack_player_flag(CHAR_DONNIE, false) 
  358.  
  359. 	thread_new("bh04_make_donnie_vulnerable") 
  360. 	THREAD_FLEE = thread_new("bh04_donnie_flee") 
  361. 	THREAD_NO_SHIELD = thread_new("bh04_donnie_cant_be_shielded") 
  362.  
  363. 	-- Tell the player to lay the smack down on Donnie 
  364. 	mission_help_table(TEXT_PUSH_DONNIE) 
  365.  
  366. 	local function get_conversation() 
  367.  
  368. 		local health_ratio = get_current_hit_points(CHAR_DONNIE) / Bh04_donnie_initial_hp 
  369. 		for i=sizeof_table(INTERROGATION_CONVERSATIONS), 1, -1 do 
  370. 			if(health_ratio <= INTERROGATION_CONVERSATIONS[i][1]) then 
  371. 				return i 
  372. 			end 
  373. 		end 
  374.  
  375. 		return nil 
  376.  
  377. 	end 
  378.  
  379. 	local prev_conversation = nil 
  380. 	local final_conversation = sizeof_table(INTERROGATION_CONVERSATIONS) 
  381. 	while(not (prev_conversation == final_conversation) ) do 
  382. 		local new_conversation = get_conversation() 
  383. 		if (new_conversation ~= prev_conversation) then 
  384.  
  385. 			local local_close_enough = get_dist(LOCAL_PLAYER, CHAR_DONNIE) < 10 
  386. 			local remote_close_enough = false 
  387. 			if (IN_COOP and (get_dist(REMOTE_PLAYER, CHAR_DONNIE) < 10)) then 
  388. 				remote_close_enough = true 
  389. 			end 
  390.  
  391. 			-- Play the line for the remote player if only the remote playeor is close enough, or 50% 
  392. 			-- of the time if both players are close enough 
  393. 			local play_for_remote = (	remote_close_enough and  
  394. 												( (not local_close_enough) or (rand_int(1,2) == 1) ) 
  395. 											) 
  396.  
  397. 			local conversation = INTERROGATION_CONVERSATIONS[new_conversation][2] 
  398. 			if (play_for_remote) then 
  399. 				conversation[1][2] = REMOTE_PLAYER 
  400. 			end 
  401.  
  402. 			bh04_play_interrogation_conversation(conversation) 
  403. 			prev_conversation = new_conversation 
  404. 		end 
  405. 		thread_yield() 
  406. 	end 
  407.  
  408. 	thread_kill(THREAD_FLEE) 
  409. 	thread_kill(THREAD_NO_SHIELD) 
  410.  
  411. 	marker_remove_npc(CHAR_DONNIE, SYNC_ALL) 
  412.  
  413. 	if not character_is_dead(CHAR_DONNIE) then 
  414. 		on_death("", CHAR_DONNIE) 
  415. 		turn_invulnerable(CHAR_DONNIE) 
  416.  
  417. 		mission_set_checkpoint(CHECKPOINT_DONNIE) 
  418. 		bh04_save_carlos() 
  419. 	end 
  420.  
  421. end 
  422.  
  423. function bh04_make_donnie_vulnerable() 
  424.  
  425. 	delay(5) 
  426. 	turn_vulnerable(CHAR_DONNIE) 
  427. 	 
  428. end 
  429.  
  430.  
  431. function bh04_play_interrogation_conversation( dialog_stream) 
  432.  
  433.    for segment_index, dialog_segment in pairs( dialog_stream ) do 
  434.       local audio_name = dialog_segment[DIALOG_STREAM_AUDIO_NAME_INDEX] 
  435.       local speaking_character = dialog_segment[DIALOG_STREAM_CHAR_NAME_INDEX] 
  436.       local delay_seconds = dialog_segment[DIALOG_STREAM_DELAY_SECONDS_INDEX] 
  437.  
  438. 		repeat 
  439. 			thread_yield() 
  440. 		until ( bh04_character_is_ready_to_speak( speaking_character ) ) 
  441.  
  442. 		audio_play_for_character( audio_name, speaking_character, "voice", false, true) 
  443. 		delay( delay_seconds ) 
  444.    end 
  445.  
  446. end 
  447.  
  448. function bh04_character_is_ready_to_speak( speaking_character ) 
  449.    -- Check for a character that does not exist first 
  450.    if (not character_exists(speaking_character)) then 
  451. 		return false 
  452. 	end 
  453.  
  454. 	if (character_is_dead(speaking_character)) then 
  455. 		return false 
  456. 	end 
  457.  
  458. 	if (character_is_ragdolled(speaking_character) and (speaking_character ~= CHAR_DONNIE)) then 
  459. 		return false 
  460. 	end 
  461. 	 
  462. 	if (character_is_on_fire(speaking_character)) then 
  463.       return false 
  464.    end 
  465.  
  466. 	-- The character can speak 
  467.    return true 
  468. end 
  469.  
  470. function bh04_donnie_cant_be_shielded() 
  471.  
  472. 	while(true) do 
  473. 		 
  474. 		if(character_has_specific_human_shield(LOCAL_PLAYER, CHAR_DONNIE)) then 
  475. 			character_release_human_shield(LOCAL_PLAYER) 
  476. 		elseif (IN_COOP and character_has_specific_human_shield(REMOTE_PLAYER, CHAR_DONNIE)) then 
  477. 			character_release_human_shield(REMOTE_PLAYER) 
  478. 		end 
  479. 		thread_yield() 
  480. 	end 
  481.  
  482. end 
  483.  
  484. function bh04_donnie_flee() 
  485. 	 
  486. 	move_to(CHAR_DONNIE, NAV_DONNIE_FLEE[1], 2, true) 
  487. 	bh04_door_open(DOOR_1, false) 
  488. 	move_to(CHAR_DONNIE, NAV_DONNIE_FLEE[2], 2, true) 
  489.  
  490. 	local donnie_use_mover_dist = 75 
  491.  
  492. 	while(1) do 
  493. 		thread_yield() 
  494.  
  495. 		-- If the server isn't near donnie, all the mesh mover code won't work, just have donnie attack 
  496. 		if (get_dist(LOCAL_PLAYER, CHAR_DONNIE) > donnie_use_mover_dist) then 
  497. 		 
  498. 			if (IN_COOP) then 
  499. 				set_dont_attack_me_on_sight_flag(CHAR_DONNIE, false) 
  500. 				set_attack_player_flag(CHAR_DONNIE, true) 
  501. 				set_ignore_ai_flag(CHAR_DONNIE, false) 
  502. 				attack(CHAR_DONNIE) 
  503. 			end 
  504. 			delay(5) 
  505.  
  506. 		else 
  507.  
  508. 			set_dont_attack_me_on_sight_flag(CHAR_DONNIE, true) 
  509. 			set_attack_player_flag(CHAR_DONNIE, false) 
  510. 			set_ignore_ai_flag(CHAR_DONNIE, true) 
  511. 			while ( not (mesh_mover_wielding(CHAR_DONNIE) or (get_dist(LOCAL_PLAYER, CHAR_DONNIE) > donnie_use_mover_dist)) ) do 
  512. 				thread_yield() 
  513.  
  514. 				local weapon, location = bh04_donnie_select_weapon_and_location() 
  515.  
  516. 				if ( (weapon ~= "") and (location ~= nil) and (not mesh_mover_wielding(CHAR_DONNIE))) then 
  517.  
  518. 					-- Only move to a new location if Donnie can't reach the item from where he's standing 
  519. 					if (get_dist(CHAR_DONNIE, weapon) > MAX_WIELD_DIST) then 
  520. 						move_to(CHAR_DONNIE, location, 2, true) 
  521. 					end 
  522.  
  523. 					-- Make sure that no one else picked up the weapon 
  524. 					if ( (get_dist(CHAR_DONNIE, weapon) < MAX_WIELD_DIST) and (not mesh_mover_being_wielded(weapon))) then 
  525. 						mesh_mover_wield(weapon, CHAR_DONNIE, false) 
  526. 					end 
  527.  
  528. 					turn_to(CHAR_DONNIE, NAV_DONNIE_FLEE[2], false) 
  529. 					delay(0.1) 
  530. 				end 
  531.  
  532. 			end 
  533.  
  534. 			local dist,player = get_dist_closest_player_to_object(CHAR_DONNIE) 
  535. 			while (dist > 7) do 
  536. 				dist,player = get_dist_closest_player_to_object(CHAR_DONNIE) 
  537. 				thread_yield() 
  538. 			end 
  539.  
  540. 			if (get_dist(LOCAL_PLAYER, CHAR_DONNIE) < donnie_use_mover_dist) then 
  541. 				delay(0.5) 
  542. 				turn_to(CHAR_DONNIE, player, false) 
  543. 				mesh_mover_throw(CHAR_DONNIE) 
  544. 				delay(0.75) 
  545. 			end 
  546. 		end 
  547.  
  548. 	end 
  549. end 
  550.  
  551. function bh04_donnie_select_weapon_and_location() 
  552.  
  553. 	local objects_examined = 0 
  554. 	while(objects_examined < 10) do 
  555.  
  556. 		objects_examined = objects_examined + 1 
  557.  
  558. 		local weapon = "" 
  559. 		if ((rand_int(1,6) == 1)) then 
  560. 			weapon = UNLIKELY_WIELDABLE_MOVERS[rand_int(1,sizeof_table(UNLIKELY_WIELDABLE_MOVERS))] 
  561. 		else 
  562. 			weapon = WIELDABLE_MOVERS[rand_int(1,sizeof_table(WIELDABLE_MOVERS))] 
  563. 		end 
  564.  
  565. 		if (not mesh_mover_being_wielded(weapon) ) then 
  566.  
  567. 			for i, location in pairs(WIELD_LOCATIONS) do 
  568. 				if (get_dist(weapon, location) < MAX_WIELD_DIST) then 
  569. 					return weapon, location 
  570. 				end 
  571. 			end 
  572.  
  573. 		end 
  574.  
  575. 	end 
  576.  
  577. 	return "", nil 
  578.  
  579. end 
  580.  
  581. function bh04_save_carlos() 
  582. 	group_create(GROUP_RAGDOLL, true) 
  583. 	local Bergen_hp = get_current_hit_points(BERGEN) 
  584. 	Bergen_hp = Bergen_hp * BERGEN_HEALTH_MULTIPLIER 
  585. 	set_max_hit_points(BERGEN, Bergen_hp) 
  586. 	set_current_hit_points(BERGEN, Bergen_hp) 
  587. 	vehicle_set_untowable(BERGEN, true) 
  588. 	vehicle_max_speed(BERGEN, BERGEN_SPEED) 
  589. 	set_unjackable_flag(BERGEN, true) 
  590. 	set_ignore_ai_flag(CHAR_CARLOS, true) 
  591. 	turn_invulnerable(CHAR_CARLOS, false) 
  592. 	vehicle_enter_group_teleport(CHAR_PASSENGERS, BERGEN) 
  593. 	vehicle_suppress_npc_exit(BERGEN, true) 
  594. 	for i, npc in pairs(CHAR_PASSENGERS) do 
  595. 		set_attack_player_flag(npc, true) 
  596. 	end 
  597.  
  598. 	marker_add_vehicle(BERGEN, MINIMAP_ICON_KILL, INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL) 
  599. 	mission_waypoint_add(BERGEN, SYNC_ALL) 
  600.  
  601. 	hud_bar_on(0, "Health", TEXT_CARLOS_HEALTH, 1.0) 
  602. 	hud_bar_set_range(0, 0.0, 100.0, SYNC_ALL) 
  603. 	hud_bar_set_value(0, 75.0, SYNC_ALL) 
  604.  
  605. 	THREAD_CARLOS_TIMER = thread_new("bh04_carlos_slow_death") 
  606. 	vehicle_drag_ragdoll_start(BERGEN, CHAR_CARLOS) 
  607. 	Carlos_being_dragged = true 
  608. 	THREAD_RAGDOLL = thread_new("bh04_pathfind") 
  609. 	THREAD_COLLISION_PENALTY = thread_new("bh04_collision_penalty") 
  610.  
  611. 	delay(4) 
  612. 	mission_help_table(TEXT_STOP_TRUCK) 
  613.  
  614. 	THREAD_NOTORIETY = thread_new("bh04_raise_tribal_notoriety") 
  615.  
  616. 	bh04_watch_truck() 
  617. end 
  618.  
  619. function bh04_collision_penalty() 
  620. 	while 1 do 
  621. 		thread_yield() 
  622. 		if ((get_dist_char_to_char(LOCAL_PLAYER, CHAR_CARLOS) < 2) and character_is_in_vehicle(LOCAL_PLAYER)) 
  623. 		   or (IN_COOP and (get_dist_char_to_char(REMOTE_PLAYER, CHAR_CARLOS) < 2) and character_is_in_vehicle(REMOTE_PLAYER)) then 
  624. 			Carlos_health_pct = Carlos_health_pct - 5.0 
  625. 			delay(2) 
  626. 		end 
  627. 	end 
  628. end 
  629.  
  630. function bh04_watch_truck() 
  631.  
  632. 	local Stopped = false 
  633. 	local Bergen_slowed_time = 0.0 
  634. 	local Message_displayed = {[LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false} 
  635. 	local Next_los_check		= {[LOCAL_PLAYER] = 0.0, [REMOTE_PLAYER] = 0.5} 
  636. 	local Bergen_gear_speeds = {20, 45, BERGEN_SPEED} 
  637. 	local Bergen_gear = 3 
  638.  
  639. 	-- Kill the threads associated with this sequence, maybe have npcs exit the vehicle 
  640. 	local function stop_bergen(exit) 
  641. 		Stopped = true 
  642. 		thread_kill(THREAD_RAGDOLL) 
  643. 		thread_kill(THREAD_CARLOS_TIMER) 
  644. 		thread_kill(THREAD_COLLISION_PENALTY) 
  645. 		vehicle_suppress_npc_exit(BERGEN, false) 
  646. 		set_unjackable_flag(BERGEN, true) 
  647. 		if(exit) then 
  648. 			bh04_exit_bergen() 
  649. 		end 
  650. 	end 
  651.  
  652. 	-- Display "Damage the truck and force it to stop!" when Carlos first enters player's LOS 
  653. 	local function update_message(player) 
  654.  
  655. 		if ( not Message_displayed[player] ) then 
  656.  
  657. 			-- Only do LOS checks once per second 
  658. 			if(Next_los_check[player] <= 0.0) then 
  659. 				Next_los_check[player] = 1.0				 
  660.  
  661. 				if(los_check(player, CHAR_CARLOS)) then 
  662. 					Message_displayed[player] = true 
  663. 					mission_help_table(TEXT_DAMAGE_TRUCK, "", "", PLAYER_SYNC[player]) 
  664. 				end				 
  665. 			else 
  666. 				-- Otherwise update the time til the next los check. 
  667. 				Next_los_check[player] = Next_los_check[player] - get_frame_time() 
  668. 			end 
  669. 			 
  670. 		end 
  671. 	end 
  672.  
  673. 	while(not Stopped) do 
  674. 		thread_yield() 
  675.  
  676. 		if(vehicle_is_destroyed(BERGEN)) then 
  677. 		-- Stop Bergen if destroyed 
  678. 			stop_bergen(false) 
  679. 		else 
  680. 			-- Get closest player to truck 
  681. 			local dist,player = get_dist_closest_player_to_object(BERGEN) 
  682.  
  683. 			-- Display message if we've gotten close enough 
  684. 			update_message(LOCAL_PLAYER) 
  685. 			if ( IN_COOP ) then  
  686. 				update_message(REMOTE_PLAYER) 
  687. 			end 
  688.  
  689. 			-- Stop bergen if it is on fire or smoking or its driver is dead. 
  690. 			local Vehicle_smoke, Vehicle_fire = vehicle_get_smoke_and_fire_state(BERGEN) 
  691. 			if (	Vehicle_smoke or Vehicle_fire or character_is_dead(CHAR_DRIVER)) then 
  692. 				stop_bergen(true) 
  693. 			elseif ( (dist <= 30) and get_vehicle_speed(CHAR_DRIVER) <= BERGEN_STOPPED_SPEED) then 
  694. 			-- Stop Bergen if physically stopped/slowed for enough time 
  695. 				Bergen_slowed_time = Bergen_slowed_time + get_frame_time() 
  696. 				if Bergen_slowed_time >= BERGEN_STOPPED_TIME then 
  697. 					stop_bergen(true) 
  698. 				end 
  699. 			else 
  700. 				Bergen_slowed_time = 0.0 
  701.  
  702. 			-- The Bergen isn't stopped... slow it down if far enough from the players 
  703. 				local new_gear = 3 
  704. 				if(dist > 200 ) then 
  705. 					new_gear = 1 
  706. 				elseif(dist > 100 ) then 
  707. 					new_gear = 2 
  708. 				end 
  709. 				if (Bergen_gear ~= new_gear) then 
  710. 					Bergen_gear = new_gear 
  711. 					vehicle_max_speed(BERGEN, Bergen_gear_speeds[Bergen_gear]) 
  712. 				end 
  713.  
  714. 			end 
  715. 		end 
  716. 	end 
  717.  
  718. 	bh04_get_to_carlos() 
  719. end 
  720.  
  721. function bh04_exit_bergen() 
  722. 	turn_invulnerable(BERGEN, false) 
  723. 	for i, npc in pairs(CHAR_PASSENGERS) do 
  724. 		if not character_is_dead(npc) then 
  725. 			thread_new("vehicle_exit", npc, false) 
  726. 			if IN_COOP and mod(i,2) == 0 then 
  727. 				attack(npc, REMOTE_PLAYER) 
  728. 			else 
  729. 				attack(npc, LOCAL_PLAYER) 
  730. 			end 
  731. 		end 
  732. 	end 
  733.  
  734. end 
  735.  
  736. function bh04_get_to_carlos() 
  737.  
  738. 	mission_help_table_nag(TEXT_HELP_CARLOS) 
  739. 	turn_invulnerable(CHAR_CARLOS) 
  740. 	set_unjackable_flag(BERGEN, true) 
  741. 	--npc_revive(CHAR_CARLOS) 
  742. 	thread_new("bh04_ragdoll_carlos") 
  743.  
  744. 	marker_remove_vehicle(BERGEN, SYNC_ALL) 
  745. 	mission_waypoint_remove(SYNC_ALL) 
  746. 	marker_add_npc(CHAR_CARLOS, MINIMAP_ICON_PROTECT_ACQUIRE, INGAME_EFFECT_PROTECT_ACQUIRE, SYNC_ALL) 
  747.  
  748. 	if THREAD_FLEE ~= -1 then 
  749. 		thread_kill(THREAD_FLEE) 
  750. 	end 
  751. 	if THREAD_NO_SHIELD ~= -1 then 
  752. 		thread_kill(THREAD_NO_SHIELD) 
  753. 	end 
  754.  
  755. 	delay(3) 
  756.  
  757. 	while (get_dist_char_to_char(LOCAL_PLAYER, CHAR_CARLOS) > 3) and ((not IN_COOP) or (IN_COOP and get_dist_char_to_char(REMOTE_PLAYER, CHAR_CARLOS) > 3)) do 
  758. 		thread_yield() 
  759. 	end 
  760.  
  761. 	marker_remove_npc(CHAR_CARLOS, SYNC_ALL) 
  762.  
  763. 	--cutscene_out() 
  764. 	turn_invulnerable(LOCAL_PLAYER) 
  765. 	if (IN_COOP) then 
  766. 		turn_invulnerable(REMOTE_PLAYER) 
  767. 	end 
  768.  
  769. 	if (vehicle_exists(BERGEN) and (not vehicle_is_destroyed(BERGEN))) then 
  770. 		-- Make suree that Carlos doesn't get up. 
  771. 		character_kill(CHAR_CARLOS) 
  772. 		vehicle_drag_ragdoll_stop(BERGEN, CHAR_CARLOS) 
  773. 	end 
  774.  
  775. 	bh04_success_carlos_saved() 
  776. end 
  777.  
  778. function bh04_ragdoll_carlos() 
  779. 	while (true) do 
  780. 		if (character_exists(CHAR_CARLOS) and (not character_is_dead(CHAR_CARLOS)) ) then 
  781. 			character_ragdoll(CHAR_CARLOS) 
  782. 		end 
  783. 		thread_yield() 
  784. 	end 
  785. end 
  786.  
  787. function bh04_raise_tribal_notoriety() 
  788. 	--[[ 
  789. 	while(1) do 
  790. 		thread_yield() 
  791. 		delay(10) 
  792. 		local new_bh_notoriety = notoriety_get("Brotherhood") + 1 
  793. 		if new_bh_notoriety <= MAX_BH_NOTORIETY then 
  794. 			notoriety_set_max("Brotherhood", new_bh_notoriety) 
  795. 			notoriety_set("Brotherhood", new_bh_notoriety) 
  796. 			notoriety_set_min("Brotherhood", new_bh_notoriety) 
  797. 		end 
  798. 	end 
  799. 	]]-- 
  800.  
  801. 	while(1) do 
  802. 		thread_yield() 
  803. 		while (notoriety_get_decimal("Brotherhood") < MAX_BH_NOTORIETY) do 
  804. 			thread_yield() 
  805. 			local notoriety = notoriety_get_decimal("Brotherhood") 
  806. 			local new_notoriety = notoriety + 0.02 
  807. 			if new_notoriety > MAX_BH_NOTORIETY then 
  808. 				new_notoriety = MAX_BH_NOTORIETY 
  809. 			end 
  810. 			notoriety_set("Brotherhood", new_notoriety) 
  811. 			delay(0.5) 
  812. 		end 
  813. 	end 
  814. end 
  815.  
  816. function bh04_carlos_slow_death() 
  817. 	local Warning_displayed = false 
  818. 	Carlos_health_pct = 75.0 
  819. 	while(Carlos_health_pct > 0.0) do 
  820. 		thread_yield() 
  821. 		Carlos_health_pct = Carlos_health_pct - (CARLOS_DEATH_SPEED * get_frame_time()) 
  822. 		if Carlos_health_pct <= 0.0 then 
  823. 			Carlos_health_pct = 0.0 
  824. 		end 
  825. 		hud_bar_set_value(0, Carlos_health_pct, SYNC_ALL) 
  826. 		if Carlos_health_pct <= 20.0 and not Warning_displayed then 
  827. 			mission_help_table(TEXT_HURRY) 
  828. 			Warning_displayed = true 
  829. 		end 
  830. 	end 
  831. 	character_kill(CHAR_CARLOS) 
  832. 	bh04_failure_carlos_died() 
  833. end 
  834.  
  835. function bh04_pathfind() 
  836. 	while(1) do 
  837. 		thread_yield() 
  838. 		for i,path_segment in pairs(NAV_DRAG_ROUTE) do 
  839. 		vehicle_pathfind_to(BERGEN, path_segment, true, false) 
  840. 		end 
  841. 	end 
  842. end 
  843.  
  844. function bh04_door_open(door, reverse) 
  845. 	thread_new("bh04_door_keep_open", door, reverse) 
  846. end 
  847.  
  848. function bh04_door_keep_open(door, reverse) 
  849.  
  850. 	while(true) do 
  851. 		if(not door_is_open(door)) then 
  852. 			door_open(door, reverse) 
  853. 		end 
  854. 		delay(1.0) 
  855. 		thread_yield() 
  856. 	end 
  857.  
  858. end 
  859.  
  860. function bh04_success_carlos_saved() 
  861. 	marker_remove_npc(CHAR_CARLOS, SYNC_ALL) 
  862. 	hud_bar_off(0) 
  863. 	delay(2) 
  864. 	mission_end_success("bh04", "br04-02") 
  865. end 
  866.  
  867. function bh04_failure_donnie_died() 
  868. 	on_death("", CHAR_DONNIE) 
  869. 	delay(3) 
  870. 	mission_end_failure("bh04", TEXT_DONNIE_DIED) 
  871. end 
  872.  
  873. function bh04_failure_carlos_died() 
  874. 	delay(3) 
  875. 	mission_end_failure("bh04", TEXT_CARLOS_DIED) 
  876. end 
  877.  
  878. function bh04_cleanup() 
  879.  
  880. 	set_weather(-1) 
  881.  
  882. 	-- Cleanup mission here 
  883.  
  884. 	if (Carlos_being_dragged and vehicle_exists(BERGEN) and (not vehicle_is_destroyed(BERGEN))) then 
  885. 		vehicle_drag_ragdoll_stop(BERGEN, CHAR_CARLOS) 
  886. 	end 
  887.  
  888. 	hud_bar_off(0) 
  889.  
  890. 	for i, mover in pairs(WIELDABLE_MOVERS) do 
  891. 		mesh_mover_reset(mover) 
  892. 	end 
  893. 	for i, mover in pairs(UNLIKELY_WIELDABLE_MOVERS) do 
  894. 		mesh_mover_reset(mover) 
  895. 	end 
  896.  
  897. 	door_lock(DOOR_1, false) 
  898. 	door_open(DOOR_1) 
  899. 	door_lock(DOOR_2, false) 
  900. 	door_open(DOOR_2) 
  901.  
  902. 	if THREAD_RAGDOLL ~= -1 then 
  903. 		thread_kill(THREAD_RAGDOLL) 
  904. 	end 
  905. 	if THREAD_CARLOS_TIMER ~= -1 then 
  906. 		thread_kill(THREAD_CARLOS_TIMER) 
  907. 	end 
  908. 	if THREAD_FLEE ~= -1 then 
  909. 		thread_kill(THREAD_FLEE) 
  910. 	end 
  911. 	if THREAD_NOTORIETY ~= -1 then 
  912. 		thread_kill(THREAD_NOTORIETY) 
  913. 	end 
  914. 	if THREAD_NO_SHIELD ~= -1 then 
  915. 		thread_kill(THREAD_NO_SHIELD) 
  916. 	end 
  917. 	if THREAD_COLLISION_PENALTY ~= -1 then 
  918. 		thread_kill(THREAD_COLLISION_PENALTY) 
  919. 	end 
  920.  
  921. 	mission_waypoint_remove(SYNC_ALL) 
  922. 	marker_remove_vehicle(BERGEN, SYNC_ALL) 
  923. 	marker_remove_npc(CHAR_CARLOS, SYNC_ALL) 
  924. 	marker_remove_navpoint(NAV_GARAGE_LOCATION, SYNC_ALL) 
  925.  
  926. 	on_death("", CHAR_DONNIE) 
  927.  
  928. 	bh04_stop_persona_overrides() 
  929. 	 
  930. 	turn_vulnerable(LOCAL_PLAYER) 
  931. 	if (coop_is_active()) then 
  932. 		turn_vulnerable(REMOTE_PLAYER) 
  933. 	end 
  934.  
  935. 	group_destroy(GROUP_DONNIE_CAR) 
  936.  
  937. end 
  938.  
  939. function bh04_success() 
  940. 	-- Called when the mission has ended with success 
  941. --	bink_play_movie(CUTSCENE_OUT) 
  942. end 
  943.