--[[
M06.lua
SR3 Mission Script
DATE: 06-09-2010
AUTHOR: Neil Ryan
]]--
-- Debug flags --
-- Tweakable Parameters --
M06_BOMB_TIMER_INITIAL_MS = 960000
M06_BOMB_TIMER_FACTORY_MS = 900000
M06_BOMB_TIMER_BRUTE_KILLED_MS = 540000
M06_BOMB_TIMER_BALL_DROP_MS = 480000
-- Groups --
M06_group = {
-- loading dock trucks
trucks = {
name = "trucks_group"
},
escape_truck = {
name = "Escape_truck_group",
vehicle = "Escape Truck"
},
workers = {
name = "Dock_workers",
members1 = { "Dock_worker 001", "Dock_worker 002", "Dock_worker 003",
"Dock_worker 004", "Dock_worker 005", "Dock_worker 006" }
},
dock = {
name = "Dock_thugs",
members = { "Dock_sniper 001", "Dock_thug 007", "Dock_thug 008",
"Dock_thug 009", "Dock_thug 011", "Dock_thug 004<001>" }
},
dock1 = {
name = "Dock_reenforcement 000",
members = { "Dock_thug 002",
"Dock_thug 001", "Dock_thug 018" },
navpoints = { "Dock_Nav 002",
"Dock_Nav 003", "Dock_Nav 004" }
},
dock2 = {
name = "Dock_reenforcement 001",
members = { "Dock_sniper 003", "Dock_thug 003",
"Dock_thug 004", "Dock_thug 006"},
navpoints = { "Dock_Nav 011", "Dock_Nav 012",
"Dock_Nav 014", "Dock_Nav 015"}
},
-- These guys come out of the elevators
dock3 = {
name = "Dock_reenforcement 002",
members = { "Dock_thug 013",
"Dock_thug 015", "Dock_thug 017" },
navpoints = { "Dock_Nav 006",
"Dock_Nav 009", "Dock_Nav 010" }
},
dock_brute = {
name = "Dock_brute_group",
brute = "Dock_brute",
brute_killed = false,
},
saints_backup = {
name = "saints_backup_group",
vehicle = "saint_truck",
members = { "Saint_Backup 001", "Saint_Backup 002",
"Saint_Backup 003", "Saint_Backup 004" },
navpoint = "saints_backup_nav",
thread = INVALID_THREAD_HANDLE
},
bomb_truck = {
name = "bomb_truck_group",
driver = "bomb_truck_driver",
vehicle = "bomb_truck",
path = "bomb_drive_spline",
nav = "bomb_end_nav"
},
-- This groups starts active in the cloning facility
-- There are two snipers in the group not shown below as they dont wander
factory1 = {
name = "factory_thugs 001",
members = { "factory_thug 003", "factory_thug 004", "factory_thug 013",
"factory_thug 006", "factory_thug 007", "factory_thug 008" },
wander = { "Factory_Wander 002", "Factory_Wander 002", "Factory_Wander 001",
"Factory_Wander 003", "Factory_Wander 001", "Factory_Wander 001" },
distance = { 3, 3, 5, 5, 5, 5, 5 },
walker = "factory_thug 007<001>",
walk_nav = "Hall Walk",
},
factory1a = {
members = { "factory_thug 005", "factory_thug 009",
"factory_thug 022", "factory_thug 035" },
navpoints = { "Factory_Nav 019", "Factory_Nav 020",
"Factory_Nav 021", "Factory_Nav 022" }
},
factory2 = {
trigger = "factory_wave_trigger 001",
hit = false,
name = "factory_thugs 002",
members = { "factory_thug 001", "factory_thug 002",
"factory_thug 010", "factory_thug 011" },
navpoints = { "Factory_Nav 001", "Factory_Nav 002",
"Factory_Nav 003", "Factory_Nav 004" }
},
factory3 = {
trigger = "factory_wave_trigger 002",
hit = false,
name = "factory_thugs 003",
members = { "factory_thug 012", "factory_thug 014", "factory_thug 015",
"factory_thug 016", "factory_thug 017", "factory_thug 018" },
navpoints = { "Factory_Nav 005", "Factory_Nav 006", "Factory_Nav 007",
"Factory_Nav 008", "Factory_Nav 009", "Factory_Nav 010" }
},
factory4 = {
trigger = "factory_wave_trigger 003",
hit = false,
name = "factory_thugs 004",
members = { "factory_thug 019", "factory_thug 021",
"factory_thug 023", "factory_thug 024", "factory_thug 025",
"factory_thug 026", "factory_thug 027" },
navpoints = { "Factory_Nav 011", "Factory_Nav 012", "Factory_Nav 013",
"Factory_Nav 015", "Factory_Nav 016",
"Factory_Nav 017", "Factory_Nav 018" }
},
factory_brute = {
name = "Factory_brute_group",
brute = "factory_brute",
brute_killed = false,
brute_flamer = "factory_brute_flamer",
flamer_killed = false,
navpoint = "Brute_Nav 001"
},
top_floor = {
name = "Top_floor_thugs",
members = { "top_floor_thug 001", "top_floor_thug 002", "top_floor_thug 003", "top_floor_thug 004",
"top_floor_thug 005", "top_floor_thug 006", "top_floor_thug 007", "top_floor_thug 008",
"top_floor_thug 009", "top_floor_thug 010", "top_floor_thug 011", "top_floor_thug 012",
"top_floor_thug 013", "top_floor_thug 014", "top_floor_thug 015", "top_floor_thug 016" },
},
Phillipe = {
name = "Phillipe 001",
phillipe = "Phillipe"
},
-- Ball Drop Groups
ball = {
name = "ball_group",
vehicle = "the_ball",
nav = "ball_start",
},
-- not exactly homies
ball_saints = {
name = "ball_saints_group",
oleg = "Oleg_ball_drop"
},
ball_thugs = {
name = "support_thugs_group",
-- broken down by floor and cable being broken
floor1 = {
{ "Support_thug_first 001" },
{ "Support_thug_first 002", "Support_thug_first 003" },
{}
},
-- "Cable__nav 00"
floor1_nav = { "Cable_one_nav 003", "Cable_two_nav 003", "Cable_three_nav 003" },
-- only on Oleg's floor (keep watching Oleg do cool stuff)
floor2 = {
{ "Support_thug_second 001", "Support_thug_second 002" },
{ "Support_thug_second 003", "Support_thug_second 004" },
{ "Support_thug_second 005" },
},
floor2_nav = { "Cable_one_nav 003", "Cable_two_nav 003", "Cable_three_nav 003" },
floor3 = {
{},
{ "Support_thug_third 001", "Support_thug_third 002" },
{ "Support_thug_third 003" }
},
floor3_nav = { "Cable_one_nav 002", "Cable_two_nav 002", "Cable_three_nav 002" },
},
ball_stop1 = {
name = "ball_stop1_group",
members = { "ball_stop1_attacker 001", "ball_stop1_attacker 002", "ball_stop1_attacker 003",
"ball_stop1_attacker 004", "ball_stop1_attacker 005", "ball_stop1_attacker 006",
"ball_stop1_attacker 007", "ball_stop1_attacker 008", "ball_stop1_attacker 009",
"ball_stop1_attacker 010", "ball_stop1_attacker 011", "ball_stop1_attacker 012",
"ball_stop1_attacker 013", "ball_stop1_attacker 014", "ball_stop1_attacker 015"
},
lookat = "stop1_lookat"
},
ball_stop2 = {
name = "ball_stop2_group",
members = { "ball_stop2_attacker 001", "ball_stop2_attacker 002", "ball_stop2_attacker 003",
"ball_stop2_attacker 004", "ball_stop2_attacker 005", "ball_stop2_attacker 006",
"ball_stop2_attacker 007", "ball_stop2_attacker 008", "ball_stop2_attacker 009",
"ball_stop2_attacker 010", "ball_stop2_attacker 011", "ball_stop2_attacker 012",
"ball_stop2_attacker 013", "ball_stop2_attacker 014", "ball_stop2_attacker 015"
},
brute = "ball_stop2_attacker 002",
brute_nav = "Brute_run_to",
brute_restart = "brute_restart",
lookat = "stop2_lookat"
},
ball_stop3 = {
name = "ball_stop3_group",
brute = "ball_stop3_attacker 001",
brute_nav = "Brute_nav",
lookat = "stop3_lookat",
upper_nav = "Upper_nav",
mid_nav = "Mid_nav",
lower_nav = "Lower_nav",
set1 = { "ball_stop3_attacker 006", "ball_stop3_attacker 007" },
set2 = { "ball_stop3_attacker 010" },
set3 = { "ball_stop3_attacker 005" },
set4 = { "ball_stop3_attacker 011", "ball_stop3_attacker 012" },
set5 = { "ball_stop3_attacker 013" },
set6 = { "ball_stop3_attacker 014" },
set7 = { "ball_stop3_attacker 015", "ball_stop3_attacker 016" }
},
start_homies = {
name = "start_homies",
pierce = "Pierce_start",
shaundi = "Shaundi_start",
oleg = "",
vehicle = "Script_Vehicle 001" -- car for you if you like
},
dock_homies = {
name = "dock_homies",
pierce = "Pierce_dock",
shaundi = "Shaundi_dock",
oleg = ""
},
factory_homies = {
name = "factory_homies",
pierce = "Pierce_factory",
shaundi = "Shaundi_factory",
oleg = ""
},
-- after you find Oleg, before you are upstairs
brute_killed_homies = {
name = "brute_killed_homies",
pierce = "Pierce_brute_killed",
shaundi = "Shaundi_brute_killed",
oleg = "Oleg_brute_killed"
},
top_floor_homies = {
name = "top_floor_homies",
pierce = "Pierce_top_floor",
shaundi = "Shaundi_top_floor",
oleg = "Oleg_top_floor"
},
off_ball_homies = {
name = "off_ball_homies",
pierce = "Pierce_off_ball",
shaundi = "Shaundi_off_ball",
oleg = "Oleg_off_ball",
falling_brute = "Falling Brute"
},
}
-- Keep track of the current homie
M06_current_Pierce = ""
M06_current_Shaundi = ""
-- Navpoints --
M06_sniper_leash_nav = "Sniper_Leash_Nav"
M06_elevator_noise = "Elevator_Noise_Nav"
M06_found_Phillipe_nav = "Phillipe_teleport_nav"
M06_bomb_arm_nav = "Bomb_arm_nav"
M06_worker_nav = "Worker_run_nav"
M06_done_with_ball_nav = "Done_on_ball"
M06_done_with_ball_nav1 = "Done_on_ball<001>"
M06_oleg_zscene_navs = { "Oleg_zscene_nav 001", "Oleg_zscene_nav 002" }
M06_falling_brute = "Falling Brute Nav"
M06_Oleg_path = {
stair = "Oleg Spline 01",
climbs = "Oleg Spline 02",
offices = "Oleg Spline 03",
stairs = {"Oleg_floor_nav0", "Oleg_floor_nav1", "Oleg_floor_nav2", "Oleg_floor_nav3"},
climb = {"Oleg_stairs_nav1", "Oleg_stairs_nav2", "Oleg_stairs_nav3", "Oleg_stairs_nav4"},
office = "Oleg_door_nav",
upstairs = {"Oleg_upstairs_nav0", "Oleg_upstairs_nav1", "Oleg_upstairs_nav2", "Oleg_upstairs_nav3"}
}
-- Audio Emitters --
M06_emitter = {
dock_start = "M06_em_alarm",
dock_end = "M06_em_alarm_STOP",
clone_room_start = { "M06_amb_cloning_room", "M06_em_elec_unit_hum", "M06_em_elec_unit_hum<001>",
"M06_em_chem_tank_hiss", "M06_em_chem_tank_hiss<001>", "M06_em_chem_tank_hiss<002>",
"M06_em_chem_tank_hiss<003>", "M06_em_chem_tank_hiss<004>", "M06_em_hi_tech_hum",
"M06_em_hi_tech_hum<001>", "M06_em_hi_tech_hum<002>", "M06_em_flutter_throb",
"M06_em_flutter_throb<001>", "M06_em_flutter_throb<002>", "M06_em_flutter_throb<003>",
"M06_em_flutter_throb<004>", "M06_em_power_hum", "M06_em_power_hum<001>",
"M06_em_power_hum<002>", "M06_em_power_hum<003>", "M06_em_power_hum<004>",
"M06_em_power_hum<005>", "M06_em_power_hum<006>", "M06_em_turbine_throb",
"M06_em_turbine_throb<001>", "M06_em_turbine_throb<002>", "M06_em_turbine_throb<003>" },
clone_room_end = "M06_amb_cloning_room_STOP",
office_start = "M06_amb_offices",
office_end = "M06_amb_offices_STOP",
ball_start = "M06_amb_cweight_shaft",
ball_end = "M06_amb_cweight_shaft_STOP",
ball_groan = "m06_sfx_counterweight_groans",
ball_traffic = "m06_sfx_cweight_roll_traffic",
music = {
mission_start = "M06_music_mission_start",
dock_start = "M06_music_loading_dock",
dock_end = "M06_music_loading_dock_end",
clone_start = "M06_music_cloning_lab",
clone_end = "M06_music_cloning_lab_end",
clone_cp = "M06_music_cloning_lab_checkpoint",
follow_oleg = "M06_music_follow_oleg",
hanging = "M06_music_ball_hang",
ball_start = "M06_music_ball_fall",
ball_end = "M06_music_ball_fall_end",
stop = "M06_music_STOP ",
},
}
-- Triggers --
M06_trigger = {
dock = {
name = "Dock_trigger",
hit = false
},
closet = {
name = "Closet Trigger",
hit = false
},
notice_snipers = {
name = "notice_snipers",
hit = false
},
dock_thug_trigger01 = {
name = "Dock_Thug_Trigger_01",
hit = false
},
dock_thug_trigger02 = {
name = "Dock_Thug_Trigger_02",
hit = false
},
arm_bomb = {
name = "bomb_trigger",
hit = false
},
enter_factory = {
name = "enter_factory",
hit = false
},
factory_breadcrumb1 = {
name = "factory_breadcrumb_001",
hit = false
},
factory_breadcrumb2 = {
name = "factory_breadcrumb_002",
hit = false
},
factory_breadcrumb3 = {
name = "factory_breadcrumb_003",
hit = false
},
factory_brute = {
name = "factory_brute_trigger",
hit = false
},
factory_brute_flamer = {
name = "factory_brute_flamer_trigger",
hit = false
},
oleg_cutscene = {
name = "Oleg_trigger",
hit = false
},
oleg_crash1 = {
name = "Oleg Crash 01",
hit = false
},
oleg_crash2 = {
name = "Oleg Crash 02",
hit = false
},
ball_drop = {
name = "ball_drop_trigger",
hit = false
},
brute_net = {
name = "brute_safety_net",
hit = false
},
destroy_building = {
name = "bomb_leave",
hit = false
},
disarm_bomb = {
name = "bomb_disarm",
hit = false
},
stairs1 = {
name = "At_stairs_trigger 001",
hit = false
},
stairs2 = {
name = "At_stairs_trigger 002",
hit = false
},
office = {
name = "At_office_trigger",
hit = false
},
phillipe = {
name = "Phillipe_trigger",
hit = false
},
}
-- Characters --
-- Vehicles --
-- Animations --
M06_anim = {
brute_break_cable = "brute finish 2 hug a",
brute_taunt = "brotherhood insult c",
brute_crawl = "ball brute attack"
}
-- Text --
-- Threads --
-- Checkpoints --
M06_checkpoint = {
start = {
name = MISSION_START_CHECKPOINT,
nav1 = "start_nav 001",
nav2 = "start_nav 002",
p1_car = "Player_car_check1<001>",
p2_car = "Player_car_check1<002>"
},
dock = {
name = "m06_dock",
nav1 = "dock_start_nav 001",
nav2 = "dock_start_nav 002"
},
factory = {
name = "m06_factory",
nav1 = "Factory_start_nav",
nav2 = "Factory_start_nav<001>"
},
brute_killed = {
name = "m06_brute_killed",
nav1 = "Top_floor_nav",
nav2 = "Top_floor_nav2"
},
ball_drop = {
name = "m06_checkpoint_ball_drop",
nav1 = "ball_drop_nav 001",
nav2 = "ball_drop_nav 002"
}
}
M06_swap_vault_seats = false
-- Cutscenes --
M06_scene = {
intro = "06_in",
oleg = "06_Mid", -- z-scene
phillipe = "06_Z01", -- z-scene
ballsmash = "06_Z_ballsmash",
disarm_bomb = "06_Out2",
destroy_building = "06_Out1",
}
-- Conversations --
M06_convo = {
mission_start = {
name = "m06_convo_1",
handle = INVALID_CONVERSATION_HANDLE
},
driving1 = {
name = "M06_Driving_1",
handle = INVALID_CONVERSATION_HANDLE
},
driving2 = {
name = "M06_Driving_2",
handle = INVALID_CONVERSATION_HANDLE
},
driving3 = {
name = "M06_Driving_3",
handle = INVALID_CONVERSATION_HANDLE
},
dock3 = {
name = "M06_Loading_Dock_3",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = true
},
bomb_set = {
name = "M06_Bomb_Set_1",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = true
},
elevator = {
name = "M06_Elevator_Stop",
handle = INVALID_CONVERSATION_HANDLE,
phillipe_persona_id = INVALID_PERSONA_HANDLE
},
clone2 = {
name = "M06_Clone_Room_2",
handle = INVALID_CONVERSATION_HANDLE
},
clone3 = {
name = "M06_Clone_Room_3",
handle = INVALID_CONVERSATION_HANDLE
},
oleg = {
name = "m06_convo_2",
handle = INVALID_CONVERSATION_HANDLE
},
ball_start = {
name = "M06_Break_Cables",
handle = INVALID_CONVERSATION_HANDLE
},
counter_balance = {
name = "m06_convo_3",
handle = INVALID_CONVERSATION_HANDLE
},
decision = {
name = "m06_convo_4",
handle = INVALID_CONVERSATION_HANDLE
},
}
M06_attack_info = {
situation = "M06_attack",
delay = 10.0,
callback = "m06_process_attack_cb",
timer = INVALID_THREAD_HANDLE
}
-- Threads --
M06_thread = {
conversations = INVALID_THREAD_HANDLE,
ball_setup = INVALID_THREAD_HANDLE,
oleg_navigate0 = INVALID_THREAD_HANDLE,
oleg_navigate1 = INVALID_THREAD_HANDLE,
oleg_navigate2 = INVALID_THREAD_HANDLE,
weapon_check = INVALID_THREAD_HANDLE,
}
-- Movers --
M06_mover = {
platform1 = "stage_mover 001",
--platform2 = "stage_mover 002",
closet = "Dock Closet",
elevator1 = "CF_Elevator_Door",
elevator2 = "Post_Oleg_Elevator",
garage = "syn_garage_door_mover",
damage = "syn_damaged_floor"
}
-- Effects --
M06_effects = {
ball_effect = {
name = "Gp M06 Balldust<001>",
effect_handle = -1
},
tunnel_effect = {
name = "Gp M06 Dustplumes<001>",
effect_handle = -1
}
}
-- Other --
M06_WAIT = true
M06_DO_NOT_WAIT = false
M06_INTERRUPT = true
M06_DO_NOT_INTERRUPT = false
M06_WASHER_CAMERA = "Washer_camera"
SNAP_CAMERA = true
M06_PLAYER_PISTOL = "Pistol-NG"
M06_PLAYER_SMG = "SMG-Gang"
M06_PLAYER_RIFLE = "Rifle-Gang"
M06_BALL_PLAYER_LOADOUT = { M06_PLAYER_RIFLE }
M06_DOCK_THUGS = 16
M06_MONSTER_TALLY = 0
M06_ball_support = {
support1 = {
target = "Support_target 001",
object = "ball_support 001",
brute_nav = "Break_cable_nav 001",
},
support2 = {
target = "Support_target 003",
object = "ball_support 003",
brute_nav = "Break_cable_nav 002",
},
support3 = {
target = "Support_target 002",
object = "ball_support 002",
brute_nav = "Break_cable_nav 003",
}
}
M06_cancel_nav = {
host = "m06_cancel_nav",
coop = "m06_cancel_nav_coop"
}
M06_stilwater_nav = {
"m06_stilwater_water", "m06_stilwater_water_coop"
}
In_coop = false
M06_decision_made = false
M06_entered_garage = true -- usually true
-- elevator
M06_elevator_trigger = ""
M06_elevator_destination = ""
M06_elevator_destination_remote = ""
M06_dock_elevator = "dock_elevator"
M06_factory_elevator = "Factory_elevator"
M06_ball_brute_killed = false
M06_oleg_crash1_nav = "Oleg Crash1 Nav"
M06_oleg_crash2_nav = "Oleg Crash2 Nav"
-- Emergency Ragdoll Survival Navs
M06_ragdoll_emergency = {"dock_start_nav 001", "Factory_start_nav", "Top_floor_nav", "Done_on_ball<001>"}
M06_mission_completed = false
-- *************************
--
-- Standard functions
--
-- *************************
-- This is the primary entry point for the mission, and is responsible for starting up the mission
-- at the specified checkpoint.
-- CALLED FROM CODE
--
-- checkpoint: The checkpoint the mission should begin at
-- is_restart: TRUE if the mission is restarting, FALSE otherwise
--
function m06_start(checkpoint, is_restart)
In_coop = coop_is_active()
M06_mission_completed = false
if checkpoint == "m06_checkpoint_coop" then
M06_swap_vault_seats = true
checkpoint = M06_checkpoint.ball_drop.name
end
-- Check if this mission starting from the beginning
if (checkpoint == M06_checkpoint.start.name) then
if (is_restart == false) then
-- First time playing mission
local fade_in_after = false
-- Play an intro cutscene???
if (M06_scene.intro ~= "") then
cutscene_play(M06_scene.intro, nil, {M06_checkpoint.start.nav1, M06_checkpoint.start.nav2}, fade_in_after)
--bink_play(M06_scene.intro)
end
else
teleport_coop(M06_checkpoint.start.nav1, M06_checkpoint.start.nav2, true)
end
fade_out(0)
end
-- Handle mission initialization for the current checkpoint
m06_initialize(checkpoint)
-- Run the mission from the current checkpoint
m06_run(checkpoint)
end
-- This is the primary function responsible for running the entire mission from start to finish.
--
-- first_checkpoint: The first checkpoint to begin running the mission at
--
function m06_run(first_checkpoint)
local current_checkpoint = first_checkpoint
-- Always have the garage door open and hide damaged floor piece
mesh_mover_hide(M06_mover.garage)
mesh_mover_hide(M06_mover.damage)
-- Run the mission from the beginning
if current_checkpoint == M06_checkpoint.start.name then
M06_entered_garage = false
objective_text( 0, "m06_obj_syn_tower", "", "", SYNC_ALL, OI_ASSET_LOCATION )
m06_go_to_dock()
objective_text_clear(0)
current_checkpoint = M06_checkpoint.dock.name
mission_set_checkpoint(current_checkpoint, true)
end
-- Cancel after here and you're warped in front of the building
mission_set_cancel_warp_location(M06_cancel_nav.host, M06_cancel_nav.coop)
-- You're stuck in interior for the rest of the mission. Throttle density.
set_ped_density(0.01)
set_traffic_density(0.01)
-- everyone's pissed
notoriety_set_min("morningstar", 5)
if current_checkpoint == M06_checkpoint.dock.name then
objective_text( 0, "m06_obj_dock_thugs", "", "", SYNC_ALL, OI_ASSET_KILL )
notoriety_force_no_spawn("morningstar", true)
m06_emergency_ragdoll_save(1)
door_lock(M06_mover.closet, true)
m06_kill_dock_guards()
objective_text_clear(0)
m06_enter_bomb_truck()
objective_text( 0, "m06_obj_set_bomb", "", "", SYNC_ALL, OI_ASSET_USE )
m06_set_bomb()
hud_timer_set( 1, M06_BOMB_TIMER_INITIAL_MS, "m06_failure_truck_destroyed_cb" )
objective_text_clear(0)
objective_text( 0, "m06_obj_to_factory", "", "", SYNC_ALL, OI_ASSET_LOCATION )
m06_go_to_factory()
objective_text_clear(0)
m06_clear_crew(M06_group.dock_homies)
m06_clear_crew(M06_group.start_homies)
current_checkpoint = M06_checkpoint.factory.name
mission_set_checkpoint(current_checkpoint, true)
end
if current_checkpoint == M06_checkpoint.factory.name then
zscene_prep(M06_scene.oleg)
m06_setup_crew(M06_group.factory_homies)
objective_text( 0, "m06_obj_to_oleg", "", "", SYNC_ALL, OI_ASSET_LOCATION )
audio_ambient_emitter_stop(M06_emitter.dock_start)
for i, sound in pairs(M06_emitter.clone_room_start) do
audio_ambient_emitter_start(sound)
end
m06_emergency_ragdoll_save(2)
m06_fight_through_factory()
objective_text_clear(0)
m06_meet_oleg()
objective_text( 0, "m06_obj_to_oleg", "", "", SYNC_ALL, OI_ASSET_LOCATION )
m06_go_to_top_floor()
m06_clear_crew(M06_group.brute_killed_homies)
current_checkpoint = M06_checkpoint.brute_killed.name
mission_set_checkpoint(current_checkpoint, true)
end
if current_checkpoint == M06_checkpoint.brute_killed.name then
zscene_prep(M06_scene.phillipe)
m06_setup_crew(M06_group.top_floor_homies)
objective_text( 0, "m06_obj_phillipe", "", "", SYNC_ALL, OI_ASSET_LOCATION )
for i, sound in pairs(M06_emitter.clone_room_start) do
audio_ambient_emitter_stop(M06_emitter.office_start)
end
audio_ambient_emitter_start(M06_emitter.office_start)
m06_emergency_ragdoll_save(3)
m06_fight_through_top_floor()
objective_text_clear(0)
m06_watch_phillipe()
objective_text( 0, "m06_obj_find_ball", "", "", SYNC_ALL, OI_ASSET_USE )
m06_go_to_ball()
objective_text_clear(0)
m06_clear_crew(M06_group.top_floor_homies)
current_checkpoint = M06_checkpoint.ball_drop.name
mission_set_checkpoint(current_checkpoint, true)
end
if current_checkpoint == M06_checkpoint.ball_drop.name then
zscene_prep(M06_scene.ballsmash)
objective_text( 0, "m06_obj_ride_ball", "", "", SYNC_ALL, OI_ASSET_KILL )
audio_ambient_emitter_stop(M06_emitter.office_start)
audio_ambient_emitter_start(M06_emitter.ball_start)
m06_ball_stop1()
m06_ball_stop_brute()
m06_scrape_off_brute()
m06_ball_stop2()
objective_text_clear(0)
objective_text( 0, "m06_obj_decide", "", "", SYNC_ALL, OI_ASSET_INVALID )
audio_ambient_emitter_stop(M06_emitter.ball_start)
audio_ambient_emitter_start(M06_emitter.dock_start)
m06_emergency_ragdoll_save(4)
door_lock(M06_mover.closet, true)
m06_final_decision()
objective_text_clear(0)
hud_timer_stop(1)
end
-- Next up, back to the Stilwater bridge!
mission_set_next_mission("m07")
-- No more cancel warps
mission_set_cancel_warp_location()
-- flag to not do end teleport
M06_mission_completed = true
-- teleport to the water where the m07 cutscene will take place to avoid unneeded teleports
if M06_trigger.disarm_bomb.hit then
if (M06_scene.disarm_bomb ~= "") then
mission_end_success("m06", M06_scene.disarm_bomb, M06_stilwater_nav)
--bink_play(M06_scene.disarm_bomb)
--mission_end_success("m06")
end
else
if (M06_scene.destroy_building ~= "") then
mission_end_success("m06", M06_scene.destroy_building, M06_stilwater_nav)
--bink_play(M06_scene.destroy_building)
--mission_end_success("m06")
end
end
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function m06_cleanup()
hud_timer_stop(1)
-- restore ped/traffic density
set_ped_density(1.0)
set_traffic_density(1.0)
-- stop any conversations
cleanup_conversations(M06_convo)
-- allow notoriety spawns again
notoriety_set_min("morningstar", 0)
notoriety_force_no_spawn("morningstar", false)
-- stop any music that may be playing
for i,emitter in pairs(M06_emitter.music) do
audio_ambient_emitter_stop(emitter)
end
-- clear any elevators
m06_clear_elevator()
-- This might be set separately
m06_clear_trigger(M06_factory_elevator)
-- clean up dock groups/triggers
m06_cleanup_docks()
-- clean up factory groups/triggers
m06_cleanup_factory()
-- clean up top floor groups/triggers
m06_cleanup_top_floor()
-- clean up the ball drop sequence
action_sequence_end()
-- clean up homies
m06_clear_crew(M06_group.start_homies)
m06_clear_crew(M06_group.dock_homies)
m06_clear_crew(M06_group.factory_homies)
m06_clear_crew(M06_group.brute_killed_homies)
m06_clear_crew(M06_group.top_floor_homies)
m06_clear_crew(M06_group.off_ball_homies)
-- clean up final choice triggers
m06_clear_trigger(M06_trigger.brute_net.name)
m06_clear_trigger(M06_trigger.dock.name)
m06_clear_trigger(M06_trigger.notice_snipers.name)
m06_clear_trigger(M06_trigger.destroy_building.name)
m06_clear_trigger(M06_trigger.disarm_bomb.name)
-- kick everyone out!
if group_is_loaded(M06_group.ball.name) then
vehicle_evacuate(M06_group.ball.vehicle)
end
m06_cleanup_ball_drop_checkpoint_groups()
-- cleanup escape truck
if group_is_loaded(M06_group.escape_truck.name) then
group_destroy(M06_group.escape_truck.name)
end
-- remove temp weapons
inv_remove_temp_loadout(M06_BALL_PLAYER_LOADOUT)
-- re-enable all weapons
inv_weapon_disable_all_slots(false)
-- Don't force me to look at anything
camera_restrict_set_active(DISABLE)
-- clear animation states for ball drop
clear_animation_state(LOCAL_PLAYER)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
set_players_can_be_downed(LOCAL_PLAYER, true)
if In_coop then
clear_animation_state(REMOTE_PLAYER)
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
set_players_can_be_downed(REMOTE_PLAYER, true)
end
-- if we were in the building at any point
if M06_entered_garage and not M06_mission_completed then
-- teleport them outside
local exit_vehicles = true
teleport(LOCAL_PLAYER, M06_cancel_nav.host, exit_vehicles)
if (coop_is_active()) then
teleport( REMOTE_PLAYER, M06_cancel_nav.coop, exit_vehicles)
end
end
-- cleanup the threads
cleanup_threads(M06_thread)
end
-- Called when the mission has ended with success
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function m06_success()
--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]--
if M06_trigger.disarm_bomb.hit then
game_choice_set_state( MISSION_06_CHOICE, M06_CHOICE_BRANDED_TOWER )
else
game_choice_set_state( MISSION_06_CHOICE, M06_CHOICE_BLOWN_TOWER )
end
local skip_teleport = true
m06_coop_skip(skip_teleport) -- do the stuff we'd do in the skip case
end
-- *************************
--
-- Local functions
--
-- *************************
-- Initialize the mission for the specified checkpoint
--
-- checkpoint: Checkpoint to initialize the mission to
--
function m06_initialize(checkpoint)
-- Make sure the screen is completly faded out
mission_start_fade_out(0.0)
-- Set the mission author
set_mission_author("Neil Ryan")
-- Common initialization
m06_initialize_common()
-- Checkpoint specific initialization
m06_initialize_checkpoint(checkpoint)
-- Start fading in
mission_start_fade_in()
--Swap in the garage
-- city_zone_swap("SG", true)
end
function m06_go_to_dock()
M06_trigger.dock.hit = false
-- m06_music(M06_emitter.music.mission_start) --SP 7/21 - disabling as this doesn't fit.
-- conversations
M06_thread.conversations = thread_new("m06_start_convos_thread")
repeat
thread_yield()
until action_play_is_finished(LOCAL_PLAYER, 1.0)
-- set waypoint to morning star tower dock
mission_waypoint_add(M06_trigger.dock.name)
trigger_enable(M06_trigger.dock.name, true)
on_trigger("m06_dock_trigger_cb", M06_trigger.dock.name)
marker_add_trigger(M06_trigger.dock.name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
while not M06_trigger.dock.hit do
thread_yield()
end
M06_entered_garage = true
door_lock(M06_mover.closet, true)
m06_music(M06_emitter.music.clone_start) --SP changed to cloning from dock
-- when hit trigger, spawn dock workers and continue
group_create( M06_group.dock.name, true )
m06_setup_attack_lines(M06_group.dock.members)
group_create( M06_group.workers.name, true )
group_create_hidden( M06_group.dock1.name, false )
m06_setup_attack_lines(M06_group.dock1.members)
end
function m06_kill_dock_guards()
M06_convo.dock3.handle = audio_conversation_load_direct(M06_convo.dock3.name)
-- manual process_enemy_set()
for i, guard in pairs(M06_group.dock.members) do
m06_dock_goons(guard)
end
audio_play_persona_line(M06_current_Pierce, "M06_Loading_Dock_01")
trigger_enable(M06_trigger.notice_snipers.name, true)
on_trigger("m06_notice_snipers_cb", M06_trigger.notice_snipers.name)
trigger_enable(M06_trigger.dock_thug_trigger01.name, true)
on_trigger("m06_dock_thugs01_cb", M06_trigger.dock.name)
trigger_enable(M06_trigger.dock_thug_trigger02.name, true)
on_trigger("m06_dock_thugs02_cb", M06_trigger.dock.name)
audio_ambient_emitter_start(M06_emitter.dock_start)
while (not M06_trigger.notice_snipers.hit) do
thread_yield()
end
delay(3.0)
audio_conversation_play(M06_convo.dock3.handle)
-- get the dock workers running
while M06_DOCK_THUGS > 14 do
thread_yield()
end
for i, worker in pairs(M06_group.workers.members1) do
ai_do_scripted_move(worker, M06_worker_nav, true, false)
end
-- spawn the guys that are hiding among the crates and trucks
while M06_DOCK_THUGS > 13 do
thread_yield()
end
if not group_is_loaded(M06_group.dock2.name) then
group_create_hidden( M06_group.dock2.name, false )
m06_setup_attack_lines(M06_group.dock2.members)
end
-- Make sure we havent already spawned them via trigger
if (not M06_trigger.dock_thug_trigger01.hit) then
group_show( M06_group.dock1.name, true )
for i, guard in pairs(M06_group.dock1.members) do
m06_dock_goons(guard)
ai_do_scripted_move(guard, M06_group.dock1.navpoints[i])
end
m06_clear_trigger(M06_trigger.dock_thug_trigger01.name)
end
-- spawn the group of guys on the far right
while M06_DOCK_THUGS > 9 do
thread_yield()
end
-- bring in a few Saints reenforcements
M06_group.saints_backup.thread = thread_new("m06_saint_reenforcement_thread")
-- Make sure we havent already spawned them via trigger
if (not M06_trigger.dock_thug_trigger02.hit) then
group_show( M06_group.dock2.name, true )
for i, guard in pairs(M06_group.dock2.members) do
m06_dock_goons(guard)
ai_do_scripted_move(guard, M06_group.dock2.navpoints[i])
end
m06_clear_trigger(M06_trigger.dock_thug_trigger02.name)
end
-- spawn the group of guys in the elevator shafts
while M06_DOCK_THUGS > 5 do
thread_yield()
end
group_create( M06_group.dock3.name, true )
m06_setup_attack_lines(M06_group.dock3.members)
-- spawn in the brute and make him a required kill
group_create(M06_group.dock_brute.name, true)
M06_group.dock_brute.brute_killed = false
m06_brute_attack(M06_group.dock_brute.brute, "m06_dock_brute_killed_cb")
door_open(M06_mover.closet, false)
for i, guard in pairs(M06_group.dock3.members) do
m06_dock_goons(guard)
ai_do_scripted_rush(guard, M06_group.dock3.navpoints[i])
end
delay(2)
-- say a line
audio_play_persona_line(M06_current_Pierce, "M06_Loading_Dock_Brute")
while ( M06_DOCK_THUGS > 0 ) or (not M06_group.dock_brute.brute_killed) do
thread_yield()
end
-- make sure markers are removed
enemy_set_cleanup(M06_group.dock.members)
end
function m06_dock_goons(goon)
on_death("m06_dock_goon_dead_cb", goon)
marker_add(goon, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL)
end
function m06_setup_bomb_truck()
group_show(M06_group.bomb_truck.name, true)
-- set_ignore_ai_flag( M06_group.bomb_truck.driver, true )
vehicle_enter_teleport(M06_group.bomb_truck.driver, M06_group.bomb_truck.vehicle, 0)
-- somebody set us up the bomb
on_vehicle_destroyed("m06_failure_truck_destroyed_cb", M06_group.bomb_truck.vehicle)
set_unjackable_flag(M06_group.bomb_truck.vehicle, true)
vehicle_infinite_mass(M06_group.bomb_truck.vehicle)
radio_block(M06_group.bomb_truck.vehicle)
end
function m06_enter_bomb_truck()
m06_setup_bomb_truck()
audio_play_persona_line(M06_current_Pierce, "M06_Bomb_Arrive")
vehicle_pathfind_to(M06_group.bomb_truck.vehicle, M06_group.bomb_truck.path, true)
vehicle_exit(M06_group.bomb_truck.driver)
set_unjackable_flag(M06_group.bomb_truck.vehicle, true)
end
function m06_setup_saint_reenforcement()
group_create(M06_group.saints_backup.name, true)
delay(1)
for i, saint in pairs(M06_group.saints_backup.members) do
vehicle_enter_teleport(saint, M06_group.saints_backup.vehicle, (i-1))
end
radio_block(M06_group.saints_backup.vehicle)
end
-- Arm the bomb on the truck
function m06_set_bomb()
M06_convo.bomb_set.handle = audio_conversation_load_direct(M06_convo.bomb_set.name)
M06_trigger.arm_bomb.hit = false
trigger_enable(M06_trigger.arm_bomb.name, true)
on_trigger("m06_bomb_cb", M06_trigger.arm_bomb.name)
marker_add_trigger(M06_trigger.arm_bomb.name, MINIMAP_ICON_USE, INGAME_EFFECT_CHECKPOINT, OI_ASSET_USE, OI_FLAGS_LOCATION, SYNC_ALL)
while not M06_trigger.arm_bomb.hit do
thread_yield()
end
audio_conversation_play(M06_convo.bomb_set.handle)
end
function m06_go_to_factory()
m06_factory_setup()
m06_set_elevator( M06_dock_elevator, M06_checkpoint.factory.nav1, M06_checkpoint.factory.nav2 )
while M06_elevator_trigger ~= "" do
thread_yield()
end
-- destroy dock groups
m06_cleanup_docks()
end
-- set all the spawns/triggers for the factory
function m06_factory_setup()
-- spawn factory workers (not required kills)
group_create_hidden(M06_group.factory1.name, true)
m06_setup_attack_lines(M06_group.factory1.members)
-- spawn the brute and setup trigger region to make him mad
group_create_hidden(M06_group.factory_brute.name, true)
-- This is now a flamer brute
M06_trigger.factory_brute.hit = false
trigger_enable(M06_trigger.factory_brute.name, true)
on_trigger("m06_brute_cb", M06_trigger.factory_brute.name)
door_lock(M06_mover.elevator1, true)
-- Flamer removed for now
-- M06_trigger.factory_brute_flamer.hit = true --false
-- trigger_enable(M06_trigger.factory_brute_flamer.name, true)
-- on_trigger("m06_brute_flamer_cb", M06_trigger.factory_brute_flamer.name)
end
-- Fight through people in the factory and kill the brutes
function m06_fight_through_factory()
trigger_enable(M06_trigger.factory_breadcrumb1.name, true)
marker_add_trigger(M06_trigger.factory_breadcrumb1.name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
on_trigger("m06_factory_breadcrumb1_cb", M06_trigger.factory_breadcrumb1.name)
thread_kill(M06_thread.conversations)
door_lock(M06_mover.elevator2, true)
-- create first mob
group_show( M06_group.factory1.name, true )
-- Wander
for i, goon in pairs(M06_group.factory1.members) do
wander_start(goon, M06_group.factory1.wander[i], M06_group.factory1.distance[i])
end
-- load persona early so it has enough time to get loaded
M06_convo.elevator.phillipe_persona_id = audio_persona_load_2d("Phillipe")
-- Wait a few seconds then unlock and open the elevator door
delay(1)
audio_play_for_navpoint("M06_sfx_elevator_grind_halt", M06_elevator_noise)
thread_new("m06_stumble", LOCAL_PLAYER)
if (coop_is_active() == true) then
thread_new("m06_stumble", REMOTE_PLAYER)
end
delay(1.0)
M06_thread.conversations = thread_new("m06_factory_convos_thread")
delay(3.0)
door_open(M06_mover.elevator1)
ai_do_scripted_move(M06_group.factory1.walker, M06_group.factory1.walk_nav, false, true)
M06_trigger.enter_factory.hit = false
trigger_enable(M06_trigger.enter_factory.name, true)
on_trigger("m06_enter_factory_cb", M06_trigger.enter_factory.name)
M06_group.factory2.hit = false
trigger_enable(M06_group.factory2.trigger, true )
on_trigger("m06_factory_wave2", M06_group.factory2.trigger)
M06_group.factory3.hit = false
trigger_enable(M06_group.factory3.trigger, true )
on_trigger("m06_factory_wave3", M06_group.factory3.trigger)
M06_group.factory4.hit = false
trigger_enable(M06_group.factory4.trigger, true )
on_trigger("m06_wave4_cb", M06_group.factory4.trigger)
while not M06_group.factory_brute.brute_killed do --or not M06_group.factory_brute.flamer_killed do
thread_yield()
end
M06_trigger.oleg_cutscene.hit = false
trigger_enable(M06_trigger.oleg_cutscene.name, true)
on_trigger("m06_oleg_cb", M06_trigger.oleg_cutscene.name)
delay(3.0) -- a few seconds if you are already in the trigger
while not M06_trigger.oleg_cutscene.hit do
thread_yield()
end
end
function m06_factory_wave2()
trigger_enable(M06_group.factory2.trigger, false )
for i, goon in pairs(M06_group.factory1a.members) do
ai_do_scripted_move(goon, M06_group.factory1a.navpoints[i], true, false)
delay(1)
end
group_create( M06_group.factory2.name, true )
m06_setup_attack_lines(M06_group.factory2.members)
for i, guard in pairs(M06_group.factory2.members) do
ai_do_scripted_move(guard, M06_group.factory2.navpoints[i])
delay(1)
end
M06_group.factory2.hit = true
end
function m06_factory_wave3()
trigger_enable(M06_group.factory3.trigger, false )
group_create( M06_group.factory3.name, true )
m06_setup_attack_lines(M06_group.factory3.members)
for i, guard in pairs(M06_group.factory3.members) do
ai_do_scripted_move(guard, M06_group.factory3.navpoints[i], true, false)
delay(1)
end
M06_group.factory3.hit = true
end
function m06_factory_brute()
-- Bring on the brute
group_show(M06_group.factory_brute.name)
ai_do_scripted_move(M06_group.factory_brute.brute, M06_group.factory_brute.navpoint, true, false)
end
function m06_factory_wave4()
-- and some flamer fodder
group_create( M06_group.factory4.name, true )
m06_setup_attack_lines(M06_group.factory4.members)
for i, guard in pairs(M06_group.factory4.members) do
ai_do_scripted_move(guard, M06_group.factory4.navpoints[i], true, true)
end
end
-- Z-Scene talking to Oleg
function m06_meet_oleg()
--bink_play(M06_scene.oleg)
--fade_out(0.0)
--fade_out_block()
m06_clear_crew(M06_group.factory_homies)
m06_cleanup_factory()
m06_music(M06_emitter.music.clone_end) -- SP: moved to stop it before the cinematic so it doesn't overrun the z-scene
m06_music(M06_emitter.music.mission_start) --SP: start mission start audio to chill things out
--teleport_coop(M06_oleg_zscene_navs[1], M06_oleg_zscene_navs[2], true)
local create_this_group = nil
local fade_in_after = true
cutscene_play(M06_scene.oleg, create_this_group, M06_oleg_zscene_navs, fade_in_after)
m06_setup_crew(M06_group.brute_killed_homies)
--fade_in(0.5)
--fade_in_block()
end
function m06_go_to_top_floor()
-- need to handle this elevator a little different. We have teleporting and creating and we
-- have to make sure everyone is in place so we don't error playing the conversation
-- setup the elevator trigger
M06_elevator_trigger = M06_factory_elevator -- still use this
trigger_enable(M06_elevator_trigger, true)
marker_add_trigger(M06_elevator_trigger, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- we will use a custom callback that doesn't fade back in
on_trigger("m06_elevator_to_top_floor_cb", M06_elevator_trigger)
M06_elevator_destination = M06_checkpoint.brute_killed.nav1
M06_elevator_destination_remote = M06_checkpoint.brute_killed.nav2
audio_play_persona_line(M06_group.brute_killed_homies.oleg, "M06_Office")
while M06_elevator_trigger ~= "" do
thread_yield()
end
m06_top_floor_setup()
group_show(M06_group.top_floor.name)
-- now we can fade back in
fade_in(0.5)
end
-- setup spawns/triggers for top floor
function m06_top_floor_setup()
-- TEMP TEMP TEMP
-- city_zone_swap("SGDest", true)
-- spawn factory workers (not required kills)
group_create_hidden(M06_group.top_floor.name, true)
m06_spawn_ball()
-- spawn Phillipe and setup trigger region to make him run away
M06_trigger.phillipe.hit = false
group_create_hidden(M06_group.Phillipe.name)
trigger_enable(M06_trigger.phillipe.name, true)
on_trigger("m06_Phillipe_callback", M06_trigger.phillipe.name)
end
-- Fight through people in the top floors until you find the Phillipe.
function m06_fight_through_top_floor()
group_show(M06_group.top_floor.name)
--group_show(M06_group.Phillipe.name)
--marker_add(M06_group.Phillipe.phillipe, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL)
for i, npc in pairs(M06_group.top_floor.members) do
cower(npc, M06_group.top_floor_homies.oleg, true, true)
end
-- follow oleg
marker_add(M06_group.top_floor_homies.oleg, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_ALL)
follower_make_independent(M06_group.top_floor_homies.oleg, true)
-- setup follow Oleg triggers
M06_trigger.stairs1.hit = false
M06_trigger.stairs2.hit = false
M06_trigger.office.hit = false
trigger_enable(M06_trigger.stairs1.name, true)
trigger_enable(M06_trigger.stairs2.name, true)
trigger_enable(M06_trigger.office.name, true)
trigger_enable(M06_trigger.oleg_crash1.name, true)
trigger_enable(M06_trigger.oleg_crash2.name, true)
on_trigger("m06_stairs_cb", M06_trigger.stairs1.name)
on_trigger("m06_stairs_cb", M06_trigger.stairs2.name)
on_trigger("m06_office_cb", M06_trigger.office.name)
on_trigger("m06_oleg_door1_cb", M06_trigger.oleg_crash1.name)
on_trigger("m06_oleg_door2_cb", M06_trigger.oleg_crash2.name)
-- send Oleg to the stairs
ai_do_scripted_move(M06_group.top_floor_homies.oleg, M06_Oleg_path.stair, true, false)
-- say your line
delay(2.0)
M06_convo.oleg.handle = audio_conversation_load(M06_convo.oleg.name)
audio_conversation_play(M06_convo.oleg.handle)
m06_music(M06_emitter.music.follow_oleg)
while not M06_trigger.stairs1.hit do
thread_yield()
end
ai_do_scripted_move(M06_group.top_floor_homies.oleg, M06_Oleg_path.climbs, true, false)
while not M06_trigger.office.hit do
thread_yield()
end
-- send Oleg upstairs
ai_do_scripted_move(M06_group.top_floor_homies.oleg, M06_Oleg_path.offices, true, false)
while not M06_trigger.phillipe.hit do
thread_yield()
end
end
-- Z-Scene talking to Oleg
function m06_watch_phillipe()
--M06_thread.ball_setup = thread_new("m06_go_to_ball")
if audio_conversation_playing(M06_convo.oleg.handle) then
audio_conversation_end(M06_convo.oleg.handle)
end
local teleport_navs = { M06_checkpoint.ball_drop.nav1, M06_checkpoint.ball_drop.nav2 }
m06_music(M06_emitter.music.dock_start) --SP changed from follow_oleg to dock to ramp the intensity, moved to trigger as you reach the z-scene
local fade_in_after = false -- stay faded so we can get on the damn ball
cutscene_play(M06_scene.phillipe, nil, teleport_navs, fade_in_after)
if group_is_loaded(M06_group.top_floor_homies.name) then
marker_remove(M06_group.top_floor_homies.oleg)
end
-- combining cutscene with next section
end
function m06_go_to_ball()
m06_cleanup_top_floor()
m06_ball_setup()
fade_in(0.5)
end
function m06_ball_stop1()
--m06_lookat(M06_group.ball_stop1.lookat)
m06_lookat("top_floor_lookat")
camera_restrict_set_limits( -20, 23, -60, 60 )
-- m06_music(M06_emitter.music.hanging) SP: disabling as it's too low intensity
-- focus on the door
camera_restrict_target_object("top_floor_lookat")
camera_restrict_set_active(ENABLE)
m06_support_thugs(1)
-- audio_play_persona_line(LOCAL_PLAYER, "M06_Ball_Stuck")
M06_convo.ball_start.handle = audio_conversation_load(M06_convo.ball_start.name)
audio_conversation_play(M06_convo.ball_start.handle)
m06_support_thugs(2)
m06_support_thugs(3)
-- player has some time to shoot some guys
delay(10.0)
audio_object_post_event(M06_emitter.ball_groan, nil, nil, LOCAL_PLAYER)
delay(10.5)
-- Fucktastic! when we put the brute on the ball, other morningstar try to jump on and kick off the coop player. WTF!
-- So, we need to make sure the morningstar can't get on, but that blocks players so we're fucked if the coop player isn't on yet.
-- Delay the call to make the ball unjackable for as long as is reasonable.
-- Are you shitting me? People are jacking my ball?
set_unjackable_flag(M06_group.ball.vehicle, true)
delay(4.0)
-- m06_music(M06_emitter.music.ball_start) SP: disabling as it's too low intensity
audio_play_persona_line(M06_group.ball_saints.oleg, "M06_Finished_Breaking_Cables",3)
delay(0.5)
-- fall
camera_restrict_set_active(DISABLE)
audio_play_persona_line(LOCAL_PLAYER, "M06_Ball_Start")
-- play some effects
local tag_name = ""
local looping = true
--M06_effects.ball_effect.effect_handle = effect_play_on_script_object(M06_effects.ball_effect.name, M06_group.ball.vehicle, nil, looping)
M06_effects.ball_effect.effect_handle = effect_play_on_script_object(M06_effects.ball_effect.name, LOCAL_PLAYER, nil, looping)
M06_effects.tunnel_effect.effect_handle = effect_play(M06_effects.tunnel_effect.name, looping)
--camera_restrict_target_object("stop2_lookat", 5000)
--camera_restrict_set_active(ENABLE)
--m06_play_next_ball_animations(M06_WAIT, M06_DO_NOT_INTERRUPT)
-- brute goes on right away and start playing his animation (may need to move this to MAS)
local seat = 3
vehicle_enter_teleport(M06_group.ball_stop2.brute, M06_group.ball.vehicle, seat)
m06_play_next_ball_animations(M06_DO_NOT_WAIT, M06_INTERRUPT)
audio_play_persona_line(LOCAL_PLAYER, "M06_Ball_Stuck")
local anim_name = "brute ball climb"
local morph_name = anim_name
local force_play = true
local percentage = 0.1
action_play(M06_group.ball_stop2.brute, anim_name, morph_name, force_play, percentage)
audio_play_persona_line(LOCAL_PLAYER, "M06_Brute_On_Ball")
end
function m06_ball_stop_brute()
-- the short version
-- wait a few seconds
delay(0.5)
local ignore_pitch = true
camera_restrict_set_limits( -15, 25, -15, 15, nil, ignore_pitch )
-- look at brute (offset)
camera_restrict_target_object(M06_group.ball_stop2.brute, 0, nil, -2.0, 1.0, 0.0)
--camera_restrict_target_object(LOCAL_PLAYER, 0, nil, -2.0, 1.0, 0.0)
----camera_end_look_through( SNAP_CAMERA )
-- look at the brute
-- lock it
camera_restrict_set_active(ENABLE)
-- and get on the ball
-- local seat = 3
-- vehicle_enter_teleport(M06_group.ball_stop2.brute, M06_group.ball.vehicle, seat)
-- wait a second or two
delay(6.0)
if (M06_effects.ball_effect.effect_handle ~= -1) then
effect_stop(M06_effects.ball_effect.effect_handle)
M06_effects.ball_effect.effect_handle = -1
end
--repeat
-- thread_yield()
--until not action_sequence_is_playing()
-- script cut (eww)
delay(4.0)
--repeat
-- thread_yield()
--until action_play_is_finished(M06_group.ball_stop2.brute, 1.0)
end
-- Shoot the brute to make him fall off
function m06_scrape_off_brute()
-- Hackery or magic?
camera_restrict_set_active(DISABLE)
-- teleport_vehicle(M06_group.ball.vehicle, "ball_spot 001")
-- thread_yield()
-- camera_restrict_set_active(ENABLE)
-- Start the next animation before we swtich the camera
m06_play_next_ball_animations(M06_DO_NOT_WAIT, M06_INTERRUPT)
M06_ball_brute_killed = false
on_damage("m06_ball_brute_damage_cb", M06_group.ball_stop2.brute, 0.8)
turn_vulnerable(M06_group.ball_stop2.brute)
marker_add(M06_group.ball_stop2.brute, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL)
-- start brute's animations
local anim_name = M06_anim.brute_crawl
local morph_name = anim_name
local force_play = true
local percentage = 0.0
-- thread this animation. If the animation plays to 80%(?) without the brute being 'killed', kill the player
action_play(M06_group.ball_stop2.brute, anim_name, morph_name, force_play, percentage)
delay(0.1)
camera_restrict_set_active(ENABLE)
delay(0.1)
set_players_can_be_downed(LOCAL_PLAYER, false)
set_players_can_be_downed(REMOTE_PLAYER, false)
-- 8 seconds to kill him
delay(4.0)
audio_play_persona_line(LOCAL_PLAYER, "M06_Brute_On_Ball")
delay(4.0)
if not M06_ball_brute_killed then
local kill_player_pct = 0.79
repeat
thread_yield()
until action_play_is_finished(M06_group.ball_stop2.brute, kill_player_pct)
character_kill(LOCAL_PLAYER, true)
character_kill(REMOTE_PLAYER, true)
marker_remove(M06_group.ball_stop2.brute)
while true do
thread_yield()
-- wait for player death
end
end
set_players_can_be_downed(LOCAL_PLAYER, true)
set_players_can_be_downed(REMOTE_PLAYER, true)
marker_remove(M06_group.ball_stop2.brute)
-- you did it!
local anim_name = "ball brute death"
local morph_name = anim_name
local force_play = true
local percentage = 0.8
-- thread this animation. If the animation plays to 80%(?) without the brute being 'killed', kill the player
action_play(M06_group.ball_stop2.brute, anim_name, morph_name, force_play, percentage)
camera_restrict_set_active(DISABLE)
-- cut to next sequence
--m06_play_next_ball_animations(M06_DO_NOT_WAIT, M06_INTERRUPT)
vehicle_exit_teleport(M06_group.ball_stop2.brute)
------ kill him twice to get past his DBNO
----character_kill(M06_group.ball_stop2.brute, true)
----character_kill(M06_group.ball_stop2.brute, true)
-- nuke him
on_damage("", M06_group.ball_stop2.brute)
group_destroy(M06_group.ball_stop2.name)
--delay(1.5)
--repeat
-- thread_yield()
--until not action_sequence_is_playing()
end
function m06_ball_stop2()
--delay(4.0)
local player_navs = {M06_done_with_ball_nav, M06_done_with_ball_nav1}
m06_music(M06_emitter.music.dock_end) --SP: changed to end the high intensity dock music
mesh_mover_show(M06_mover.damage)
cutscene_play(M06_scene.ballsmash, nil, player_navs)
-- clean up the ball drop sequence
action_sequence_end()
-- make sure garage is hidden
mesh_mover_hide(M06_mover.garage)
-- stop checking weapons
thread_kill(M06_thread.weapon_check)
-- all done with custom player states
clear_animation_state(LOCAL_PLAYER)
if In_coop then
clear_animation_state(REMOTE_PLAYER)
end
-- no more infinite ammo
inv_remove_temp_loadout(M06_BALL_PLAYER_LOADOUT)
-- re-enable all weapons
inv_weapon_disable_all_slots(false)
end
function m06_final_decision()
if group_is_loaded(M06_group.trucks.name) then
group_destroy(M06_group.trucks.name)
end
group_create(M06_group.escape_truck.name, true)
set_unjackable_flag(M06_group.escape_truck.vehicle, true)
vehicle_infinite_mass(M06_group.escape_truck.vehicle)
radio_block(M06_group.escape_truck.vehicle)
if not group_is_loaded(M06_group.bomb_truck.name) then
-- may or may not be loaded
group_create_hidden(M06_group.bomb_truck.name, true)
end
audio_object_post_event(M06_emitter.ball_traffic, nil, nil, LOCAL_PLAYER)
-- teleport out of ball
if In_coop then
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
--vehicle_exit_teleport(REMOTE_PLAYER)
end
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
--vehicle_exit_teleport(LOCAL_PLAYER, true)
-- teleport to spot
--teleport_coop(M06_done_with_ball_nav, M06_done_with_ball_nav1, true)
-- camera cut to show homies getting out of elevator so we can teleport the player
m06_setup_bomb_truck()
teleport_vehicle(M06_group.bomb_truck.vehicle, M06_group.bomb_truck.nav)
M06_convo.decision.handle = audio_conversation_load_direct(M06_convo.decision.name)
m06_cleanup_ball_drop_checkpoint_groups()
m06_setup_crew(M06_group.off_ball_homies)
--fade_in(0.5)
--fade_in_block()
M06_decision_made = false
--player_choice_tut_open("m06")
-- set up the triggers to make choice
m06_set_choice_trigger(M06_trigger.destroy_building.name, "m06_choice_destroy_cb")
m06_set_choice_trigger(M06_trigger.disarm_bomb.name, "m06_choice_disarm_cb")
delay(.5)
-- drop a brute
teleport(M06_group.off_ball_homies.falling_brute, M06_falling_brute)
character_kill(M06_group.off_ball_homies.falling_brute)
delay(1)
audio_play_persona_line(LOCAL_PLAYER, "M06_Phillipe_Crushed")
delay(4.5)
audio_conversation_play(M06_convo.decision.handle)
thread_yield()
audio_conversation_wait_for_end(M06_convo.decision.handle)
M06_convo.decision.handle = INVALID_CONVERSATION_HANDLE
--tutorial_start("player_choice")
while not M06_decision_made do
thread_yield()
end
end
-- ***************************************************
-- M06_run Helper Functions
-- ***************************************************
-- Set a trigger enabled with a mission marker
--
-- trigger: (string) Name of the trigger
-- destination: (string) Name of the navpoint destination
--
function m06_set_elevator(trigger, destination, destination_remote)
--waypoint_add(trigger)
M06_elevator_trigger = trigger
trigger_enable(M06_elevator_trigger, true)
marker_add_trigger(M06_elevator_trigger, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- we have an inactive elevator while waiting for brute battle, so don't set this
-- We "shouldn't" be able to get to the inactive elevator, but peoples are smart
if destination ~= "" then
on_trigger("m06_elevator_callback", M06_elevator_trigger)
M06_elevator_destination = destination
M06_elevator_destination_remote = destination_remote
end
end
-- Disable elevator
--
function m06_clear_elevator()
if M06_elevator_trigger ~= "" then
m06_clear_trigger(M06_elevator_trigger)
M06_elevator_trigger = ""
M06_elevator_destination = ""
end
end
-- clear trigger
--
function m06_clear_trigger(trigger)
on_trigger("", trigger)
trigger_enable(trigger, false)
marker_remove_trigger(trigger, SYNC_ALL)
mission_waypoint_remove()
end
-- Set the final choice triggers
--
-- trigger: (string) name of trigger to set
-- callback: (string) function name to call on trigger activation
--
function m06_set_choice_trigger(trigger, callback)
--mission_waypoint_add(trigger)
trigger_enable(trigger, true)
-- color-code options
if trigger == M06_trigger.disarm_bomb.name then
marker_add_trigger(trigger, MINIMAP_ICON_USE, INGAME_EFFECT_CHECKPOINT, OI_ASSET_USE, OI_FLAGS_LOCATION, SYNC_ALL)
object_indicator_add_objective_text(M06_trigger.disarm_bomb.name, "PLAYER_CHOICE_M06_OPTION2_TITLE", "PLAYER_CHOICE_M06_OPTION2_BODY")
else
marker_add_trigger(trigger, MINIMAP_ICON_KILL, INGAME_EFFECT_CHECKPOINT, OI_ASSET_KILL_FULL, OI_FLAGS_LOCATION, SYNC_ALL)
object_indicator_add_objective_text(M06_trigger.destroy_building.name, "PLAYER_CHOICE_M06_OPTION1_TITLE", "PLAYER_CHOICE_M06_OPTION1_BODY")
end
on_trigger(callback, trigger)
end
-- send thugs to a ball support to be killed
--
-- support_num: (int) number of the support that will be broken next
--
function m06_support_thugs(support_num)
-- wake up some new guys
m06_wake_up_group(M06_group.ball_thugs.floor1[support_num])
m06_wake_up_group(M06_group.ball_thugs.floor2[support_num])
m06_wake_up_group(M06_group.ball_thugs.floor3[support_num])
-- send them and any earlier guys still alive to the navpoint to get killed
local group_num = support_num
--while group_num > 0 do
m06_send_group_to(M06_group.ball_thugs.floor1[group_num], M06_group.ball_thugs.floor2_nav[support_num])
m06_send_group_to(M06_group.ball_thugs.floor2[group_num], M06_group.ball_thugs.floor2_nav[support_num])
m06_send_group_to(M06_group.ball_thugs.floor3[group_num], M06_group.ball_thugs.floor3_nav[support_num])
-- group_num = group_num - 1
--end
end
-- force the camera to look at a navpoint and release control
--
-- lookat_nav: (string) name of the navpoint to look at
function m06_lookat(lookat_nav)
-- use current camera facing as start direction
camera_restrict_target_object()
camera_restrict_set_limits( 0.0, 0.0, 0.0, 0.0)
-- lock it
camera_restrict_set_active(ENABLE)
thread_yield()
camera_restrict_target_object(lookat_nav, 500)
delay(0.6)
-- make sure we are looking at it
camera_restrict_target_object(lookat_nav)
thread_yield()
camera_restrict_set_active(DISABLE)
end
-- setup followers as necessary
function m06_setup_crew( homie_table )
group_create(homie_table.name, true)
party_add( homie_table.pierce, LOCAL_PLAYER )
follower_set_can_abandon( homie_table.pierce, true )
on_death("m06_failure_pierce_died_cb", homie_table.pierce)
on_dismiss("m06_failure_dismissed_cb", homie_table.pierce)
M06_current_Pierce = homie_table.pierce
--turn_invulnerable(homie_table.pierce)
-- in coop, remote gets Shaundi
if false then --In_coop then
party_add( homie_table.shaundi, REMOTE_PLAYER )
else
party_add( homie_table.shaundi, LOCAL_PLAYER )
end
follower_set_can_abandon( homie_table.shaundi, true )
on_death("m06_failure_shaundi_died_cb", homie_table.shaundi)
on_dismiss("m06_failure_dismissed_cb", homie_table.shaundi)
M06_current_Shaundi = homie_table.shaundi
--turn_invulnerable(homie_table.shaundi)
-- Oleg if we got him
if homie_table.oleg ~= "" then
party_add( homie_table.oleg, LOCAL_PLAYER )
--turn_invulnerable(homie_table.oleg)
follower_set_can_abandon( homie_table.oleg, true )
on_death("m06_failure_oleg_died_cb", homie_table.oleg)
on_dismiss("m06_failure_dismissed_cb", homie_table.oleg)
end
end
-- clear followers as necessary
function m06_clear_crew( homie_table )
if group_is_loaded(homie_table.name) then
on_death("", homie_table.pierce)
on_dismiss("", homie_table.pierce)
on_death("", homie_table.shaundi)
on_dismiss("", homie_table.shaundi)
-- Oleg if we got him
if homie_table.oleg ~= "" then
on_death("", homie_table.oleg)
on_dismiss("", homie_table.oleg)
end
group_destroy(homie_table.name)
end
end
-- teleport followers to a set of navpoints
function m06_teleport_crew( homie_table, navs )
teleport(homie_table.pierce, navs[1])
teleport(homie_table.shaundi, navs[2])
if homie_table.oleg ~= "" then
teleport(homie_table.oleg, navs[3])
end
end
-- set crew to ignore ai (to say lines)
function m06_dumb_crew( homie_table )
set_ignore_ai_flag( homie_table.pierce, true )
set_ignore_ai_flag( homie_table.shaundi, true )
if homie_table.oleg ~= "" then
set_ignore_ai_flag( homie_table.oleg, true )
end
end
-- ***************************************************
-- M06_initialize Helper Functions
-- ***************************************************
-- Handle any common initialization
--
function m06_initialize_common()
-- loading dock trucks
group_create(M06_group.trucks.name, true)
-- create the bomb truck so we make sure we have the resources (customized vehicle slot)
group_create_hidden(M06_group.bomb_truck.name, true)
-- show platforms (action sequence will hide these)
mesh_mover_show(M06_mover.platform1)
--mesh_mover_show(M06_mover.platform2)
end
-- Checkpoint specific initialization
--
-- checkpoint: The checkpoint to be initialized
function m06_initialize_checkpoint(checkpoint)
if (checkpoint == M06_checkpoint.start.name) then
teleport_player_vehicles(M06_checkpoint.start.p1_car, M06_checkpoint.start.p2_car)
m06_setup_crew(M06_group.start_homies)
-- let the vehicle go or it will fall through the world when you leave it (is bad)
release_to_world(M06_group.start_homies.vehicle)
-- Player look cool GO!
local anim_name = "M06 Player Mission Start"
local morph_name = "M06 Player Mission Start"
local force_play = false
local stand_still = false
local zero_movement = false
action_play_non_blocking(LOCAL_PLAYER, anim_name, morph_name, force_play, stand_still, zero_movement)
player_script_controlled_clear(LOCAL_PLAYER) -- let player escape this animation
if (coop_is_active()) then
action_play_non_blocking(REMOTE_PLAYER, anim_name, morph_name, force_play, stand_still, zero_movement)
player_script_controlled_clear(REMOTE_PLAYER) -- let player escape this animation
end
end
if (checkpoint == M06_checkpoint.dock.name) then
teleport_coop(M06_checkpoint.dock.nav1, M06_checkpoint.dock.nav2, true)
m06_setup_crew(M06_group.dock_homies)
group_create( M06_group.dock.name, true )
m06_setup_attack_lines(M06_group.dock.members)
group_create( M06_group.workers.name, true )
group_create_hidden( M06_group.dock1.name, false )
m06_setup_attack_lines(M06_group.dock1.members)
group_create_hidden( M06_group.dock2.name, false )
m06_setup_attack_lines(M06_group.dock2.members)
m06_music(M06_emitter.music.clone_cp)
end
if (checkpoint == M06_checkpoint.factory.name) then
teleport_coop(M06_checkpoint.factory.nav1, M06_checkpoint.factory.nav2, true)
hud_timer_set( 1, M06_BOMB_TIMER_FACTORY_MS, "m06_failure_truck_destroyed_cb" )
notoriety_force_no_spawn("morningstar", true)
m06_factory_setup()
m06_music(M06_emitter.music.clone_cp)
end
if (checkpoint == M06_checkpoint.brute_killed.name) then
teleport_coop(M06_checkpoint.brute_killed.nav1, M06_checkpoint.brute_killed.nav2, true)
hud_timer_set( 1, M06_BOMB_TIMER_BRUTE_KILLED_MS, "m06_failure_truck_destroyed_cb" )
notoriety_force_no_spawn("morningstar", true)
m06_top_floor_setup()
end
if (checkpoint == M06_checkpoint.ball_drop.name) then
teleport_coop(M06_checkpoint.ball_drop.nav1, M06_checkpoint.ball_drop.nav2, true)
hud_timer_set( 1, M06_BOMB_TIMER_BALL_DROP_MS, "m06_failure_truck_destroyed_cb" )
notoriety_force_no_spawn("morningstar", true)
m06_spawn_ball()
m06_ball_setup()
m06_music(M06_emitter.music.dock_start)
end
end
function m06_spawn_ball()
-- spawn the ball
group_create(M06_group.ball.name, true)
teleport_vehicle(M06_group.ball.vehicle, M06_group.ball.nav)
while not vehicle_enable_physics(M06_group.ball.vehicle, false) do
thread_yield()
end
vehicle_suppress_npc_exit(M06_group.ball.vehicle)
end
function m06_ball_setup()
-- make sure we know what loadout we have
inv_add_temp_loadout(M06_BALL_PLAYER_LOADOUT)
thread_yield()
inv_weapon_disable_all_but_this_slot( WEAPON_SLOT_RIFLE )
thread_yield()
-- spawn the dudes to shoot at
--group_create(M06_group.ball_stop1.name, true)
group_create(M06_group.ball_stop2.name, true)
--group_create(M06_group.ball_stop3.name, true)
-- Saints
group_create(M06_group.ball_saints.name, true)
-- guys to shoot
group_create_hidden(M06_group.ball_thugs.name, true)
local block = true
local local_seat = 1
local remote_seat = 2
if M06_swap_vault_seats then
local_seat = 2
remote_seat = 1
end
while not vehicle_enter_teleport(LOCAL_PLAYER, M06_group.ball.vehicle, local_seat, block) do
thread_yield()
end
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
if ( In_coop ) then
while not vehicle_enter_teleport(REMOTE_PLAYER, M06_group.ball.vehicle, remote_seat, block) do
thread_yield()
end
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
end
-- restrict his view angle so animation plays properly
camera_restrict_set_limits( -20, 23, -60, 60 )
-- focus on the door
camera_restrict_target_object("top_floor_lookat")
camera_restrict_set_active(ENABLE)
-- spawn a thread to keep trying to give the weapon until we are sure we have it
M06_thread.weapon_check = thread_new("m06_check_weapon_thread")
action_sequence_setup(BALL_SEQUENCE, M06_group.ball.vehicle)
end
-- ***************************************************
-- Miscellaneous M06 Helper Functions
-- ***************************************************
function m06_cleanup_docks()
-- destroy dock group
if group_is_loaded(M06_group.dock.name) then
for i, guard in pairs(M06_group.dock.members) do
on_death("", guard)
on_attack_performed("", guard)
end
group_destroy(M06_group.dock.name)
end
-- destroy dock brute
if group_is_loaded(M06_group.dock_brute.name) then
m06_brute_cleanup(M06_group.dock_brute.brute)
group_destroy(M06_group.dock_brute.name)
end
-- enemy reinforcements 1
if group_is_loaded(M06_group.dock1.name) then
for i, guard in pairs(M06_group.dock1.members) do
on_death("", guard)
on_attack_performed("", guard)
end
group_destroy(M06_group.dock1.name)
end
-- enemy reinforcements 2
if group_is_loaded(M06_group.dock2.name) then
for i, guard in pairs(M06_group.dock2.members) do
on_death("", guard)
on_attack_performed("", guard)
end
group_destroy(M06_group.dock2.name)
end
-- enemy reinforcements 3
if group_is_loaded(M06_group.dock3.name) then
for i, guard in pairs(M06_group.dock3.members) do
on_death("", guard)
on_attack_performed("", guard)
end
group_destroy(M06_group.dock3.name)
end
-- dock workers
if group_is_loaded(M06_group.workers.name) then
group_destroy(M06_group.workers.name)
end
-- destroy car bomb group
if group_is_loaded(M06_group.bomb_truck.name) then
m06_clear_trigger(M06_trigger.arm_bomb.name)
on_vehicle_destroyed("", M06_group.bomb_truck.vehicle)
group_destroy(M06_group.bomb_truck.name)
end
-- destroy trucks in dock
if group_is_loaded(M06_group.trucks.name) then
group_destroy(M06_group.trucks.name)
end
-- cleanup saints
if group_is_loaded(M06_group.saints_backup.name) then
thread_kill(M06_group.saints_backup.thread)
group_destroy(M06_group.saints_backup.name)
end
end
function m06_cleanup_factory()
if group_is_loaded(M06_group.factory1.name) then
for i, guard in pairs(M06_group.factory1.members) do
on_attack_performed("", guard)
end
group_destroy(M06_group.factory1.name)
end
if group_is_loaded(M06_group.factory2.name) then
for i, guard in pairs(M06_group.factory2.members) do
on_attack_performed("", guard)
end
group_destroy(M06_group.factory2.name)
end
if group_is_loaded(M06_group.factory3.name) then
for i, guard in pairs(M06_group.factory3.members) do
on_attack_performed("", guard)
end
group_destroy(M06_group.factory3.name)
end
if group_is_loaded(M06_group.factory4.name) then
for i, guard in pairs(M06_group.factory4.members) do
on_attack_performed("", guard)
end
group_destroy(M06_group.factory4.name)
end
if group_is_loaded(M06_group.factory_brute.name) then
m06_brute_cleanup(M06_group.factory_brute.brute)
--m06_brute_cleanup(M06_group.factory_brute.brute_flamer)
group_destroy(M06_group.factory_brute.name)
end
-- Unload personas
if (M06_convo.elevator.phillipe_persona_id ~= INVALID_PERSONA_HANDLE) then
audio_persona_remove_2d(M06_convo.elevator.phillipe_persona_id)
M06_convo.elevator.phillipe_persona_id = INVALID_PERSONA_HANDLE
end
-- clear conversation triggers
m06_clear_trigger(M06_trigger.enter_factory.name)
-- clear breadcrumb triggers
m06_clear_trigger(M06_trigger.factory_breadcrumb1.name)
m06_clear_trigger(M06_trigger.factory_breadcrumb2.name)
m06_clear_trigger(M06_trigger.factory_breadcrumb3.name)
-- clear factory thug triggers
m06_clear_trigger(M06_group.factory2.trigger)
m06_clear_trigger(M06_group.factory3.trigger)
m06_clear_trigger(M06_group.factory4.trigger)
-- clear the brute trigger
m06_clear_trigger(M06_trigger.factory_brute.name)
--m06_clear_trigger(M06_trigger.factory_brute_flamer.name)
m06_clear_trigger(M06_trigger.oleg_cutscene.name)
end
function m06_cleanup_top_floor()
if group_is_loaded(M06_group.top_floor.name) then
group_destroy(M06_group.top_floor.name)
end
if group_is_loaded(M06_group.Phillipe.name) then
marker_remove(M06_group.Phillipe.phillipe)
group_destroy(M06_group.Phillipe.name)
end
-- clear follow the Oleg triggers
m06_clear_trigger(M06_trigger.stairs1.name)
m06_clear_trigger(M06_trigger.stairs2.name)
m06_clear_trigger(M06_trigger.office.name)
m06_clear_trigger(M06_trigger.oleg_crash1.name)
m06_clear_trigger(M06_trigger.oleg_crash2.name)
-- clear the ball drop trigger
m06_clear_trigger(M06_trigger.ball_drop.name)
-- clear the Phillipe trigger
m06_clear_trigger(M06_trigger.phillipe.name)
end
function m06_cleanup_ball_drop_checkpoint_groups()
if group_is_loaded(M06_group.ball_stop1.name) then
group_destroy(M06_group.ball_stop1.name)
end
if group_is_loaded(M06_group.ball_stop2.name) then
on_damage("", M06_group.ball_stop2.brute)
marker_remove(M06_group.ball_stop2.brute)
group_destroy(M06_group.ball_stop2.name)
end
if group_is_loaded(M06_group.ball_stop3.name) then
group_destroy(M06_group.ball_stop3.name)
end
if group_is_loaded(M06_group.ball.name) then
group_destroy(M06_group.ball.name)
end
if group_is_loaded(M06_group.ball_saints.name) then
group_destroy(M06_group.ball_saints.name)
end
if group_is_loaded(M06_group.ball_thugs.name) then
group_destroy(M06_group.ball_thugs.name)
end
if (M06_effects.ball_effect.effect_handle ~= -1) then
effect_stop(M06_effects.ball_effect.effect_handle)
M06_effects.ball_effect.effect_handle = -1
end
if (M06_effects.tunnel_effect.effect_handle ~= -1) then
effect_stop(M06_effects.tunnel_effect.effect_handle)
M06_effects.tunnel_effect.effect_handle = -1
end
end
function m06_music(disco)
audio_object_post_event(disco, nil, nil, LOCAL_PLAYER)
end
function m06_emergency_ragdoll_save(area)
character_ragdoll_clear_last_resort_position()
character_ragdoll_set_last_resort_position(M06_ragdoll_emergency[area])
end
-- play a conversation during the driving section of the mission
--
-- convo: (table) conversation information
--
function m06_play_driving_convo(convo)
convo.handle = audio_conversation_load(convo.name)
audio_conversation_play(convo.handle)
delay(1.0)
while audio_conversation_playing(convo.handle) and (not M06_trigger.dock.hit) do
thread_yield()
end
if audio_conversation_playing(convo.handle) then
audio_conversation_end(convo.handle)
end
end
-- wake up and unleash an npc
--
-- npc_name: (string) npc to wake up
function m06_wake_up_npc(npc_name)
-- make him vulnerable
turn_vulnerable(npc_name)
-- make him hear you
npc_hearing_enable(npc_name, true)
-- set him free
npc_leash_remove(npc_name)
end
-- go through a table of npcs and wake up each one
--
-- npc_table: (table) list of npc names to wake up (may be 0)
function m06_wake_up_group(npc_table)
for i, npc_name in pairs(npc_table) do
character_show(npc_name)
m06_wake_up_npc(npc_name)
end
end
-- tell a group of npcs to go to a navpoint
--
-- npc_table: (table) list of npcs to move
-- navpoint: (string) name of the place to go
function m06_send_group_to(npc_table, navpoint)
local should_run = true
local should_fire = false
for i, npc_name in pairs(npc_table) do
ai_do_scripted_move(npc_name, navpoint, should_run, should_fire)
end
end
-- a brute has been found. Tag him and make him attack.
--
-- brute: (string) name of the attacking brute
-- callback: (string) name of function to call when brute is killed
--
function m06_brute_attack(brute, callback)
m06_wake_up_npc(brute)
-- set a marker on him
on_death(callback, brute)
marker_add(brute, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL)
-- ai_add_enemy_target(brute, CLOSEST_PLAYER, 2)
-- update the objective
objective_text( 0, "m06_obj_kill_brute", "", "", SYNC_ALL, OI_ASSET_KILL )
end
-- remove markers/callbacks on brute
function m06_brute_cleanup(brute)
marker_remove(brute)
on_death("", brute)
end
-- maybe restore the go upstairs objective
function m06_maybe_restore_factory_objective()
-- if all of the brute's we've triggered are dead, reset objective and fake elevator
local brute_check = M06_group.factory_brute.brute_killed == M06_trigger.factory_brute.hit
local flamer_check = true --M06_group.factory_brute.flamer_killed == M06_trigger.factory_brute_flamer.hit
if brute_check and flamer_check then
m06_set_elevator( M06_factory_elevator, "", "" )
objective_text( 0, "m06_obj_to_oleg", "", "", SYNC_ALL, OI_ASSET_LOCATION )
end
end
-- Send an npc to a navpoint to play an animation
--
-- npc_name: (string) name of script npc to go do this
-- navpoint: (string) name of navpoint to perform action at (exactly)
-- action: (string) name of action to perform at navpoint
--
-- returns after action has been completed
function m06_go_here_and_do_this(npc_name, navpoint, action)
-- get npc to navpoint
local close_enough = 0.5 -- how close npc needs to be to navpoint to start action
while close_enough < get_dist(navpoint, npc_name) do
-- tell npc to go to the navpoint
local should_run = true
local should_fire = false
ai_do_scripted_move(npc_name, navpoint, should_run, should_fire)
-- wait until that is done
repeat
thread_yield()
until ai_scripted_action_is_complete(npc_name)
end
delay(0.2)
-- turn AI off while we do the action
set_ignore_ai_flag( npc_name, true )
-- tell npc to play action at navpoint (sliding into place as necessary)\
local anim_name = action
local morph_name = action
local force_play = false
local percentage = 1.0
local stand_still = true
local zero_movement = true
action_play(npc_name, anim_name, morph_name, force_play, percentage, stand_still, zero_movement, navpoint)
repeat
thread_yield()
until action_play_is_finished(npc_name)
-- turn AI back on
set_ignore_ai_flag( npc_name, false )
end
-- Play the next ball animations
-- Handle all animations while on the ball including
-- ball vehicle animations
-- vfx
-- player animations
-- player animation state changes
--
-- wait: (bool) true to wait for the vehicle actions to complete
-- interrupt: (bool) true to possibly interrupt a playing animation
function m06_play_next_ball_animations(wait, interrupt)
action_sequence_advance(interrupt)
-- make sure physics is still disabled in case we teleport MOTHERFUCKER (not bitter)
while not vehicle_enable_physics(M06_group.ball.vehicle, false) do
thread_yield()
end
if wait then
repeat
thread_yield()
until not action_sequence_is_playing()
end
end
-- set attack callbacks on all group members to override their attack lines
--
-- members: (table) list of npcs to override attack lines
--
function m06_setup_attack_lines(members)
for i,npc in pairs(members) do
on_attack_performed(M06_attack_info.callback, npc)
end
end
-- *************************
--
-- Callback functions
--
-- *************************
-- Handle playing the attack lines
--
-- name: (string) name of character
-- weapon: (string) name of weapon
-- attack: (string) type of attack performed
--
function m06_process_attack_cb(name, weapon, attack)
-- don't play this if we have done this recently
if (not thread_check_done(M06_attack_info.timer)) then
return
end
-- start timer
M06_attack_info.timer = thread_new("delay", M06_attack_info.delay)
-- play situation
if not audio_play_persona_line(name, M06_attack_info.situation) then
-- line didn't play, kill our timer
thread_kill(M06_attack_info.timer)
M06_attack_info.timer = INVALID_THREAD_HANDLE
end
end
function m06_dock_trigger_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.dock.name)
M06_trigger.dock.hit = true
end
function m06_notice_snipers_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.notice_snipers.name)
M06_trigger.notice_snipers.hit = true
audio_play_persona_line(M06_current_Shaundi, "M06_Loading_Dock_02")
end
function m06_dock_thugs01_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.dock_thug_trigger01.name)
M06_trigger.dock_thug_trigger01.hit = true
group_show( M06_group.dock1.name )
for i, guard in pairs(M06_group.dock1.members) do
m06_dock_goons(guard)
ai_do_scripted_move(guard, M06_group.dock1.navpoints[i])
end
end
function m06_dock_thugs02_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.dock_thug_trigger02.name)
M06_trigger.dock_thug_trigger02.hit = true
group_show( M06_group.dock2.name )
for i, guard in pairs(M06_group.dock2.members) do
m06_dock_goons(guard)
ai_do_scripted_move(guard, M06_group.dock2.navpoints[i])
end
end
function m06_dock_goon_dead_cb(goon)
marker_remove(goon)
on_death("", goon)
on_attack_performed("", goon)
M06_DOCK_THUGS = M06_DOCK_THUGS - 1
end
function m06_bomb_cb(triggerer)
-- clear the trigger
m06_clear_trigger(M06_trigger.arm_bomb.name)
M06_trigger.arm_bomb.hit = true
-- no animation for you.
-- action_play( triggerer, "m24 computer hack", nil, nil, nil, nil, true )
end
function m06_enter_factory_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.enter_factory.name)
M06_trigger.enter_factory.hit = true
end
function m06_factory_breadcrumb1_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.factory_breadcrumb1.name)
M06_trigger.factory_breadcrumb1.hit = true
trigger_enable(M06_trigger.factory_breadcrumb2.name, true)
marker_add_trigger(M06_trigger.factory_breadcrumb2.name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
on_trigger("m06_factory_breadcrumb2_cb", M06_trigger.factory_breadcrumb2.name)
end
function m06_factory_breadcrumb2_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.factory_breadcrumb2.name)
M06_trigger.factory_breadcrumb2.hit = true
trigger_enable(M06_trigger.factory_breadcrumb3.name, true)
marker_add_trigger(M06_trigger.factory_breadcrumb3.name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
on_trigger("m06_factory_breadcrumb3_cb", M06_trigger.factory_breadcrumb3.name)
end
function m06_factory_breadcrumb3_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.factory_breadcrumb3.name)
M06_trigger.factory_breadcrumb3.hit = true
-- fake elevator to tell the player where to go
m06_set_elevator( M06_factory_elevator, "", "" )
end
function m06_failure_truck_destroyed_cb()
mission_end_failure("m06", "m06_failure_destroy_bomb")
end
function m06_failure_pierce_died_cb()
-- End the mission, Pierce died
mission_end_failure("m06", "m06_failure_pierce_died")
end
function m06_failure_shaundi_died_cb()
-- End the mission, Shaundi died
mission_end_failure("m06", "m06_failure_shaundi_died")
end
function m06_failure_oleg_died_cb()
-- End the mission, Oleg died
mission_end_failure("m06", "m06_failure_oleg_died")
end
function m06_failure_dismissed_cb()
mission_end_failure("m06", "m06_failure_homie_dismissed")
end
function m06_elevator_callback()
fade_out(0.5)
fade_out_block() -- wait for blackness
-- make sure we aren't in cars
if character_is_in_vehicle(LOCAL_PLAYER) then
vehicle_exit(LOCAL_PLAYER)
thread_yield()
end
if coop_is_active() and character_is_in_vehicle(REMOTE_PLAYER) then
vehicle_exit(REMOTE_PLAYER)
thread_yield()
end
teleport_coop( M06_elevator_destination, M06_elevator_destination_remote )
m06_clear_elevator()
fade_in(0.5)
end
-- custom callback that doesn't fade back in
function m06_elevator_to_top_floor_cb()
fade_out(0.5)
fade_out_block() -- wait for blackness
m06_clear_crew(M06_group.brute_killed_homies)
-- make sure we aren't in cars
if character_is_in_vehicle(LOCAL_PLAYER) then
vehicle_exit(LOCAL_PLAYER)
thread_yield()
end
if coop_is_active() and character_is_in_vehicle(REMOTE_PLAYER) then
vehicle_exit(REMOTE_PLAYER)
thread_yield()
end
teleport_coop( M06_elevator_destination, M06_elevator_destination_remote )
m06_clear_elevator()
end
-- callback for brute being killed
function m06_dock_brute_killed_cb()
M06_group.dock_brute.brute_killed = true
m06_brute_cleanup(M06_group.dock_brute.brute)
objective_text( 0, "m06_obj_dock_thugs", "", "", SYNC_ALL, OI_ASSET_KILL )
end
-- callback for brute being killed
function m06_brute_killed_cb()
M06_group.factory_brute.brute_killed = true
m06_brute_cleanup(M06_group.factory_brute.brute)
m06_maybe_restore_factory_objective()
end
-- callback for brute being killed
function m06_flamer_killed_cb()
M06_group.factory_brute.flamer_killed = true
m06_brute_cleanup(M06_group.factory_brute.brute_flamer)
m06_maybe_restore_factory_objective()
end
-- trigger near the brute has been hit
function m06_brute_cb()
m06_factory_brute()
delay(1)
m06_brute_attack(M06_group.factory_brute.brute, "m06_brute_killed_cb")
-- clear the trigger
m06_clear_trigger(M06_trigger.factory_brute.name)
M06_trigger.factory_brute.hit = true
-- disable the elevator
m06_clear_elevator()
end
function m06_wave4_cb()
-- clear the trigger
m06_clear_trigger(M06_group.factory4.trigger)
M06_trigger.factory_brute.hit = true
-- bring in reenforcements
m06_factory_wave4()
end
-- trigger near the flamer brute has been hit
function m06_brute_flamer_cb()
m06_brute_attack(M06_group.factory_brute.brute_flamer, "m06_flamer_killed_cb")
-- clear the trigger
m06_clear_trigger(M06_trigger.factory_brute_flamer.name)
M06_trigger.factory_brute_flamer.hit = true
-- disable the elevator
m06_clear_elevator()
end
-- found Oleg in the factory
function m06_oleg_cb()
-- clear the trigger
m06_clear_trigger(M06_trigger.oleg_cutscene.name)
M06_trigger.oleg_cutscene.hit = true
end
-- followed Oleg to the stairs (or found them on your own)
function m06_stairs_cb()
-- clear them both. Doesn't matter which was hit
m06_clear_trigger(M06_trigger.stairs1.name)
m06_clear_trigger(M06_trigger.stairs2.name)
M06_trigger.stairs1.hit = true
M06_trigger.stairs2.hit = true
end
-- followed Oled to the office (or found it on your own)
function m06_office_cb()
m06_clear_trigger(M06_trigger.office.name)
M06_trigger.office.hit = true
end
function m06_oleg_door1_cb(whodunit)
if whodunit == "Oleg_top_floor" then
m06_clear_trigger(M06_trigger.oleg_crash1.name)
audio_play_for_navpoint("m06_sfx_oleg_smash_doors", M06_oleg_crash1_nav)
end
end
function m06_oleg_door2_cb(whodunit)
if (whodunit == "Oleg_top_floor") then
m06_clear_trigger(M06_trigger.oleg_crash2.name)
audio_play_for_navpoint("m06_sfx_oleg_smash_doors", M06_oleg_crash2_nav)
end
end
-- followed Oled to Phillipe (or found him on your own)
function m06_Phillipe_callback()
-- clear the trigger
m06_clear_trigger(M06_trigger.phillipe.name)
M06_trigger.phillipe.hit = true
end
function m06_ball_drop_callback()
-- clear the trigger
m06_clear_trigger(M06_trigger.ball_drop.name)
M06_trigger.ball_drop.hit = true
end
-- if the brute that is supposed to jump on the ball falls, teleport him back to where he needs to be
function m06_brute_net_cb()
-- make sure he is where he should be
teleport(M06_group.ball_stop2.brute, M06_group.ball_stop2.brute_restart)
-- we don't clear because this could possibly (hopefully not) happen multiple times
end
function m06_choice_disarm_cb()
if not M06_decision_made then
M06_decision_made = true
M06_trigger.disarm_bomb.hit = true
-- disable respect modifier reward, player gets cash modifier for destroying the building
mission_set_excluded_reward("Respect_Bonus_Modifier")
m06_clear_trigger(M06_trigger.disarm_bomb.name)
m06_clear_trigger(M06_trigger.destroy_building.name)
end
end
function m06_choice_destroy_cb()
if not M06_decision_made then
M06_decision_made = true
M06_trigger.destroy_building.hit = true
-- disable cash reward, player gets respect modifier for destroying the building
mission_set_excluded_reward("Cash_Bonus_Modifier")
m06_clear_trigger(M06_trigger.disarm_bomb.name)
m06_clear_trigger(M06_trigger.destroy_building.name)
end
end
-- callback when ball brute is killed
function m06_ball_brute_damage_cb()
M06_ball_brute_killed = true
on_damage("", M06_group.ball_stop2.brute)
end
-- *************************
--
-- Thread functions
--
-- *************************
-- Send some Saints in a car as reinforcements
-- Threaded in case pathfind fails so we don't break the mission
function m06_saint_reenforcement_thread()
m06_setup_saint_reenforcement()
vehicle_pathfind_to(M06_group.saints_backup.vehicle, M06_group.saints_backup.navpoint, true)
for i, saint in pairs(M06_group.saints_backup.members) do
vehicle_exit(saint)
end
end
function m06_stumble(player)
player_release_human_shield(player)
character_clear_combat_move(player)
action_play(player, "Plane Stumble Forward")
end
-- Handle playing all of the conversations on the drive to the tower
-- Exit if tower trigger is hit
--
function m06_start_convos_thread()
m06_play_driving_convo(M06_convo.mission_start)
-- wait
if (not M06_trigger.dock.hit) then
delay(4.0)
end
-- next convo
if (not M06_trigger.dock.hit) then
m06_play_driving_convo(M06_convo.driving1)
end
-- wait
if (not M06_trigger.dock.hit) then
delay(3.0)
end
-- next convo
if (not M06_trigger.dock.hit) then
m06_play_driving_convo(M06_convo.driving2)
end
-- wait
if (not M06_trigger.dock.hit) then
delay(5.0)
end
-- next convo
if (not M06_trigger.dock.hit) then
m06_play_driving_convo(M06_convo.driving3)
end
end
-- Handle the conversations in the factory
--
function m06_factory_convos_thread()
-- Elevator stopped...Mwahahaha
M06_convo.elevator.handle = audio_conversation_load(M06_convo.elevator.name)
audio_conversation_play(M06_convo.elevator.handle)
audio_conversation_wait_for_end(M06_convo.elevator.handle)
-- enter the factory
while not M06_trigger.enter_factory.hit do
thread_yield()
end
-- knew there would be dudes here
audio_play_persona_line(M06_current_Pierce, "M06_Clone_Room_01")
delay(2.0)
-- down the first stairs
while not M06_group.factory2.hit do
thread_yield()
end
-- What are these dudes?
M06_convo.clone2.handle = audio_conversation_load(M06_convo.clone2.name)
audio_conversation_play(M06_convo.clone2.handle)
audio_conversation_wait_for_end(M06_convo.clone2.handle)
delay(1.0)
-- up the second stairs
while not M06_group.factory3.hit do
thread_yield()
end
-- what do we call them?
M06_convo.clone3.handle = audio_conversation_load(M06_convo.clone3.name)
audio_conversation_play(M06_convo.clone3.handle)
audio_conversation_wait_for_end(M06_convo.clone3.handle)
-- found brute
while not M06_trigger.factory_brute.hit do
thread_yield()
end
delay(4.0)
audio_play_persona_line(M06_current_Pierce, "M06_Clone_Room_04")
-- killed the brute
while not M06_group.factory_brute.brute_killed do
thread_yield()
end
end
function m06_monster_closet_add()
M06_MONSTER_TALLY = M06_MONSTER_TALLY + 1
if M06_MONSTER_TALLY > 0 then
if not door_is_open(M06_mover.closet) then
door_open(M06_mover.closet, false)
end
end
end
function m06_monster_closet_remove()
M06_MONSTER_TALLY = M06_MONSTER_TALLY - 1
if M06_MONSTER_TALLY < 1 then
if door_is_open(M06_mover.closet) then
door_close(M06_mover.closet, false)
end
end
end
function m06_oleg_go0() -- Move to base of stairs
ai_do_scripted_move(M06_group.top_floor_homies.oleg, M06_Oleg_path.stair, true, false)
while (not ai_scripted_action_is_complete(M06_group.top_floor_homies.oleg)) do
thread_yield()
end
-- npc_leash_to_nav(M06_group.top_floor_homies.oleg, "Oleg_floor_nav3", 0)
end
function m06_oleg_go1() -- climb up stairs to office door
-- npc_leash_remove(M06_group.top_floor_homies.oleg)
ai_do_scripted_move(M06_group.top_floor_homies.oleg, M06_Oleg_path.climbs, true, false)
while (not ai_scripted_action_is_complete(M06_group.top_floor_homies.oleg)) do
thread_yield()
end
-- npc_leash_to_nav(M06_group.top_floor_homies.oleg, "Oleg_stairs_nav4", 0)
end
function m06_oleg_go2() -- go through door to next staircase
-- npc_leash_remove(M06_group.top_floor_homies.oleg)
ai_do_scripted_move(M06_group.top_floor_homies.oleg, M06_Oleg_path.offices, true, false)
while (not ai_scripted_action_is_complete(M06_group.top_floor_homies.oleg)) do
thread_yield()
end
end
-- make sure each player gets their rifle or they will not animate properly
function m06_check_weapon_thread()
-- handle problem child first
if coop_is_active() then
while not inv_item_is_firearm_equipped(REMOTE_PLAYER) do
inv_weapon_add_temporary(REMOTE_PLAYER, M06_PLAYER_RIFLE, 1, true)
inv_item_equip( M06_PLAYER_RIFLE, REMOTE_PLAYER )
delay(0.3)
end
end
while not inv_item_is_firearm_equipped(LOCAL_PLAYER) do
inv_weapon_add_temporary(LOCAL_PLAYER, M06_PLAYER_RIFLE, 1, true)
inv_item_equip( M06_PLAYER_RIFLE, LOCAL_PLAYER )
delay(0.3)
end
end