--[[
m17.lua
SR3 Mission Script
DATE: 05-07-2010
AUTHOR: Albert McDaniel
]]--
-- Tweakable values --
M17_SALUTE_DIST = 10.0 -- Distance at which STAG guys will salute the player while they're following Kia.
M17_TEMP_PISTOL_NAME = "Pistol-Gang" -- We give the player a temporary pistol after the cutscene to make sure a pistol
-- is equipped at that point; if the player has a better pistol they'll keep that.
M17_NO_NOTORIETY_TIME = 2 * 60 -- How long to prevent notoriety and cop spawns at the beginning of the mission (in seconds).
M17_ESCAPE_VTOL_AUTO_SPLODE_DIST = 15.0
M17_KEYPAD_ANIM = "m13_cardswipe"
M17_KEYPAD_DELAY = 1.0
M17_HOMIE_WEAPON_1 = "Rifle-STAG"
M17_HOMIE_WEAPON_2 = "Shotgun-STAG"
-- Debug flags --
-- Groups --
M17_group = {
homies = {
name = "m17_group_homies",
pierce = "m17_pierce",
viola = "m17_viola"
},
heli = {
name = "m17_group_heli",
heli = "m17_heli"
},
kia = {
name = "m17_group_kia",
kia = "m17_kia"
},
-- meeting = {
-- name = "m17_group_meeting",
-- },
ambush = {
name = "m17_group_ambush",
npcs = {
{
name = "m17_ambush 001",
has_saluted = false,
},
{
name = "m17_ambush 002",
has_saluted = false,
},
{
name = "m17_ambush 003",
has_saluted = false,
},
{
name = "m17_ambush 004",
has_saluted = false,
},
{
name = "m17_ambush 005",
has_saluted = false,
},
{
name = "m17_ambush 006",
has_saluted = false,
},
{
name = "m17_ambush 007",
has_saluted = false,
},
{
name = "m17_ambush 008",
has_saluted = false,
},
{
name = "m17_ambush 009",
has_saluted = false,
},
{
name = "m17_ambush 010",
has_saluted = false,
},
},
},
captive_homies = {
name = "m17_group_captive_homies",
pierce = "m17_captive_pierce",
shaundi = "m17_captive_shaundi",
viola = "m17_captive_viola"
},
captives_misc = {
name = "m17_group_captives_misc",
},
tanks = {
name = "m17_group_tanks",
vehicles = { "m17_tank 001", "m17_tank 002", "m17_tank 003" },
drivers = { "m17_tank_driver 001", "m17_tank_driver 002", "m17_tank_driver 003" }
},
jailors = {
name = "m17_group_jailors"
},
barricade = {
name = "m17_group_barricade",
npcs = { "m17_barricade 001", "m17_barricade 002", "m17_barricade 003", "m17_barricade 004", "m17_barricade 005" }
},
reactor_hall = {
name = "m17_group_reactor_hall",
script = {
[1] = {
{ npc = "m17_guard_rhall<001>", nav = "m17_nav_rhall<001>" },
{ npc = "m17_guard_rhall<002>", nav = "m17_nav_rhall<002>" },
},
[2] = {
{ npc = "m17_guard_rhall<003>", nav = "m17_nav_rhall<003>" },
{ npc = "m17_guard_rhall<004>", nav = "m17_nav_rhall<004>" },
{ npc = "m17_guard_rhall<005>", nav = "m17_nav_rhall<005>" },
},
},
npcs = { "m17_guard_rhall<001>", "m17_guard_rhall<002>", "m17_guard_rhall<003>", "m17_guard_rhall<004>", "m17_guard_rhall<005>", }
},
reactor = {
name = "m17_group_reactor",
npcs = { "m17_guard_reactor 001", "m17_guard_reactor 002", "m17_guard_reactor 003", "m17_guard_reactor 004", "m17_guard_reactor 005",
"m17_guard_reactor 006", "m17_guard_reactor 007", "m17_guard_reactor 008", "m17_guard_reactor 009", "m17_guard_reactor 010",
"m17_guard_reactor 011", }
},
ehall = {
name = "m17_group_ehall",
script = {
[1] = "m17_ehall<001>",
[2] = {
{ npc = "m17_ehall<002>", nav = "m17_nav_ehall<002>" },
{ npc = "m17_ehall<003>", nav = "m17_nav_ehall<003>" },
{ npc = "m17_ehall<004>", nav = "m17_nav_ehall<004>" },
{ npc = "m17_ehall<005>", nav = "m17_nav_ehall<005>" },
{ npc = "m17_ehall<006>", nav = "m17_nav_ehall<006>" },
},
[3] = {
{ npc = "m17_ehall<007>", nav = "m17_nav_ehall<007>" },
{ npc = "m17_ehall<008>", nav = "m17_nav_ehall<008>" },
},
},
explosion = { "m17_nav_ehall<001>", "m17_nav_ehall<009>" },
},
fire = {
name = "m17_group_fire",
script = {
[1] = { "m17_fire<001>", "m17_fire<002>", "m17_fire<003>", "m17_fire<006>" },
[2] = { "m17_fire<004>", "m17_fire<005>" },
},
nav = { "m17_nav_fire<001>" },
},
hanger = {
name = "m17_group_hanger",
vtols = { "m17_fake_vtol<001>", "m17_fake_vtol<002>", "m17_fake_vtol<003>" },
npcs = { "m17_fake_pilot<001>", "m17_fake_pilot<002>", "m17_fake_pilot<003>" },
triggers = { "m17_tgr_fake_vtol 001", "m17_tgr_fake_vtol 002", "m17_tgr_fake_vtol 003" },
},
at_1 = {
name = "m17_group_at 001"
},
at_2 = {
name = "m17_group_at 002"
},
cs_1 = {
name = "m17_group_cs 001"
},
cs_2 = {
name = "m17_group_cs 002"
},
cs_3 = {
name = "m17_group_cs 003"
},
vtol = {
name = "m17_group_vtol",
vtol = "m17_vtol"
},
vtol_reward = {
name = "m17_group_vtol_reward",
vtol = "m17_vtol_reward"
},
}
M17_self_exploding_guys = {M17_group.reactor, M17_group.reactor_hall, M17_group.barricade}
-- Navpoints --
M17_nav_anim = {
brig_entry = "nav_brig_entry_anim",
brig = "nav_brig_anim",
pierce_cell = "nav_pierce_cell_anim",
viola_cell = "nav_viola_cell_anim",
shaundi_cell = "nav_shaundi_cell_anim",
}
M17_nav_cancel = {
dock_local = "m17_nav_cancel_dock",
dock_remote = "m17_nav_cancel_dock_coop",
}
M17_nav_wp = {
heli = "m17_nav_heli",
tank_hall = "m17_nav_tank_hall",
tank_entry = "m17_nav_tank_entry",
brig_hall = "m17_nav_brig_hall",
brig_stairs = "m17_nav_brig_stairs",
reactor = "m17_nav_reactor",
escape_stairs = "m17_nav_escape_stairs",
hanger_n = "m17_nav_hanger_n",
}
M17_path_kia = { "kia_path_01", "kia_path_02", "kia_path_03", "kia_path_04", "kia_path_05", "kia_path_06", "kia_path_07", "kia_path_08",
"kia_path_09", "kia_path_10", "kia_path_11", "kia_path_12", "kia_path_13", --[["kia_path_14",--]] "kia_path_15", "kia_path_16",
"kia_path_17", "kia_path_18", "kia_path_19", }
M17_nav_barricade = { "m17_nav_barricade 001", "m17_nav_barricade 002", "m17_nav_barricade 003", "m17_nav_barricade 004", "m17_nav_barricade 005" }
M17_explosions = {
effect = { "rpg", "satchel" },
reactor = { "m17_explosion 001", "m17_explosion 002", "m17_explosion 003", "m17_explosion 004", "m17_explosion 005",
"m17_explosion 006", "m17_explosion 007", "m17_explosion 008", "m17_explosion 009", "m17_explosion 010",
"m17_explosion 011", "m17_explosion 012", "m17_explosion 013", "m17_explosion 014", "m17_explosion 015",
"m17_explosion 035", "m17_explosion 036" },
hall = { "m17_explosion 037", "m17_explosion 038", "m17_explosion 039", "m17_explosion 040", "m17_explosion 041",
"m17_explosion 042", "m17_explosion 043", "m17_explosion 044", "m17_explosion 045", "m17_explosion 046",
"m17_explosion 047", "m17_explosion 048", "m17_explosion 049", "m17_explosion 050", "m17_explosion 051",
"m17_explosion 052", "m17_explosion 053", "m17_explosion 054", "m17_explosion 055", "m17_explosion 056",
"m17_explosion 057", "m17_explosion 058", "m17_explosion 059", "m17_explosion 060", "m17_explosion 061",
"m17_explosion 062" },
deck = { "m17_explosion 016", "m17_explosion 017", "m17_explosion 018", "m17_explosion 019", "m17_explosion 020",
"m17_explosion 021", "m17_explosion 022", "m17_explosion 023", "m17_explosion 024", "m17_explosion 025",
"m17_explosion 026", "m17_explosion 027", "m17_explosion 028", "m17_explosion 029", "m17_explosion 030",
"m17_explosion 031", "m17_explosion 032", "m17_explosion 033", "m17_explosion 034", "m17_explosion 063",
"m17_explosion 064", "m17_explosion 065", "m17_explosion 066", "m17_explosion 067", "m17_explosion 068",
"m17_explosion 069", "m17_explosion 070", "m17_explosion 071", "m17_explosion 072" },
}
-- Triggers --
M17_triggers = {
armory_island = "m17_trigger_armory_island",
convo_getting_close = "m17_trigger_convo_close",
armory = "m17_trigger_nga",
carrier = "m17_trigger_carrier",
tank_exit = "m17_trigger_tank_exit",
brig = "m17_trigger_brig",
brig_entry = "m17_trigger_brig_entry",
brig_esc = "m17_trigger_brig_esc_001",
brig_stairs = "m17_trigger_brig_stairs",
reactor_spawn = "m17_trigger_rspawn",
reactor_hall = "m17_trigger_rhall",
pierce = "m17_trigger_pierce",
shaundi = "m17_trigger_shaundi",
viola = "m17_trigger_viola",
ehall_1 = "m17_trigger_ehall<001>",
ehall_2 = "m17_trigger_ehall<002>",
escape_hall = "m17_trigger_escape_hall",
fire = "m17_trigger_fire",
enter_tank_bay = "trigger_enter_tank_bay",
enter_reactor = "trigger_enter_reactor",
enter_hangar = "trigger_enter_hangar",
}
-- Spawn Regions --
M17_regions = {
start_stairs = "m17_region_start_stairs",
start_hall = "m17_region_start_hall",
tank_e = "m17_region_tank_e",
tank_w = "m17_region_tank_w",
tank_exit = "m17_region_tank_exit",
brig_exit = "m17_region_brig_exit",
reactor_hall = "m17_region_reactor_hall",
escape_hall = "m17_region_escape_hall",
escape_stairs = "m17_region_escape_stairs",
reactor_1 = "m17_region_reactor 001",
reactor_2 = "m17_region_reactor 002",
}
-- Spawn Groups --
-- Script Movers --
M17_CONSOLE = "m17_console"
M17_MEETING_DOOR_1 = "m17_door_meeting_1"
M17_MEETING_DOOR_2 = "m17_door_meeting_2"
M17_doors = {
start_stairs = "m17_door_start_stairs",
start_hall = "m17_door_start_hall",
tank_hall = "m17_door_tank_hall",
tank_exit = "m17_door_tank_exit",
brig_hall = "m17_door_brig_hall",
pierce = "m17_door_pierce",
shaundi = "m17_door_shaundi",
viola = "m17_door_viola",
brig_big = "m17_door_brig_big",
brig_inner = "m17_door_brig_inner",
brig_outer = "m17_door_brig_outer",
brig_ambush = "m17_door_brig_ambush",
brig_stairs_1 = "m17_door_brig_stairs",
brig_stairs_2 = "m17_door_brig_stairs_2",
escape_stairs = "m17_door_escape_stairs",
hanger_s = "m17_door_hanger_s",
brig_1 = "m17_door_brig_001",
brig_2 = "m17_door_brig_002",
brig_3 = "m17_door_brig_003",
brig_4 = "m17_door_brig_004",
}
M17_automatic_doors = {
tank_entry = {
trigger = "m17_trigger_tank_entry",
door = "m17_door_tank_entry",
},
tank_ne = {
trigger = "m17_trigger_tank_ne",
door = "m17_door_tank_ne",
},
tank_nw = {
trigger = "m17_trigger_tank_nw",
door = "m17_door_tank_nw",
},
tank_se = {
trigger = "m17_trigger_tank_se",
door = "m17_door_tank_se",
},
tank_sw = {
trigger = "m17_trigger_tank_sw",
door = "m17_door_tank_sw",
},
reactor = {
trigger = "m17_trigger_reactor",
door = "m17_door_reactor",
},
reactor_1 = {
trigger = "m17_trigger_reactor 001",
door = "m17_door_reactor 001",
},
reactor_2 = {
trigger = "m17_trigger_reactor 002",
door = "m17_door_reactor 002",
},
reactor_3 = {
trigger = "m17_trigger_reactor 003",
door = "m17_door_reactor 003",
},
reactor_4 = {
trigger = "m17_trigger_reactor 004",
door = "m17_door_reactor 004",
},
reactor_5 = {
trigger = "m17_trigger_reactor 005",
door = "m17_door_reactor 005",
},
reactor_6 = {
trigger = "m17_trigger_reactor 006",
door = "m17_door_reactor 006",
},
reactor_7 = {
trigger = "m17_trigger_reactor 007",
door = "m17_door_reactor 007",
},
reactor_8 = {
trigger = "m17_trigger_reactor 008",
door = "m17_door_reactor 008",
},
-- Locked automatic door
hanger_n = {
trigger = "m17_trigger_hanger_n",
door = "m17_door_hanger_n",
},
}
-- Text --
-- Conversations --
M17_conv = {
start = {
name = "m17_convo_1",
handle = INVALID_CONVERSATION_HANDLE,
},
drive_1 = {
name = "M17_Drive_To_Heli_1",
handle = INVALID_CONVERSATION_HANDLE,
},
drive_2 = {
name = "M17_Drive_To_Heli_2",
handle = INVALID_CONVERSATION_HANDLE,
},
flying = {
name = "M17_Flying",
handle = INVALID_CONVERSATION_HANDLE,
},
handcuffs = {
name = "m17_convo_2",
handle = INVALID_CONVERSATION_HANDLE,
},
lead_the_way = {
name = "M17_Lead_The_Way",
handle = INVALID_CONVERSATION_HANDLE,
},
kia = {
name = "m17_convo_3",
handle = INVALID_CONVERSATION_HANDLE,
},
reward = {
name = "M17_Reward_Choices",
handle = INVALID_CONVERSATION_HANDLE,
},
shaundi_thanks = {
name = "M17_Shaundi_Thanks",
handle = INVALID_CONVERSATION_HANDLE,
},
reactor = {
name = "M17_Reactor",
handle = INVALID_CONVERSATION_HANDLE,
},
flash_bang = {
name = "M17_Flash_Bang_Event",
handle = INVALID_CONVERSATION_HANDLE,
},
consoles = {
name = "M17_Consoles",
handle = INVALID_CONVERSATION_HANDLE,
},
escape = {
name = "M17_Escape",
handle = INVALID_CONVERSATION_HANDLE,
},
}
M17_personas = {
kia = {
name = "Kia",
id = INVALID_PERSONA_HANDLE,
},
cyrus = {
name = "Cyrus",
id = INVALID_PERSONA_HANDLE,
},
computer = {
name = "Code9857",
id = INVALID_PERSONA_HANDLE,
},
}
M17_music = {
music_a = "M17_music_a",
music_a_stop = "M17_music_a_stop",
music_b = "M17_music_b",
music_b_stop = "M17_music_b_stop",
}
-- Threads --
M17_threads = {
no_notoriety = INVALID_THREAD_HANDLE,
police_notoriety_monitor = INVALID_THREAD_HANDLE,
follow = INVALID_THREAD_HANDLE,
kia_path = INVALID_THREAD_HANDLE,
convo = INVALID_THREAD_HANDLE,
salute = INVALID_THREAD_HANDLE,
pa = INVALID_THREAD_HANDLE,
explosions = INVALID_THREAD_HANDLE,
escape_talk = INVALID_THREAD_HANDLE,
convo_failsafe = INVALID_THREAD_HANDLE,
explode_guys = INVALID_THREAD_HANDLE,
auto_explode_vtols = INVALID_THREAD_HANDLE,
}
-- Checkpoints --
M17_checkpoint_start = {
name = MISSION_START_CHECKPOINT, -- defined in ug_lib.lua
player = "m17_nav_cp_start_player",
coop = "m17_nav_cp_start_coop",
player_vehicle = "m17_nav_start_host_veh",
coop_vehicle = "m17_nav_start_client_veh",
}
M17_checkpoint_meeting = {
name = "meeting",
player = "m17_nav_cp_meeting_player",
coop = "m17_nav_cp_meeting_coop"
}
M17_checkpoint_jailbreak = {
name = "jailbreak",
player = "m17_nav_cp_jailbreak_player",
coop = "m17_nav_cp_jailbreak_coop"
}
M17_checkpoint_reactor = {
name = "reactor",
player = "m17_nav_cp_reactor_player",
coop = "m17_nav_cp_reactor_coop"
}
M17_checkpoint_escape = {
name = "escape",
player = "m17_nav_cp_escape_player",
coop = "m17_nav_cp_escape_coop"
}
-- Cutscenes --
M17_CUTSCENE_MISSION_INTRO = "17_in"
M17_CUTSCENE_THERM_LANDING = "17_mid"
M17_CUTSCENE_MISSION_OUTRO = "17_out"
M17_ZSCENE_01 = "17_z01"
-- Other --
M17_in_coop = false
M17_has_reached_goal = false
M17_began_freeing_pierce = false
M17_has_pierce = false
M17_began_freeing_shaundi = false
M17_has_shaundi = false
M17_began_freeing_viola = false
M17_has_viola = false
M17_mission_success = false
M17_stealh_section = false
M17_MAX_KIA_DISTANCE = 8
M17_MIN_KIA_DISTANCE = 2
M17_ESCAPE_TIME = 180000
M17_ESCAPE_TIMER_TAG = "M17_TIMER_ESCAPE"
M17_BAR_INDEX = 0
M17_TIMER_INDEX = 0
M17_CHOICE_SCREEN = "msn_proto_select"
M17_rewards = {
[1] = "M17_Vehicle_Jet_Bike",
[2] = "Crib_Weapon_Satchel_Charges",
[3] = "M17_Vehicle_STAG_Tank_Upgrade"
}
-- *************************
--
-- 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
--
-- m17_checkpoint: The checkpoint the mission should begin at
-- is_restart: TRUE if the mission is restarting, FALSE otherwise
--
function m17_start(m17_checkpoint, is_restart)
-- Override the checkpoint
--m17_checkpoint = M17_checkpoint_reactor.name
M17_in_coop = coop_is_active()
-- Release any homies ASAP
party_dismiss_all()
-- Check if this mission starting from the beginning
if (m17_checkpoint == M17_checkpoint_start.name) then
if (is_restart == false) then
-- First time playing mission
cutscene_play(M17_CUTSCENE_MISSION_INTRO, nil, {M17_checkpoint_start.player, M17_checkpoint_start.coop}, false)
end
end
-- Handle mission initialization for the current checkpoint
m17_initialize(m17_checkpoint, is_restart)
-- Run the mission from the current checkpoint
m17_run(m17_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 m17_run(first_checkpoint)
local current_checkpoint = first_checkpoint
-- For this section, warp to the plastic surgeon on cancel
mission_set_cancel_warp_location(M17_checkpoint_start.player, M17_checkpoint_start.coop)
audio_ambient_emitter_stop("NG_Island_Siren<001>")
-- Run the mission from the beginning
if current_checkpoint == M17_checkpoint_start.name then
--[[ INSERT PROCESSING FOR THE FIRST CHECKPOINT HERE ]]--
-- Begin a stealth section; notoriety increases will fail the mission.
m17_begin_stealth_section()
-- Find a helicopter
m17_hijack_heli()
-- Land on the carrier
m17_board_ship()
-- Set the next checkpoint
current_checkpoint = M17_checkpoint_meeting.name
mission_set_checkpoint(M17_checkpoint_meeting.name, true)
end
-- For the rest of the mission, warp to the dock on cancel
mission_set_cancel_warp_location(M17_nav_cancel.dock_local, M17_nav_cancel.dock_remote)
-- Set up the automatic doors (except the hanger)
for i, auto in pairs(M17_automatic_doors) do
trigger_enable(auto.trigger, true)
on_trigger("m17_door_enter", auto.trigger)
on_trigger_exit("m17_door_exit", auto.trigger)
end
trigger_enable(M17_automatic_doors.hanger_n.trigger, false)
on_trigger("", M17_automatic_doors.hanger_n.trigger)
on_trigger_exit("", M17_automatic_doors.hanger_n.trigger)
if current_checkpoint == M17_checkpoint_meeting.name then
character_ragdoll_set_last_resort_position(M17_checkpoint_meeting.player)
-- Make music happen.
m17_post_music_event(M17_music.music_a)
-- Begin a stealth section; notoriety increases will fail the mission.
m17_begin_stealth_section()
-- Follow Kia to the meeting
m17_follow_kia()
m17_cleanup_stealth_section()
m17_meeting()
-- Set the next checkpoint
current_checkpoint = M17_checkpoint_jailbreak.name
mission_set_checkpoint(M17_checkpoint_jailbreak.name, true)
end
-- Turn off special Cyrus status
m17_cover_broken()
-- Set up the brig doors
trigger_enable(M17_triggers.brig, true)
on_trigger("m17_brig_activated", M17_triggers.brig)
door_open(M17_doors.brig_outer, false, false)
-- Open the doors to the rest of the ship
door_open(M17_doors.start_stairs)
door_open(M17_doors.start_hall)
door_open(M17_doors.brig_hall)
door_open(M17_doors.brig_1, false, false)
door_open(M17_doors.brig_2, false, false)
door_open(M17_doors.brig_3, false, false)
door_open(M17_doors.brig_4, false, false)
door_open(M17_doors.brig_stairs_1, false, false)
door_open(M17_doors.brig_stairs_2, false, false)
-- Load Cyrus' persona for intercom VO
M17_personas.cyrus.id = audio_persona_load_2d(M17_personas.cyrus.name)
if current_checkpoint == M17_checkpoint_jailbreak.name then
character_ragdoll_set_last_resort_position(M17_checkpoint_jailbreak.player)
-- Fire up some audio action.
audio_object_post_event("m17_checkpoint_jailbreak")
-- Free the Saints from the brig
m17_free_friends()
-- Set the next checkpoint
current_checkpoint = M17_checkpoint_reactor.name
mission_set_checkpoint(M17_checkpoint_reactor.name, true)
end
if current_checkpoint == M17_checkpoint_reactor.name then
character_ragdoll_set_last_resort_position(M17_checkpoint_reactor.player)
-- Fire up some audio action.
audio_object_post_event("m17_checkpoint_reactor")
-- Destroy the nuclear reactor
m17_destroy_reactor()
-- Set the next checkpoint
current_checkpoint = M17_checkpoint_escape.name
mission_set_checkpoint(M17_checkpoint_escape.name, true)
end
-- Load the computer persona for intercom VO
--M17_personas.computer.id = audio_persona_load_2d(M17_personas.computer.name)
if current_checkpoint == M17_checkpoint_escape.name then
character_ragdoll_set_last_resort_position(M17_checkpoint_escape.player)
-- Fire up some audio action.
audio_object_post_event("m17_checkpoint_escape")
-- Escape the carrier
m17_escape()
end
M17_mission_success = true
-- Create the reward VTOL
group_create(M17_group.vtol_reward.name, true)
-- Stop the music.
m17_post_music_event(M17_music.music_b_stop)
homie_mission_unlock("shaundi") -- Allow Shaundi to be called as a homie again (locked in M16)
mission_end_success("m17", M17_CUTSCENE_MISSION_OUTRO, {M17_nav_cancel.dock_local, M17_nav_cancel.dock_remote})
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE
--
function m17_cleanup()
--[[ INSERT ANY MISSION SPECIFIC CLEAN-UP ]]--
-- Restart ambient alarms on NG island
audio_ambient_emitter_start("NG_Island_Siren<001>")
-- Stop the situation override.
persona_clear_global_situation_override()
-- Check to see if we're still in co-op; the remote player may have dropped.
M17_in_coop = coop_is_active()
-- Swap out the interior.
city_zone_swap("ThermInt1", false)
-- If the player didn't complete the mission, we need to swap the Thermopylae
-- exterior back in.
if M17_mission_success == false then
city_zone_swap("therm2", true)
city_zone_swap("thermext1", true)
end
-- Stop any threads
for i, thrd in pairs(M17_threads) do
if (thrd ~= INVALID_THREAD_HANDLE) then
thread_kill(thrd)
thrd = INVALID_THREAD_HANDLE
end
end
--- Cut short any conversations
for i, conv in pairs(M17_conv) do
if conv.handle ~= INVALID_CONVERSATION_HANDLE then
audio_conversation_end(conv.handle)
conv.handle = INVALID_CONVERSATION_HANDLE
end
end
-- Remove loaded personas
for i, pers in pairs(M17_personas) do
if pers.id ~= INVALID_PERSONA_HANDLE then
audio_persona_remove_2d(pers.id)
pers.id = INVALID_PERSONA_HANDLE
end
end
-- Clean up all triggers.
for i, trigger in pairs(M17_triggers) do
m17_clear_trigger(trigger)
end
-- Clean up objective-specific items
m17_hijack_heli_cleanup()
m17_board_ship_cleanup()
m17_follow_kia_cleanup()
m17_meeting_cleanup()
m17_free_friends_cleanup()
m17_reactor_cleanup()
m17_escape_cleanup()
m17_cleanup_stealth_section()
-- Reenable recruitment.
party_set_recruitable(true)
-- Clear any objective text
objective_text_clear(0)
mission_waypoint_remove()
-- Cleanup waypoint markers
for i, wp in pairs(M17_nav_wp) do
marker_remove(wp, SYNC_ALL)
end
-- Disable automatic doors
for i, auto in pairs(M17_automatic_doors) do
trigger_enable(auto.trigger, false)
on_trigger("", auto.trigger)
on_trigger_exit("", auto.trigger)
end
-- Clear any triggers
for i, trig in pairs(M17_triggers) do
m17_clear_trigger(trig)
end
-- Clear any spawn regions and spawn groups
continuous_spawn_stop(M17_group.cs_1.name)
continuous_spawn_stop(M17_group.cs_2.name)
continuous_spawn_stop(M17_group.cs_3.name)
continuous_spawn_stop(M17_group.at_1.name)
continuous_spawn_stop(M17_group.at_2.name)
for i, region in pairs(M17_regions) do
spawn_region_enable(region, false)
end
-- Clean up spawned groups
if group_is_loaded(M17_group.captive_homies.name) then
on_death("", M17_group.captive_homies.pierce)
on_death("", M17_group.captive_homies.shaundi)
on_death("", M17_group.captive_homies.viola)
on_dismiss("", M17_group.captive_homies.pierce)
on_dismiss("", M17_group.captive_homies.shaundi)
on_dismiss("", M17_group.captive_homies.viola)
end
if group_is_loaded(M17_group.homies.name) then
on_death("", M17_group.homies.pierce)
on_death("", M17_group.homies.viola)
on_dismiss("", M17_group.homies.pierce)
on_dismiss("", M17_group.homies.viola)
end
if group_is_loaded(M17_group.vtol.name) then
marker_remove(M17_group.vtol.vtol, SYNC_ALL)
end
if group_is_loaded(M17_group.vtol_reward.name) then
release_to_world(M17_group.vtol_reward.name)
end
if group_is_loaded(M17_group.tanks.name) then
group_destroy(M17_group.tanks.name)
end
cleanup_groups(M17_group)
-- Allow notoriety again
hud_set_fake_notoriety("police", false, 0)
notoriety_set_can_decay(true)
notoriety_force_no_spawn("police", false)
notoriety_restricted_zones_enable(true)
notoriety_set_max("police", 5)
notoriety_spawn_only_air(false)
notoriety_force_no_spawn_group("stag_attack_heli", false)
notoriety_force_no_spawn_group("stag_heli", false)
-- Turn the player back into themselves
customization_item_revert( SYNC_LOCAL )
customization_restore_player_rig( SYNC_LOCAL )
if coop_is_active() then
customization_item_revert( SYNC_REMOTE )
end
-- Allow human shields again and reset team
set_player_can_take_human_shields(LOCAL_PLAYER, true)
set_player_undercover_team(LOCAL_PLAYER, "None")
if (M17_in_coop == true) then
set_player_can_take_human_shields(REMOTE_PLAYER, true)
set_player_undercover_team(REMOTE_PLAYER, "None")
end
-- Allow weapon selection again
inv_weapon_disable_all_slots(false)
player_grenades_enable()
auto_pickup_enable();
action_nodes_enable(true)
-- Allow ped spawning again.
spawning_pedestrians(true)
-- Remove the temporary pistol we give the player after the meeting cutscene.
inv_weapon_remove_temporary(LOCAL_PLAYER, M17_TEMP_PISTOL_NAME)
-- Stop using the mission specified ragdoll get up last resort.
character_ragdoll_clear_last_resort_position()
-- Stop all music.
m17_post_music_event(M17_music.music_a_stop)
m17_post_music_event(M17_music.music_b_stop)
end
-- Called when the mission has ended with success
-- CALLED FROM CODE
--
function m17_success()
--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]--
local skip_teleport = true
m17_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
-- is_restart: Whether or not the mission is restarting.
--
function m17_initialize(checkpoint, is_restart)
-- Make sure the screen is completly faded out
mission_start_fade_out(0.0)
-- Set the mission author
set_mission_author("Albert McDaniel")
-- Set the persona situation override for the player dressed as Cyrus.
persona_set_global_situation_override(PS_OVERRIDE_MISSION17)
-- Ensure the requisite zones are swapped in
-- Swap in the interior.
if checkpoint == M17_checkpoint_meeting.name or
checkpoint == M17_checkpoint_jailbreak.name or
checkpoint == M17_checkpoint_reactor.name or
checkpoint == M17_checkpoint_escape.name then
city_zone_swap("ThermInt1", true)
city_zone_swap("thermext1", false)
city_zone_swap("therm2", false)
else
-- If we're starting the mission fresh or restarting the mission from the
-- start we need to swap out the interior and make sure the exterior is swapped in.
-- Swapping it out in the cleanup function only disables the zone swap
-- if the mission is cancelled.
city_zone_swap("ThermInt1", false)
city_zone_swap("thermext1", true)
city_zone_swap("Therm2", true)
end
-- Any notoriety is fake for this mission
notoriety_force_no_spawn("police", true)
notoriety_set_can_decay(false)
notoriety_set_max("police", 0)
notoriety_restricted_zones_enable(false)
notoriety_force_no_spawn_group("stag_attack_heli", true)
notoriety_force_no_spawn_group("stag_heli", true)
-- Turn the player into Cyrus
customization_item_wear( "Cyrus Suit", "cyrus_hires.cmeshx", "Cyrus", false, SYNC_LOCAL )
customization_item_wear( "Cyrus Head", "cyrus_hires_head.cmeshx", "Cyrus", false, SYNC_LOCAL )
customization_swap_player_rig( "cyrus.rig", "PLYM", SYNC_LOCAL )
if coop_is_active() then
-- Put the remote player into a regular STAG soldier outfit.
customization_item_wear("cm_stag", "cm_stag.cmeshx", "Stag_Body", false, SYNC_REMOTE)
customization_item_wear("cm_hat_m_staghelmet", "cm_hat_m_staghelmet.cmeshx", "StagCommando_Body", false, SYNC_REMOTE)
end
-- Prevent taking human shields and set the players to the STAG team
set_player_can_take_human_shields(LOCAL_PLAYER, false)
set_player_undercover_team(LOCAL_PLAYER, "STAG")
if (M17_in_coop == true) then
set_player_can_take_human_shields(REMOTE_PLAYER, false)
set_player_undercover_team(REMOTE_PLAYER, "STAG")
end
-- Prevent weapon selection
auto_pickup_disable();
inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_UNARMED)
player_grenades_disable()
-- Prevent recruitment, otherwise the player could recruit STAG, which is funny but probably bad.
party_set_recruitable(false)
-- Set up the mission based on the checkpoint
if (checkpoint == M17_checkpoint_start.name) then
--[[ INSERT ANY INITIALIZATION CODE FOR STARTING THE MISSION AT THE BEGINNING ]]--
-- Get the players' vehicles out of the way.
teleport_player_vehicles(M17_checkpoint_start.player_vehicle, M17_checkpoint_start.coop_vehicle)
-- Teleport the players
if is_restart == true then
teleport_coop(M17_checkpoint_start.player, M17_checkpoint_start.coop, true)
end
-- Spawn and add homies
group_create(M17_group.homies.name, true)
set_dont_attack_me_on_sight_flag(M17_group.homies.pierce, true)
set_dont_attack_me_on_sight_flag(M17_group.homies.viola, true)
-- Pierce and Viola shouldn't enter combat; they're supposed to be prisoners.
npc_combat_enable(M17_group.homies.pierce, false)
npc_combat_enable(M17_group.homies.viola, false)
on_death("m17_fail_pierce_died", M17_group.homies.pierce)
on_death("m17_fail_viola_died", M17_group.homies.viola)
party_add_ignore_limits(M17_group.homies.pierce, LOCAL_PLAYER)
if (M17_in_coop) then
party_add_ignore_limits(M17_group.homies.viola, REMOTE_PLAYER)
else
party_add_ignore_limits(M17_group.homies.viola, LOCAL_PLAYER)
end
follower_set_can_abandon(M17_group.homies.pierce, true)
follower_set_can_abandon(M17_group.homies.viola, true)
on_dismiss("m17_fail_dismissed_cb", M17_group.homies.pierce)
on_dismiss("m17_fail_dismissed_cb", M17_group.homies.viola)
tutorial_start("mis_undercover", 5, true, false) --SP 7/12: Added tutorial about undercover, feel free to move it if it's in a bad place
-- Spawn a heli (the player does NOT have to use this heli)
group_create(M17_group.heli.name, true)
end
if (checkpoint == M17_checkpoint_meeting.name) then
-- Teleport the players
teleport_coop(M17_checkpoint_meeting.player, M17_checkpoint_meeting.coop, true)
-- We need to hide the door to the R&D lab because it sticks through the wall when it's open...
mesh_mover_hide(M17_MEETING_DOOR_1)
mesh_mover_hide(M17_MEETING_DOOR_2)
-- Spawn Kia
group_create(M17_group.kia.name, true)
-- Spawn the scientists
-- group_create(M17_group.meeting.name, true)
-- Spawn guards to ambush the player later
group_create(M17_group.ambush.name, true)
-- Disable ped spawning while inside the Thermopylae.
spawning_pedestrians(false)
end
if (checkpoint == M17_checkpoint_jailbreak.name) then
-- Make music happen.
m17_post_music_event(M17_music.music_a)
-- Teleport the players
teleport_coop(M17_checkpoint_jailbreak.player, M17_checkpoint_jailbreak.coop, true)
-- Spawn guards to ambush the player
group_create(M17_group.ambush.name, true)
-- Equip a pistol on the local player to match the cutscene after the meeting.
m17_equip_pistol()
-- Spawn the next objective before fading in
m17_free_friends_setup()
-- Disable ped spawning while inside the Thermopylae.
spawning_pedestrians(false)
end
if (checkpoint == M17_checkpoint_reactor.name) then
-- Spawn the captive homies
group_create(M17_group.captive_homies.name, true)
--group_create(M17_group.captive_misc.name, true)
on_death("m17_fail_pierce_died", M17_group.captive_homies.pierce)
on_death("m17_fail_shaundi_died", M17_group.captive_homies.shaundi)
on_death("m17_fail_viola_died", M17_group.captive_homies.viola)
-- Give them some weapons.
inv_item_add(M17_HOMIE_WEAPON_1, 1, M17_group.captive_homies.pierce, true)
inv_item_add(M17_HOMIE_WEAPON_2, 1, M17_group.captive_homies.shaundi, true)
inv_item_add(M17_HOMIE_WEAPON_1, 1, M17_group.captive_homies.viola, true)
-- Add everyone to the player's party
if (M17_in_coop) then
party_add_ignore_limits(M17_group.captive_homies.pierce, M17_group.captive_homies.shaundi, LOCAL_PLAYER)
party_add_ignore_limits(M17_group.captive_homies.viola, REMOTE_PLAYER)
else
party_add_ignore_limits(M17_group.captive_homies.pierce, M17_group.captive_homies.viola, M17_group.captive_homies.shaundi, LOCAL_PLAYER)
end
follower_set_can_abandon(M17_group.captive_homies.pierce, true)
follower_set_can_abandon(M17_group.captive_homies.viola, true)
follower_set_can_abandon(M17_group.captive_homies.shaundi, true)
on_dismiss("m17_fail_dismissed_cb", M17_group.captive_homies.pierce)
on_dismiss("m17_fail_dismissed_cb", M17_group.captive_homies.viola)
on_dismiss("m17_fail_dismissed_cb", M17_group.captive_homies.shaundi)
-- Teleport the players after adding followers so they come along with.
teleport_coop(M17_checkpoint_reactor.player, M17_checkpoint_reactor.coop, true)
-- Disable ped spawning while inside the Thermopylae.
spawning_pedestrians(false)
end
if (checkpoint == M17_checkpoint_escape.name) then
-- Make music happen.
m17_post_music_event(M17_music.music_b)
-- Spawn the captive homies
group_create(M17_group.captive_homies.name, true)
on_death("m17_fail_pierce_died", M17_group.captive_homies.pierce)
on_death("m17_fail_shaundi_died", M17_group.captive_homies.shaundi)
on_death("m17_fail_viola_died", M17_group.captive_homies.viola)
-- Give them some weapons.
inv_item_add(M17_HOMIE_WEAPON_1, 1, M17_group.captive_homies.pierce, true)
inv_item_add(M17_HOMIE_WEAPON_2, 1, M17_group.captive_homies.shaundi, true)
inv_item_add(M17_HOMIE_WEAPON_1, 1, M17_group.captive_homies.viola, true)
-- Add everyone to the player's party
if (M17_in_coop) then
party_add_ignore_limits(M17_group.captive_homies.pierce, M17_group.captive_homies.shaundi, LOCAL_PLAYER)
party_add_ignore_limits(M17_group.captive_homies.viola, REMOTE_PLAYER)
else
party_add_ignore_limits(M17_group.captive_homies.pierce, M17_group.captive_homies.viola, M17_group.captive_homies.shaundi, LOCAL_PLAYER)
end
-- Teleport the players after adding followers so they come along with.
teleport_coop(M17_checkpoint_escape.player, M17_checkpoint_escape.coop, true)
-- Disable ped spawning while inside the Thermopylae.
spawning_pedestrians(false)
end
-- Start fading in
mission_start_fade_in()
end
-- Turn off special Cyrus status
function m17_cover_broken()
-- Set the notoriety to 5 stars to force attacking
notoriety_set_max("police", 3)
notoriety_set("police", 3)
hud_set_fake_notoriety("police", false, 5)
-- Allow human shields again and reset team
set_player_can_take_human_shields(LOCAL_PLAYER, true)
set_player_undercover_team(LOCAL_PLAYER, "None")
if (M17_in_coop == true) then
set_player_can_take_human_shields(REMOTE_PLAYER, true)
set_player_undercover_team(REMOTE_PLAYER, "None")
end
-- Allow weapon selection again
inv_weapon_disable_all_slots(false)
player_grenades_enable()
auto_pickup_enable();
end
-- Disable trigger
--
-- trigger: (string) Name of the trigger
--
function m17_clear_trigger(trigger)
on_trigger("", trigger)
on_trigger_exit("", trigger)
trigger_enable(trigger, false)
marker_remove_trigger(trigger, SYNC_ALL)
end
-- *************************
-- Objective: Hijack Heli
-- *************************
-- Find a helicopter
function m17_hijack_heli()
-- Load the intro conversation
M17_conv.start.handle = audio_conversation_load(M17_conv.start.name)
-- Disable notoriety and ambient cop spawns for a while at the beginning of the mission.
M17_threads.no_notoriety = thread_new("m17_disable_notoriety_for_drive_to_armory_thread")
-- Set the heli as the next goal
M17_has_reached_goal = false
objective_text(0, "M17_OBJ_FIND_HELI", "", "", SYNC_ALL, OI_ASSET_LOCATION)
on_vehicle_enter("m17_heli_entered", LOCAL_PLAYER)
if (M17_in_coop == true) then
on_vehicle_enter("m17_heli_entered", REMOTE_PLAYER)
end
mission_waypoint_add(M17_triggers.armory, SYNC_ALL)
trigger_enable(M17_triggers.armory, true)
on_trigger("m17_armory_enter_cb", M17_triggers.armory)
marker_add_trigger(M17_triggers.armory, MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
turn_invulnerable(M17_group.heli.heli)
-- Tell the player to hijack a heli
audio_conversation_play(M17_conv.start.handle)
audio_conversation_wait_for_end(M17_conv.start.handle)
M17_conv.start.handle = INVALID_CONVERSATION_HANDLE
-- Load the next conversation
M17_conv.drive_1.handle = audio_conversation_load(M17_conv.drive_1.name)
delay(6)
-- Start the conversation
audio_conversation_play(M17_conv.drive_1.handle)
audio_conversation_wait_for_end(M17_conv.drive_1.handle)
M17_conv.drive_1.handle = INVALID_CONVERSATION_HANDLE
-- Load the next conversation
M17_conv.drive_2.handle = audio_conversation_load(M17_conv.drive_2.name)
delay(6)
-- Start the conversation
audio_conversation_play(M17_conv.drive_2.handle)
-- Wait until the player enters a heli
while not M17_has_reached_goal do
thread_yield()
end
-- Clean up the objective
m17_hijack_heli_cleanup()
objective_text_clear(0)
mission_waypoint_remove()
end
-- When the player enters the NG armory island.
--
function m17_enter_armory_island_cb()
m17_clean_up_notoriety_stuff_for_driving_to_armory()
end
function m17_armory_enter_cb()
m17_clear_trigger(M17_triggers.armory)
mission_waypoint_remove()
marker_add(M17_group.heli.heli, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
end
-- Clean up the Hijack Heli objective
function m17_hijack_heli_cleanup()
if group_is_loaded(M17_group.heli.name) then
marker_remove(M17_group.heli.heli, SYNC_ALL)
turn_vulnerable(M17_group.heli.heli)
end
on_vehicle_enter("", LOCAL_PLAYER)
if (M17_in_coop == true) then
on_vehicle_enter("", REMOTE_PLAYER)
end
m17_clean_up_notoriety_stuff_for_driving_to_armory()
end
-- *************************
-- Objective: Board Ship
-- *************************
-- Land on the carrier
function m17_board_ship()
-- Tell the player to board the ship
M17_has_reached_goal = false
objective_text(0, "M17_OBJ_BOARD_SHIP", "", "", SYNC_ALL, OI_ASSET_LOCATION)
trigger_enable(M17_triggers.carrier, true)
marker_add_trigger(M17_triggers.carrier, MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Enable the trigger that kicks off the "getting close" conversation.
trigger_enable(M17_triggers.convo_getting_close, true)
on_trigger("m17_trigger_reached", M17_triggers.convo_getting_close)
-- Load the compliment conversation
audio_conversation_wait_for_end(M17_conv.drive_2.handle)
M17_conv.drive_2.handle = INVALID_CONVERSATION_HANDLE
M17_conv.flying.handle = audio_conversation_load_direct(M17_conv.flying.name)
delay(6)
-- Tell the player he looks good
audio_conversation_play(M17_conv.flying.handle)
audio_conversation_wait_for_end(M17_conv.flying.handle)
M17_conv.flying.handle = INVALID_CONVERSATION_HANDLE
-- Load the handcuffs conversation
M17_conv.handcuffs.handle = audio_conversation_load(M17_conv.handcuffs.name)
delay(6)
-- Wait until the player reached the trigger to start the "getting close" conversation.
while not M17_has_reached_goal do
thread_yield()
end
M17_has_reached_goal = false
-- Set the trigger for landing on the carrier.
on_trigger("m17_trigger_reached", M17_triggers.carrier)
-- Tell the homies to put on handcuffs
audio_conversation_play(M17_conv.handcuffs.handle)
-- Wait until the player reached the carrier
while not M17_has_reached_goal do
thread_yield()
end
-- If the last conversation is not yet done, force-end it
audio_conversation_end(M17_conv.handcuffs.handle)
M17_conv.handcuffs.handle = INVALID_CONVERSATION_HANDLE
objective_text_clear(0)
-- Play the arrival cutscene
m17_board_ship_cutscene()
end
-- Play the boarding cutscene
function m17_board_ship_cutscene()
-- Make sure the screen is completly faded out
--fade_out(0.5)
--fade_out_block()
-- Play the Z-scene
--bink_play("17_Mid_Block_v01")
cutscene_play(M17_CUTSCENE_THERM_LANDING, nil, nil, false)
-- Clean up the objective
m17_board_ship_cleanup()
-- Swap in the interior and swap out the exterior.
city_zone_swap("ThermInt1", true)
city_zone_swap("thermext1", false)
city_zone_swap("therm2", false)
thread_yield()
-- Put the players in the correct location following the cutscene
teleport_coop(M17_checkpoint_meeting.player, M17_checkpoint_meeting.coop, true)
-- We need to hide the door to the R&D lab because it sticks through the wall when it's open...
mesh_mover_hide(M17_MEETING_DOOR_1)
mesh_mover_hide(M17_MEETING_DOOR_2)
-- Spawn Kia
group_create(M17_group.kia.name, true)
-- Spawn the scientists
-- group_create(M17_group.meeting.name, true)
-- Spawn guards to ambush the player later
group_create(M17_group.ambush.name, true)
-- Start fading in
fade_in(0.5)
fade_in_block()
end
-- Clean up the Board Ship objective
function m17_board_ship_cleanup()
-- Remove homies
if group_is_loaded(M17_group.homies.name) then
on_death("", M17_group.homies.pierce)
on_death("", M17_group.homies.viola)
on_dismiss("", M17_group.homies.pierce)
on_dismiss("", M17_group.homies.viola)
group_destroy(M17_group.homies.name)
end
-- Remove heli
if group_is_loaded(M17_group.heli.name) then
group_destroy(M17_group.heli.name)
end
end
-- *************************
-- Objective: Follow Kia
-- *************************
-- Follow Kia to the meeting
function m17_follow_kia()
while not character_is_ready(M17_group.kia.kia) do
thread_yield()
end
-- Stop spawning peds while inside the Thermopylae.
spawning_pedestrians(false)
-- Set the meeting room as the next goal
objective_text(1, "M17_OBJ_FOLLOW_KIA", "", "", SYNC_ALL, OI_ASSET_LOCATION)
marker_add(M17_group.kia.kia, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_ALL)
-- Display a "suspicion" bar
hud_bar_on(M17_BAR_INDEX, "annoyance", "", M17_MAX_KIA_DISTANCE - M17_MIN_KIA_DISTANCE, SYNC_ALL)
-- Start a thread to update the conversation
M17_threads.convo = thread_new("m17_follow_kia_conversation")
delay(2.0)
-- Start a thread to update the suspicion bar
M17_threads.follow = thread_new("m17_follow_kia_update")
-- Start up a thread to make STAG soldiers salute the player.
M17_threads.salute = thread_new("m17_salute_thread")
-- Open the door to the meeting room
--door_open(M17_doors.meeting, false, false)
-- Damaging Kia or killing a guard results in fail
on_damage("m17_fail_suspicion", M17_group.kia.kia)
for i, npc in pairs(M17_group.ambush.npcs) do
on_damage("m17_fail_suspicion", npc.name)
-- Also prevent them from entering combat. This prevents them
-- from hunkering down briefly after they salute. And really...
-- I don't think they'd attack Cyrus.
npc_combat_enable(npc.name, false)
end
-- Start prepping the Z-scene
zscene_prep(M17_ZSCENE_01)
-- Start Kia walking to the meeting
npc_combat_enable(M17_group.kia.kia, false)
delay(1)
M17_threads.kia_path = thread_new("m17_kia_path_thread")
-- Wait for the conversation to end, we won't force the player to wait
-- for Kia if they're a jerk and block her path or something.
threads_wait_for_completion(M17_threads.convo)
delay(20.0)
action_nodes_enable(false)
-- Unhide the door to the R&D lab. (Doing this in cleanup would rarely cause an assert in
-- co-op if we cancel the mission and the client doesn't get the packet before the door
-- streams out).
mesh_mover_show(M17_MEETING_DOOR_1)
mesh_mover_show(M17_MEETING_DOOR_2)
-- Clean up the objective
m17_follow_kia_cleanup()
end
-- Update the Follow Kia thread
function m17_follow_kia_update()
local furthest_dist = 0
while(true) do
-- Get the furthest player's distance from Kia
furthest_dist = get_dist(LOCAL_PLAYER, M17_group.kia.kia)
if (M17_in_coop == true) then
local p2_dist = get_dist(REMOTE_PLAYER, M17_group.kia.kia)
if (p2_dist > furthest_dist) then
furthest_dist = p2_dist
end
end
-- Update the suspicion bar based on distance
if (furthest_dist < M17_MIN_KIA_DISTANCE) then
-- They're close enough, so show a full bar
hud_bar_set_value(M17_BAR_INDEX, M17_MAX_KIA_DISTANCE - M17_MIN_KIA_DISTANCE)
else
hud_bar_set_value(M17_BAR_INDEX, M17_MAX_KIA_DISTANCE - furthest_dist)
end
-- Fail if the player strayed too far
if (furthest_dist > M17_MAX_KIA_DISTANCE) then
m17_fail_suspicion()
end
thread_yield()
end
end
-- Update the Kia 'lead-the-way' thread
function m17_lead_the_way_conversation()
-- Load the Kia conversation
M17_conv.lead_the_way.handle = audio_conversation_load(M17_conv.lead_the_way.name)
-- Now start the Kia conversation
audio_conversation_play(M17_conv.lead_the_way.handle)
audio_conversation_wait_for_end(M17_conv.lead_the_way.handle)
M17_conv.lead_the_way.handle = INVALID_CONVERSATION_HANDLE
end
-- Update the Kia conversation thread
function m17_follow_kia_conversation()
-- Load the Kia start convo
M17_conv.lead_the_way.handle = audio_conversation_load(M17_conv.lead_the_way.name)
-- Now start the Kia start convo
audio_conversation_play(M17_conv.lead_the_way.handle)
audio_conversation_wait_for_end(M17_conv.lead_the_way.handle)
M17_conv.lead_the_way.handle = INVALID_CONVERSATION_HANDLE
-- Load the Kia conversation
M17_conv.kia.handle = audio_conversation_load(M17_conv.kia.name)
-- Wait a bit after the following starts
delay(6)
-- Now start the Kia conversation
audio_conversation_play(M17_conv.kia.handle)
audio_conversation_wait_for_end(M17_conv.kia.handle)
M17_conv.kia.handle = INVALID_CONVERSATION_HANDLE
-- After a few seconds, Kia explains choices
M17_conv.reward.handle = audio_conversation_load(M17_conv.reward.name)
delay(4)
audio_conversation_play(M17_conv.reward.handle)
audio_conversation_wait_for_end(M17_conv.reward.handle)
M17_conv.reward.handle = INVALID_CONVERSATION_HANDLE
end
-- Clean up the Follow Kia objective
function m17_follow_kia_cleanup()
-- Stop the update thread
if (M17_threads.follow ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.follow)
M17_threads.follow = INVALID_THREAD_HANDLE
end
-- Stop the conversation thread
if (M17_threads.convo ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.convo)
M17_threads.convo = INVALID_THREAD_HANDLE
end
-- Stop the salute thread
if (M17_threads.salute ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.salute)
M17_threads.salute = INVALID_THREAD_HANDLE
end
-- Stop Kia's pathing thread
if (M17_threads.kia_path ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.kia_path)
M17_threads.kia_path = INVALID_THREAD_HANDLE
end
-- Clean up anything we set up for the saluting guys.
if group_is_loaded(M17_group.ambush.name) then
for i, npc in pairs(M17_group.ambush.npcs) do
npc.has_saluted = false
npc_combat_enable(npc.name, true)
ai_clear_scripted_action(npc.name)
end
end
-- Clear the suspicion bar
hud_bar_off(M17_BAR_INDEX)
-- Remove the objective markers
marker_remove(M17_group.kia.kia, SYNC_ALL)
objective_text_clear(1)
end
-- *************************
-- Objective: Meeting
-- *************************
-- Hold the meeting
function m17_meeting()
-- Put up the choice screen
hud_push_screen(M17_CHOICE_SCREEN, SYNC_ALL)
-- Wait until the choice is complete
local sel = -1
while (sel == -1) do
thread_yield()
sel = hud_get_proto_selection()
end
sel = sel + 1 -- Convert from 0-based to 1-based index
-- Exclude the reward not chosen
mission_set_excluded_reward(M17_rewards[sel])
-- Remove the screen for the client.
hud_pop_screen(M17_CHOICE_SCREEN, SYNC_REMOTE)
-- Start the meeting cutscene
m17_meeting_cutscene()
end
-- Play the meeting cutscene
function m17_meeting_cutscene()
-- Make sure the screen is completly faded out
--fade_out(0.5)
--fade_out_block()
-- Play the Z-scene
cutscene_play(M17_ZSCENE_01, nil, nil, false)
-- Equip a pistol, since the player has one equipped at the end of the cutscene.
m17_equip_pistol()
-- Put the players in the correct location following the cutscene
teleport_coop(M17_checkpoint_jailbreak.player, M17_checkpoint_jailbreak.coop, true)
-- Close the door to the meeting room
--door_close(M17_doors.meeting, false)
-- Clean up the objective
m17_meeting_cleanup()
-- Spawn the next objective before fading in
m17_free_friends_setup()
-- Start fading in
fade_in(0.5)
fade_in_block()
end
-- Clean up the meeting
function m17_meeting_cleanup()
-- Remove Kia
if group_is_loaded(M17_group.kia.name) then
on_damage("", M17_group.kia.kia)
group_destroy(M17_group.kia.name)
end
-- if group_is_loaded(M17_group.meeting.name) then
-- group_destroy(M17_group.meeting.name)
-- end
-- Remove the kill guard fail condition
for i, npc in pairs(M17_group.ambush.npcs) do
on_damage("", npc.name)
on_death("", npc.name)
end
end
-- *************************
-- Objective: Free Friends
-- *************************
-- Free the Saints from the brig
function m17_free_friends_setup()
-- Load Kia's persona, now that she's unloaded
M17_personas.kia.id = audio_persona_load_2d(M17_personas.kia.name)
-- Spawn the captive homies
group_create(M17_group.captive_homies.name, true)
on_death("m17_fail_pierce_died", M17_group.captive_homies.pierce)
on_death("m17_fail_shaundi_died", M17_group.captive_homies.shaundi)
on_death("m17_fail_viola_died", M17_group.captive_homies.viola)
-- Prevent your homies from saying anything (especially complimenting you)
-- before they are freed.
npc_suppress_persona(M17_group.captive_homies.pierce, true)
npc_suppress_persona(M17_group.captive_homies.shaundi, true)
npc_suppress_persona(M17_group.captive_homies.viola, true)
-- Ignore homies until they are freed
set_ignore_ai_flag(M17_group.captive_homies.pierce, true)
set_ignore_ai_flag(M17_group.captive_homies.shaundi, true)
set_ignore_ai_flag(M17_group.captive_homies.viola, true)
set_dont_attack_me_on_sight_flag(M17_group.captive_homies.pierce, true)
set_dont_attack_me_on_sight_flag(M17_group.captive_homies.shaundi, true)
set_dont_attack_me_on_sight_flag(M17_group.captive_homies.viola, true)
-- Spawn the tank bay as hidden, so they don't move around until the player reaches them
group_create_hidden(M17_group.tanks.name, true)
-- Prevent the tanks from going ambient. They get confused by the fact that they're in the middle of the bay.
for i, vehicle in pairs(M17_group.tanks.vehicles) do
vehicle_prevent_transition_to_ambient(vehicle, true)
end
-- Spawn the jailors
group_create_hidden(M17_group.jailors.name, false)
end
-- Free the Saints from the brig
function m17_free_friends()
-- Enable the spawn regions and spawn groups
--spawn_region_enable(M17_regions.start_stairs, true)
spawn_region_enable(M17_regions.start_hall, true)
continuous_spawn_start(M17_group.cs_1.name, 3, 10)
--continuous_spawn_start(M17_group.cs_2.name, 2, 10)
action_nodes_enable(false)
-- Set the brig security room as the objective
objective_text(0, "M17_OBJ_FIND_BRIG", "", "", SYNC_ALL, OI_ASSET_LOCATION)
-- Start a thread to update the PA announcements
M17_threads.pa = thread_new("m17_pa_kia")
-- Mark the hall door as an intermediate waypoint
marker_add(M17_nav_wp.tank_hall, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Wait until the player reaches the hall door
while not door_is_open(M17_doors.tank_hall) do
thread_yield()
end
marker_remove(M17_nav_wp.tank_hall, SYNC_ALL)
-- Release existing spawn groups as ambient
continuous_spawn_stop(M17_group.cs_1.name)
--continuous_spawn_stop(M17_group.cs_2.name)
-- Disable the entry spawn regions
--spawn_region_enable(M17_regions.start_stairs, false)
spawn_region_enable(M17_regions.start_hall, false)
--== WAYPOINT ==--
-- Mark the tank bay door as an intermediate waypoint
marker_add(M17_nav_wp.tank_entry, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Wait until the player reaches the tank bay
M17_has_reached_goal = false
trigger_enable(M17_triggers.enter_tank_bay, true)
on_trigger("m17_trigger_reached", M17_triggers.enter_tank_bay)
while M17_has_reached_goal == false do
thread_yield()
end
marker_remove(M17_nav_wp.tank_entry, SYNC_ALL)
--== WAYPOINT ==--
-- Done with the ambush
release_to_world(M17_group.ambush.name)
-- Show the tank bay enemies
group_show(M17_group.tanks.name)
-- Set the brig hallway as the next waypoint
marker_add(M17_nav_wp.brig_hall, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Enable the tank bay spawn regions
spawn_region_enable(M17_regions.tank_e, true)
spawn_region_enable(M17_regions.tank_w, true)
spawn_region_enable(M17_regions.tank_exit, true)
-- Enable the tank bay exit trigger
trigger_enable(M17_triggers.tank_exit, true)
on_trigger("m17_tank_exit_cb", M17_triggers.tank_exit)
-- Re-spawn continuous spawn groups further ahead
continuous_spawn_start(M17_group.cs_1.name, 3, 10)
continuous_spawn_start(M17_group.cs_2.name, 2, 10)
-- Wait a moment, then send the drivers to the tanks
delay(8)
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_PA_Enter_Tank_Bay")
vehicle_enter(M17_group.tanks.drivers[1], M17_group.tanks.vehicles[1], 0, false, false)
vehicle_enter(M17_group.tanks.drivers[2], M17_group.tanks.vehicles[2], 0, false, false)
-- vehicle_enter(M17_group.tanks.drivers[3], M17_group.tanks.vehicles[3], 0, false, false)
on_vehicle_destroyed("m17_antitank_spawn_cb", M17_group.tanks.vehicles[1])
on_vehicle_destroyed("m17_antitank_spawn_cb", M17_group.tanks.vehicles[2])
-- Wait until the player reaches the brig hallway
while not door_is_open(M17_doors.tank_exit) do
thread_yield()
end
marker_remove(M17_nav_wp.brig_hall, SYNC_ALL)
--== WAYPOINT ==--
-- Show the jailors
group_show(M17_group.jailors.name)
-- Set the brig as the next objective
objective_text_clear(0)
objective_text(0, "M17_OBJ_JAILBREAK", "", "", SYNC_ALL, OI_ASSET_USE)
marker_add_trigger(M17_triggers.brig, MINIMAP_ICON_USE, INGAME_EFFECT_CHECKPOINT, OI_ASSET_USE, OI_FLAGS_LOCATION, SYNC_ALL)
-- Stop continuous spawn while the player is in the brig
continuous_spawn_stop(M17_group.cs_1.name)
continuous_spawn_stop(M17_group.cs_2.name)
continuous_spawn_stop(M17_group.at_1.name)
continuous_spawn_stop(M17_group.at_2.name)
-- Disable the tank bay spawn regions
spawn_region_enable(M17_regions.tank_e, false)
spawn_region_enable(M17_regions.tank_w, false)
-- Wait until the player activates the brig doors
while (not door_is_open(M17_doors.brig_inner)) do
thread_yield()
end
marker_remove_trigger(M17_triggers.brig, SYNC_ALL)
-- Leave the effect there, since you can still use the trigger.
ingame_effect_add_trigger(M17_triggers.brig, INGAME_EFFECT_CHECKPOINT, SYNC_ALL)
--== WAYPOINT ==--
-- Disable the tank bay exit spawn region
spawn_region_enable(M17_regions.tank_exit, false)
-- Mark each homie so the player can find them
marker_add_trigger(M17_triggers.pierce, MINIMAP_ICON_USE, INGAME_EFFECT_LOCATION, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
trigger_enable(M17_triggers.pierce, true)
on_trigger("m17_pierce_freed", M17_triggers.pierce)
marker_add_trigger(M17_triggers.shaundi, MINIMAP_ICON_USE, INGAME_EFFECT_LOCATION, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
trigger_enable(M17_triggers.shaundi, true)
on_trigger("m17_shaundi_freed", M17_triggers.shaundi)
marker_add_trigger(M17_triggers.viola, MINIMAP_ICON_USE, INGAME_EFFECT_LOCATION, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
trigger_enable(M17_triggers.viola, true)
on_trigger("m17_viola_freed", M17_triggers.viola)
-- Wait until all homies are free
while M17_has_shaundi == false or M17_has_pierce == false or M17_has_viola == false do
thread_yield()
end
objective_text_clear(0)
-- Done with Kia
if (M17_threads.pa ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.pa)
M17_threads.pa = INVALID_THREAD_HANDLE
end
if M17_personas.kia.id ~= INVALID_PERSONA_HANDLE then
audio_persona_remove_2d(M17_personas.kia.id)
M17_personas.kia.id = INVALID_PERSONA_HANDLE
end
-- Release the tank bay and jailor guys, as we are now past that part
--release_to_world(M17_group.tanks.name) -- Don't release the tanks; they freak out after the mission is over
-- when they find themselves in the middle of the bay if they're not destroyed.
release_to_world(M17_group.jailors.name)
m17_free_friends_cleanup()
end
function m17_free_friends_cleanup()
on_vehicle_destroyed("", M17_group.tanks.vehicles[1])
on_vehicle_destroyed("", M17_group.tanks.vehicles[2])
end
-- Make PA announcements every so often
function m17_pa_kia()
audio_play_persona_line_2d(M17_personas.kia.id, "M17_Kia_PA_First_Announcement")
delay(8)
audio_play_persona_line(LOCAL_PLAYER, "M17_Fight_To_Brig")
delay(22)
while(true) do
audio_play_persona_line_2d(M17_personas.kia.id, "M17_PA_Attack_Player_Kia_01")
delay(30)
audio_play_persona_line_2d(M17_personas.kia.id, "M17_PA_Attack_Player_Kia_02")
delay(30)
audio_play_persona_line_2d(M17_personas.kia.id, "M17_PA_Attack_Player_Kia_03")
delay(30)
end
end
function m17_tank_exit_cb()
m17_clear_trigger(M17_triggers.tank_exit)
-- group_foreach_npc(M17_group.tanks.name, npc_leash_remove)
end
-- *************************
-- Objective: Destroy Reactor
-- *************************
-- Destroy the nuclear reactor
function m17_destroy_reactor()
-- Load the blow up boat conversation
M17_conv.reactor.handle = audio_conversation_load(M17_conv.reactor.name)
action_nodes_enable(false)
-- Spawn the brig response barricade and reactor personnel
group_create(M17_group.barricade.name, true)
group_create_hidden(M17_group.reactor_hall.name, false)
group_create_hidden(M17_group.reactor.name, false)
-- Enable the stairs spawn regions
--spawn_region_enable(M17_regions.brig_exit, true)
-- Re-enable continuous spawn groups
--continuous_spawn_start(M17_group.cs_1.name, 0, 10)
-- Tell the player to blow up the ship
audio_conversation_play(M17_conv.reactor.handle)
audio_conversation_wait_for_end(M17_conv.reactor.handle)
-- Set up the ambush
trigger_enable(M17_triggers.brig_esc, true)
on_trigger("m17_brig_esc_flash", M17_triggers.brig_esc)
-- Start a thread to update the PA announcements
M17_threads.pa = thread_new("m17_pa_cyrus")
-- Set the reactor room as the objective
objective_text(0, "M17_OBJ_FIND_REACTOR", "", "", SYNC_ALL, OI_ASSET_LOCATION)
-- Set up a gate as an intermediate waypoint
M17_has_reached_goal = false
trigger_enable(M17_triggers.brig_stairs, true)
marker_add_trigger(M17_triggers.brig_stairs, MINIMAP_ICON_LOCATION, "", OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
on_trigger("m17_trigger_reached", M17_triggers.brig_stairs)
-- Delay slightly and kick off the second stage of music.
delay(3.0)
m17_post_music_event(M17_music.music_b)
while not M17_has_reached_goal do
thread_yield()
end
-- Enable the lower spawn region
--spawn_region_enable(M17_regions.brig_exit, false)
--spawn_region_enable(M17_regions.reactor_hall, true)
-- Show the reactor hall NPCs
group_show(M17_group.reactor_hall.name)
--== WAYPOINT ==--
-- Set the reactor room as the next waypoint
marker_add(M17_nav_wp.reactor, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Wait until the player reaches the bottom of the stairs
M17_has_reached_goal = false
trigger_enable(M17_triggers.reactor_spawn, true)
on_trigger("m17_trigger_reached", M17_triggers.reactor_spawn)
while not M17_has_reached_goal do
thread_yield()
end
-- Release existing spawn groups as ambient
--continuous_spawn_stop(M17_group.cs_1.name)
-- Enable the spawn region further ahead
--spawn_region_enable(M17_regions.escape_hall, true)
-- Re-spawn continuous spawn groups further ahead
--continuous_spawn_start(M17_group.cs_1.name, 0, 10)
--continuous_spawn_start(M17_group.cs_2.name, 0, 10)
-- Script some guys to run out
for i, group in pairs(M17_group.reactor_hall.script[1]) do
ai_do_scripted_move(group.npc, group.nav, true, false)
end
-- Wait until the player reaches the mid-hallway
M17_has_reached_goal = false
trigger_enable(M17_triggers.reactor_hall, true)
on_trigger("m17_trigger_reached", M17_triggers.reactor_hall)
while not M17_has_reached_goal do
thread_yield()
end
-- Script some guys to run out
for i, group in pairs(M17_group.reactor_hall.script[2]) do
ai_do_scripted_move(group.npc, group.nav, true, false)
end
-- Show the reactor NPCs
group_show(M17_group.reactor.name)
-- Wait until the player reaches the reactor room
M17_has_reached_goal = false
trigger_enable(M17_triggers.enter_reactor, true)
on_trigger("m17_trigger_reached", M17_triggers.enter_reactor)
while M17_has_reached_goal == false do
thread_yield()
end
marker_remove(M17_nav_wp.reactor, SYNC_ALL)
--== WAYPOINT ==--
-- Load the blow up console conversation
M17_conv.consoles.handle = audio_conversation_load(M17_conv.consoles.name)
objective_text_clear(0)
-- Disable continuous spawn until the reactor is blown
--continuous_spawn_stop(M17_group.cs_1.name)
--continuous_spawn_stop(M17_group.cs_2.name)
--spawn_region_enable(M17_regions.reactor_hall, false)
--spawn_region_enable(M17_regions.escape_hall, false)
-- Set the reactor console as the goal
marker_add(M17_CONSOLE, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL)
objective_text(0, "M17_OBJ_DESTROY_REACTOR", "", "", SYNC_ALL, OI_ASSET_KILL)
-- Point out the consoles
audio_conversation_play(M17_conv.consoles.handle)
audio_conversation_wait_for_end(M17_conv.consoles.handle)
M17_conv.consoles.handle = INVALID_CONVERSATION_HANDLE
-- Wait until the player destroys the reactor console
while not mesh_mover_destroyed(M17_CONSOLE) do
thread_yield()
end
--[[
-- Release the NPCs we're done with
release_to_world(M17_group.barricade.name)
release_to_world(M17_group.reactor_hall.name)
--]]
-- Clean up the reactor objective
m17_reactor_cleanup()
-- Pause a moment for dramatic effect
delay(4)
-- Explode everything nearby
for i, effect_nav in pairs(M17_explosions.reactor) do
explosion_create(M17_explosions.effect[rand_int(1, 2)], effect_nav)
delay(0.1)
end
-- Explode all the guards in the area.
M17_threads.explode_guys = thread_new("m17_blow_up_dudes_thread")
end
-- Make PA announcements every so often
function m17_pa_cyrus()
audio_conversation_wait_for_end(M17_conv.reactor.handle)
M17_conv.reactor.handle = INVALID_CONVERSATION_HANDLE
delay(4)
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_PA_After_Prisoner_Release")
delay(30)
while(true) do
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_PA_Attack_Player_Cyrus_01")
delay(30)
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_PA_Attack_Player_Cyrus_02")
delay(30)
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_PA_Attack_Player_Cyrus_03")
delay(30)
end
end
-- Clean up the reactor objective
function m17_reactor_cleanup()
-- Remove the console markers
marker_remove(M17_CONSOLE, SYNC_ALL)
objective_text_clear(0)
-- Done with Cyrus
if (M17_threads.pa ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.pa)
M17_threads.pa = INVALID_THREAD_HANDLE
end
end
-- *************************
-- Objective: Escape
-- *************************
-- Escape the carrier
function m17_escape()
-- Load the countdown conversation
M17_conv.escape.handle = audio_conversation_load(M17_conv.escape.name)
-- Don't allow your followers to be abandoned when you're trying to escape.
follower_set_can_abandon(M17_group.captive_homies.pierce, false)
follower_set_can_abandon(M17_group.captive_homies.viola, false)
follower_set_can_abandon(M17_group.captive_homies.shaundi, false)
on_dismiss("", M17_group.captive_homies.pierce)
on_dismiss("", M17_group.captive_homies.shaundi)
on_dismiss("", M17_group.captive_homies.viola)
action_nodes_enable(false)
--[[
-- Enable the reactor and escape path spawn regions
spawn_region_enable(M17_regions.reactor_1, true)
spawn_region_enable(M17_regions.reactor_2, true)
spawn_region_enable(M17_regions.escape_hall, true)
--spawn_region_enable(M17_regions.escape_stairs, true)
-- Restart continuous spawn in the reactor
continuous_spawn_start(M17_group.cs_1.name, 0, 10)
continuous_spawn_start(M17_group.cs_2.name, 0, 10)
--continuous_spawn_start(M17_group.cs_3.name, 0, 10)
--]]
-- Prepare scripted events on the way out
group_create(M17_group.ehall.name, true)
trigger_enable(M17_triggers.ehall_1, true)
on_trigger("m17_escape_event_1", M17_triggers.ehall_1)
trigger_enable(M17_triggers.ehall_2, true)
on_trigger("m17_escape_event_2", M17_triggers.ehall_2)
-- Set the VTOL as the next objective
objective_text(1, "M17_OBJ_ESCAPE_SHIP", "", "", SYNC_ALL, OI_ASSET_LOCATION)
-- Set the reactor room as the next waypoint
marker_add(M17_nav_wp.reactor, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Start the countdown
hud_critical_timer_set(M17_ESCAPE_TIME, M17_ESCAPE_TIMER_TAG, "m17_fail_timer_expired", SYNC_ALL)
-- Start a thread to create random explosions
M17_threads.explosions = thread_new("m17_escape_explosions")
-- Start a thread to tell the player to escape
M17_threads.escape_talk = thread_new("m17_escape_talk")
-- Wait until the player reaches the reactor room
M17_has_reached_goal = false
trigger_enable(M17_triggers.enter_reactor, true)
on_trigger("m17_trigger_reached", M17_triggers.enter_reactor)
while M17_has_reached_goal == false do
thread_yield()
end
marker_remove(M17_nav_wp.reactor, SYNC_ALL)
--== WAYPOINT ==--
-- Set the escape hallway as the next waypoint
M17_has_reached_goal = false
trigger_enable(M17_triggers.escape_hall, true)
marker_add_trigger(M17_triggers.escape_hall, MINIMAP_ICON_LOCATION, "", OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
on_trigger("m17_trigger_reached", M17_triggers.escape_hall)
-- Wait until the player reaches the hallway
while not M17_has_reached_goal do
thread_yield()
end
--== WAYPOINT ==--
-- Done with the reactor
release_to_world(M17_group.reactor.name)
-- Open the way forward
door_lock(M17_doors.escape_stairs, false)
-- Set the stairs to the flight deck as the next waypoint
marker_add(M17_nav_wp.escape_stairs, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Release existing spawn groups as ambient
continuous_spawn_stop(M17_group.cs_1.name)
continuous_spawn_stop(M17_group.cs_2.name)
--continuous_spawn_stop(M17_group.cs_3.name)
-- Disable the spawn regions which are now behind the player
spawn_region_enable(M17_regions.reactor_1, false)
spawn_region_enable(M17_regions.reactor_2, false)
spawn_region_enable(M17_regions.escape_hall, false)
-- Re-spawn continuous spawn groups further ahead
continuous_spawn_start(M17_group.cs_1.name, 0, 10)
continuous_spawn_start(M17_group.cs_2.name, 0, 10)
-- Script some guys to walk toward the exit, firing
for i, group in pairs(M17_group.ehall.script[3]) do
if not character_is_dead(group.npc) then
ai_add_enemy_target(group.npc, CLOSEST_PLAYER, ATTACK_NOW)
ai_do_scripted_move(group.npc, group.nav, true, true)
end
end
-- Wait until the player reaches the stairs
while not door_is_open(M17_doors.escape_stairs) do
thread_yield()
end
marker_remove(M17_nav_wp.escape_stairs, SYNC_ALL)
--== WAYPOINT ==--
-- Spawn the escaping scientists
-- group_create(M17_group.fire.name, true)
-- Watch for the player to reach the top of the stairs
-- trigger_enable(M17_triggers.fire, true)
-- on_trigger("m17_escape_event_3", M17_triggers.fire)
-- Open the final door
trigger_enable(M17_automatic_doors.hanger_n.trigger, true)
on_trigger("m17_door_enter", M17_automatic_doors.hanger_n.trigger)
on_trigger_exit("m17_door_exit", M17_automatic_doors.hanger_n.trigger)
-- Set the flight deck as the next waypoint
marker_add(M17_nav_wp.hanger_n, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Disable the spawn regions which are now behind the player
spawn_region_enable(M17_regions.escape_stairs, false)
-- Re-enable the entry spawn regions
spawn_region_enable(M17_regions.start_stairs, true)
spawn_region_enable(M17_regions.start_hall, true)
-- Spawn the hanger
release_to_world(M17_group.ehall.name)
group_create(M17_group.hanger.name, true)
group_create(M17_group.vtol.name, true)
-- Wait until the player reaches the flight deck
M17_has_reached_goal = false
trigger_enable(M17_triggers.enter_hangar, true)
on_trigger("m17_trigger_reached", M17_triggers.enter_hangar)
while M17_has_reached_goal == false do
thread_yield()
end
marker_remove(M17_nav_wp.hanger_n, SYNC_ALL)
--== WAYPOINT ==--
-- Set the VTOL as the next waypoint
objective_text_clear(1)
objective_text(1, "M17_OBJ_HIJACK_VTOL", "", "", SYNC_ALL, OI_ASSET_USE)
marker_add(M17_group.vtol.vtol, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
vehicle_set_invulnerable(M17_group.vtol.vtol)
marker_add(M17_group.hanger.vtols[1], MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
marker_add(M17_group.hanger.vtols[2], MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
marker_add(M17_group.hanger.vtols[3], MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
for i, trigger in pairs(M17_group.hanger.triggers) do
trigger_enable(trigger, true)
end
on_trigger("m17_fake_vtol_01_cb", M17_group.hanger.triggers[1])
on_trigger("m17_fake_vtol_02_cb", M17_group.hanger.triggers[2])
on_trigger("m17_fake_vtol_03_cb", M17_group.hanger.triggers[3])
-- Set people on fire
explosion_create("Molotov Explosion", M17_group.hanger.npcs[2])
explosion_create("Molotov Explosion", M17_group.hanger.npcs[3])
-- Fire up a thread to automatically detonate the VTOLs if a player gets close enough.
M17_threads.auto_explode_vtols = thread_new("m17_blow_up_vtols_on_proximity")
-- Wait until the player enters the VTOL
while (get_dist_closest_player_to_object(M17_group.vtol.vtol) > 20) do
thread_yield()
end
audio_play_persona_line(LOCAL_PLAYER, "M17_Entering_Escape_VTOL")
continuous_spawn_stop(M17_group.cs_1.name)
continuous_spawn_stop(M17_group.cs_2.name)
-- Clean up the escape objective
m17_escape_cleanup()
end
function m17_fake_vtol_01_cb()
-- Script a pilot to run toward a VTOL, then BOOM!
vehicle_enter(M17_group.hanger.npcs[1], M17_group.hanger.vtols[1])
delay(2.5)
audio_play_persona_line(LOCAL_PLAYER, "M17_Wrong_Vtol_Explosion_01")
marker_remove(M17_group.hanger.vtols[1], SYNC_ALL)
vehicle_detonate(M17_group.hanger.vtols[1])
end
function m17_fake_vtol_02_cb()
marker_remove(M17_group.hanger.vtols[2], SYNC_ALL)
vehicle_detonate(M17_group.hanger.vtols[2])
end
function m17_fake_vtol_03_cb()
audio_play_persona_line(LOCAL_PLAYER, "M17_Wrong_Vtol_Explosion_02")
marker_remove(M17_group.hanger.vtols[3], SYNC_ALL)
vehicle_detonate(M17_group.hanger.vtols[3])
end
-- Genarate random explosions
function m17_escape_explosions()
while(true) do
-- Delay a random time and explode a random navpoint
delay(0.1 * rand_int(1, 10))
explosion_create(M17_explosions.effect[rand_int(1, 2)], get_random_table_entry(M17_explosions.reactor))
delay(0.1 * rand_int(1, 10))
explosion_create(M17_explosions.effect[rand_int(1, 2)], get_random_table_entry(M17_explosions.hall))
delay(0.1 * rand_int(1, 10))
explosion_create(M17_explosions.effect[rand_int(1, 2)], get_random_table_entry(M17_explosions.deck))
end
end
-- Play the escape conversation and warn when low on time
function m17_escape_talk()
-- Announce the destruction of the ship
--audio_play_persona_line_2d(M17_personas.computer.id, "M17_Computer_Countdown_01")
--delay(3)
-- Tell the player to escape
audio_conversation_play(M17_conv.escape.handle)
audio_conversation_wait_for_end(M17_conv.escape.handle)
M17_conv.escape.handle = INVALID_CONVERSATION_HANDLE
-- Cyrus announcement
delay(4)
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_Cyrus_Abandon_Ship_01")
-- Warn the player when low on time
local warning_played = 1
while (warning_played < 6) do
if (warning_played == 1) and (hud_critical_timer_get_remainder() < 120000) then
warning_played = 2
-- audio_play_persona_line_2d(M17_personas.computer.id, "M17_Computer_Countdown_02")
elseif (warning_played == 2) and (hud_critical_timer_get_remainder() < 90000) then
warning_played = 3
audio_play_persona_line(M17_group.captive_homies.pierce, "M17_Meltdown_Timer")
elseif (warning_played == 3) and (hud_critical_timer_get_remainder() < 60000) then
warning_played = 4
-- audio_play_persona_line_2d(M17_personas.computer.id, "M17_Computer_Countdown_03")
delay(5)
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_Cyrus_Abandon_Ship_02")
elseif (warning_played == 4) and (hud_critical_timer_get_remainder() < 30000) then
warning_played = 5
-- audio_play_persona_line_2d(M17_personas.computer.id, "M17_Computer_Countdown_04")
end
thread_yield()
end
end
-- Clean up the escape objective
function m17_escape_cleanup()
-- Stop the explosions thread
if (M17_threads.explosions ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.explosions)
M17_threads.explosions = INVALID_THREAD_HANDLE
end
-- Stop the talk thread
if (M17_threads.escape_talk ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.escape_talk)
M17_threads.escape_talk = INVALID_THREAD_HANDLE
end
-- Stop the VTOL auto detonate thread
if (M17_threads.auto_explode_vtols ~= INVALID_THREAD_HANDLE) then
thread_kill(M17_threads.auto_explode_vtols)
M17_threads.auto_explode_vtols = INVALID_THREAD_HANDLE
end
-- Clean up VTOLs
if group_is_loaded(M17_group.hanger.name) then
for i, vtol in pairs(M17_group.hanger.vtols) do
marker_remove(vtol, SYNC_ALL)
end
group_destroy(M17_group.hanger.name)
end
for i, trigger in pairs(M17_group.hanger.triggers) do
trigger_enable(trigger, false)
on_trigger("", trigger)
end
hud_critical_timer_stop()
objective_text_clear(1)
end
-- *************************
--
-- Callback functions
--
-- *************************
function m17_heli_entered()
-- Check if either player is in an aircraft
local v_type_p = get_char_vehicle_type(LOCAL_PLAYER)
local v_type_c = VT_NONE
if (M17_in_coop == true) then
v_type_c = get_char_vehicle_type(REMOTE_PLAYER)
end
if ((v_type_p == VT_HELICOPTER) or (v_type_c == VT_HELICOPTER)) or ((v_type_p == VT_AIRPLANE) or (v_type_c == VT_AIRPLANE)) or ((v_type_p == VT_VTOL) or (v_type_c == VT_VTOL)) then
-- Mark the next goal as reached
m17_clear_trigger(M17_triggers.armory)
mission_waypoint_remove()
M17_has_reached_goal = true
end
end
-- Reached the next trigger
function m17_trigger_reached(char, trig)
m17_clear_trigger(trig)
-- Mark the next goal as reached
M17_has_reached_goal = true
end
-- Open a door automatically when someone nears it
function m17_door_enter(char, trig)
for i, auto in pairs(M17_automatic_doors) do
if (trig == auto.trigger) then
door_open(auto.door)
end
end
end
-- Close a door automatically when noone is near it
function m17_door_exit(char, trig)
-- If someone else is still in the region, leave it open
if (get_num_humans_in_trigger(trig) > 0) then
return
end
-- Close the door
for i, auto in pairs(M17_automatic_doors) do
if (trig == auto.trigger) then
door_close(auto.door)
end
end
end
-- Activate anti-tank spawns once two of the tanks in the tank bay have been destroyed.
function m17_antitank_spawn_cb()
if (character_is_in_vehicle(LOCAL_PLAYER) or character_is_in_vehicle(REMOTE_PLAYER)) then
if (vehicle_is_destroyed(M17_group.tanks.vehicles[1]) and vehicle_is_destroyed(M17_group.tanks.vehicles[2])) then
audio_play_persona_line_2d(M17_personas.cyrus.id, "M17_PA_Anti_Armor_On_Tanks")
-- Stop regular continuous spawns
continuous_spawn_stop(M17_group.cs_1.name)
continuous_spawn_stop(M17_group.cs_2.name)
-- Start anti-tank continuous spawns
continuous_spawn_start(M17_group.at_1.name, 2, 10)
continuous_spawn_start(M17_group.at_2.name, 2, 10)
end
end
end
-- Toggle the open brig doors when activated
function m17_brig_activated(char, trigger)
-- Play the door open anim on the player.
action_play(char, M17_KEYPAD_ANIM, M17_KEYPAD_ANIM, false, 0.8, false, true, M17_nav_anim.brig)
delay(M17_KEYPAD_DELAY)
-- Make some audio magic.
audio_object_post_event("m17_cell_door_terminal_activate")
if door_is_open(M17_doors.brig_inner) then
door_close(M17_doors.brig_inner)
delay(1)
-- door_open(M17_doors.brig_outer)
-- delay(1)
else
-- door_close(M17_doors.brig_outer)
-- delay(1)
door_open(M17_doors.brig_inner)
delay(1)
end
-- Enable the trigger to get back in if someone is stuck outside (co-op)
trigger_enable(M17_triggers.brig_entry)
on_trigger("m17_brig_entry_activated", M17_triggers.brig_entry)
ingame_effect_add_trigger(M17_triggers.brig_entry, INGAME_EFFECT_CHECKPOINT, SYNC_ALL)
end
-- Opens the door into the brig control room for 5 seconds.
function m17_brig_entry_activated(char, trigger)
-- Play the door open anim on the player.
action_play(char, M17_KEYPAD_ANIM, M17_KEYPAD_ANIM, false, 0.8, false, true, M17_nav_anim.brig_entry)
delay(M17_KEYPAD_DELAY)
door_open(M17_doors.brig_outer)
delay(5.0)
door_close(M17_doors.brig_outer)
end
function m17_pierce_freed(char, trig)
-- First thing, disable the trigger.
m17_clear_trigger(trig)
-- There's a slim chance the players could manage to double up the trigger, so prevent that.
if M17_began_freeing_pierce then
return
end
M17_began_freeing_pierce = true
-- Let your homie talk again.
npc_suppress_persona(M17_group.captive_homies.pierce, false)
-- Play the door open anim on the player.
action_play(char, M17_KEYPAD_ANIM, M17_KEYPAD_ANIM, false, 0.8, false, true, M17_nav_anim.pierce_cell)
delay(M17_KEYPAD_DELAY)
-- Open the door
door_open(M17_doors.pierce)
-- Wait to make sure we don't stomp on one of the other prisoner freed conversations.
M17_threads.convo_failsafe = thread_new("delay", 5.0)
while audio_persona_line_playing(M17_group.captive_homies.viola) and not thread_check_done(M17_threads.convo_failsafe) do
thread_yield()
end
M17_threads.convo_failsafe = INVALID_THREAD_HANDLE
audio_conversation_wait_for_end(M17_conv.shaundi_thanks.handle)
-- Add as a homie
party_add_ignore_limits(M17_group.captive_homies.pierce, char)
set_ignore_ai_flag(M17_group.captive_homies.pierce, false)
set_dont_attack_me_on_sight_flag(M17_group.captive_homies.pierce, false)
follower_set_can_abandon(M17_group.captive_homies.pierce, true)
on_dismiss("m17_fail_dismissed_cb", M17_group.captive_homies.pierce)
audio_conversation_wait_for_end(M17_conv.shaundi_thanks.handle)
audio_play_persona_line(M17_group.captive_homies.pierce, "M17_Pierce_Thanks")
M17_has_pierce = true
end
function m17_shaundi_freed(char, trig)
-- First thing, disable the trigger.
m17_clear_trigger(trig)
-- There's a slim chance the players could manage to double up the trigger, so prevent that.
if M17_began_freeing_shaundi then
return
end
M17_began_freeing_shaundi = true
-- Let your homie talk again.
npc_suppress_persona(M17_group.captive_homies.shaundi, false)
-- Play the door open anim on the player.
action_play(char, M17_KEYPAD_ANIM, M17_KEYPAD_ANIM, false, 0.8, false, true, M17_nav_anim.shaundi_cell)
delay(M17_KEYPAD_DELAY)
-- Load the Shaundi thanks conversation
M17_conv.shaundi_thanks.handle = audio_conversation_load(M17_conv.shaundi_thanks.name)
-- Open the door
door_open(M17_doors.shaundi)
-- Wait to make sure we don't stomp on one of the other prisoner freed conversations.
M17_threads.convo_failsafe = thread_new("delay", 5.0)
while audio_persona_line_playing(M17_group.captive_homies.viola) and not thread_check_done(M17_threads.convo_failsafe) do
thread_yield()
end
M17_threads.convo_failsafe = thread_new("delay", 5.0)
while audio_persona_line_playing(M17_group.captive_homies.pierce) and not thread_check_done(M17_threads.convo_failsafe) do
thread_yield()
end
M17_threads.convo_failsafe = INVALID_THREAD_HANDLE
-- Add as a homie
party_add_ignore_limits(M17_group.captive_homies.shaundi, char)
set_ignore_ai_flag(M17_group.captive_homies.shaundi, false)
set_dont_attack_me_on_sight_flag(M17_group.captive_homies.shaundi, false)
follower_set_can_abandon(M17_group.captive_homies.shaundi, true)
on_dismiss("m17_fail_dismissed_cb", M17_group.captive_homies.shaundi)
-- Talk to Shaundi
audio_conversation_play(M17_conv.shaundi_thanks.handle)
audio_conversation_wait_for_end(M17_conv.shaundi_thanks.handle)
M17_conv.shaundi_thanks.handle = INVALID_CONVERSATION_HANDLE
M17_has_shaundi = true
end
function m17_viola_freed(char, trig)
-- First thing, disable the trigger.
m17_clear_trigger(trig)
-- There's a slim chance the players could manage to double up the trigger, so prevent that.
if M17_began_freeing_viola then
return
end
M17_began_freeing_viola = true
-- Let your homie talk again.
npc_suppress_persona(M17_group.captive_homies.viola, false)
-- Play the door open anim on the player.
action_play(char, M17_KEYPAD_ANIM, M17_KEYPAD_ANIM, false, 0.8, false, true, M17_nav_anim.viola_cell)
delay(M17_KEYPAD_DELAY)
-- Open the door
door_open(M17_doors.viola)
-- Wait to make sure we don't stomp on one of the other prisoner freed conversations.
M17_threads.convo_failsafe = thread_new("delay", 5.0)
while audio_persona_line_playing(M17_group.captive_homies.pierce) and not thread_check_done(M17_threads.convo_failsafe) do
thread_yield()
end
M17_threads.convo_failsafe = INVALID_THREAD_HANDLE
audio_conversation_wait_for_end(M17_conv.shaundi_thanks.handle)
-- Add as a homie
party_add_ignore_limits(M17_group.captive_homies.viola, char)
set_ignore_ai_flag(M17_group.captive_homies.viola, false)
set_dont_attack_me_on_sight_flag(M17_group.captive_homies.viola, false)
follower_set_can_abandon(M17_group.captive_homies.viola, true)
on_dismiss("m17_fail_dismissed_cb", M17_group.captive_homies.viola)
audio_conversation_wait_for_end(M17_conv.shaundi_thanks.handle)
audio_play_persona_line(M17_group.captive_homies.viola, "M17_Viola_Thanks")
M17_has_viola = true
end
function m17_brig_esc_flash()
-- Clear the trigger
trigger_enable(M17_triggers.brig_esc, false)
on_trigger("", M17_triggers.brig_esc)
-- Open the way forward
door_open(M17_doors.brig_big)
door_open(M17_doors.brig_ambush)
delay(1.0)
-- Throw the flashbangs
for i, char in pairs(M17_group.barricade.npcs) do
explosion_create("Flashbang", M17_nav_barricade[i], char, false)
delay(0.1)
end
-- Send the barricaders into the room
for i,npc in pairs(M17_group.barricade.npcs) do
ai_do_scripted_move(npc, M17_nav_barricade[i], true, false)
end
-- Play a response
M17_conv.flash_bang.handle = audio_conversation_load(M17_conv.flash_bang.name)
audio_conversation_end(M17_conv.reactor.handle)
M17_conv.reactor.handle = INVALID_CONVERSATION_HANDLE
audio_conversation_play(M17_conv.flash_bang.handle)
audio_conversation_wait_for_end(M17_conv.flash_bang.handle)
M17_conv.flash_bang.handle = INVALID_CONVERSATION_HANDLE
end
function m17_escape_event_1(char, trig)
-- Clear the trigger
trigger_enable(trig, false)
on_trigger("", trig)
-- BOOM! Knock the guy across the intersection
explosion_create(M17_explosions.effect[1], M17_group.ehall.explosion[1], nil, false)
if not character_is_dead(M17_group.ehall.script[1]) then
character_kill(M17_group.ehall.script[1])
end
end
function m17_escape_event_2(char, trig)
-- Clear the trigger
trigger_enable(trig, false)
on_trigger("", trig)
-- Script some guys to run out
for i, group in pairs(M17_group.ehall.script[2]) do
if not character_is_dead(group.npc) then
ai_do_scripted_move(group.npc, group.nav, true, false)
end
end
-- Wait for it...
delay(3)
-- BOOM!
explosion_create(M17_explosions.effect[1], M17_group.ehall.explosion[2], nil, false)
for i, group in pairs(M17_group.ehall.script[2]) do
if not character_is_dead(group.npc) then
character_kill(group.npc)
end
end
-- Stumble the players (can't call non-blocking because it will never give control back to the player)
thread_new("m17_stumble", LOCAL_PLAYER, M17_group.ehall.explosion[2])
if (coop_is_active() == true) then
thread_new("m17_stumble", REMOTE_PLAYER, M17_group.ehall.explosion[2])
end
-- Stumble the homies
--if (character_is_ready(M17_group.captive_homies.pierce) and (not character_playing_combat_move(M17_group.captive_homies.pierce)) and (not character_is_jumping(M17_group.captive_homies.pierce))) then
-- character_release_human_shield(M17_group.captive_homies.pierce, true)
-- action_play_non_blocking(M17_group.captive_homies.pierce, "Plane Cabin Stumble")
--end
--if (character_is_ready(M17_group.captive_homies.shaundi) and (not character_playing_combat_move(M17_group.captive_homies.shaundi)) and (not character_is_jumping(M17_group.captive_homies.shaundi))) then
-- character_release_human_shield(M17_group.captive_homies.shaundi, true)
-- action_play_non_blocking(M17_group.captive_homies.shaundi, "Plane Cabin Stumble")
--end
--if (character_is_ready(M17_group.captive_homies.viola) and (not character_playing_combat_move(M17_group.captive_homies.viola)) and (not character_is_jumping(M17_group.captive_homies.viola))) then
-- character_release_human_shield(M17_group.captive_homies.viola, true)
-- action_play_non_blocking(M17_group.captive_homies.viola, "Plane Cabin Stumble")
--end
end
function m17_escape_event_3(char, trig)
-- Clear the trigger
trigger_enable(trig, false)
on_trigger("", trig)
-- Set some scientists on fire
for i, npc in pairs(M17_group.fire.script[2]) do
explosion_create("Molotov Explosion", npc)
end
-- Send the rest running for the exit
for i, npc in pairs(M17_group.fire.script[1]) do
set_always_cower_flag(npc, true)
ai_do_scripted_move(npc, M17_group.fire.nav[1], true, false)
end
-- Set another on fire after a bit
delay(4)
explosion_create("Molotov Explosion", M17_group.fire.script[1][4])
delay(2)
explosion_create("Molotov Explosion", M17_group.fire.script[1][2])
end
function m17_fail_suspicion()
-- End the mission, the carrier blew up
mission_end_failure("m17", "m17_failure_follow")
end
function m17_fail_timer_expired()
-- End the mission, the carrier blew up
mission_end_failure("m17", "m17_failure_escape")
end
function m17_fail_pierce_died()
-- End the mission, Pierce died
mission_end_failure("m17", "m17_failure_pierce_died")
end
function m17_fail_shaundi_died()
-- End the mission, Shaundi died
mission_end_failure("m17", "m17_failure_shaundi_died")
end
function m17_fail_viola_died()
-- End the mission, Viola died
mission_end_failure("m17", "m17_failure_viola_died")
end
function m17_fail_dismissed_cb()
mission_end_failure("m17", "m17_failure_homie_abandoned")
end
-- *************************
--
-- Thread functions
--
-- *************************
-- Fails the mission if the player reaches level 1 police notoriety.
--
function m17_monitor_police_notoriety_thread()
-- Loop until killed.
while true do
if M17_stealh_section == false then
return
end
if notoriety_get("police") > 0 then
m17_fail_suspicion()
return
end
thread_yield()
end
end
-- Immediately destroys any of the VTOLs that are scripted to explode in the
-- hangar if a player gets too close to them.
--
function m17_blow_up_vtols_on_proximity()
-- Just loop until the thread is killed.
while true do
for i, vtol in pairs(M17_group.hanger.vtols) do
if vehicle_exists(vtol) then
if vehicle_is_destroyed(vtol) == false then
if get_dist(vtol, LOCAL_PLAYER) < M17_ESCAPE_VTOL_AUTO_SPLODE_DIST then
vehicle_detonate(vtol)
elseif coop_is_active() and get_dist(vtol, REMOTE_PLAYER) < M17_ESCAPE_VTOL_AUTO_SPLODE_DIST then
vehicle_detonate(vtol)
end
end
end
end
thread_yield()
end
end
-- For every guy in the provided table, this function creates an explosion
-- at their position and kills them, with a slight delay between booms.
--
function m17_blow_up_dudes_thread()
local dist_okay = true
for i, group in pairs(M17_self_exploding_guys) do
for i, dude in pairs(group.npcs) do
-- Make sure this guy isn't too close to a player.
dist_okay = (get_dist(dude, LOCAL_PLAYER) > 3.0)
if dist_okay == true and coop_is_active() then
dist_okay = (get_dist(dude, REMOTE_PLAYER) > 3.0)
end
if dist_okay == true then
-- This guy's far enough from a player. Blow him up!
delay(rand_float(0.25, 0.75))
explosion_create(M17_explosions.effect[2], dude, nil, nil, nil, 1.0)
character_kill(dude)
end
end
end
end
-- Thread used to disable notoriety stuff at the beginning of the mission.
--
function m17_disable_notoriety_for_drive_to_armory_thread()
m17_disable_notoriety_stuff_for_drive_to_armory()
-- Set up the NG armory island trigger which will also re-enable notoriety.
trigger_enable(M17_triggers.armory_island, true)
on_trigger("m17_enter_armory_island_cb", M17_triggers.armory_island)
-- Wait until our time limit on disabled notoriety elapses.
delay(M17_NO_NOTORIETY_TIME)
m17_enable_notoriety_stuff_after_drive_to_armory()
end
-- Thread to make Kia follow her path.
--
function m17_kia_path_thread()
for i, nav_name in pairs(M17_path_kia) do
-- Walk to the nav, retry if we fail. The thread will be killed
-- even if we get stuck somehow.
local path_index = move_to_do(M17_group.kia.kia, nav_name, 1, true, false, false, 0)
while get_dist(M17_group.kia.kia, nav_name) > 0.5 do
if move_to_check_done(path_index, M17_group.kia.kia, nav_name, 1, true, false, false, 0) then
-- Looks like we failed somehow, try again.
path_index = move_to_do(M17_group.kia.kia, nav_name, 1, true, false, false, 0)
end
thread_yield()
end
end
ai_clear_scripted_action(M17_group.kia.kia)
end
-- Thread to make STAG dudes salute the player as they walk by while following Kia.
--
function m17_salute_thread()
-- Loop until the thread is killed.
while true do
-- We can't script dudes on action nodes, so just settle for the guys we spawn from scripting.
for i, npc in pairs(M17_group.ambush.npcs) do
if npc.has_saluted == false and get_dist(npc.name, LOCAL_PLAYER) < M17_SALUTE_DIST then
npc.has_saluted = true
-- Turn to face the player.
turn_to(npc.name, LOCAL_PLAYER)
-- Play the salute action, don't block for it to finish.
action_play_non_blocking(npc.name, "stag stand salute")
-- Go back into idle, otherwise they tend to start wandering around all hunched over and comat ready.
ai_suggest_action(npc.name, "idle")
character_set_combat_ready(npc.name, false)
end
end
-- Only check every so often.
delay(0.5)
end
end
-- Thread to process player stumble animations (can't call non-blocking because it will never give control back to the player)
--
-- player: Player to play the stumble animation for
-- nav: The nav to stumble away from.
--
function m17_stumble(player, nav)
player_release_human_shield(player, true)
character_clear_combat_move(player)
if (character_is_ready(player) and (not character_is_jumping(player))) then
action_play_directional_stumble(player, nav)
end
end
-- *************************
--
-- Helper functions
--
-- *************************
-- Posts a music event.
--
-- event_name: Name of the event to post.
--
function m17_post_music_event(event_name)
audio_object_post_event(event_name, nil, nil, LOCAL_PLAYER)
end
-- Sets up the mission to fail if a player breaks their cover.
--
function m17_begin_stealth_section()
-- Register a callback to check to for anything that would blow the players cover
M17_stealh_section = true
M17_threads.police_notoriety_monitor = thread_new("m17_monitor_police_notoriety_thread")
end
-- Cleans up a stealth section for this mission.
--
function m17_cleanup_stealth_section()
M17_stealh_section = false
thread_kill(M17_threads.police_notoriety_monitor)
M17_threads.police_notoriety_monitor = INVALID_THREAD_HANDLE
end
-- Re-enables notoriety and cleans up the trigger and the notoriety thread if it's running.
--
function m17_clean_up_notoriety_stuff_for_driving_to_armory()
if M17_threads.no_notoriety ~= INVALID_THREAD_HANDLE then
thread_kill(M17_threads.no_notoriety)
end
M17_threads.no_notoriety = INVALID_THREAD_HANDLE
m17_clear_trigger(M17_triggers.armory_island)
m17_enable_notoriety_stuff_after_drive_to_armory()
end
-- Prevent the player from getting any notoriety while driving to the NG island and disable ambient cop spawns.
--
function m17_disable_notoriety_stuff_for_drive_to_armory()
spawning_allow_cop_ambient_spawns(false)
notoriety_set_max("police", 0)
end
-- Undo anything we do in m17_disable_notoriety_stuff_for_drive_to_armory.
--
function m17_enable_notoriety_stuff_after_drive_to_armory()
spawning_allow_cop_ambient_spawns(true)
notoriety_reset("police")
end
-- Equips the player's pistol or gives them a temporary pistol to match the
-- fact that the player had their pistol equipped at the end of the meeting
-- cutscene.
--
function m17_equip_pistol()
local pistol_name = inv_item_in_slot(LOCAL_PLAYER, "pistol")
if pistol_name ~= "none" then
inv_item_equip(pistol_name, LOCAL_PLAYER)
else
-- The player has no pistol, give them a crappy temporary pistol.
inv_weapon_add_temporary(LOCAL_PLAYER, M17_TEMP_PISTOL_NAME, 1, false, true)
end
end