-- bh09.lua
-- SR2 mission script
-- 3/28/07
-- Groups --
GROUP_ULTOR = "bh09_$ultor"
GROUP_WAVE1 = "bh09_$wave1"
GROUP_WAVE2 = "bh09_$wave2"
GROUP_WAVE3 = "bh09_$wave3"
GROUPS_WAVES = { GROUP_WAVE1, GROUP_WAVE2, GROUP_WAVE3 }
GROUP_START = "bh09_$start"
GROUP_START_COOP = "bh09_$start_coop"
GROUP_SAINTS = "bh09_$saints"
GROUP_COURTESY_HELI = "bh09_$courtesy_heli"
GROUP_HELI_DESTROYERS = "bh09_$Heli_Destroyers"
-- Navpoints --
NAV_LOCAL_START = "bh09_$n010"
NAV_REMOTE_START = "bh09_$n011"
NAV_SHIP = "bh09_$n000"
NAV_HELI_PATHS = { "bh09_$heli_path_01", "bh09_$heli_path_02", "bh09_$heli_path_03",
"bh09_$heli_path_04", "bh09_$heli_path_05", "bh09_$heli_path_06" }
NAV_HELI_DROPOFFS = { "bh09_$heli_dropoff_01", "bh09_$heli_dropoff_02", "bh09_$heli_dropoff_03",
"bh09_$heli_dropoff_04", "bh09_$heli_dropoff_05", "bh09_$heli_dropoff_06" }
NAV_BOAT_LEFT_GOAL = "bh09_$boat_left_goal"
NAV_BOAT_RIGHT_GOAL = "bh09_$boat_right_goal"
NAV_BOAT_PATH_LEFT = "bh09_$boat_path_left"
NAV_BOAT_PATH_RIGHT = "bh09_$boat_path_right"
NAV_BOAT_LEAVE_PATH_LEFT = "bh09_$boat_leave_path_left"
NAV_BOAT_LEAVE_PATH_RIGHT = "bh09_$boat_leave_path_right"
NAV_CHECKPOINT_LOCAL = "bh09_$nav_checkpoint_local"
NAV_CHECKPOINT_REMOTE = "bh09_$nav_checkpoint_remote"
NAV_STAIRS_LEFT_PATH_STARTS = { "bh09_$stairs_left_path_start_01", "bh09_$stairs_left_path_start_02", "bh09_$stairs_left_path_start_03" }
NUM_LEFT_PATH_STARTS = sizeof_table( NAV_STAIRS_LEFT_PATH_STARTS )
NAV_STAIRS_RIGHT_PATH_STARTS = { "bh09_$stairs_right_path_start_01", "bh09_$stairs_right_path_start_02", "bh09_$stairs_right_path_start_03" }
NUM_RIGHT_PATH_STARTS = sizeof_table( NAV_STAIRS_RIGHT_PATH_STARTS )
NAV_STAIRS_LEFT_PATH = "bh09_$stairs_left"
NAV_STAIRS_RIGHT_PATH = "bh09_$stairs_right"
-- Characters --
TABLE_ULTOR_RPG = {"bh09_$UAD_RPG01", "bh09_$UAD_RPG02", "bh09_$UAD_RPG03", "bh09_$UAD_RPG04"}
TABLE_ULTOR_ABOVEDECKS = { "bh09_$UAD_M01", "bh09_$UAD_M02", "bh09_$UAD_M03", "bh09_$UAD_M04", "bh09_$UAD_M05",
"bh09_$UAD_M06", "bh09_$UAD_M07", "bh09_$UAD_M08", "bh09_$UAD_M09",
TABLE_ULTOR_RPG[1], TABLE_ULTOR_RPG[2], TABLE_ULTOR_RPG[3], TABLE_ULTOR_RPG[4],
TABLE_ULTOR_RPG[5] }
TABLE_ULTOR_BELOWDECKS = { "bh09_$UBD_M01", "bh09_$UBD_M02", "bh09_$UBD_M03", "bh09_$UBD_M04", "bh09_$UBD_M05" }
TABLE_ULTOR_STD = { "bh09_$UAD_M01", "bh09_$UAD_M02", "bh09_$UAD_M03", "bh09_$UAD_M04", "bh09_$UAD_M05",
"bh09_$UAD_M06", "bh09_$UAD_M07", "bh09_$UAD_M08", "bh09_$UAD_M09",
"bh09_$UBD_M01", "bh09_$UBD_M02", "bh09_$UBD_M03", "bh09_$UBD_M04", "bh09_$UBD_M05" }
TABLE_ALL_ULTOR = { "bh09_$UAD_M01", "bh09_$UAD_M02", "bh09_$UAD_M03", "bh09_$UAD_M04", "bh09_$UAD_M05",
"bh09_$UAD_M06", "bh09_$UAD_M07", "bh09_$UAD_M08", "bh09_$UAD_M09",
TABLE_ULTOR_RPG[1], TABLE_ULTOR_RPG[2], TABLE_ULTOR_RPG[3], TABLE_ULTOR_RPG[4],
TABLE_ULTOR_RPG[5],
"bh09_$UBD_M01", "bh09_$UBD_M02", "bh09_$UBD_M03", "bh09_$UBD_M04", "bh09_$UBD_M05" }
TABLE_HELI_DESTROYERS = { "bh09_$HD1", "bh09_$HD2", "bh09_$HD3" }
CHARS_WAVE1_HELIS = { { "bh09_$w1_h1_m1", "bh09_$w1_h1_m2" },
{ "bh09_$w1_h2_m1", "bh09_$w1_h2_m2" } }
CHARS_WAVE2_HELIS = { { "bh09_$w2_h1_m1", "bh09_$w2_h1_m2" },
{ "bh09_$w2_h2_m1", "bh09_$w2_h2_m2" },
{ "bh09_$w2_h3_m1", "bh09_$w2_h3_m2" } }
CHARS_WAVE3_HELIS = { { "bh09_$w3_h1_m1", "bh09_$w3_h1_m2" },
{ "bh09_$w3_h2_m1", "bh09_$w3_h2_m2" },
{ "bh09_$w3_h3_m1", "bh09_$w3_h3_m2" },
{ "bh09_$w3_h4_m1", "bh09_$w3_h4_m2" },
{ "bh09_$w3_h5_m1", "bh09_$w3_h5_m2" },
{ "bh09_$w3_h6_m1", "bh09_$w3_h6_m2" } }
CHARS_WAVES_HELIS = { CHARS_WAVE1_HELIS, CHARS_WAVE2_HELIS, CHARS_WAVE3_HELIS }
CHARS_WAVE1_BOATS = { { "bh09_$w1_b1_m1", "bh09_$w1_b1_m2", "bh09_$w1_b1_m3" },
{ "bh09_$w1_b2_m1", "bh09_$w1_b2_m2" },
{ "bh09_$w1_b3_m1", "bh09_$w1_b3_m2", "bh09_$w1_b3_m3" },
{ "bh09_$w1_b4_m1", "bh09_$w1_b4_m2", "bh09_$w1_b4_m3" },
{ "bh09_$w1_b5_m1", "bh09_$w1_b5_m2", "bh09_$w1_b5_m3" } }
CHARS_WAVE2_BOATS = { { "bh09_$w2_b1_m1", "bh09_$w2_b1_m2" },
{ "bh09_$w2_b2_m1", "bh09_$w2_b2_m2", "bh09_$w2_b2_m3" },
{ "bh09_$w2_b3_m1", "bh09_$w2_b3_m2", "bh09_$w2_b3_m3" },
{ "bh09_$w2_b4_m1", "bh09_$w2_b4_m2", "bh09_$w2_b4_m3" },
{ "bh09_$w2_b5_m1", "bh09_$w2_b5_m2", "bh09_$w2_b5_m3" },
{ "bh09_$w2_b6_m1", "bh09_$w2_b6_m2" } }
CHARS_WAVE3_BOATS = { { "bh09_$w3_b1_m1", "bh09_$w3_b1_m2", "bh09_$w3_b1_m3" },
{ "bh09_$w3_b2_m1", "bh09_$w3_b2_m2", "bh09_$w3_b2_m3" },
{ "bh09_$w3_b3_m1", "bh09_$w3_b3_m2" },
{ "bh09_$w3_b4_m1", "bh09_$w3_b4_m2", "bh09_$w3_b4_m3" },
{ "bh09_$w3_b5_m1", "bh09_$w3_b5_m2", "bh09_$w3_b5_m3" },
{ "bh09_$w3_b6_m1", "bh09_$w3_b6_m2" },
{ "bh09_$w3_b7_m1", "bh09_$w3_b7_m2" },
{ "bh09_$w3_b8_m1", "bh09_$w3_b8_m2", "bh09_$w3_b8_m3" } }
CHARS_WAVES_BOATS = { CHARS_WAVE1_BOATS, CHARS_WAVE2_BOATS, CHARS_WAVE3_BOATS }
BOAT_DRIVER_COUNT = 1
BOAT_DRIVER_INDEX = 1
CHARS_SAINTS = {"bh09_$c062", "bh09_$c063"}
-- Vehicles --
VEH_START = { "bh09_$v022", "bh09_$v023", "bh09_$v024" }
VEH_WAVE1_HELIS = { "bh09_$w1_heli1", "bh09_$w1_heli2" }
VEH_WAVE1_BOATS = { "bh09_$w1_boat1", "bh09_$w1_boat2", "bh09_$w1_boat3",
"bh09_$w1_boat4", "bh09_$w1_boat5" }
VEH_WAVE1_BOATS_LEFT = { VEH_WAVE1_BOATS[1], VEH_WAVE1_BOATS[2] }
VEH_WAVE1_BOATS_RIGHT = { VEH_WAVE1_BOATS[3], VEH_WAVE1_BOATS[4], VEH_WAVE1_BOATS[5] }
VEH_WAVE2_HELIS = { "bh09_$w2_heli1", "bh09_$w2_heli2", "bh09_$w2_heli3" }
VEH_WAVE2_BOATS = { "bh09_$w2_boat1", "bh09_$w2_boat2", "bh09_$w2_boat3",
"bh09_$w2_boat4", "bh09_$w2_boat5", "bh09_$w2_boat6" }
VEH_WAVE2_BOATS_LEFT = { VEH_WAVE2_BOATS[4], VEH_WAVE2_BOATS[5], VEH_WAVE2_BOATS[6] }
VEH_WAVE2_BOATS_RIGHT = { VEH_WAVE2_BOATS[1], VEH_WAVE2_BOATS[2], VEH_WAVE2_BOATS[3] }
VEH_WAVE3_HELIS = { "bh09_$w3_heli1", "bh09_$w3_heli2", "bh09_$w3_heli3",
"bh09_$w3_heli4", "bh09_$w3_heli5", "bh09_$w3_heli6" }
VEH_WAVE3_BOATS = { "bh09_$w3_boat1", "bh09_$w3_boat2", "bh09_$w3_boat3",
"bh09_$w3_boat4", "bh09_$w3_boat5", "bh09_$w3_boat6",
"bh09_$w3_boat7", "bh09_$w3_boat8" }
VEH_WAVE3_BOATS_LEFT = { VEH_WAVE3_BOATS[1], VEH_WAVE3_BOATS[2], VEH_WAVE3_BOATS[3],
VEH_WAVE3_BOATS[4] }
VEH_WAVE3_BOATS_RIGHT = { VEH_WAVE3_BOATS[5], VEH_WAVE3_BOATS[6], VEH_WAVE3_BOATS[7],
VEH_WAVE3_BOATS[8] }
VEH_SAINTS = "bh09_$v025"
VEH_WAVES_HELIS = { VEH_WAVE1_HELIS, VEH_WAVE2_HELIS, VEH_WAVE3_HELIS }
VEH_WAVES_BOATS = { VEH_WAVE1_BOATS, VEH_WAVE2_BOATS, VEH_WAVE3_BOATS }
VEH_WAVES_BOATS_LEFT = { VEH_WAVE1_BOATS_LEFT, VEH_WAVE2_BOATS_LEFT, VEH_WAVE3_BOATS_LEFT }
VEH_WAVES_BOATS_RIGHT = { VEH_WAVE1_BOATS_RIGHT, VEH_WAVE2_BOATS_RIGHT, VEH_WAVE3_BOATS_RIGHT }
WAVE_BOAT_IS_TWO_SEATER = { { false, true, false, false, false },
{ true, false, false, false, false, true },
{ false, false, true, false, false, true, true, false } }
COURTESY_HELI = "bh09_$v001"
-- Text --
TEXT_BOARD_THE_SHIP = "bh09_board_the_ship"
TEXT_ELIMINATE_GANG = "bh09_eliminate_gang"
TEXT_30_SECONDS = "bh09_30_seconds"
TEXT_NEXT_WAVE = "bh09_next_wave"
TEXT_FIRST_WAVE = "bh09_first_wave"
TEXT_SECOND_WAVE = "bh09_second_wave"
TEXT_THIRD_WAVE = "bh09_third_wave"
TEXTS_WAVES = { TEXT_FIRST_WAVE, TEXT_SECOND_WAVE, TEXT_THIRD_WAVE }
TEXT_SHIP_ABANDONED = "bh09_ship_abandoned"
TEXT_ULTOR_KILLED = "bh09_ultor_killed"
-- Triggers --
TRIGGER_AK47_AMMO = "bh09_$t000"
TRIGGER_RPG_AMMO = "bh09_$t002"
TRIGGER_HOTEL_ELEVATOR = "airport_$AI_crib_elevator_up"
TRIGGER_BELOWDECKS = "bh09_$belowdecks"
MISSION_ELEVATOR_TRIGGER = "bh09_$Hotel_Elevator"
MISSION_ELEVATOR_DOWN_TRIGGER = "bh09_$Hotel_Elevator_Down"
HELIPAD_UP_ELEVATOR_DESTINATION = "bh09_$Hotel_Elevator_Down"
HELIPAD_DOWN_ELEVATOR_DESTINATION = "bh09_$Hotel_Elevator"
-- Threads --
THREAD_STAY_ON_SHIP = -1
THREAD_WAVE1_BOATS = {}
THREAD_WAVE2_BOATS = {}
THREAD_WAVE3_BOATS = {}
THREAD_WAVE1_HELIS = {}
THREAD_WAVE2_HELIS = {}
THREAD_WAVE3_HELIS = {}
THREAD_BOARDING = {}
THREAD_WAVES_BOATS = { THREAD_WAVE1_BOATS, THREAD_WAVE2_BOATS, THREAD_WAVE3_BOATS }
THREAD_WAVES_HELIS = { THREAD_WAVE1_HELIS, THREAD_WAVE2_HELIS, THREAD_WAVE3_HELIS }
-- Voice --
VOICE_INTRO_PHONECALL = {{"BR09_INTRO_L1", CELLPHONE_CHARACTER, 0},
{"PLAYER_BR09_INTRO_L2", LOCAL_PLAYER, 0},
{"BR09_INTRO_L3", CELLPHONE_CHARACTER, .25},
{"PLAYER_BR09_INTRO_L4", LOCAL_PLAYER, .25},
{"BR09_INTRO_L5", CELLPHONE_CHARACTER, .25},
{"PLAYER_BR09_INTRO_L6", LOCAL_PLAYER, .25},
{"BR09_INTRO_L7", CELLPHONE_CHARACTER, .25},
{"BR09_INTRO_L8", CELLPHONE_CHARACTER, 0},
{"PLAYER_BR09_INTRO_L9", LOCAL_PLAYER, .25},
{"BR09_INTRO_L10", CELLPHONE_CHARACTER, 0},
{"PLAYER_BR09_INTRO_L11", LOCAL_PLAYER, .25}}
VOICE_OUTRO_PHONECALL = {{"PLAYER_BR09_OUTRO_L1", LOCAL_PLAYER, .25},
{"BR09_OUTRO_L2", nil, 1}}
-- Checkpoints --
CHECKPOINT_BOAT = "bh09_checkpoint_boat"
-- Cutscenes --
CUTSCENE_IN = "br09-01"
CUTSCENE_ATTACK = "br09-02"
-- Other --
SHIP_BELOWDECKS_DOOR = "bh09_$Ship_Belowdecks_Entrance"
AIRPORT_CRIB_NAME = "AI_Hotel_Crib"
ATTACK_HELICOPTER_INDEX = 2
BETWEEN_WAVES_DELAY_SECONDS = 10
BOAT_HIT_POINTS_PERCENT_OF_NORMAL = 0.75
HELI_MEMBER_TO_SEAT_INDEX_MAPPING = { 0, 5, 4, 1 }
HELI_ATTACKER_WEAPON = "ak47"
HELI_ATTACKER_WEAPON_AMMO_COUNT = 1000
IN_COOP = false
Last_wave_completed = 0
Ultor_killed = 0
INITIAL_NUM_ULTOR = 18
SHIP_DISTANCE = 50
SHIP_ABANDON_DISTANCE = 100
INITIAL_SHIP_ABANDON_DISTANCE_METERS = 500
Num_abovedecks_remaining = sizeof_table( TABLE_ULTOR_ABOVEDECKS )
Players_out_of_current_boat_range = { [LOCAL_PLAYER] = true, [REMOTE_PLAYER] = true }
Wave_members_remaining = { 0, 0, 0 }
Cur_left_path_start_index = 0
Cur_right_path_start_index = 0
Mission_won = false
function bh09_all_players_in_boat_range()
if ( Players_out_of_current_boat_range[LOCAL_PLAYER] == false ) then
if ( coop_is_active() ) then
if ( Players_out_of_current_boat_range[REMOTE_PLAYER] == false ) then
return true
end
else
return true
end
end
return false
end
function bh09_start(bh09_checkpoint, is_restart)
-- Start trigger is hit...the activate button was hit
set_mission_author("Aaron Hanson (aka Father Zucosos)")
if coop_is_active() then
IN_COOP = true
end
-- interior = false, blocking = true, temporary = true
city_chunk_swap("sr2_chunk012", "ship", false, true, true )
mission_start_fade_out()
notoriety_force_no_spawn("police", true)
notoriety_force_no_spawn("ultor", true)
notoriety_force_no_spawn("brotherhood", true)
--group_create_hidden( GROUP_HELI_DESTROYERS, true )
--disable warping to shore.
player_warp_to_shore_disable(LOCAL_PLAYER)
if IN_COOP then
player_warp_to_shore_disable(REMOTE_PLAYER)
end
-- TEMP
--bh09_checkpoint = "blarg!"
--teleport_coop( TRIGGER_AK47_AMMO, TRIGGER_AK47_AMMO )
-- END TEMP
if bh09_checkpoint == MISSION_START_CHECKPOINT then
door_lock( SHIP_BELOWDECKS_DOOR, true )
if (not is_restart) then
cutscene_play( CUTSCENE_IN, "", "", false )
end
mission_debug( "teleport coop started.", 60, 1 )
teleport_coop( NAV_LOCAL_START, NAV_REMOTE_START )
mission_debug( "teleport coop finished, group create started.", 60, 2 )
if IN_COOP then
group_create(GROUP_START_COOP, true)
end
group_create(GROUP_START, true)
mission_debug( "group create finished.", 60, 3 )
bh09_notoriety_force_no_spawn()
mission_start_fade_in()
bh09_get_to_the_ship()
else--if ( bh09_checkpoint == CHECKPOINT_BOAT ) then
teleport( LOCAL_PLAYER, NAV_CHECKPOINT_LOCAL )
if ( coop_is_active() ) then
teleport( REMOTE_PLAYER, NAV_CHECKPOINT_REMOTE )
end
if ( group_is_loaded( GROUP_START ) == false ) then
group_create(GROUP_START, true)
end
if ( IN_COOP and group_is_loaded( GROUP_START_COOP ) == false ) then
group_create( GROUP_START_COOP, true )
end
bh09_notoriety_force_no_spawn()
trigger_enable(TRIGGER_AK47_AMMO, true)
marker_add_trigger(TRIGGER_AK47_AMMO, "", INGAME_EFFECT_LOCATION, SYNC_ALL)
on_trigger("bh09_give_ak47_ammo", TRIGGER_AK47_AMMO)
trigger_enable(TRIGGER_RPG_AMMO, true)
marker_add_trigger(TRIGGER_RPG_AMMO, "", INGAME_EFFECT_LOCATION, SYNC_ALL)
on_trigger("bh09_give_rpg_ammo", TRIGGER_RPG_AMMO)
--thread_new( "bh09_destroy_helicopter" )
mission_start_fade_in()
door_open( SHIP_BELOWDECKS_DOOR )
-- Update the "players near ship" stuff
bh09_update_player_locations( INITIAL_SHIP_ABANDON_DISTANCE_METERS )
bh09_do_waves_attack()
--bh09_first_wave()
end
end
function bh09_update_player_locations( distance_meters )
if get_dist_char_to_nav(LOCAL_PLAYER, NAV_SHIP) < distance_meters then
Players_out_of_current_boat_range[LOCAL_PLAYER] = false
end
if ( IN_COOP and get_dist_char_to_nav(REMOTE_PLAYER, NAV_SHIP) < distance_meters ) then
Players_out_of_current_boat_range[REMOTE_PLAYER] = false
end
end
function bh09_went_down_hotel_elevator( triggerer_name, trigger_name )
teleport( triggerer_name, HELIPAD_DOWN_ELEVATOR_DESTINATION )
end
function bh09_went_up_hotel_elevator_initial( triggerer_name, trigger_name )
-- Remove the marker and guidance
marker_remove_trigger( trigger_name, SYNC_ALL )
mission_waypoint_remove( SYNC_ALL )
-- Give the up trigger a normal "this can be used" effect
marker_add_trigger( trigger_name, "", INGAME_EFFECT_LOCATION, SYNC_ALL )
-- Mark the vehicle
marker_add_vehicle( VEH_START[ATTACK_HELICOPTER_INDEX],
MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_INTERACT, SYNC_ALL )
bh09_went_up_hotel_elevator( triggerer_name, trigger_name )
on_trigger( "bh09_went_up_hotel_elevator", trigger_name )
end
function bh09_went_up_hotel_elevator( triggerer_name, trigger_name )
teleport( triggerer_name, HELIPAD_UP_ELEVATOR_DESTINATION )
end
function bh09_get_to_the_ship()
-- For the attack helicopter, disable the elevator's original trigger and enable the
-- mission's trigger
if ( crib_is_unlocked( AIRPORT_CRIB_NAME ) ) then
trigger_enable( TRIGGER_HOTEL_ELEVATOR, false )
end
trigger_enable( MISSION_ELEVATOR_TRIGGER, true )
trigger_enable( MISSION_ELEVATOR_DOWN_TRIGGER, true )
on_trigger( "bh09_went_down_hotel_elevator", MISSION_ELEVATOR_DOWN_TRIGGER )
on_trigger( "bh09_went_up_hotel_elevator_initial", MISSION_ELEVATOR_TRIGGER )
-- Add guidance to the mission's trigger
marker_add_trigger( MISSION_ELEVATOR_TRIGGER, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL)
mission_waypoint_add( MISSION_ELEVATOR_TRIGGER, SYNC_ALL )
-- Add marker for the "elevator down" trigger
marker_add_trigger( MISSION_ELEVATOR_DOWN_TRIGGER, "", INGAME_EFFECT_LOCATION, SYNC_ALL)
thread_new( "bh09_phone_conversation" )
delay ( 3.0 )
group_create(GROUP_ULTOR, true)
for i, npc in pairs(TABLE_ALL_ULTOR) do
on_death("bh09_ultor_killed", npc)
end
for i, npc in pairs(TABLE_ULTOR_ABOVEDECKS) do
on_death( "bh09_ultor_abovedecks_killed", npc )
end
for i, veh in pairs(VEH_START) do
if i == ATTACK_HELICOPTER_INDEX then
-- Don't add anything - yet
else
marker_add_vehicle(veh, MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_INTERACT, SYNC_ALL)
end
end
mission_help_table(TEXT_BOARD_THE_SHIP)
while (get_char_vehicle_type(LOCAL_PLAYER) ~= VT_AIRPLANE) and
(get_char_vehicle_type(LOCAL_PLAYER) ~= VT_HELICOPTER) and
(get_char_vehicle_type(LOCAL_PLAYER) ~= VT_WATERCRAFT) and
(get_dist_char_to_nav(LOCAL_PLAYER, NAV_SHIP) > SHIP_DISTANCE) do
thread_yield()
end
mission_waypoint_remove(SYNC_ALL)
for i, veh in pairs(VEH_START) do
marker_remove_vehicle(veh, SYNC_ALL)
end
if ( crib_is_unlocked( AIRPORT_CRIB_NAME ) ) then
trigger_enable( TRIGGER_HOTEL_ELEVATOR, true )
end
trigger_enable( MISSION_ELEVATOR_TRIGGER, false )
marker_add_navpoint(NAV_SHIP, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL)
mission_waypoint_add(NAV_SHIP, SYNC_ALL)
while (Ultor_killed == 0) and (get_dist_char_to_nav(LOCAL_PLAYER, NAV_SHIP) > SHIP_DISTANCE)
and (not IN_COOP or (IN_COOP and get_dist_char_to_nav(REMOTE_PLAYER, NAV_SHIP) > SHIP_DISTANCE)) do
thread_yield()
end
-- Make sure the players don't completely abandon the ship
Players_out_of_current_boat_range[LOCAL_PLAYER] = false
Players_out_of_current_boat_range[REMOTE_PLAYER] = false
THREAD_STAY_ON_SHIP = thread_new( "bh09_stay_on_ship", INITIAL_SHIP_ABANDON_DISTANCE_METERS )
if (get_char_vehicle_type(LOCAL_PLAYER) == VT_WATERCRAFT) then
bh09_less_rpgs()
end
marker_remove_navpoint(NAV_SHIP, SYNC_ALL)
mission_waypoint_remove(SYNC_ALL)
bh09_eliminate_ultor()
end
function bh09_phone_conversation()
audio_play_conversation(VOICE_INTRO_PHONECALL, INCOMING_CALL)
end
function bh09_eliminate_ultor()
bh09_show_ultor_counter()
mission_help_table(TEXT_ELIMINATE_GANG)
for i, npc in pairs( TABLE_ULTOR_ABOVEDECKS ) do
npc_combat_enable(npc, true)
if not character_is_dead(npc) then
marker_add_npc(npc, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL)
end
end
while bh09_not_done_killing_ultor() do
thread_yield()
end
-- Disable boat spawning - it gets in the way of the waves
spawning_boats( false )
fade_out( 0 )
character_evacuate_from_all_vehicles( LOCAL_PLAYER )
if ( coop_is_active() ) then
character_evacuate_from_all_vehicles( REMOTE_PLAYER )
end
cutscene_play( CUTSCENE_ATTACK )
door_open( SHIP_BELOWDECKS_DOOR )
-- Now that the player knows about the ammo, add the triggers for it
trigger_enable(TRIGGER_AK47_AMMO, true)
ingame_effect_add_trigger(TRIGGER_AK47_AMMO, INGAME_EFFECT_LOCATION, SYNC_ALL)
on_trigger("bh09_give_ak47_ammo", TRIGGER_AK47_AMMO)
trigger_enable(TRIGGER_RPG_AMMO, true)
ingame_effect_add_trigger(TRIGGER_RPG_AMMO, INGAME_EFFECT_LOCATION, SYNC_ALL)
on_trigger("bh09_give_rpg_ammo", TRIGGER_RPG_AMMO)
objective_text_clear(0)
--thread_new( "bh09_destroy_helicopter" )
--vehicle_detonate(VEH_START[2])
delay(2)
mission_set_checkpoint(CHECKPOINT_BOAT)
release_to_world(GROUP_ULTOR)
bh09_do_waves_attack()
--bh09_first_wave()
end
function bh09_destroy_helicopter()
group_show( GROUP_HELI_DESTROYERS )
local helicopter_was_attacked = false
--
local attack_heli = VEH_START[ATTACK_HELICOPTER_INDEX]
for index, member_name in pairs( TABLE_HELI_DESTROYERS ) do
-- Mark and set up these people as if they're members of the first wave
marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL )
Wave_members_remaining[1] = Wave_members_remaining[1] + 1
on_death( "bh09_wave_member_died_wave1", member_name )
-- Have them attack the helicopter if it's close enough
if ( vehicle_is_destroyed( attack_heli ) == false ) then
local dist_to_heli = get_dist_char_to_vehicle( member_name, attack_heli )
if ( dist_to_heli < 125 ) then
-- fire_once = false
force_fire_object_position( member_name, attack_heli, false )
helicopter_was_attacked = true
end
end
end
-- If the attackers attacked the helicopter, destroy it
if ( helicopter_was_attacked ) then
-- Have the helicopter detonate
delay( 3.0 )
-- smoke = true, fire = true
vehicle_set_smoke_and_fire_state( attack_heli, true, true )
delay( 15.0 )
vehicle_detonate( attack_heli )
end
for index, member_name in pairs( TABLE_HELI_DESTROYERS ) do
if ( character_is_dead( member_name ) == false ) then
attack_closest_player( member_name )
end
end
end
function bh09_less_rpgs()
for i, npc in pairs(TABLE_ULTOR_RPG) do
if (i ~= 1) then
inv_item_remove_all(npc)
inv_item_add("ak47", 1, npc)
inv_item_equip("ak47", npc)
end
end
end
function bh09_not_done_killing_ultor()
return (Ultor_killed < INITIAL_NUM_ULTOR)
end
function bh09_give_ak47_ammo( triggerer_name, trigger_name )
bh09_maybe_cleanup_vehicles()
local rifle_slot_weapon = inv_item_in_slot( triggerer_name, "rifle" )
if ( rifle_slot_weapon == "none" ) then
inv_item_add( "ak47", 1, triggerer_name )
inv_item_equip( "ak47", triggerer_name )
else
inv_item_add_ammo( triggerer_name, rifle_slot_weapon, 30 )
end
end
function bh09_weapon_is_not_rocket_launcher( weapon_name )
if ( weapon_name == "rpg_launcher" or weapon_name == "rpg_annihilator" ) then
return false
end
return true
end
function bh09_give_rpg_ammo( triggerer_name, trigger_name )
bh09_maybe_cleanup_vehicles()
local rpg_slot_weapon = inv_item_in_slot( triggerer_name, "launcher" )
if ( rpg_slot_weapon == "none" or bh09_weapon_is_not_rocket_launcher( rpg_slot_weapon ) ) then
inv_item_add( "rpg_launcher", 1, triggerer_name )
inv_item_equip( "rpg_launcher", triggerer_name )
else
inv_item_add_ammo( triggerer_name, rpg_slot_weapon, 5 )
end
end
function bh09_maybe_cleanup_vehicles()
if (Last_wave_completed == 1) then
Last_wave_completed = 0
for i, veh in pairs(VEH_WAVE1_BOATS) do
object_destroy(veh)
end
for i, veh in pairs(VEH_WAVE1_HELIS) do
object_destroy(veh)
end
elseif (Last_wave_completed == 2) then
Last_wave_completed = 0
for i, veh in pairs(VEH_WAVE2_BOATS) do
object_destroy(veh)
end
for i, veh in pairs(VEH_WAVE2_HELIS) do
object_destroy(veh)
end
end
end
function bh09_ak47_ammo_trigger_watch()
while(1) do
thread_yield()
if (get_dist_char_to_nav(LOCAL_PLAYER, TRIGGER_AK47_AMMO) < 3) and player_button_just_pressed(3) then
local equipped_item = inv_item_get_equipped_item(LOCAL_PLAYER)
inv_item_add("ak47", 1, LOCAL_PLAYER)
if (equipped_item ~= nil) and (equipped_item ~= "") and (inv_has_item(equipped_item, LOCAL_PLAYER)) then
inv_item_equip(equipped_item, LOCAL_PLAYER)
else
inv_item_equip("ak47", LOCAL_PLAYER)
end
end
end
end
function bh09_rpg_ammo_trigger_watch()
while(1) do
thread_yield()
if (get_dist_char_to_nav(LOCAL_PLAYER, TRIGGER_RPG_AMMO) < 3) and player_button_just_pressed(3) then
local equipped_item = inv_item_get_equipped_item(LOCAL_PLAYER)
inv_item_add("rpg_launcher", 1, LOCAL_PLAYER)
if (equipped_item ~= nil) and (equipped_item ~= "") and (inv_has_item(equipped_item, LOCAL_PLAYER)) then
inv_item_equip(equipped_item, LOCAL_PLAYER)
else
inv_item_equip("rpg_launcher", LOCAL_PLAYER)
end
end
end
end
function bh09_wave_member_died_wave1( member_name )
bh09_wave_member_died( member_name, 1 )
end
function bh09_wave_member_died_wave2( member_name )
bh09_wave_member_died( member_name, 2 )
end
function bh09_wave_member_died_wave3( member_name )
bh09_wave_member_died( member_name, 3 )
end
function bh09_wave_member_died( member_name, wave_index )
-- Decrement the number of wave members left in this wave
Wave_members_remaining[wave_index] = Wave_members_remaining[wave_index] - 1
mission_debug( Wave_members_remaining[wave_index].." members remaining in wave "..wave_index..".", 10 )
bh09_soldier_died( member_name )
end
-- Sets up completion tracking for a wave.
--
function bh09_setup_wave_completion_tracking_and_mark_attackers( wave_index )
-- Add the heli destroyers for the first wave
if ( wave_index == 1 ) then
-- ( They're marked/tracked on spawn, so no need to mark or track them here. )
Wave_members_remaining[wave_index] = Wave_members_remaining[wave_index] + sizeof_table( TABLE_HELI_DESTROYERS )
end
for index, heli_group in pairs( CHARS_WAVES_HELIS[wave_index] ) do
Wave_members_remaining[wave_index] = Wave_members_remaining[wave_index] + sizeof_table( heli_group )
for member_index, member_name in pairs( heli_group ) do
on_death( "bh09_wave_member_died_wave"..wave_index, member_name )
marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL )
end
end
for index, boat_group in pairs( CHARS_WAVES_BOATS[wave_index] ) do
local cur_boat_two_seater = WAVE_BOAT_IS_TWO_SEATER[wave_index][index]
for member_index, member_name in pairs( boat_group ) do
-- Only include drivers as required kills if the boat is a two-seater. Otherwise the driver will drive away
-- after dropping off the other members
if ( member_index ~= BOAT_DRIVER_INDEX or cur_boat_two_seater ) then
Wave_members_remaining[wave_index] = Wave_members_remaining[wave_index] + 1
on_death( "bh09_wave_member_died_wave"..wave_index, member_name )
marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL )
end
end
end
end
function bh09_do_waves_attack()
-- Don't start the attack until all players are in range of the boat
repeat
thread_yield()
until ( bh09_all_players_in_boat_range() )
-- Make sure the players stay near the ship - closer, now that they're defending it
thread_kill( THREAD_STAY_ON_SHIP )
THREAD_STAY_ON_SHIP = thread_new( "bh09_stay_on_ship", SHIP_ABANDON_DISTANCE )
-- Before we attack, delay for a few seconds
delay(3)
-- Setup notoriety
notoriety_set("Brotherhood", 2)
notoriety_set_min("Brotherhood", 2)
-- Don't actually start the attack until both players are close enough
while (get_dist_char_to_nav(LOCAL_PLAYER, NAV_SHIP) > SHIP_DISTANCE)
and (not IN_COOP or (IN_COOP and get_dist_char_to_nav(REMOTE_PLAYER, NAV_SHIP) > SHIP_DISTANCE)) do
thread_yield()
end
-- ( Note that these wave functions yield until the respective waves are defeated )
-- First wave and intermission
bh09_do_wave( 1 )
bh09_do_intermission_and_prev_wave_cleanup( 1 )
-- Second wave and intermission
bh09_do_wave( 2 )
bh09_do_intermission_and_prev_wave_cleanup( 2 )
-- Third wave
bh09_do_wave( 3 )
bh09_waves_final_cleanup()
bh09_success_all_waves_defeated()
end
function bh09_any_wave_member_alive( wave_index )
if ( wave_index == 1 ) then
for member_index, member_name in pairs( TABLE_HELI_DESTROYERS ) do
if ( character_is_released( member_name ) == false ) then
if ( character_is_dead( member_name ) == false ) then
return true
else
marker_remove_npc( member_name, SYNC_ALL )
end
end
end
end
for heli_group_index, heli_group_name in pairs( CHARS_WAVES_HELIS[wave_index] ) do
for member_index, member_name in pairs( heli_group_name ) do
if ( character_is_released( member_name ) == false ) then
if ( character_is_dead( member_name ) == false ) then
return true
else
marker_remove_npc( member_name, SYNC_ALL )
end
end
end
end
for boat_group_index, boat_group_name in pairs( CHARS_WAVES_BOATS[wave_index] ) do
for member_index, member_name in pairs( boat_group_name ) do
if ( member_index ~= BOAT_DRIVER_INDEX ) then
if ( character_is_released( member_name ) == false ) then
if ( character_is_dead( member_name ) == false ) then
return true
else
marker_remove_npc( member_name, SYNC_ALL )
end
end
end
end
end
return false
end
function bh09_do_wave( wave_index )
-- Inform the player of the incoming wave
mission_help_table( TEXTS_WAVES[wave_index] )
-- Create the wave and setup tracking for it so that we'll
-- know when it's dead
group_create( GROUPS_WAVES[wave_index], true )
bh09_setup_wave_completion_tracking_and_mark_attackers( wave_index )
-- Go through all of the vehicles and have them attack
-- Helicopters
for heli_index, heli in pairs(VEH_WAVES_HELIS[wave_index]) do
THREAD_WAVES_HELIS[wave_index][heli_index] = thread_new( "bh09_heli", heli,
CHARS_WAVES_HELIS[wave_index][heli_index],
heli_index )
end
-- Boats
for boat_index, boat in pairs(VEH_WAVES_BOATS[wave_index]) do
--marker_add_vehicle( boat, MINIMAP_ICON_KILL, INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL )
vehicle_enter_group_teleport( CHARS_WAVES_BOATS[wave_index][boat_index], boat )
on_vehicle_destroyed( "bh09_boat_destroyed", boat )
-- Set the boat's HP to a new, lower, value
local cur_max_boat_hp = get_max_hit_points( boat )
local new_max_boat_hp = cur_max_boat_hp * BOAT_HIT_POINTS_PERCENT_OF_NORMAL
set_current_hit_points( boat, new_max_boat_hp )
set_max_hit_points( boat, new_max_boat_hp )
end
-- Have the left-hand boats take the left paths, and the right-hand boats take the right-hand paths
for left_index, boat in pairs(VEH_WAVES_BOATS_LEFT[wave_index]) do
local _wave_index, boat_index = bh09_get_boat_wave_index_and_boat_index( boat )
THREAD_WAVES_BOATS[wave_index][boat_index] = thread_new( "bh09_boat", boat, left_index,
NAV_BOAT_PATH_LEFT, NAV_STAIRS_LEFT_PATH, CHARS_WAVES_BOATS[wave_index][boat_index] )
end
for right_index, boat in pairs(VEH_WAVES_BOATS_RIGHT[wave_index]) do
local _wave_index, boat_index = bh09_get_boat_wave_index_and_boat_index( boat )
THREAD_WAVES_BOATS[wave_index][boat_index] = thread_new( "bh09_boat", boat, right_index,
NAV_BOAT_PATH_RIGHT, NAV_STAIRS_RIGHT_PATH, CHARS_WAVES_BOATS[wave_index][boat_index] )
end
-- Yield until this wave is killed
while bh09_any_wave_member_alive(wave_index) do--Wave_members_remaining[wave_index] > 0 do
thread_yield()
end
Last_wave_completed = wave_index
end
function bh09_do_intermission_and_prev_wave_cleanup( last_wave_index )
delay(3)
mission_help_table_nag( TEXT_NEXT_WAVE, BETWEEN_WAVES_DELAY_SECONDS )
hud_timer_set(0, BETWEEN_WAVES_DELAY_SECONDS * 1000, "", false)
minimap_icon_add_trigger( TRIGGER_AK47_AMMO, MINIMAP_ICON_PROTECT_ACQUIRE )
minimap_icon_add_trigger( TRIGGER_RPG_AMMO, MINIMAP_ICON_PROTECT_ACQUIRE )
for i, thread in pairs(THREAD_WAVES_HELIS[last_wave_index]) do
if thread ~= -1 then
thread_kill(thread)
end
end
for i, thread in pairs(THREAD_WAVES_BOATS[last_wave_index]) do
if thread ~= -1 then
thread_kill(thread)
end
end
while(hud_timer_get_remainder(0) > 0) do
thread_yield()
end
hud_timer_stop(0)
minimap_icon_remove_trigger(TRIGGER_AK47_AMMO, SYNC_ALL)
minimap_icon_remove_trigger(TRIGGER_RPG_AMMO, SYNC_ALL)
release_to_world( GROUPS_WAVES[last_wave_index] )
end
function bh09_waves_final_cleanup()
for i, thread in pairs(THREAD_BOARDING) do
if thread ~= -1 then
thread_kill(thread)
end
end
end
function bh09_wave_complete(chars, helis)
for i, set in pairs(chars) do
for j, npc in pairs(set) do
if not character_is_dead(npc) then
return false
end
end
end
for i, heli in pairs(helis) do
if not vehicle_is_destroyed(heli) then
return false
end
end
return true
end
function bh09_get_boat_path_goal( boat_path_name )
if ( boat_path_name == NAV_BOAT_PATH_LEFT ) then
return NAV_BOAT_LEFT_GOAL
else--if ( boat_path_name == NAV_BOAT_PATH_RIGHT ) then
return NAV_BOAT_RIGHT_GOAL
end
end
function bh09_get_boat_leave_path( boat_path_name )
if ( boat_path_name == NAV_BOAT_PATH_LEFT ) then
return NAV_BOAT_LEAVE_PATH_LEFT
else--if ( boat_path_name == NAV_BOAT_PATH_RIGHT ) then
return NAV_BOAT_LEAVE_PATH_RIGHT
end
end
function bh09_get_boat_wave_index_and_boat_index( boat_name )
for wave_index, boat_group in pairs( VEH_WAVES_BOATS ) do
for boat_index, boat in pairs( boat_group ) do
if ( boat_name == boat ) then
return wave_index, boat_index
end
end
end
script_assert( false, "Boat with name "..boat_name.." not found." )
end
function bh09_is_boat_two_seater( boat_name )
local wave_index, boat_index = bh09_get_boat_wave_index_and_boat_index( boat_name )
return WAVE_BOAT_IS_TWO_SEATER[wave_index][boat_index]
end
function bh09_boat(boat, delay_factor, boat_path, stairs_path, passengers )
vehicle_disable_chase( boat, true )
vehicle_disable_flee( boat, true )
delay(6 * delay_factor)
local THREAD_PATHFIND = thread_new("bh09_boat_pathfind", boat, boat_path)
local goal = bh09_get_boat_path_goal( boat_path )
local boat_two_seater = bh09_is_boat_two_seater( boat )
while (get_dist_vehicle_to_nav(boat, goal) > 10) do
thread_yield()
end
thread_kill(THREAD_PATHFIND)
delay(2)
for index, name in pairs( passengers ) do
-- Everyone in a two-seat boat gets off, but drivers of four-seat boats need to drive the boat
-- back so they don't get off
if ( index ~= BOAT_DRIVER_INDEX or boat_two_seater ) then
if ( not character_is_dead( name ) and character_is_in_vehicle( name ) ) then
mission_debug( "telling character "..name.." in boat "..boat.." to board.", 15 )
THREAD_BOARDING[name] = thread_new("bh09_boarding", name, stairs_path, index * 2 )
end
end
end
marker_remove_vehicle(boat, SYNC_ALL)
vehicle_stop( boat )
delay( 1.0 )
-- Boats with more than two seats pathfind back to their origin after making a dropoff.
if ( boat_two_seater == false ) then
local departure_path = bh09_get_boat_leave_path( boat_path )
if ( vehicle_is_destroyed( boat ) == false and vehicle_get_driver( boat ) ~= nil ) then
vehicle_pathfind_to(boat, departure_path, true, true)
end
if ( vehicle_is_destroyed( boat ) == false ) then
vehicle_exit( passengers[BOAT_DRIVER_INDEX] )
release_to_world( passengers[BOAT_DRIVER_INDEX] )
end
end
release_to_world( boat )
end
function bh09_boat_pathfind(boat, boat_path)
while not vehicle_is_destroyed(boat) do
thread_yield()
vehicle_pathfind_to(boat, boat_path, true, true)
end
end
function bh09_get_stairs_path_start( stairs_path )
if ( stairs_path == NAV_STAIRS_LEFT_PATH ) then
Cur_left_path_start_index = Cur_left_path_start_index + 1
if ( Cur_left_path_start_index > NUM_LEFT_PATH_STARTS ) then
Cur_left_path_start_index = 1
end
return NAV_STAIRS_LEFT_PATH_STARTS[Cur_left_path_start_index]
else--if ( stairs_path == NAV_STAIRS_RIGHT_PATH ) then
Cur_right_path_start_index = Cur_right_path_start_index + 1
if ( Cur_right_path_start_index > NUM_RIGHT_PATH_STARTS ) then
Cur_right_path_start_index = 1
end
return NAV_STAIRS_RIGHT_PATH_STARTS[Cur_right_path_start_index]
end
end
function bh09_boarding(npc, nav_stairs, delay_amount)
vehicle_exit_teleport(npc)
delay(delay_amount)
local stairs_path_start = bh09_get_stairs_path_start( nav_stairs )
teleport( npc, stairs_path_start )
attack_closest_player(npc)
move_to_safe( npc, nav_stairs, 2, false, true )
if ( character_is_dead( npc ) ) then
return
end
attack_closest_player(npc)
while not character_is_dead(npc) do
thread_yield()
delay(1)
if (not character_is_dead(npc)) and character_is_swimming(npc) then
delay(2)
teleport( npc, stairs_path_start )
attack_closest_player(npc)
move_to_safe( npc, nav_stairs, 2, false, true )
if ( character_is_dead( npc ) ) then
return
end
attack_closest_player(npc)
end
end
end
function bh09_soldier_died(npc)
on_death("", npc)
if ( THREAD_BOARDING[npc] ~= INVALID_THREAD_HANDLE and
THREAD_BOARDING[npc] ~= nil ) then
thread_kill(THREAD_BOARDING[npc])
end
marker_remove_npc(npc, SYNC_ALL)
end
function bh09_boat_destroyed(boat)
on_vehicle_destroyed("", boat)
marker_remove_vehicle(boat, SYNC_ALL)
end
function bh09_heli(heli, chars, i)
--marker_add_vehicle(heli, MINIMAP_ICON_KILL, INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL)
for member_index, member_name in pairs( chars ) do
inv_item_remove_all( member_name )
inv_item_add( HELI_ATTACKER_WEAPON, 1, member_name )
inv_item_add_ammo( member_name, HELI_ATTACKER_WEAPON, HELI_ATTACKER_WEAPON_AMMO_COUNT )
vehicle_enter_teleport( member_name, heli, HELI_MEMBER_TO_SEAT_INDEX_MAPPING[member_index] )
end
delay((i-1) * 4)
--local THREAD_TEMP_CHASE = thread_new("vehicle_chase", heli, LOCAL_PLAYER)
--delay(8)
--thread_kill(THREAD_TEMP_CHASE)
helicopter_fly_to_direct( heli, 20, NAV_HELI_DROPOFFS[i] )
vehicle_exit( chars[2] )
delay( 2.0 )
if ( i == 1 ) then
helicopter_fly_to_direct( heli, 20, "bh09_$To_Path1_Start" )
end
while not vehicle_is_destroyed(heli) do
helicopter_fly_to_direct(heli, 20, NAV_HELI_PATHS[i])
thread_yield()
end
marker_remove_vehicle(heli, SYNC_ALL)
end
function bh09_stay_on_ship( distance_meters )
while 1 do
thread_yield()
if get_dist_char_to_nav(LOCAL_PLAYER, NAV_SHIP) > distance_meters then
mission_help_table_nag(TEXT_30_SECONDS, SYNC_LOCAL)
hud_timer_set(1, 30000, "bh09_failure_abandoned_ship", true)
minimap_icon_add_navpoint_radius( NAV_SHIP, MINIMAP_ICON_LOCATION, distance_meters, nil, SYNC_LOCAL )
Players_out_of_current_boat_range[LOCAL_PLAYER] = true
while get_dist_char_to_nav(LOCAL_PLAYER, NAV_SHIP) > distance_meters do
thread_yield()
end
Players_out_of_current_boat_range[LOCAL_PLAYER] = false
minimap_icon_remove_navpoint( NAV_SHIP, SYNC_LOCAL )
hud_timer_stop(1)
end
if IN_COOP and get_dist_char_to_nav(REMOTE_PLAYER, NAV_SHIP) > distance_meters then
mission_help_table_nag(TEXT_30_SECONDS, SYNC_REMOTE)
hud_timer_set(1, 30000, "bh09_failure_abandoned_ship", true)
minimap_icon_add_navpoint_radius( NAV_SHIP, MINIMAP_ICON_LOCATION, distance_meters, nil, SYNC_REMOTE )
Players_out_of_current_boat_range[REMOTE_PLAYER] = true
while get_dist_char_to_nav(REMOTE_PLAYER, NAV_SHIP) > distance_meters do
thread_yield()
end
Players_out_of_current_boat_range[REMOTE_PLAYER] = false
minimap_icon_remove_navpoint( NAV_SHIP, SYNC_REMOTE )
hud_timer_stop(1)
end
end
end
function bh09_ultor_abovedecks_killed( npc )
Num_abovedecks_remaining = Num_abovedecks_remaining - 1
if ( Num_abovedecks_remaining == 0 ) then
trigger_enable( TRIGGER_BELOWDECKS, true )
on_trigger( "bh09_reached_belowdecks_door", TRIGGER_BELOWDECKS )
marker_add_trigger( TRIGGER_BELOWDECKS, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL )
for i, npc in pairs( TABLE_ULTOR_BELOWDECKS ) do
npc_combat_enable(npc, true)
if not character_is_dead(npc) then
marker_add_npc(npc, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL)
end
end
door_lock( SHIP_BELOWDECKS_DOOR, false )
door_open( SHIP_BELOWDECKS_DOOR )
end
bh09_ultor_killed( npc )
end
function bh09_reached_belowdecks_door( triggerer_name, trigger_name )
marker_remove_trigger( trigger_name, SYNC_ALL )
trigger_enable( trigger_name, false )
end
function bh09_ultor_killed(npc)
on_death("", npc)
marker_remove_npc(npc, SYNC_ALL)
Ultor_killed = Ultor_killed + 1
bh09_show_ultor_counter()
end
function bh09_show_ultor_counter()
objective_text(0, TEXT_ULTOR_KILLED, Ultor_killed, INITIAL_NUM_ULTOR)
end
function bh09_failure_abandoned_ship()
delay(3)
mission_end_failure("bh09", TEXT_SHIP_ABANDONED)
end
function bh09_success_all_waves_defeated()
audio_play_conversation(VOICE_OUTRO_PHONECALL, INCOMING_CALL)
delay(3)
Mission_won = true
mission_end_success("bh09")
end
function bh09_cleanup()
-- Cleanup mission here
-- Revert boat spawning
spawning_boats( true )
character_evacuate_from_all_vehicles( LOCAL_PLAYER )
if ( coop_is_active() ) then
character_evacuate_from_all_vehicles( REMOTE_PLAYER )
end
-- Swap the chunks back to their permanent state
-- interior = false, blocking = false, temporary = false
city_chunk_swap("sr2_chunk012", "normal", false, false, false )
minimap_icon_remove_trigger( TRIGGER_AK47_AMMO, SYNC_ALL )
ingame_effect_remove_trigger(TRIGGER_AK47_AMMO, SYNC_ALL)
on_trigger("", TRIGGER_AK47_AMMO)
minimap_icon_remove_trigger( TRIGGER_RPG_AMMO, SYNC_ALL )
ingame_effect_remove_trigger(TRIGGER_RPG_AMMO, SYNC_ALL)
on_trigger("", TRIGGER_RPG_AMMO)
if ( crib_is_unlocked( AIRPORT_CRIB_NAME ) ) then
trigger_enable( TRIGGER_HOTEL_ELEVATOR, true )
end
for i, set in pairs(CHARS_WAVE1_BOATS) do
for j, npc in pairs(set) do
marker_remove_npc(npc, SYNC_ALL)
end
end
for i, set in pairs(CHARS_WAVE2_BOATS) do
for j, npc in pairs(set) do
marker_remove_npc(npc, SYNC_ALL)
end
end
for i, set in pairs(CHARS_WAVE3_BOATS) do
for j, npc in pairs(set) do
marker_remove_npc(npc, SYNC_ALL)
end
end
for i, thread in pairs(THREAD_WAVE1_BOATS) do
if thread ~= -1 then
thread_kill(thread)
end
end
for i, thread in pairs(THREAD_WAVE2_BOATS) do
if thread ~= -1 then
thread_kill(thread)
end
end
for i, thread in pairs(THREAD_WAVE3_BOATS) do
if thread ~= -1 then
thread_kill(thread)
end
end
for i, thread in pairs(THREAD_WAVE1_HELIS) do
if thread ~= -1 then
thread_kill(thread)
end
end
for i, thread in pairs(THREAD_WAVE2_HELIS) do
if thread ~= -1 then
thread_kill(thread)
end
end
for i, thread in pairs(THREAD_WAVE3_HELIS) do
if thread ~= -1 then
thread_kill(thread)
end
end
if THREAD_STAY_ON_SHIP ~= -1 then
thread_kill(THREAD_STAY_ON_SHIP)
end
if group_is_loaded(GROUP_SAINTS) then
group_show(GROUP_SAINTS)
end
notoriety_set_min("Brotherhood", 0)
--re enable warping to shore.
player_warp_to_shore_enable(LOCAL_PLAYER)
if IN_COOP then
player_warp_to_shore_enable(REMOTE_PLAYER)
end
if ( Mission_won == false ) then
teleport( LOCAL_PLAYER, NAV_LOCAL_START )
if ( coop_is_active() ) then
teleport( REMOTE_PLAYER, NAV_REMOTE_START )
end
end
bh09_notoriety_force_no_spawn( false )
end
-- Disables or enables notoriety spawning for all teams for which
-- it should be disabled for during this mission.
--
-- no_spawning: True to disable ( defaults to true. ) False to enable.
--
function bh09_notoriety_force_no_spawn( no_spawning )
if ( no_spawning == nil ) then
no_spawning = true
end
notoriety_force_no_spawn( "samedi", no_spawning )
notoriety_force_no_spawn( "brotherhood", no_spawning )
notoriety_force_no_spawn( "ronin", no_spawning )
notoriety_force_no_spawn( "police", no_spawning )
notoriety_force_no_spawn( "ultor", no_spawning )
end
function bh09_success()
-- Called when the mission has ended with success
group_create(GROUP_COURTESY_HELI, true)
release_to_world(COURTESY_HELI)
end