--[[
dlc2_m03.lua
SR3 Mission Script
DATE: September 2011
AUTHOR: John Karczewski
]]--
-- Debug flags --
-- Tweakable Parameters --
DLC2_M03_AIRCRAFT_HITPOINTS = 9000
DLC2_M03_AIRCRAFT_RESTORE_PERCENT = 50 -- Percent to restore the aircraft by every transmitter
DLC2_M03_NEAR_CRASH_LENGTH = 100 -- ft
-- Groups --
DLC2_M03_group = {
actress = {
name = "actress_group",
members = { "Actress" },
},
starting_vehicle = {
name = "starting_vehicle_group",
members = { "Player_starting_vehicle<001>" },
vehicle = "Player_starting_vehicle<001>",
nav = { "Start_player_nav<001>", "Start_player_nav<002>" },
},
starting_camera = {
name = "start_camera_group",
members = { "npc_start_init 001", "npc_start_init 002" },
vehicle = { "veh_start_init 001", "veh_start_init 002" },
},
checkpoint_one_vehicle = {
name = "checkpoint1_veh_group",
vehicle = "Veh_checkpoint<001>",
nav = { "nav_check_local 001", "nav_check_remote 001" },
},
checkpoint_two_vehicle = {
name = "checkpoint2_veh_group",
vehicle = "Veh_checkpoint<002>",
nav = { "nav_check_local 002", "nav_check_remote 002" },
},
checkpoint_three_vehicle = {
name = "checkpoint3_veh_group",
vehicle = "Veh_checkpoint<003>",
nav = { "nav_check_local 003", "nav_check_remote 003" },
},
checkpoint_four_vehicle = {
name = "checkpoint4_veh_group",
vehicle = "Veh_checkpoint<004>",
nav = { "nav_check_local 004", "nav_check_remote 004" },
},
checkpoint_five_vehicle = {
name = "checkpoint5_veh_group",
vehicle = "Veh_checkpoint<005>",
nav = { "nav_check_local 005", "nav_check_remote 005" },
},
checkpoint_six_vehicle = {
name = "checkpoint6_veh_group",
vehicle = "Veh_checkpoint<006>",
nav = { "Start_player_nav<001>", "Start_player_nav<002>" },
},
---------------------
-- Transmitter One --
---------------------
trans_one_initial = {
name = "trans_one_init_group",
members = { "Npc_trans_one_init<001>", "Npc_trans_one_init<002>", "Npc_trans_one_init<003>", "Npc_trans_one_init<004>",
"Npc_trans_one_init<005>", "Npc_trans_one_init<006>" },
vehicles = { "Veh_trans_one_init<001>", },
pilots = { "Npc_trans_one_air_init<001>" },
passengers = { "Npc_trans_one_air_init<002>" },
is_hostile = { true, --[[true]] },
explode_on_transmit = { false },
},
trans_one_air_wave1 = {
name = "trans_one_wave1_group",
pilots = { "Npc_trans_one_wave1<001>", "Npc_trans_one_wave1<002>" },
passengers = { nil, nil },
vehicles = { "Veh_trans_one_wave1<001>", "Veh_trans_one_wave1<002>" },
is_hostile = { true, true },
explode_on_transmit = { false, true },
},
trans_one_air_wave2 = {
name = "trans_one_wave2_group",
pilots = { "Npc_trans_one_wave2<001>", "Npc_trans_one_wave2<002>", "Npc_trans_one_wave2<003>" },
passengers = { nil, nil, nil },
vehicles = { "Veh_trans_one_wave2<001>", "Veh_trans_one_wave2<002>", "Veh_trans_one_wave2<003>" },
is_hostile = { true, true, true },
explode_on_transmit = { false, true, true },
},
---------------------
-- Transmitter Two --
---------------------
trans_two_initial = {
name = "trans_two_init_group",
members = { "Npc_trans_two_init<001>", "Npc_trans_two_init<002>", "Npc_trans_two_init<003>", "Npc_trans_two_init<004>",
--[["Npc_trans_two_init<005>", "Npc_trans_two_init<006>"]] },
vehicles = { "Veh_trans_two_init<001>", "Veh_trans_two_init<002>" },
pilots = { "Npc_trans_two_air_init<001>", "Npc_trans_two_air_init<002>" },
passengers = { nil, nil },
is_hostile = { true, true },
explode_on_transmit = { false, false },
},
trans_two_air_wave1 = {
name = "trans_two_wave1_group",
pilots = { "Npc_trans_two_wave1<001>", "Npc_trans_two_wave1<002>", "Npc_trans_two_wave1<003>" },
passengers = { nil, nil, nil },
vehicles = { "Veh_trans_two_wave1<001>", "Veh_trans_two_wave1<002>", "Veh_trans_two_wave1<003>" },
is_hostile = { true, true, false },
explode_on_transmit = { false, true, false },
},
trans_two_air_wave2 = {
name = "trans_two_wave2_group",
pilots = { "Npc_trans_two_wave2<001>", "Npc_trans_two_wave2<002>", "Npc_trans_two_wave2<003>" },
passengers = { nil, nil, nil },
vehicles = { "Veh_trans_two_wave2<001>", "Veh_trans_two_wave2<002>", "Veh_trans_two_wave2<003>" },
is_hostile = { true, true, true },
explode_on_transmit = { false, false, true },
},
--[[trans_two_shield1 = {
name = "trans_two_shield1_group",
members = { "Npc_trans_two_shield<001>", },
vehicles = { "Veh_trans_two_shield<001>", },
is_hostile = { true },
explode_on_transmit = { true },
},
trans_two_shield2 = {
name = "trans_two_shield2_group",
members = { "Npc_trans_two_shield<002>", "Npc_trans_two_shield<003>", },
vehicles = { "Veh_trans_two_shield<002>", "Veh_trans_two_shield<003>", },
is_hostile = { true, true },
explode_on_transmit = { false, false },
},]]
-----------------------
-- Transmitter Three --
-----------------------
trans_three_initial = {
name = "trans_three_init_group",
members = { "Npc_trans_three_init<001>", "Npc_trans_three_init<002>", "Npc_trans_three_init<003>", "Npc_trans_three_init<004>",
"Npc_trans_three_init<005>", "Npc_trans_three_init<006>" },
vehicles = { "Veh_trans_three_init<001>", "Veh_trans_three_init<002>" },
pilots = { "Npc_trans_three_air_init<001>", "Npc_trans_three_air_init<002>" },
passengers = { nil, nil },
is_hostile = { true, true },
explode_on_transmit = { false, false },
},
trans_three_air_wave1 = {
name = "trans_three_wave1_group",
pilots = { "Npc_trans_three_wave1<001>", "Npc_trans_three_wave1<002>", "Npc_trans_three_wave1<003>" },
passengers = { nil, nil, nil },
vehicles = { "Veh_trans_three_wave1<001>", "Veh_trans_three_wave1<002>", "Veh_trans_three_wave1<003>" },
is_hostile = { true, true, false },
explode_on_transmit = { false, false, false },
},
trans_three_air_wave2 = {
name = "trans_three_wave2_group",
pilots = { "Npc_trans_three_wave2<001>", "Npc_trans_three_wave2<002>", "Npc_trans_three_wave2<003>" },
passengers = { nil, nil, nil },
vehicles = { "Veh_trans_three_wave2<001>", "Veh_trans_three_wave2<002>", "Veh_trans_three_wave2<003>" },
is_hostile = { true, true },
explode_on_transmit = { false, false, false },
},
trans_three_air_wave3 = {
name = "trans_three_wave3_group",
pilots = { "Npc_trans_three_wave3<001>", "Npc_trans_three_wave3<002>" },
passengers = { nil, nil },
vehicles = { "Veh_trans_three_wave3<001>", "Veh_trans_three_wave3<002>" },
is_hostile = { true, true },
explode_on_transmit = { false, false },
},
trans_three_ground_wave1 = {
name = "trans_three_waveNG_group",
pilots = { "Npc_trans_three_waveNG<001>", "Npc_trans_three_waveNG<002>" },
passengers = { nil, nil },
vehicles = { "Veh_trans_three_waveNG<001>", "Veh_trans_three_waveNG<002>" },
is_hostile = { true, true },
explode_on_transmit = { false, false },
},
---------------------------
-- Nation Guard Trap --
---------------------------
trap = {
name = "trap_group",
members = { "Npc_trap<001>", "Npc_trap<002>", "Npc_trap<003>", "Npc_trap<004>",
"Npc_trap<005>", "Npc_trap<006>", "Npc_trap<007>", "Npc_trap<008>" },
pilots = { "Npc_trap_pilot<001>", "Npc_trap_pilot<002>"},
vehicles = { "Veh_trap<001>", "Veh_trap<002>" },
},
escape1 = {
name = "escape1_group",
members = { "Npc_escape<001>" },
vehicles = { "Veh_escape<001>" },
navpoint = "Nav_escape_spawn<001>",
spawned = false,
},
escape2 = {
name = "escape2_group",
members = { "Npc_escape<002>" },
vehicles = { "Veh_escape<002>" },
navpoint = "Nav_escape_spawn<002>",
spawned = false,
},
escape3 = {
name = "escape3_group",
members = { "Npc_escape<003>" },
vehicles = { "Veh_escape<003>" },
navpoint = "Nav_escape_spawn<003>",
spawned = false,
},
escape4 = {
name = "escape4_group",
members = { "Npc_escape<004>" },
vehicles = { "Veh_escape<004>" },
navpoint = "Nav_escape_spawn<004>",
spawned = false,
},
}
-- Vehicles --
DLC2_M03_vehicle = {
starting = DLC2_M03_group.starting_vehicle.vehicle,
checkpoint_one = DLC2_M03_group.checkpoint_one_vehicle.vehicle,
checkpoint_two = DLC2_M03_group.checkpoint_two_vehicle.vehicle,
checkpoint_three = DLC2_M03_group.checkpoint_three_vehicle.vehicle,
checkpoint_four = DLC2_M03_group.checkpoint_four_vehicle.vehicle,
checkpoint_five = DLC2_M03_group.checkpoint_five_vehicle.vehicle,
checkpoint_six = DLC2_M03_group.checkpoint_six_vehicle.vehicle,
}
DLC2_M03_vehicle_cb_list = {
"Veh_trans_one_init<001>", "Veh_trans_one_wave1<001>", "Veh_trans_one_wave1<002>", "Veh_trans_one_wave2<001>",
"Veh_trans_one_wave2<002>", "Veh_trans_one_wave2<003>", "Veh_trans_three_init<001>", "Veh_trans_three_init<002>",
"Veh_trans_three_wave1<001>", "Veh_trans_three_wave1<002>", "Veh_trans_three_wave1<003>", "Veh_trans_three_wave2<001>",
"Veh_trans_three_wave2<002>", "Veh_trans_three_wave2<003>", "Veh_trans_three_wave3<001>", "Veh_trans_three_wave3<002>",
"Veh_trans_two_init<001>", "Veh_trans_two_init<002>", "Veh_trans_two_wave1<001>", "Veh_trans_two_wave1<002>",
"Veh_trans_two_wave1<003>", "Veh_trans_two_wave2<001>", "Veh_trans_two_wave2<002>", "Veh_trans_two_wave2<003>",
}
-- Navpoints --
DLC2_M03_navpoint = {
host_start = "Start_player_nav<001>",
client_start = "Start_player_nav<002>",
transmitter_one_spawns = {
air = { "Nav_one_wave_spawn<001>", "Nav_one_wave_spawn<002>", "Nav_one_wave_spawn<003>", "Nav_one_wave_spawn<004>" },
ground = { },
shield = { },
},
transmitter_two_spawns = {
air = { "Nav_two_wave_spawn<001>", "Nav_two_wave_spawn<002>", "Nav_two_wave_spawn<003>", "Nav_two_wave_spawn<004>"},
ground = { },
shield = { --[["Nav_two_wave_spawn<001>", "Nav_two_wave_spawn<002>", "Nav_two_wave_spawn<003>", "Nav_two_wave_spawn<004>" --]] },
},
transmitter_three_spawns = {
air = { "Nav_three_wave_spawn<001>", "Nav_three_wave_spawn<002>", "Nav_three_wave_spawn<003>", "Nav_three_wave_spawn<004>"},
ground = { "Nav_three_wave_spawn<005>", "Nav_three_wave_spawn<006>", "Nav_three_wave_spawn<007>", "Nav_three_wave_spawn<008>"},
shield = { },
},
}
-- Threads --
DLC2_M03_thread = {
virus_transfer = INVALID_THREAD_HANDLE,
air_wave_spawn = INVALID_THREAD_HANDLE,
ground_wave_spawn = INVALID_THREAD_HANDLE,
shield_destroyed_spawn = INVALID_THREAD_HANDLE,
escape_spawn = INVALID_THREAD_HANDLE,
}
-- Achievement Data --
DLC2_M03_acheivements = {
alien_ships = {
name = "Shoot that Green Stuff",
slot_idx = 0,
current_count = 0,
target_goal = 10,
},
stunts = {
name = "MDK3000",
slot_idx = 1,
current_count = 0,
target_goal = 3,
},
}
-- Checkpoints --
DLC2_M03_checkpoint = {
start = {
name = MISSION_START_CHECKPOINT,
host_start = DLC2_M03_navpoint.host_start,
client_start = DLC2_M03_navpoint.client_start,
vehicle = DLC2_M03_vehicle.starting,
},
transmitter_one_infected = {
name = "dlc2_m03_transmitter_one_infected",
host_start = DLC2_M03_navpoint.host_start,
client_start = DLC2_M03_navpoint.client_start,
vehicle = DLC2_M03_vehicle.checkpoint_one,
},
stunt_sequence_complete = {
name = "dlc2_m03_stunt_sequence_complete",
host_start = DLC2_M03_navpoint.host_start,
client_start = DLC2_M03_navpoint.client_start,
vehicle = DLC2_M03_vehicle.checkpoint_one,
},
transmitter_two_infected = {
name = "dlc2_m03_transmitter_two_infected",
host_start = DLC2_M03_navpoint.host_start,
client_start = DLC2_M03_navpoint.client_start,
vehicle = DLC2_M03_vehicle.checkpoint_two,
},
national_guard_trap_destroyed = {
name = "dlc2_m03_national_guard_trap_destroyed",
host_start = DLC2_M03_navpoint.host_start,
client_start = DLC2_M03_navpoint.client_start,
vehicle = DLC2_M03_vehicle.checkpoint_three,
},
transmitter_three_infected = {
name = "dlc2_m03_transmitter_three_infected",
host_start = DLC2_M03_navpoint.host_start,
client_start = DLC2_M03_navpoint.client_start,
vehicle = DLC2_M03_vehicle.checkpoint_four,
},
virus_executed = {
name = "dlc2_m03_virus_executed",
host_start = DLC2_M03_navpoint.host_start,
client_start = DLC2_M03_navpoint.client_start,
vehicle = DLC2_M03_vehicle.checkpoint_five,
},
}
-- Cutscenes --
DLC2_M03_scene = {
intro = "",
outro = "DLC2_GIS_Outro"
}
-- Conversations --
DLC2_M03_personas = {
{ name = "PAK2_Director", handle = INVALID_PERSONA_HANDLE },
{ name = "PAK2_Kwilanna", handle = INVALID_PERSONA_HANDLE },
}
DLC2_M03_convo_playing = "" -- name of currently playing conversation
DLC2_M03_convo_phone_complete = false
DLC2_M03_convo_priority_high = 1
DLC2_M03_convo_priority_normal = 2
DLC2_M03_convo_priority_optional = 3
DLC2_M03_convo = {
--[[ = {
name = "file_name without voice (_bm, _wm, _bf...",
player_talks = true or false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high or DLC2_M03_convo_priority_normal or DLC2_M03_convo_priority_optional
played = false,
(optional) persona_line = true, -- this is a single line
(required if persona_line) speaker_name = "name of speaker", -- single line speaker (might be set before call to play is made?)
(optional)phone_call = true, -- this is a phone conversation (phone persona must be preloaded)
(required if phone_call) receiving_call = true or false -- auto-answer is always true in missions (until proven otherwise)
},]]
generic_action = {
name = "pak2_generic_actions",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high,
played = false,
persona_line = true, -- this is a single line
speaker_name = "PAK2_Director", -- single line speaker (might be set before call to play is made?)
},
generic_cut = {
name = "pak2_generic_cuts",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high,
played = false,
persona_line = true, -- this is a single line
speaker_name = "PAK2_Director", -- single line speaker (might be set before call to play is made?)
},
mission_start_01 = {
name = "dlc2_m03_mission_start",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
and_action_01 = {
name = "pak2_m03_trans1_start_movie_01",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high,
played = false,
persona_line = true, -- this is a single line
speaker_name = "PAK2_Director", -- single line speaker (might be set before call to play is made?)
},
arrive_trans_01 = {
name = "dlc2_m03_arrive_trans1",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
upload_start_01 = {
name = "dlc2_m03_upload_1_start",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
upload_done_01 = {
name = "dlc2_m03_upload_1_done",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
end_trans_01 = {
name = "dlc2_m03_end_trans1",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
stunt_flying_01 = {
name = "dlc2_m03_stunt_flying",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
stunt_reaction_01 = {
name = "pak2_m03_stunt_reaction_01",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high,
played = false,
persona_line = true, -- this is a single line
speaker_name = "PAK2_Director", -- single line speaker (might be set before call to play is made?)
},
stunt_reaction_02 = {
name = "pak2_m03_stunt_reaction_02",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high,
played = false,
persona_line = true, -- this is a single line
speaker_name = "PAK2_Director", -- single line speaker (might be set before call to play is made?)
},
and_action_02 = {
name = "pak2_m03_trans2_start_movie_01",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high,
played = false,
persona_line = true, -- this is a single line
speaker_name = "PAK2_Director", -- single line speaker (might be set before call to play is made?)
},
arrive_trans_02 = {
name = "dlc2_m03_arrive_trans2",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
upload_start_02 = {
name = "dlc2_m03_upload_2_start",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
upload_done_02 = {
name = "dlc2_m03_upload_2_done",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
end_trans_02 = {
name = "dlc2_m03_end_trans2",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
guard_trap_01 = {
name = "dlc2_m03_ng_ambush",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
guard_trap_02 = {
name = "dlc2_m03_after_ng_ambush",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
and_action_03 = {
name = "pak2_m03_trans3_start_movie_01",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_high,
played = false,
persona_line = true, -- this is a single line
speaker_name = "PAK2_Director", -- single line speaker (might be set before call to play is made?)
},
arrive_trans_03 = {
name = "dlc2_m03_arrive_trans3",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
upload_start_03 = {
name = "dlc2_m03_upload_3_start",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
ng_attack_01 = {
name = "dlc2_m03_trans3_ng_attack",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
trans3_berating = {
name = "dlc2_m03_trans3_berating",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
end_trans_03 = {
name = "pak2_m03_end_trans3_01",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
persona_line = true,
speaker_name = "PAK2_Director",
},
fly_to_center_01 = {
name = "dlc2_m03_flying_to_center",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
arrive_at_center_01 = {
name = "dlc2_m03_arrive_at_center",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
ship_shutdown_01 = {
name = "dlc2_m03_ship_shutdown",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
outrun_virus_01 = {
name = "dlc2_m03_outrun_virus",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
end_of_scene_01 = {
name = "dlc2_m03_end_of_scene",
player_talks = true,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_normal,
played = false,
},
dir_heli_01 = {
name = "PAK2_M03_Killing_Helicopters_01",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 10,
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_optional,
played = false,
persona_line = true,
speaker_name = "PAK2_Director",
},
dir_heli_02 = {
name = "PAK2_M03_Killing_Helicopters_02",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 10,
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_optional,
played = false,
persona_line = true,
speaker_name = "PAK2_Director",
},
dir_heli_03 = {
name = "PAK2_M03_Killing_Helicopters_03",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 10,
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_optional,
played = false,
persona_line = true,
speaker_name = "PAK2_Director",
},
dir_heli_04 = {
name = "PAK2_M03_Killing_Helicopters_04",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 10,
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_optional,
played = false,
persona_line = true,
speaker_name = "PAK2_Director",
},
dir_heli_05 = {
name = "PAK2_M03_Killing_Helicopters_05",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 10,
timer_thread = INVALID_THREAD_HANDLE,
priority = DLC2_M03_convo_priority_optional,
played = false,
persona_line = true,
speaker_name = "PAK2_Director",
},
}
DLC2_M03_convo_tables = {
dir_heli = {
DLC2_M03_convo.dir_heli_01,
DLC2_M03_convo.dir_heli_02,
DLC2_M03_convo.dir_heli_03,
DLC2_M03_convo.dir_heli_04,
DLC2_M03_convo.dir_heli_05
},
}
DLC2_M03_audio_events = {
upload_01 = "M03_mus_upload_1",
upload_01_chk = "M03_mus_upload_1_checkpoint",
upload_01_end = "M03_mus_upload_1_end",
upload_02 = "M03_mus_upload_2",
upload_02_chk = "M03_mus_upload_2_checkpoint",
upload_02_end = "M03_mus_upload_2_end",
upload_03 = "M03_mus_upload_3",
upload_03_chk = "M03_mus_upload_3_checkpoint",
upload_03_end = "M03_mus_upload_3_end",
stunts = "M03_mus_stunts",
stunts_chk = "M03_mus_stunts_checkpoint",
stunts_end = "M03_mus_stunts_end",
all_down = "M03_transmitter_shutdown",
malfunction = "M03_mus_malfunction",
malfunction_chk = "M03_mus_malfunction_checkpoint",
malfunction_end = "M03_mus_malfunction_end",
virus_sound = "M03_virus_upload_start",
virus_sound_end = "M03_virus_upload_complete",
stop = "M03_mus_STOP",
}
DLC2_M03_audio_emitters = { "dlc_m03_transmitter<001>", "dlc_m03_transmitter<002>", "dlc_m03_transmitter<003>",
"dlc_m03_transmitter<004>", "dlc_m03_transmitter<005>", "dlc_m03_transmitter<006>",
"dlc_m03_transmitter<007>", "dlc_m03_transmitter<008>" }
-- Triggers --
DLC2_M03_trigger_location = {
minimap_icon_name = MINIMAP_ICON_LOCATION,
ingame_effect_name = INGAME_EFFECT_LOCATION,
object_indicator_id = OI_ASSET_LOCATION,
object_indicator_flags = OI_FLAGS_LOCATION,
sync_type = SYNC_ALL,
-- (nil for default) fade_dist
}
DLC2_M03_trigger_use = {
minimap_icon_name = MINIMAP_ICON_USE,
ingame_effect_name = INGAME_EFFECT_CHECKPOINT,
object_indicator_id = OI_ASSET_USE,
object_indicator_flags = OI_FLAGS_FULL,
sync_type = SYNC_ALL,
-- (nil for default) fade_dist
}
DLC2_M03_trigger = {
-- = {
-- name = "_trigger",
-- hit = false,
-- (optional)callback = "dlc2_m03_function_name_cb"
-- (optional)marker = DLC2_M03_trigger_location or DLC2_M03_trigger_use or custom or don't include for no marker
-- (optional)waypoint = true,
-- (optional)teleport_to = {
-- host = "host_nav",
-- client = "client_nav"
-- },
-- (optional)conversation = DLC2_M03_convo.convo_name -- play a conversation
--},
barnstorm_trigger_01 = {
name = "Trigger_Barnstorm 001",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
vfx = { "nav_exp_stunt 001", "nav_exp_stunt 002", "nav_exp_stunt 003", "nav_exp_stunt 004",
"nav_exp_stunt 005", "nav_exp_stunt 006", "nav_exp_stunt 007", "nav_exp_stunt 008", },
},
barnstorm_trigger_02 = {
name = "Trigger_Barnstorm 002",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
vfx = { "nav_exp_stunt 009", "nav_exp_stunt 010", "nav_exp_stunt 011", "nav_exp_stunt 012" },
},
transmitter_one = {
name = "Trigger_transmitter<001>",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
},
transmitter_one_virus_region = {
name = "Trigger_transmit_region<001>",
hit = false,
},
transmitter_two = {
name = "Trigger_transmitter<002>",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
},
transmitter_two_virus_region = {
name = "Trigger_transmit_region<002>",
hit = false,
},
transmitter_three = {
name = "Trigger_transmitter<003>",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
},
transmitter_three_virus_region = {
name = "Trigger_transmit_region<003>",
hit = false,
},
trap_region_spawn = {
name = "Trigger_trap_spawn",
hit = false,
},
trap_region = {
name = "Trigger_trap_region",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
},
execute_region = {
name = "Trigger_execute_region",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
},
escape_region = {
name = "Trigger_escape_region",
hit = false,
marker = DLC2_M03_trigger_location,
waypoint = false,
},
}
-- NPCs --
DLC2_M03_character = {
actress = DLC2_M03_group.actress.members[1],
}
-- Other --
DLC2_M03_transmitter_groups = {
one = {
initial = { DLC2_M03_group.trans_one_initial },
air = { DLC2_M03_group.trans_one_air_wave1, DLC2_M03_group.trans_one_air_wave2 },
ground = { },
shield = { },
},
two = {
initial = { DLC2_M03_group.trans_two_initial },
air = { DLC2_M03_group.trans_two_air_wave1, DLC2_M03_group.trans_two_air_wave2 },
ground = { },
shield = {--[[ DLC2_M03_group.trans_two_shield1, DLC2_M03_group.trans_two_shield2 ]]},
},
three = {
initial = { DLC2_M03_group.trans_three_initial },
air = { DLC2_M03_group.trans_three_air_wave1, DLC2_M03_group.trans_three_air_wave2, DLC2_M03_group.trans_three_air_wave3 },
ground = { DLC2_M03_group.trans_three_ground_wave1 },
shield = { },
},
}
DLC2_M03_escape_groups = { DLC2_M03_group.escape1, DLC2_M03_group.escape2, DLC2_M03_group.escape3, DLC2_M03_group.escape4, }
DLC2_M03_transmitter_regions = {
one = {
trigger = DLC2_M03_trigger.transmitter_one,
virus_region = DLC2_M03_trigger.transmitter_one_virus_region,
shields = { "Transmitter_shield_mover<001>", "Transmitter_shield_mover<004>" },
transmitters = { "Transmitter_mover<001>", "Transmitter_mover<002>" },
vfx = { "nav_one_explos 001", "nav_one_explos 002", "nav_one_explos 003", "nav_one_explos 004",
"nav_one_explos 005", "nav_one_explos 006", "nav_one_explos 007", "nav_one_explos 008" },
groups = DLC2_M03_transmitter_groups.one,
duration = 45, -- virus implant, seconds
additional_waves = { -- determines when additional waves are spawned
air = { 5, 50 }, -- transmit percent
ground = { }, -- transmit percent
shield = { }, -- number of shields destroyed
},
wave_spawn_navs = DLC2_M03_navpoint.transmitter_one_spawns,
dialog = {
action = DLC2_M03_convo.and_action_01,
initial = DLC2_M03_convo.arrive_trans_01, -- DLC2_M03_convo.
uploading = { convo = DLC2_M03_convo.upload_start_01, percent = 5 }, -- Convo name, percent at which to play
completed = DLC2_M03_convo.upload_done_01,
end_trans = DLC2_M03_convo.end_trans_01,
},
music = {
start = DLC2_M03_audio_events.upload_01,
checkpoint = DLC2_M03_audio_events.upload_01_chk,
stop = DLC2_M03_audio_events.upload_01_end,
},
},
two = {
trigger = DLC2_M03_trigger.transmitter_two,
virus_region = DLC2_M03_trigger.transmitter_two_virus_region,
shields = { "Transmitter_shield_mover<002>", "Transmitter_shield_mover<005>", "Transmitter_shield_mover<006>" },
transmitters = { "Transmitter_mover<003>", "Transmitter_mover<004>", "Transmitter_mover<005>" },
vfx = { "nav_two_explos 001", "nav_two_explos 002", "nav_two_explos 003", "nav_two_explos 004",
"nav_two_explos 005", "nav_two_explos 006", "nav_two_explos 007", "nav_two_explos 008"},
groups = DLC2_M03_transmitter_groups.two,
duration = 60, -- virus implant, seconds
additional_waves = { -- determines when additional waves are spawned
air = { 5, 50 }, -- transmit percent
ground = { }, -- transmit percent
shield = {--[[ 1, 2 ]] }, -- number of shields destroyed
},
wave_spawn_navs = DLC2_M03_navpoint.transmitter_two_spawns,
dialog = {
action = DLC2_M03_convo.and_action_02,
initial = DLC2_M03_convo.arrive_trans_02, -- DLC2_M03_convo.
uploading = { convo = DLC2_M03_convo.upload_start_02, percent = 5 }, -- Convo name, percent at which to play
completed = DLC2_M03_convo.upload_done_02,
end_trans = DLC2_M03_convo.generic_cut,
},
music = {
start = DLC2_M03_audio_events.upload_02,
checkpoint = DLC2_M03_audio_events.upload_02_chk,
stop = DLC2_M03_audio_events.upload_02_end,
},
},
three = {
trigger = DLC2_M03_trigger.transmitter_three,
virus_region = DLC2_M03_trigger.transmitter_three_virus_region,
shields = { "Transmitter_shield_mover<003>", "Transmitter_shield_mover<007>", "Transmitter_shield_mover<008>",
"Transmitter_shield_mover<009>" },
transmitters = { "Transmitter_mover<006>", "Transmitter_mover<007>", "Transmitter_mover<008>",
"Transmitter_mover<009>" },
vfx = { "nav_three_explos 001", "nav_three_explos 002", "nav_three_explos 003", "nav_three_explos 004" },
groups = DLC2_M03_transmitter_groups.three,
duration = 90, -- virus implant, seconds
additional_waves = { -- determines when additional waves are spawned
air = { 5, 25, 50 }, -- transmit percent
ground = { 35 }, -- transmit percent
shield = { }, -- number of shields destroyed
},
wave_spawn_navs = DLC2_M03_navpoint.transmitter_three_spawns,
dialog = {
action = DLC2_M03_convo.and_action_03,
initial = DLC2_M03_convo.arrive_trans_03, -- DLC2_M03_convo.
uploading = { convo = DLC2_M03_convo.upload_start_03, percent = 5 }, -- Convo name, percent at which to play
completed = nil,
end_trans = DLC2_M03_convo.generic_cut,
},
music = {
start = DLC2_M03_audio_events.upload_03,
checkpoint = DLC2_M03_audio_events.upload_03_chk,
stop = DLC2_M03_audio_events.upload_03_end,
},
},
}
DLC2_M03_global = {
aircraft_entered = false,
current_transmitter_sequence = nil,
current_virus_progress = 0,
near_crash_completed = false,
num_shields_destroyed = 0,
music_flagged = false
}
DLC2_M03_kill_list = { }
in_coop = false
DLC2_M03_current_vehicle_name = DLC2_M03_vehicle.starting
DLC2_M03_FEET_PER_METER = 3.2808399
-- HUD indices
DLC2_M03_GSI_OBJECTIVE_INDEX = 0
DLC2_M03_GSI_INFECT_INDEX = 1
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ 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
--
-- dlc2_m03_checkpoint: The checkpoint the mission should begin at
-- is_restart: TRUE if the mission is restarting, FALSE otherwise
--
function dlc2_m03_start(dlc2_m03_checkpoint, is_restart)
in_coop = coop_is_active()
-- Dismiss the players' party
party_dismiss_all()
-- Check if this mission starting from the beginning
if (dlc2_m03_checkpoint == DLC2_M03_checkpoint.start.name) then
-- Clear all of the acievement counters
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_reset(achievement)
end
if (is_restart == false) then
-- First time playing mission
local fade_in_after = false
-- Play an intro cutscene???
if (DLC2_M03_scene.intro ~= "") then
cutscene_play(DLC2_M03_scene.intro, nil, {DLC2_M03_checkpoint.start.host_start, DLC2_M03_checkpoint.start.client_start}, fade_in_after)
end
else
teleport_coop(DLC2_M03_checkpoint.start.host_start, DLC2_M03_checkpoint.start.client_start, true)
end
fade_out(0)
end
-- Handle mission initialization for the current checkpoint
dlc2_m03_initialize(dlc2_m03_checkpoint)
-- Run the mission from the current checkpoint
dlc2_m03_run(dlc2_m03_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 dlc2_m03_run(first_checkpoint)
local current_checkpoint = first_checkpoint
local ignore_vehicles = true
local ignore_notoriety = true
-- make sure player personas are set to dlc2
persona_set_dlc_bundle(2)
mission_set_cancel_warp_location(DLC2_M03_navpoint.host_start, DLC2_M03_navpoint.client_start)
-- Run the mission from the beginning
if current_checkpoint == MISSION_START_CHECKPOINT then
dlc2_m03_first_transmitter()
current_checkpoint = DLC2_M03_checkpoint.transmitter_one_infected.name
mission_set_checkpoint(DLC2_M03_checkpoint.transmitter_one_infected.name, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_write_checkpoint(achievement)
end
end
if current_checkpoint == DLC2_M03_checkpoint.transmitter_one_infected.name then
-- dlc_gis_film_grain_load()
dlc2_m03_stunt_sequence()
current_checkpoint = DLC2_M03_checkpoint.stunt_sequence_complete.name
mission_set_checkpoint(DLC2_M03_checkpoint.stunt_sequence_complete.name, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_write_checkpoint(achievement)
end
end
if current_checkpoint == DLC2_M03_checkpoint.stunt_sequence_complete.name then
dlc2_m03_second_transmitter()
current_checkpoint = DLC2_M03_checkpoint.transmitter_two_infected.name
mission_set_checkpoint(DLC2_M03_checkpoint.transmitter_two_infected.name, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_write_checkpoint(achievement)
end
end
if current_checkpoint == DLC2_M03_checkpoint.transmitter_two_infected.name then
dlc2_m03_national_guard_trap()
current_checkpoint = DLC2_M03_checkpoint.national_guard_trap_destroyed.name
mission_set_checkpoint(DLC2_M03_checkpoint.national_guard_trap_destroyed.name, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_write_checkpoint(achievement)
end
end
if current_checkpoint == DLC2_M03_checkpoint.national_guard_trap_destroyed.name then
if (DLC2_M03_global.music_flagged ~= true) then
audio_object_post_event( DLC2_M03_audio_events.upload_03_chk, nil, nil, LOCAL_PLAYER )
end
dlc2_m03_third_transmitter()
current_checkpoint = DLC2_M03_checkpoint.transmitter_three_infected.name
mission_set_checkpoint(DLC2_M03_checkpoint.transmitter_three_infected.name, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_write_checkpoint(achievement)
end
end
if current_checkpoint == DLC2_M03_checkpoint.transmitter_three_infected.name then
dlc2_m03_execute_the_virus()
current_checkpoint = DLC2_M03_checkpoint.virus_executed.name
mission_set_checkpoint(DLC2_M03_checkpoint.virus_executed.name, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_write_checkpoint(achievement)
end
end
if current_checkpoint == DLC2_M03_checkpoint.virus_executed.name then
dlc2_m03_escape_the_virus()
end
-- Call mission success
dlc_gis_film_grain_unload()
audio_object_post_event( DLC2_M03_audio_events.stop, nil, nil, LOCAL_PLAYER )
persona_set_dlc_bundle(-1)
mission_end_success("dlc2_m03", DLC2_M03_scene.outro, {DLC2_M03_checkpoint.start.host_start, DLC2_M03_checkpoint.start.client_start})
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function dlc2_m03_cleanup()
-- cleanup all threads
cleanup_threads(DLC2_M03_thread)
-- cleanup all conversations
dlc2_m03_convo_end_all()
-- cleanup all triggers
dlc2_m03_trigger_clear_all()
-- cleanup kill list
dlc2_m03_kill_list_clear_all()
-- unload personas
dlc2_m03_unload_personas()
-- Ambient audio emitters
for i, emitter in pairs(DLC2_M03_audio_emitters) do
audio_ambient_emitter_stop(emitter)
end
-- Remove costumes
customization_item_revert()
-- clean up checkpoint vehicle callbacks
for i, group in pairs(DLC2_M03_group) do
if group.vehicle ~= nil then
if type(group.vehicle) == "string" then
on_vehicle_destroyed("", group.vehicle)
on_vehicle_enter_water("", group.vehicle)
else
for j, vehicle in pairs(group.vehicle) do
on_vehicle_destroyed("", vehicle)
on_vehicle_enter_water("", vehicle)
end
end
end
end
-- clean up enemy vehicle callbacks
for i, vehicle in pairs(DLC2_M03_vehicle_cb_list) do
on_vehicle_destroyed("", vehicle)
end
for i, pilot in pairs(DLC2_M03_group.starting_camera.vehicle) do
on_vehicle_destroyed("", DLC2_M03_group.starting_camera.vehicle[i])
end
on_vehicle_enter("", DLC2_M03_vehicle.starting)
vehicle_set_malfunctioning(DLC2_M03_current_vehicle_name, false)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
if in_coop then
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
end
on_near_crash("", LOCAL_PLAYER)
if in_coop then
on_near_crash("", REMOTE_PLAYER)
end
if DLC2_M03_global.current_transmitter_sequence ~= nil then
-- Cleanup current transmitter sequence
for i, shield in pairs(DLC2_M03_global.current_transmitter_sequence.shields) do
on_mover_destroyed("", shield)
end
end
on_death("", DLC2_M03_character.actress)
on_dismiss("", DLC2_M03_character.actress)
cleanup_groups(DLC2_M03_group)
party_set_dismissable(true)
-- Turn off film grain
dlc_gis_film_grain_unload()
audio_object_post_event( DLC2_M03_audio_events.stop, nil, nil, LOCAL_PLAYER )
DLC2_M03_global.music_flagged = false
-- TEMP: Renable stag
notoriety_force_no_spawn("police", false)
notoriety_set_max("police", 5)
tutorial_unlock("vtol_control", false)
-- Clear the global persona override
persona_clear_global_situation_override()
end
-- Called when the mission has ended with success
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function dlc2_m03_success()
--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]--
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Initialize functions ]]--
--[[ ]]--
--[[**********************]]--
-- Initialize the mission for the specified checkpoint
--
-- checkpoint: Checkpoint to initialize the mission to
--
function dlc2_m03_initialize(checkpoint)
-- Make sure the screen is completly faded out
mission_start_fade_out(0.0)
customization_outfit_wear("GiS Space Suit")
-- Set the mission author
set_mission_author("John Karczewski")
-- Common initialization
dlc2_m03_initialize_common()
-- Checkpoint specific initialization
dlc2_m03_initialize_checkpoint(checkpoint)
-- Start fading in
mission_start_fade_in()
end
-- Handle any common initialization
--
function dlc2_m03_initialize_common()
-- TEMP: Shut off stag notoriety since we don't have aliens yet
notoriety_force_no_spawn("police", true)
notoriety_set_max("police", 0)
-- set_time_of_day(12, 0)
tutorial_lock("vtol_control")
-- Create the actress and setup callbacks
group_create(DLC2_M03_group.actress.name, true)
party_add(DLC2_M03_character.actress, LOCAL_PLAYER)
party_set_dismissable(false)
on_death("dlc2_m03_actress_died_cb", DLC2_M03_character.actress)
on_dismiss("dlc2_m03_actress_abandoned_cb", DLC2_M03_character.actress)
turn_invulnerable(DLC2_M03_character.actress)
follower_set_can_abandon(DLC2_M03_character.actress, ENABLE)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
dlc2_m03_load_personas()
-- Ambient audio emitters
for i, emitter in pairs(DLC2_M03_audio_emitters) do
audio_ambient_emitter_start(emitter)
end
if in_coop then
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
end
-- Read the achievement data from the checkpoint
for i, achievement in pairs(DLC2_M03_acheivements) do
dlc2_m03_helper_achievement_read_checkpoint(achievement)
end
-- Setup a global persona situation override to disable some of Kwilanna's ambient persona lines
persona_set_global_situation_override(9)
end
-- Checkpoint specific initialization
--
-- checkpoint: The checkpoint to be initialized
function dlc2_m03_initialize_checkpoint(checkpoint)
if (checkpoint == MISSION_START_CHECKPOINT) then
dlc2_m03_setup_checkpoint_vehicle(DLC2_M03_group.starting_vehicle)
end
if (checkpoint == DLC2_M03_checkpoint.transmitter_one_infected.name) then
dlc_gis_film_grain_load()
dlc2_m03_setup_checkpoint_vehicle(DLC2_M03_group.checkpoint_one_vehicle)
end
if (checkpoint == DLC2_M03_checkpoint.stunt_sequence_complete.name) then
dlc2_m03_setup_checkpoint_vehicle(DLC2_M03_group.checkpoint_two_vehicle)
end
if (checkpoint == DLC2_M03_checkpoint.transmitter_two_infected.name) then
dlc2_m03_setup_checkpoint_vehicle(DLC2_M03_group.checkpoint_three_vehicle)
end
if (checkpoint == DLC2_M03_checkpoint.national_guard_trap_destroyed.name) then
dlc2_m03_setup_checkpoint_vehicle(DLC2_M03_group.checkpoint_four_vehicle)
end
if (checkpoint == DLC2_M03_checkpoint.transmitter_three_infected.name) then
dlc2_m03_setup_checkpoint_vehicle(DLC2_M03_group.checkpoint_five_vehicle)
end
if (checkpoint == DLC2_M03_checkpoint.virus_executed.name) then
dlc2_m03_setup_checkpoint_vehicle(DLC2_M03_group.checkpoint_six_vehicle)
end
audio_object_post_event("PAK2_UFO_Alarm_Mute", nil, nil, DLC2_M03_current_vehicle_name )
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Checkpoint functions ]]--
--[[ ]]--
--[[**********************]]--
-- The first transmitter objective
function dlc2_m03_first_transmitter()
group_create(DLC2_M03_group.starting_camera.name)
for i, pilot in pairs(DLC2_M03_group.starting_camera.members) do
vehicle_enter_teleport(pilot, DLC2_M03_group.starting_camera.vehicle[i], 0, true, true)
vehicle_chase(DLC2_M03_group.starting_camera.vehicle[i], CLOSEST_PLAYER, false)
ai_add_enemy_target(pilot, CLOSEST_PLAYER, ATTACK_ON_SIGHT)
on_vehicle_destroyed("dlc2_m03_heli_destroyed_cb", DLC2_M03_group.starting_camera.vehicle[i])
end
-- play a conversation
dlc2_m03_convo_start(DLC2_M03_convo.mission_start_01)
tutorial_start("dlc2_alien_aircraft", 0)
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_GOTO_FIRST_TRANSMITTER", "", "", SYNC_ALL, OI_ASSET_LOCATION )
local transmitter_one = DLC2_M03_transmitter_regions.one
dlc2_m03_trigger_setup(transmitter_one.trigger)
-- Setup the transmitter sequence
dlc2_m03_setup_transmitter_sequence(transmitter_one)
while not transmitter_one.trigger.hit do
thread_yield()
end
for i, pilot in pairs(DLC2_M03_group.starting_camera.members) do
if not character_is_dead(pilot) then
on_vehicle_destroyed("", DLC2_M03_group.starting_camera.vehicle[i])
end
end
release_to_world(DLC2_M03_group.starting_camera.name)
group_destroy(DLC2_M03_group.starting_camera.name)
audio_object_post_event( DLC2_M03_audio_events.upload_01, nil, nil, LOCAL_PLAYER )
dlc2_m03_process_transmitter_sequence()
-- Cleanup
audio_object_post_event( DLC2_M03_audio_events.upload_01_end, nil, nil, LOCAL_PLAYER )
dlc2_m03_cleanup_transmitter_sequence()
objective_text_clear(DLC2_M03_GSI_OBJECTIVE_INDEX)
delay(25.0)
dlc2_m03_restore_aircraft_health()
end
-- Stunt sequence involving a near crash event and barnstorm objective
function dlc2_m03_stunt_sequence()
audio_object_post_event( DLC2_M03_audio_events.stunts, nil, nil, LOCAL_PLAYER )
-- Near crash objective --
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_PERFORM_NEAR_CRASH", "", "", SYNC_ALL, OI_ASSET_LOCATION )
tutorial_start("dlc2_near_crash", 0, false, false, true)
on_near_crash("dlc2_m03_on_near_crash_cb", LOCAL_PLAYER)
if in_coop then
on_near_crash("dlc2_m03_on_near_crash_cb", REMOTE_PLAYER)
end
while not DLC2_M03_global.near_crash_completed do
thread_yield()
end
tutorial_stop("dlc2_near_crash")
on_near_crash("", LOCAL_PLAYER)
if in_coop then
on_near_crash("", REMOTE_PLAYER)
end
-- Barnstorm objective --
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_BARNSTORM_THROUGH_BRIDGE", "", "", SYNC_ALL, OI_ASSET_LOCATION )
dlc2_m03_trigger_setup(DLC2_M03_trigger.barnstorm_trigger_01)
while not DLC2_M03_trigger.barnstorm_trigger_01.hit do
thread_yield()
end
for i, explosion in pairs(DLC2_M03_trigger.barnstorm_trigger_01.vfx) do
explosion_create("Plane", explosion)
end
dlc_gis_film_grain_unload()
dlc2_m03_convo_start(DLC2_M03_convo.generic_cut)
dlc2_m03_helper_achievement_increment(DLC2_M03_acheivements.stunts)
delay(3.0)
dlc2_m03_convo_start(DLC2_M03_convo.stunt_reaction_02)
audio_object_post_event( DLC2_M03_audio_events.stunts_end, nil, nil, LOCAL_PLAYER )
delay(3.0)
end
-- The second transmitter objective
function dlc2_m03_second_transmitter()
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_GOTO_SECOND_TRANSMITTER", "", "", SYNC_ALL, OI_ASSET_LOCATION )
local transmitter_two = DLC2_M03_transmitter_regions.two
dlc2_m03_trigger_setup(transmitter_two.trigger)
-- Setup the transmitter sequence
dlc2_m03_setup_transmitter_sequence(transmitter_two)
dlc2_m03_convo_start(DLC2_M03_convo.stunt_flying_01)
while not transmitter_two.trigger.hit do
thread_yield()
end
audio_object_post_event( DLC2_M03_audio_events.upload_02, nil, nil, LOCAL_PLAYER )
dlc2_m03_process_transmitter_sequence()
-- Cleanup
audio_object_post_event( DLC2_M03_audio_events.upload_02_end, nil, nil, LOCAL_PLAYER )
dlc2_m03_cleanup_transmitter_sequence()
dlc2_m03_restore_aircraft_health()
delay(2.0)
dlc2_m03_convo_start(DLC2_M03_convo.end_trans_02)
end
-- National Guard trap objective
function dlc2_m03_national_guard_trap()
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_GOTO_THIRD_TRANSMITTER", "", "", SYNC_ALL, OI_ASSET_LOCATION )
dlc2_m03_trigger_setup(DLC2_M03_trigger.trap_region_spawn)
dlc2_m03_trigger_setup(DLC2_M03_trigger.trap_region)
while not DLC2_M03_trigger.trap_region_spawn.hit do
thread_yield()
end
-- Set up the trap group
group_create(DLC2_M03_group.trap.name, true)
-- Put Pilots into their vehicles
for i, pilot in pairs(DLC2_M03_group.trap.pilots) do
vehicle_enter_teleport(pilot, DLC2_M03_group.trap.vehicles[i], 0, true, true)
end
while not DLC2_M03_trigger.trap_region.hit do
thread_yield()
end
dlc2_m03_convo_start(DLC2_M03_convo.generic_action)
dlc_gis_film_grain_load()
audio_object_post_event( DLC2_M03_audio_events.upload_03, nil, nil, LOCAL_PLAYER )
DLC2_M03_global.music_flagged = true
delay(2.0)
dlc2_m03_convo_start(DLC2_M03_convo.guard_trap_01)
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_KILL_NATIONAL_GUARD", "", "", SYNC_ALL, OI_ASSET_KILL )
-- Have helicopters take off
-- Put Pilots into their vehicles
for i, pilot in pairs(DLC2_M03_group.trap.pilots) do
vehicle_chase(DLC2_M03_group.trap.vehicles[i], CLOSEST_PLAYER, false)
end
-- Eliminate the National Guard
dlc2_m03_kill_list_add( DLC2_M03_group.trap.members, OI_ASSET_KILL )
dlc2_m03_kill_list_add( DLC2_M03_group.trap.pilots, OI_ASSET_KILL_FULL )
-- wait until everyone is dead
dlc2_m03_kill_list_wait_for_complete()
-- Cleanup
release_to_world(DLC2_M03_group.trap.name)
group_destroy(DLC2_M03_group.trap.name)
delay(1.0)
dlc_gis_film_grain_unload()
dlc2_m03_convo_start(DLC2_M03_convo.generic_cut)
delay(2.0)
dlc2_m03_convo_start(DLC2_M03_convo.guard_trap_02)
dlc2_m03_restore_aircraft_health()
end
-- The third transmitter objective
function dlc2_m03_third_transmitter()
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_GOTO_THIRD_TRANSMITTER", "", "", SYNC_ALL, OI_ASSET_LOCATION )
local transmitter_three = DLC2_M03_transmitter_regions.three
dlc2_m03_trigger_setup(transmitter_three.trigger)
-- Setup the transmitter sequence
dlc2_m03_setup_transmitter_sequence(transmitter_three)
while not transmitter_three.trigger.hit do
thread_yield()
end
dlc2_m03_process_transmitter_sequence()
-- Cleanup
audio_object_post_event( DLC2_M03_audio_events.upload_03_end, nil, nil, LOCAL_PLAYER )
dlc2_m03_cleanup_transmitter_sequence()
dlc2_m03_restore_aircraft_health()
end
-- Execute the virus
function dlc2_m03_execute_the_virus()
delay(2.0)
dlc2_m03_convo_start(DLC2_M03_convo.end_trans_03)
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_GOTO_VIRUS_LOCATION", "", "", SYNC_ALL, OI_ASSET_LOCATION )
dlc2_m03_trigger_setup(DLC2_M03_trigger.execute_region)
delay(9.0)
dlc2_m03_convo_start(DLC2_M03_convo.fly_to_center_01)
while not DLC2_M03_trigger.execute_region.hit do
thread_yield()
end
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_EXECUTE_VIRUS", "", "", SYNC_ALL, OI_ASSET_KILL )
dlc2_m03_convo_start(DLC2_M03_convo.arrive_at_center_01)
delay(6.0)
end
-- Escape the virus radius
function dlc2_m03_escape_the_virus()
objective_text_clear(DLC2_M03_GSI_OBJECTIVE_INDEX)
dlc_gis_film_grain_load()
dlc2_m03_convo_start(DLC2_M03_convo.generic_action)
DLC2_M03_thread.escape_spawn = thread_new("dlc2_m03_escape_npc_spawn_thread")
audio_object_post_event( DLC2_M03_audio_events.malfunction, nil, nil, LOCAL_PLAYER )
vehicle_set_malfunctioning(DLC2_M03_current_vehicle_name)
vehicle_speed_override(DLC2_M03_current_vehicle_name, 10)
delay(2.0)
dlc2_m03_convo_start(DLC2_M03_convo.ship_shutdown_01)
delay(5.0)
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_BARNSTORM_UNDER_BRIDGE", "", "", SYNC_ALL, OI_ASSET_LOCATION )
-- Barnstorm objective --
dlc2_m03_trigger_setup(DLC2_M03_trigger.barnstorm_trigger_02)
while not DLC2_M03_trigger.barnstorm_trigger_02.hit do
thread_yield()
end
for i, explosion in pairs(DLC2_M03_trigger.barnstorm_trigger_02.vfx) do
explosion_create("Plane", explosion)
end
dlc2_m03_helper_achievement_increment(DLC2_M03_acheivements.stunts)
dlc2_m03_convo_start(DLC2_M03_convo.outrun_virus_01)
vehicle_set_weapons_disarmed(DLC2_M03_current_vehicle_name, true)
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_ESCAPE", "", "", SYNC_ALL, OI_ASSET_LOCATION )
dlc2_m03_trigger_setup(DLC2_M03_trigger.escape_region)
while not DLC2_M03_trigger.escape_region.hit do
thread_yield()
end
dlc2_m03_convo_start(DLC2_M03_convo.end_of_scene_01)
audio_object_post_event( DLC2_M03_audio_events.malfunction_end, nil, nil, LOCAL_PLAYER )
delay(4.0)
vehicle_set_malfunctioning(DLC2_M03_current_vehicle_name, false)
thread_kill(DLC2_M03_thread.escape_spawn)
DLC2_M03_thread.escape_spawn = INVALID_THREAD_HANDLE
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Trigger functions ]]--
--[[ ]]--
--[[**********************]]--
-- Enable a trigger and set any markers/waypoints needed
--
-- trigger_table: (table) information about how to setup this trigger
--
function dlc2_m03_trigger_setup( trigger_table )
-- clear hit flag
trigger_table.hit = false
-- set callback
if trigger_table.callback ~= nil and trigger_table.callback ~= "" then
on_trigger(trigger_table.callback, trigger_table.name)
else
on_trigger("dlc2_m03_trigger_cb", trigger_table.name)
end
-- enable the trigger
trigger_enable(trigger_table.name, true)
-- set marker information
if trigger_table.marker ~= nil then
marker_add_trigger(trigger_table.name, trigger_table.marker.minimap_icon_name, trigger_table.marker.ingame_effect_name, trigger_table.marker.object_indicator_id, trigger_table.marker.object_indicator_flags, trigger_table.marker.sync_type, trigger_table.marker.fade_dist)
end
-- set a waypoint
if trigger_table.waypoint == true then
mission_waypoint_add(trigger_table.name)
end
end
-- Disable trigger and cleanup any markers on the trigger
--
-- trigger: (string) name of trigger to cleanup
--
function dlc2_m03_trigger_clear(trigger)
on_trigger("", trigger)
trigger_enable(trigger, false)
marker_remove_trigger(trigger, SYNC_ALL)
end
-- clear all triggers
function dlc2_m03_trigger_clear_all()
for i,trigger_table in pairs(DLC2_M03_trigger) do
dlc2_m03_trigger_clear(trigger_table.name)
end
mission_waypoint_remove()
end
-- get the trigger table from the trigger name
--
-- trigger: (string) trigger name
--
function dlc2_m03_trigger_get_table(trigger)
local trigger_table
for i,trig in pairs(DLC2_M03_trigger) do
if trig.name == trigger then
trigger_table = trig
end
end
return trigger_table
end
-- basic trigger callback
--
-- human: (string) name of human that tripped the trigger
-- trigger: (string) name of the trigger
--
function dlc2_m03_trigger_cb(human, trigger)
-- This may be called multiple times in the same frame. Never create groups in a trigger callback. Use show group instead.
-- find this trigger
local trigger_table = dlc2_m03_trigger_get_table(trigger)
if trigger_table ~= nil then
if trigger_table.hit == true then
return
end
trigger_table.hit = true
dlc2_m03_trigger_clear(trigger_table.name)
if trigger_table.teleport_to ~= nil then
mission_start_fade_out()
teleport_coop( trigger_table.teleport_to.host, trigger_table.teleport_to.client, true )
mission_start_fade_in()
end
if trigger_table.waypoint == true then
mission_waypoint_remove()
end
if trigger_table.conversation ~= nil and trigger_table.conversation ~= "" then
dlc2_m03_convo_start(trigger_table.conversation)
end
end
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[Conversation functions]]--
--[[ ]]--
--[[**********************]]--
-- spawn the convo play thread for this conversation
--
-- convo_table: (table) conversation information
--
function dlc2_m03_convo_start(convo_table)
convo_table.convo_thread = thread_new("dlc2_m03_convo_play_thread", convo_table)
end
-- end the conversation and kill any threads playing the conversation
--
-- convo_table: (table) conversation information
--
function dlc2_m03_convo_end(convo_table)
-- kill any threads that might be running
thread_kill(convo_table.convo_thread)
thread_kill(convo_table.timer_thread)
if convo_table.handle ~= INVALID_CONVERSATION_HANDLE then
audio_conversation_end(convo_table.handle)
convo_table.handle = INVALID_CONVERSATION_HANDLE
end
if convo_table.phone_call == true then
audio_remove_mission_cellphone(convo_table.name)
end
end
-- end all of the conversations
function dlc2_m03_convo_end_all()
for i,convo_table in pairs(DLC2_M03_convo) do
dlc2_m03_convo_end(convo_table)
end
DLC2_M03_convo_phone_complete = false
end
-- callback for when a phone call conversation is complete
function dlc2_m03_call_ended_cb()
DLC2_M03_convo_phone_complete = true
end
-- Determine if a conversation is playing
--
-- returns: true if playing or false if not
--
function dlc2_m03_convo_is_playing()
local convo_playing = false
if DLC2_M03_convo_playing ~= nil and DLC2_M03_convo_playing ~= "" then
convo_playing = true
end
return convo_playing
end
-- Wait for conversation to complete
-- (this may not work as desired with multiple conversations queued)
--
function dlc2_m03_convo_wait_for_end()
while dlc2_m03_convo_is_playing() do
delay(1.0)
end
end
-- Thread to play the conversation with emergency kill timer
--
-- convo_table: (table) conversation information
--
function dlc2_m03_convo_play_thread(convo_table)
-- determine priority
if convo_table.priority == DLC2_M03_convo_priority_high then
-- priority conversation
-- kill any running conversation
if dlc2_m03_convo_is_playing() then
dlc2_m03_convo_end(DLC2_M03_convo_playing)
end
elseif convo_table.priority == DLC2_M03_convo_priority_normal then
-- normal conversation
-- wait for currently playing conversation
while dlc2_m03_convo_is_playing() do
thread_yield()
end
else -- optional conversation
-- if another conversation is playing, exit
if dlc2_m03_convo_is_playing() then
return
end
end
-- Set conversation as playing
DLC2_M03_convo_playing = convo_table
-- start the backup timer thread
convo_table.timer_thread = thread_new("delay", convo_table.max_wait_seconds)
if convo_table.persona_line == true then
-- play the line
audio_play_persona_line_2d(dlc2_m03_get_persona_handle(convo_table), convo_table.name)
thread_yield()
-- while audio_persona_line_playing(convo_table.speaker_name) and (not thread_check_done(convo_table.timer_thread)) do
-- thread_yield()
-- end
elseif convo_table.phone_call == true then
-- do a phone call
local auto_answer = true -- missions always auto-answer
DLC2_M03_convo_phone_complete = false
audio_play_for_mission_cellphone(convo_table.name, convo_table.receiving_call, auto_answer, "", "dlc2_m03_call_ended_cb")
while not DLC2_M03_convo_phone_complete and (not thread_check_done(convo_table.timer_thread)) do
thread_yield()
end
audio_remove_mission_cellphone(convo_table.name)
else -- conversation
if (convo_table.player_talks) then
convo_table.handle = audio_conversation_load(convo_table.name)
else
convo_table.handle = audio_conversation_load_direct(convo_table.name)
end
audio_conversation_play(convo_table.handle)
thread_yield()
-- Wait for the conversation to end
while audio_conversation_playing(convo_table.handle) and (not thread_check_done(convo_table.timer_thread)) do
thread_yield()
end
audio_conversation_end(convo_table.handle)
convo_table.handle = INVALID_CONVERSATION_HANDLE
end
-- clear the playing conversation
convo_table.played = true
DLC2_M03_convo_playing = ""
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Kill List functions ]]--
--[[ ]]--
--[[**********************]]--
-- Add a single person or a table of people to list to be killed
--
-- npc_name: (table or string) table of names or single name of character to add to the kill_list
-- icon_type: (string) OI_ASSET_KILL or OI_ASSET_KILL_FULL
--
function dlc2_m03_kill_list_add( npc_name, icon_type )
-- Recursive call to add individual members
if (type(npc_name) == "table") then
for i,member in pairs(npc_name) do
dlc2_m03_kill_list_add( member, icon_type )
end
return
end
-- make sure it is still alive
if character_is_dead(npc_name) then
return
end
if icon_type == OI_ASSET_KILL then
marker_add(npc_name, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL)
elseif icon_type == OI_ASSET_KILL_FULL then
marker_add(npc_name, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL)
else
-- FAIL! We won't know which guy to kill
return
end
on_death("dlc2_m03_kill_list_member_dead_cb", npc_name)
-- add the name to the kill_list
DLC2_M03_kill_list[ npc_name ] = npc_name
end
-- remove an npc from the kill list and make sure it has markers and callbacks cleaned up
--
-- npc_name: (string) name of npc to remove from the kill_list
--
function dlc2_m03_kill_list_clear(npc_name)
marker_remove(npc_name)
on_death("", npc_name)
DLC2_M03_kill_list[ npc_name ] = nil
end
-- remove all entries in the kill list and make sure all markers/callbacks are cleaned up
function dlc2_m03_kill_list_clear_all()
for i, npc_name in pairs( DLC2_M03_kill_list ) do
dlc2_m03_kill_list_clear(npc_name)
end
end
-- Return number of npcs in the kill list
function dlc2_m03_kill_list_get_count()
local kill_list_size = sizeof_table(DLC2_M03_kill_list)
return kill_list_size
end
-- wait for everyone in the kill list to be killed (don't call this until everyone you want to include has been spawned and added)
function dlc2_m03_kill_list_wait_for_complete()
local npcs_alive = true
while npcs_alive do
npcs_alive = false
for i, npc_name in pairs( DLC2_M03_kill_list ) do
if character_is_dead(npc_name) then
-- remove it
dlc2_m03_kill_list_clear(npc_name)
else
npcs_alive = true
thread_yield()
end
end
thread_yield()
end
end
-- callback for kill_list member
--
-- npc_killed: (string) name of killed NPC
--
function dlc2_m03_kill_list_member_dead_cb(npc_killed)
dlc2_m03_kill_list_clear(npc_killed)
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Common functions ]]--
--[[ ]]--
--[[**********************]]--
function dlc2_m03_setup_transmitter_sequence(sequence)
DLC2_M03_global.current_transmitter_sequence = sequence
for i, shield in pairs(sequence.shields) do
mesh_mover_show(shield)
mesh_mover_set_invulnerable(shield, ENABLE)
end
for i, transmitter in pairs(sequence.transmitters) do
mesh_mover_show(transmitter)
end
local initial_group = sequence.groups.initial[1]
-- Spawn the initial npcs and vehicles
group_create(initial_group, true)
-- Place pilots into aircrafts
for i, pilot in pairs(initial_group.pilots) do
vehicle_enter_teleport(pilot, initial_group.vehicles[i], 0, true, true)
vehicle_chase(initial_group.vehicles[i], CLOSEST_PLAYER, false)
ai_add_enemy_target(pilot, CLOSEST_PLAYER, ATTACK_ON_SIGHT)
on_vehicle_destroyed("dlc2_m03_ach_veh_destroyed_cb", initial_group.vehicles[i])
end
for i, passenger in pairs(initial_group.passengers) do
if passenger ~= nil then
vehicle_enter_teleport(passenger, initial_group.vehicles[i], 1, true, true)
ai_add_enemy_target(passenger, CLOSEST_PLAYER, ATTACK_ON_SIGHT)
end
end
-- Have the rooftop enemies target the player
for i, member in pairs(initial_group.members) do
ai_add_enemy_target(member, CLOSEST_PLAYER, ATTACK_ON_SIGHT)
end
end
function dlc2_m03_process_transmitter_sequence()
dlc_gis_film_grain_load()
local sequence = DLC2_M03_global.current_transmitter_sequence
local num_shields = sizeof_table(sequence.shields)
if num_shields == 1 then
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_DESTROY_SHIELD", "", "", SYNC_ALL, OI_ASSET_KILL )
else
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_DESTROY_SHIELDS", "", "", SYNC_ALL, OI_ASSET_KILL )
end
for i, shield in pairs(sequence.shields) do
marker_add(shield, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
mesh_mover_set_invulnerable(shield, DISABLE)
on_mover_destroyed("dlc2_m03_shield_destroyed_cb", shield)
end
-- Queue up the initial dialog
if sequence.dialog.action ~= nil then
dlc2_m03_convo_start(sequence.dialog.action)
delay(3.0)
end
-- Queue up the initial dialog
if sequence.dialog.initial ~= nil then
dlc2_m03_convo_start(sequence.dialog.initial)
end
-- Start up a thread to spawn enemies when the player kills shields. Will exit if no enemies are set up
DLC2_M03_thread.shield_destroyed_spawn = thread_new("dlc2_m03_shield_destroyed_spawn_thread")
-- Wait until all shields are destroyed
while DLC2_M03_global.num_shields_destroyed < num_shields do
thread_yield()
end
audio_object_post_event(DLC2_M03_audio_events.all_down)
for i, explosion in pairs(sequence.vfx) do
explosion_create("RPG-NPC", explosion)
delay(0.1)
end
trigger_enable(sequence.virus_region.name)
audio_object_post_event( DLC2_M03_audio_events.virus_sound, nil, nil, LOCAL_PLAYER )
-- Spawn a thread to monitor implanting the virus
DLC2_M03_thread.virus_transfer = thread_new("dlc2_m03_virus_transfer_thread")
-- Need to handle reinforcements as well
DLC2_M03_thread.air_wave_spawn = thread_new("dlc2_m03_virus_air_wave_spawn_thread")
DLC2_M03_thread.ground_wave_spawn = thread_new("dlc2_m03_virus_ground_wave_spawn_thread")
local uploading_convo_queued = false
local uploading_convo_info = sequence.dialog.uploading
while DLC2_M03_global.current_virus_progress < sequence.duration do
-- Perhaps we should play the transmitting conversation
if uploading_convo_info.convo ~= nil and not uploading_convo_queued then
-- if we have an uploading conversation that hasn't been played
if uploading_convo_info.percent >= DLC2_M03_global.current_virus_progress then
-- if there isn't a conversation currently playing,
dlc2_m03_convo_start(uploading_convo_info.convo)
uploading_convo_queued = true
end
end
thread_yield()
end
audio_object_post_event( DLC2_M03_audio_events.virus_sound_end, nil, nil, LOCAL_PLAYER )
end
function dlc2_m03_cleanup_transmitter_sequence()
local sequence = DLC2_M03_global.current_transmitter_sequence
trigger_enable(sequence.virus_region.name, false)
thread_kill(DLC2_M03_thread.virus_transfer)
DLC2_M03_thread.virus_transfer = INVALID_THREAD_HANDLE
thread_kill(DLC2_M03_thread.air_wave_spawn)
DLC2_M03_thread.air_wave_spawn = INVALID_THREAD_HANDLE
thread_kill(DLC2_M03_thread.ground_wave_spawn)
DLC2_M03_thread.ground_wave_spawn = INVALID_THREAD_HANDLE
thread_kill(DLC2_M03_thread.shield_destroyed_spawn)
DLC2_M03_thread.shield_destroyed_spawn = INVALID_THREAD_HANDLE
-- Queue up the completed dialog
if sequence.dialog.completed ~= nil then
dlc2_m03_convo_start(sequence.dialog.completed)
delay(3.0)
end
dlc2_m03_cleanup_transmitter_groups(sequence.groups)
hud_bar_off(DLC2_M03_GSI_INFECT_INDEX)
DLC2_M03_global.current_virus_progress = 0
DLC2_M03_global.current_transmitter_sequence = nil
DLC2_M03_global.num_shields_destroyed = 0
delay(1.0)
if (sequence.virus_region.name ~= "Trigger_transmit_region<001>") then
dlc_gis_film_grain_unload()
end
-- Queue up the end dialog
if sequence.dialog.end_trans ~= nil then
dlc2_m03_convo_start(sequence.dialog.end_trans)
end
end
function dlc2_m03_cleanup_transmitter_groups(group_table)
for i, group_set in pairs (group_table) do
for j, group in pairs(group_set) do
-- Kill the pilots to cause death spirals on hostile planes
for j, pilot in pairs(group.pilots) do
if not character_is_dead(pilot) and group.is_hostile[j] then
on_vehicle_destroyed("", group.vehicles[j])
if (group.explode_on_transmit[j]) then
vehicle_detonate(group.vehicles[j])
end
character_kill(pilot)
elseif not group.is_hostile[j] then
on_vehicle_destroyed("", group.vehicles[j])
end
end
release_to_world(group.name)
group_destroy(group.name)
end
end
end
function dlc2_m03_setup_checkpoint_vehicle(group)
group_create_hidden(group.name, true)
character_hide(DLC2_M03_character.actress)
teleport_coop(group.nav[1], group.nav[2], true)
teleport(DLC2_M03_character.actress, group.nav[1])
DLC2_M03_current_vehicle_name = group.vehicle
on_vehicle_destroyed("dlc2_m03_alien_aircraft_destroyed", group.vehicle)
on_vehicle_enter_water("dlc2_m03_alien_aircraft_destroyed", group.vehicle)
radio_block(group.vehicle)
vehicle_enter_teleport(LOCAL_PLAYER, group.vehicle, 0, true, true)
set_max_hit_points(DLC2_M03_current_vehicle_name, DLC2_M03_AIRCRAFT_HITPOINTS)
if in_coop then
vehicle_enter_teleport(REMOTE_PLAYER, group.vehicle, 1, true, true)
vehicle_enter_teleport(DLC2_M03_character.actress, group.vehicle, 2, true, true)
else
vehicle_enter_teleport(DLC2_M03_character.actress, group.vehicle, 1, true, true)
end
group_show(group.name)
character_show(DLC2_M03_character.actress)
end
function dlc2_m03_restore_aircraft_health()
local hit_point_percent = (get_current_hit_points(DLC2_M03_current_vehicle_name)/DLC2_M03_AIRCRAFT_HITPOINTS) * 100
hit_point_percent = hit_point_percent + DLC2_M03_AIRCRAFT_RESTORE_PERCENT
if (hit_point_percent >= 100) then
hit_point_percent = 1
else
hit_point_percent = hit_point_percent / 100
end
set_current_hit_points(DLC2_M03_current_vehicle_name, hit_point_percent * DLC2_M03_AIRCRAFT_HITPOINTS)
if (vehicle_get_smoke_and_fire_state(DLC2_M03_current_vehicle_name)) then
vehicle_set_smoke_and_fire_state(DLC2_M03_current_vehicle_name, false, false)
end
audio_object_post_event("PAK2_UFO_Alarm_Mute", nil, nil, DLC2_M03_current_vehicle_name )
end
-- Loads the necessary 2D personas
--
function dlc2_m03_load_personas()
for key, persona in pairs(DLC2_M03_personas) do
persona.handle = audio_persona_load_2d(persona.name)
end
end
-- Unloads all 2d personas
--
function dlc2_m03_unload_personas()
for key, persona in pairs(DLC2_M03_personas) do
if persona.handle ~= INVALID_PERSONA_HANDLE then
audio_persona_remove_2d(persona.handle)
persona.handle = INVALID_PERSONA_HANDLE
end
end
end
-- Gets the 2d persona handle from a character name
--
function dlc2_m03_get_persona_handle(convo)
for key, persona in pairs(DLC2_M03_personas) do
if persona.name == convo.speaker_name then
return persona.handle
end
end
return nil
end
-- Reset the acheivement count for mission start
function dlc2_m03_helper_achievement_reset(achievement_table)
dlc_achievement_counter_set(achievement_table.slot_idx, 0)
achievement_table.current_count = 0
end
-- Read the stored achievement counter from the previous checkpoint
function dlc2_m03_helper_achievement_read_checkpoint(achievement_table)
achievement_table.current_count = dlc_achievement_counter_get(achievement_table.slot_idx)
end
-- Store the current achievement counter for when a checkpoint is reached
function dlc2_m03_helper_achievement_write_checkpoint(achievement_table)
dlc_achievement_counter_set(achievement_table.slot_idx, achievement_table.current_count)
end
-- Increment an acheivement counter
function dlc2_m03_helper_achievement_increment(achievement_table)
-- Check if the target goal has already been reached
if (achievement_table.current_count >= achievement_table.target_goal) then
return
end
-- Increment the counter
achievement_table.current_count = achievement_table.current_count + 1
-- Show the progress HUD
hud_achievement_show_progress(achievement_table.name, achievement_table.current_count, achievement_table.target_goal)
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Callback functions ]]--
--[[ ]]--
--[[**********************]]--
function dlc2_m03_actress_died_cb()
mission_end_failure("dlc2_m03", "DLC2_M03_FAIL_AIRCRAFT_DESTROYED")
end
function dlc2_m03_actress_abandoned_cb()
mission_end_failure("dlc2_m03", "DLC2_M03_FAIL_AIRCRAFT_DESTROYED")
end
function dlc2_m03_alien_aircraft_destroyed(vehicle_name)
on_vehicle_destroyed("", vehicle_name)
on_vehicle_enter_water("", vehicle_name)
radio_unblock(vehicle_name)
mission_end_failure("dlc2_m03", "DLC2_M03_FAIL_AIRCRAFT_DESTROYED")
end
function dlc2_m03_shield_destroyed_cb(mover_name, attacker_name)
DLC2_M03_global.num_shields_destroyed = DLC2_M03_global.num_shields_destroyed + 1
marker_remove(mover_name)
mesh_mover_hide(mover_name)
on_mover_destroyed("", mover_name)
end
function dlc2_m03_heli_destroyed_cb(vehicle_name)
on_vehicle_destroyed("", vehicle_name)
for i, convo in pairs(DLC2_M03_convo_tables.dir_heli) do
if not convo.played then
dlc2_m03_convo_start(convo)
break
end
end
end
function dlc2_m03_on_near_crash_cb(distance)
if (distance*DLC2_M03_FEET_PER_METER) >= DLC2_M03_NEAR_CRASH_LENGTH then
dlc2_m03_helper_achievement_increment(DLC2_M03_acheivements.stunts)
dlc2_m03_convo_start(DLC2_M03_convo.stunt_reaction_01)
DLC2_M03_global.near_crash_completed = true
end
end
-- Callback for when an achievement vehicle dies
function dlc2_m03_ach_veh_destroyed_cb(vehicle, attacker)
on_vehicle_destroyed("", vehicle)
dlc2_m03_helper_achievement_increment(DLC2_M03_acheivements.alien_ships)
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Thread functions ]]--
--[[ ]]--
--[[**********************]]--
function dlc2_m03_virus_transfer_thread()
local current_virus_region = DLC2_M03_global.current_transmitter_sequence.virus_region
local in_upload_region = false
local initial_check = true
while true do
if object_is_in_trigger(current_virus_region.name, DLC2_M03_current_vehicle_name) then
if not in_upload_region or initial_check then
-- Update UI
marker_remove(current_virus_region.name)
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_UPLOAD_VIRUS", "", "", SYNC_ALL, OI_ASSET_INVALID )
hud_bar_on(DLC2_M03_GSI_INFECT_INDEX, "Radioactivity", "", DLC2_M03_global.current_transmitter_sequence.duration)
in_upload_region = true
end
DLC2_M03_global.current_virus_progress = DLC2_M03_global.current_virus_progress + 1
hud_bar_set_value(DLC2_M03_GSI_INFECT_INDEX, DLC2_M03_global.current_virus_progress)
else
if in_upload_region or initial_check then
objective_text( DLC2_M03_GSI_OBJECTIVE_INDEX, "DLC2_M03_GET_IN_RANGE", "", "", SYNC_ALL, OI_ASSET_LOCATION )
hud_bar_off(DLC2_M03_GSI_INFECT_INDEX)
marker_add_trigger(current_virus_region.name, MINIMAP_ICON_LOCATION, nil, OI_ASSET_LOCATION)
in_upload_region = false
end
end
initial_check = false
delay(1)
end
end
function dlc2_m03_virus_air_wave_spawn_thread()
local transmitter_info = DLC2_M03_global.current_transmitter_sequence
local wave_number = 1
while transmitter_info.additional_waves.air[wave_number] ~= nil do
local percent_complete = DLC2_M03_global.current_virus_progress / transmitter_info.duration
if (percent_complete >= (transmitter_info.additional_waves.air[wave_number]/100)) then
local wave_group = transmitter_info.groups.air[wave_number]
group_create_hidden(wave_group.name, true)
for i, pilot in pairs(wave_group.pilots) do
local vehicle = wave_group.vehicles[i]
local is_hostile = wave_group.is_hostile[i]
local spawn_navpoint
local spawn_point_invalid = true
-- Now we need to find a valid navpoint. To be valid there must be no other npcs within range of it
while spawn_point_invalid do
spawn_navpoint = get_random_table_entry(transmitter_info.wave_spawn_navs.air)
-- Loop over all of the reinforcement npcs again
for j, test_member in pairs(wave_group.pilots) do
-- If we find ourself, the spawn point is valid
if i == j then
spawn_point_invalid = false
break
end
-- See if anyone else is close to this navpoint
local dist = get_dist(test_member, spawn_navpoint, false, true)
if dist < 15 then
break
end
-- Make sure the spawn isn't close to the player
dist = get_dist(test_member, LOCAL_PLAYER, false, true)
if dist < 15 then
break
end
end
thread_yield()
end
teleport_vehicle_to_object(vehicle, spawn_navpoint)
vehicle_enter_teleport(pilot, vehicle, 0, true, true)
vehicle_suppress_npc_exit(vehicle, true)
vehicle_chase(vehicle, CLOSEST_PLAYER, false)
if is_hostile then
set_behavior_set(pilot, "Default STAG")
ai_add_enemy_target(pilot, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true)
on_vehicle_destroyed("dlc2_m03_ach_veh_destroyed_cb", vehicle)
else
on_vehicle_destroyed("dlc2_m03_heli_destroyed_cb", vehicle)
end
character_show(pilot)
vehicle_show(vehicle)
end
wave_number = wave_number + 1
end
thread_yield()
end
end
function dlc2_m03_virus_ground_wave_spawn_thread()
local transmitter_info = DLC2_M03_global.current_transmitter_sequence
local wave_number = 1
while transmitter_info.additional_waves.ground[wave_number] ~= nil do
local percent_complete = DLC2_M03_global.current_virus_progress / transmitter_info.duration
if (percent_complete >= (transmitter_info.additional_waves.ground[wave_number]/100)) then
local wave_group = transmitter_info.groups.ground[wave_number]
group_create_hidden(wave_group.name, true)
for i, member in pairs(wave_group.pilots) do
local vehicle = wave_group.vehicles[i]
local is_hostile = wave_group.is_hostile[i]
local spawn_navpoint
local spawn_point_invalid = true
-- Now we need to find a valid navpoint. To be valid there must be no other npcs within range of it
while spawn_point_invalid do
spawn_navpoint = get_random_table_entry(transmitter_info.wave_spawn_navs.ground)
-- Loop over all of the reinforcement npcs again
for j, test_member in pairs(wave_group.pilots) do
-- If we find ourself, the spawn point is valid
if i == j then
spawn_point_invalid = false
break
end
-- See if anyone else is close to this navpoint
local dist = get_dist(test_member, spawn_navpoint, false, true)
if dist < 15 then
break
end
-- Make sure the spawn isn't close to the player
dist = get_dist(test_member, LOCAL_PLAYER, false, true)
if dist < 15 then
break
end
end
thread_yield()
end
teleport_vehicle_to_object(vehicle, spawn_navpoint)
vehicle_enter_teleport(member, vehicle, 0, true, true)
vehicle_suppress_npc_exit(vehicle, true)
vehicle_chase(vehicle, CLOSEST_PLAYER, false)
if is_hostile then
set_behavior_set(member, "Default STAG")
ai_add_enemy_target(member, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true)
end
character_show(member)
vehicle_show(vehicle)
end
wave_number = wave_number + 1
end
thread_yield()
end
end
-- Thread that handles the spawning of enemies as the player destroys transmitter shields
function dlc2_m03_shield_destroyed_spawn_thread()
local transmitter_info = DLC2_M03_global.current_transmitter_sequence
local wave_number = 1
while transmitter_info.additional_waves.shield[wave_number] ~= nil do
-- If the player has killed enough shields to trigger the spawning of a wave
if DLC2_M03_global.num_shields_destroyed >= transmitter_info.additional_waves.shield[wave_number] then
local wave_group = transmitter_info.groups.shield[wave_number]
group_create_hidden(wave_group.name, true)
for i, member in pairs(wave_group.members) do
local vehicle = wave_group.vehicles[i]
local is_hostile = wave_group.is_hostile[i]
local spawn_navpoint
local spawn_point_invalid = true
-- Now we need to find a valid navpoint. To be valid there must be no other npcs within range of it
while spawn_point_invalid do
spawn_navpoint = get_random_table_entry(transmitter_info.wave_spawn_navs.shield)
-- Loop over all of the reinforcement npcs again
for j, test_member in pairs(wave_group.members) do
-- If we find ourself, the spawn point is valid
if i == j then
spawn_point_invalid = false
break
end
-- See if anyone else is close to this navpoint
local dist = get_dist(test_member, spawn_navpoint, false, true)
if dist < 15 then
break
end
-- Make sure the spawn isn't close to the player
dist = get_dist(test_member, LOCAL_PLAYER, false, true)
if dist < 15 then
break
end
end
thread_yield()
end
teleport_vehicle_to_object(vehicle, spawn_navpoint)
vehicle_enter_teleport(member, vehicle, 0, true, true)
vehicle_suppress_npc_exit(vehicle, true)
vehicle_chase(vehicle, CLOSEST_PLAYER, false)
if is_hostile then
set_behavior_set(member, "Default STAG")
ai_add_enemy_target(member, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true)
end
character_show(member)
vehicle_show(vehicle)
end
wave_number = wave_number + 1
end
thread_yield()
end
end
-- Thread that handles the spawning of enemies during the escape sequence.
function dlc2_m03_escape_npc_spawn_thread()
while true do
for i, spawn_group in pairs(DLC2_M03_escape_groups) do
if not spawn_group.spawned then
local dist, closest_player = get_dist_closest_player_to_object(spawn_group.navpoint)
if dist < 500 then
-- Create npcs to attack the player as they try to escape
group_create(spawn_group.name, true)
for i, npc in pairs(spawn_group.members) do
vehicle_enter_teleport(npc, spawn_group.vehicles[i], 0, true, true)
vehicle_chase(spawn_group.vehicles[i], CLOSEST_PLAYER, false)
ai_add_enemy_target(npc, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true)
--marker_add(spawn_group.vehicles[i], MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL)
end
spawn_group.spawned = true
end
end
end
thread_yield()
end
end