--[[
dlc2_m01.lua
SR3 Dlc2 Mission Script (GiS)
DATE: 09/22/11
AUTHOR: Matt.Gawalek
]]--
-- Checkpoints --
Dlc2_m01_checkpoints = {
start = {
name = MISSION_START_CHECKPOINT,
player_navs = { "nav_player_start_chk01_01", "nav_player_start_chk01_02" },
},
armory_take1 = {
name = "dlc2_m01_armory_take1",
player_navs = { "nav_player_start_armory 01", "nav_player_start_armory 02" },
},
armory_take2 = {
name = "dlc2_m01_armory_take2",
player_navs = { "nav_player_start_chk02_01", "nav_player_start_chk02_01" },
},
escape_start = {
name = "dlc2_m01_escape_start",
player_navs = { "nav_player_start_chk03_01", "nav_player_start_chk03_01" },
},
rail_dt_02 = {
name = "dlc2_m01_escape_dt_02",
player_navs = { "nav_player_start_chk04_01", "nav_player_start_chk04_01" },
},
alien_ambush = {
name = "dlc2_m01_alien_ambush",
player_navs = { "nav_player_start_chk05_01", "nav_player_start_chk05_01" },
},
rail_nw_01 = {
name = "dlc2_m01_rail_nw_01",
player_navs = { "nav_player_start_chk06_01", "nav_player_start_chk06_01" },
},
jump_take2 = {
name = "dlc2_m01_jump_take2",
player_navs = { "nav_player_start_chk07_01", "nav_player_start_chk07_01" },
},
finale = {
name = "dlc2_m01_finale",
player_navs = { "nav_player_start_chk08_01", "nav_player_start_chk08_01" },
},
}
-- Tweak Values --
Dlc2_m01_tweak_values = {
--[[
Armory Take1
--]]
-- Player load-out
armory_inventory_take1 = {
{ weapon = "SMG-Gang", upgrade_lvl = WEAPON_LEVEL1 },
{ weapon = "Rifle-Gang", upgrade_lvl = WEAPON_LEVEL1 },
},
-- Player attack multiplier (greater than 1 for increased attack damage, less than 1 for less damage)
armory_player_atk_mult_take1 = 1.8,
-- Fail time (ms) for the player if the enter the heli_pad before parking the car
heli_pad_evacuate_time = 15000,
-- Trigger the guards at the gate to move into place when this many tower guards remain
num_tower_guards_to_trigger_gate = 1,
--[[
Armory Take2
--]]
-- Player load-out (Used for the rest of the mission as well)
armory_inventory_take2 = {
{ weapon = "Grenade", upgrade_lvl = WEAPON_LEVEL4, is_grenade = true },
{ weapon = "SMG-Gang", upgrade_lvl = WEAPON_LEVEL3 },
{ weapon = "Rifle-Gang", upgrade_lvl = WEAPON_LEVEL4 },
},
-- Player attack multiplier (greater than 1 for increased attack damage, less than 1 for less damage)
armory_player_atk_mult_take2 = 1.0,
-- Notoriety level after rescueing Kwilanna
armory_notoriety_rescue_kwilanna = 5,
--[[
Rail sequence
--]]
-- How far from each navpoint the player's vehicle must get in the rail to consider the path complete
player_veh_pathfind_dist = 10.0,
player_veh_pathfind_speed = 70.0,
parked_car_exp_cooldown_min = 2.0,
parked_car_exp_cooldown_max = 5.0,
-- Player attack multiplier (greater than 1 for increased attack damage, less than 1 for less damage)
rail_player_atk_mult_start = 1.0,
rail_player_atk_mult_dt2 = 4.0,
rail_player_atk_mult_nw = 2.0,
rail_player_atk_mult_end = 2.0,
-- Player attack multipliers for HARDCORE difficulty
rail_player_atk_mult_start_hc = 1.1,
rail_player_atk_mult_dt2_hc = 4.1,
rail_player_atk_mult_nw_hc = 2.4,
rail_player_atk_mult_end_hc = 2.4,
-- Rail vehicle hitpoints
player_veh_hitpoints = 19500,
player_veh_nw_hitpoints = 34500,
-- Rail vehicle hitpoints for HARDCORE difficulty
player_veh_hitpoints_hc = 19501,
player_veh_nw_hitpoints_hc = 45001,
remote_player_weapon = "Rifle-Gang",
fake_notoriety_level = 5, -- Fake notoriety level displayed to the HUD
dt_police_notoriety = 4, -- Real notoriety level that controls spawning rate
ng_vehicle_chase_speed = 85.0,
ng_heli_follow_dist = 20.0,
alien_default_hp_mult = 2.6,
num_alien_notority_vehicles = 4.0,
}
-- Groups --
Dlc2_m01_groups = {
courtesy_veh_01 = {
name = "group_courtesy_veh_chk_01",
vehicles = { "veh_player_start_chk01_01", "veh_player_start_chk01_02" },
},
kwilanna = {
name = "group_kwilanna_01",
kwilanna = "npc_kwilanna_01",
},
kwilanna_heli = {
name = "group_kwilanna_heli",
heli = {
vehicle = "veh_kwilanna_heli_01",
pilot = "npc_kwilanna_heli_pilot_01",
},
},
armory_camera_men = {
name = "group_armory_cameramen_01",
npcs = {
"npc_armory_cameraman_01", "npc_armory_cameraman_02", "npc_armory_cameraman_03", "npc_armory_cameraman_04", "npc_armory_cameraman_05", "npc_armory_cameraman_06",
"npc_armory_cameraman_07", "npc_armory_cameraman_08", "npc_armory_cameraman_09", "npc_armory_cameraman_10", "npc_armory_cameraman_11", "npc_armory_cameraman_12",
"npc_armory_cameraman_13",
},
},
armory_car_husks = {
name = "group_armory_car_husks",
vehicles = {
"veh_armory_husk 01", "veh_armory_husk 02", "veh_armory_husk 03", "veh_armory_husk 04", "veh_armory_husk 05",
},
},
armory_take_01 = {
name = "group_armory_take_01",
npcs = {
"npc_armory_take1_01", "npc_armory_take1_02", "npc_armory_take1_03", "npc_armory_take1_04", "npc_armory_take1_05",
"npc_armory_take1_06", "npc_armory_take1_10", "npc_armory_take1_11", "npc_armory_take1_12", "npc_armory_take1_13",
},
suvs = {
"veh_armory_suv_take1_01", "veh_armory_suv_take1_02", "veh_armory_suv_take1_03", "veh_armory_suv_take1_04",
"veh_armory_suv_take1_05", "veh_armory_suv_take1_06",
},
cars = {
"veh_armory_car_take1_01", "veh_armory_car_take1_02",
},
helis = {
"veh_armory_heli_take1_01", "veh_armory_heli_take1_02", "veh_armory_heli_take1_03",
},
tower_guards = {
--[["npc_armory_take1_07",--]] "npc_armory_take1_08", --[["npc_armory_take1_09", "npc_armory_take1_13", "npc_armory_take1_14",--]]
},
},
gate_gaurd_take_01 = {
name = "group_gate_guard_take1",
chase_npcs = {
{ npc = "npc_gate_guard_take1_01", nav = "nav_gate_guard_pos 01", leash = 4.0 },
{ npc = "npc_gate_guard_take1_02", nav = "nav_gate_guard_pos 02", leash = 4.0 },
{ npc = "npc_gate_guard_take1_03", nav = "nav_gate_guard_pos 03", leash = 10.0, delay = 8.0 },
{ npc = "npc_gate_guard_take1_04", nav = "nav_gate_guard_pos 04", leash = 10.0, delay = 8.2 },
},
},
stair_guard_take_01 = {
name = "group_stair_guard_take1",
chase_npcs = {
{ npc = "npc_stair_guard_take1_01", nav = "nav_player_start_chk03_01", leash = 3.0 },
},
},
armory_take_02 = {
name = "group_armory_take_02",
npcs = {
"npc_armory_take2_01", "npc_armory_take2_02", "npc_armory_take2_03", "npc_armory_take2_04", "npc_armory_take2_05",
"npc_armory_take2_06", "npc_armory_take2_07", "npc_armory_take2_08", "npc_armory_take2_09", --[["npc_armory_take2_10",--]]
"npc_armory_take2_11", "npc_armory_take2_12", "npc_armory_take2_13", --[["npc_armory_take2_14",--]] "npc_armory_take2_15",
"npc_armory_take2_16", "npc_armory_take2_17", "npc_armory_take2_18", "npc_armory_take2_19", "npc_armory_take2_20",
--[["npc_armory_suv_take2_01",--]] "npc_armory_suv_take2_02", --[["npc_armory_suv_take2_03",--]] "npc_armory_suv_take2_04",
"npc_armory_suv_take2_05", "npc_armory_suv_take2_06",
"npc_armory_suv_take2_10", "npc_armory_suv_take2_12",
},
suvs = {
"veh_armory_suv_take2_02", "veh_armory_suv_take2_04",
"veh_armory_suv_take2_05", "veh_armory_suv_take2_06", "veh_armory_suv_take2_07", "veh_armory_suv_take2_08",
"veh_armory_suv_take2_09", "veh_armory_suv_take2_10", "veh_armory_suv_take2_11", "veh_armory_suv_take2_12",
},
cars = {
"veh_armory_car_take2_01", "veh_armory_car_take2_02",
},
helis = {
"veh_armory_heli_take2_01", "veh_armory_heli_take2_02", "veh_armory_heli_take2_03",
},
-- List of manned vehicles that should have a gunner on the mounted turret
manned_vehicles = {
{ vehicle = "veh_armory_suv_take2_02", gunner = "npc_armory_suv_take2_02" },
{ vehicle = "veh_armory_suv_take2_04", gunner = "npc_armory_suv_take2_04" },
{ vehicle = "veh_armory_suv_take2_05", gunner = "npc_armory_suv_take2_05" },
{ vehicle = "veh_armory_suv_take2_06", gunner = "npc_armory_suv_take2_06" },
{ vehicle = "veh_armory_suv_take2_10", gunner = "npc_armory_suv_take2_10" },
{ vehicle = "veh_armory_suv_take2_12", gunner = "npc_armory_suv_take2_12" },
},
},
armory_player_heli = {
name = "group_player_heli",
heli = {
vehicle = "veh_player_heli",
pilot = "npc_player_heli_pilot",
},
},
armory_drop_off = {
name = "group_armory_drop_off",
heli = {
vehicle = "veh_armory_drop_off",
pilots = { "npc_armory_drop_off_01", "npc_armory_drop_off_02" },
soldiers = { "npc_armory_drop_off_03", "npc_armory_drop_off_04", "npc_armory_drop_off_05", "npc_armory_drop_off_06" },
path = "path_armory_drop_off",
speed = 25.0,
},
},
armory_get_away_car = {
name = "group_armory_get_away_car",
vehicle = "veh_armory_get_away_car",
},
armory_persue_heli = {
name = "group_armory_persue_heli",
chase_vehicles = {
{ vehicle = "veh_armory_persue_heli 01", npcs = { "npc_armory_persue_heli 01", "npc_armory_persue_heli 02" }, paths = { "path_armory_persue_heli 01" }, orient = HELI_PF_FACE_TARGET, },
{ vehicle = "veh_armory_persue_heli 02", npcs = { "npc_armory_persue_heli 03", "npc_armory_persue_heli 04" }, paths = { "path_armory_persue_heli 02" }, orient = HELI_PF_FACE_TARGET, },
},
},
armory_camera_persue_heli = {
name = "group_cameramen_heli_001",
heli = { vehicle = "veh_camera_persue_heli 01", npcs = { "npc_heli_cameraman_001", "npc_heli_cameraman_002" }, paths = { "path_cameraman_rail_heli_01" }, follow_dist = 10.0, delay = 4.5 },
},
-- Expects "group_armory_get_away_car" is also created for the vehicle (this only creates the NPCs to go in the vehicle)
dt_get_away_car_drop_off = {
name = "group_get_away_car_drop_off",
npcs = { "npc_ng_get_away_car 001", "npc_ng_get_away_car 002", "npc_ng_get_away_car 003" },
path = "nav_armory_get_away_stop",
},
dt_camera_men_01 = {
name = "group_dt_cameramen_01",
npcs = {
"npc_dt_camerman_01 01", "npc_dt_camerman_01 02", "npc_dt_camerman_01 03", "npc_dt_camerman_01 04",
"npc_dt_camerman_01 05", "npc_dt_camerman_01 06", "npc_dt_camerman_01 07", "npc_dt_camerman_01 08",
"npc_dt_camerman_01 09",
},
},
dt_camera_men_02 = {
name = "group_dt_cameramen_02",
npcs = {
"npc_dt_camerman_02 01", "npc_dt_camerman_02 02", "npc_dt_camerman_02 03", "npc_dt_camerman_02 04",
"npc_dt_camerman_02 05", "npc_dt_camerman_02 06", "npc_dt_camerman_02 07", "npc_dt_camerman_02 08",
"npc_dt_camerman_02 09", "npc_dt_camerman_02 10", "npc_dt_camerman_02 11"
},
},
dt_chase_ng_04 = {
name = "group_dt_chase_ng 04",
chase_vehicles = {
{ vehicle = "veh_ng_dt_04 01", npcs = { "npc_ng_dt_04 01", "npc_ng_dt_04 02" }, paths = { "path_ng_dt_04 01", "path_ng_dt_04 01a" }, exp_factor = 0.1, follow_dist = 10.0 },
{ vehicle = "veh_ng_dt_04 02", npcs = { "npc_ng_dt_04 03", "npc_ng_dt_04 04" }, paths = { "path_ng_dt_04 01", "path_ng_dt_04 02a" }, exp_factor = 0.1, follow_dist = 10.0 },
{ vehicle = "veh_ng_dt_04 03", npcs = { "npc_ng_dt_04 05", "npc_ng_dt_04 06" }, paths = { "path_ng_dt_04 01", "path_ng_dt_04 03a" }, exp_factor = 0.1, follow_dist = 10.0 },
},
},
dt_chase_ng_05 = {
name = "group_dt_chase_ng 05",
chase_vehicles = {
{ vehicle = "veh_ng_dt_05 01", npcs = { "npc_ng_dt_05 01", "npc_ng_dt_05 02" }, paths = { "path_ng_dt_05 01" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_05 02", npcs = { "npc_ng_dt_05 03", "npc_ng_dt_05 04" }, paths = { "path_ng_dt_05 02" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_05 03", npcs = { "npc_ng_dt_05 05", "npc_ng_dt_05 06" }, paths = { "path_ng_dt_05 03" }, exp_factor = 0.1 },
},
},
dt_chase_ng_06 = {
name = "group_dt_chase_ng 06",
chase_vehicles = {
{ vehicle = "veh_ng_dt_06 01", npcs = { "npc_ng_dt_06 01", "npc_ng_dt_06 02" }, paths = { "path_ng_dt_06 01" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_06 02", npcs = { "npc_ng_dt_06 03", "npc_ng_dt_06 04" }, paths = { "path_ng_dt_06 02" }, exp_factor = 0.1 },
},
},
dt_chase_ng_07 = {
name = "group_dt_chase_ng 07",
chase_vehicles = {
{ vehicle = "veh_ng_dt_07 01", npcs = { "npc_ng_dt_07 01", "npc_ng_dt_07 02" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_07 02", npcs = { "npc_ng_dt_07 03", "npc_ng_dt_07 04" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_07 03", npcs = { "npc_ng_dt_07 05", "npc_ng_dt_07 06" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_07 04", npcs = { "npc_ng_dt_07 07", "npc_ng_dt_07 08" }, exp_factor = 0.1 },
},
},
dt_chase_ng_08 = {
name = "group_dt_chase_ng 08",
chase_vehicles = {
{ vehicle = "veh_ng_dt_08 01", npcs = { "npc_ng_dt_08 01", "npc_ng_dt_08 02" }, paths = { "path_ng_dt_08_01" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_08 02", npcs = { "npc_ng_dt_08 03", "npc_ng_dt_08 04" }, paths = { "path_ng_dt_08_02" }, exp_factor = 0.1 },
},
},
dt_chase_ng_09 = {
name = "group_dt_chase_ng 09",
chase_vehicles = {
{ vehicle = "veh_ng_dt_09 01", npcs = { "npc_ng_dt_09 01", "npc_ng_dt_09 02" }, paths = { "path_ng_dt_09_01" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_09 02", npcs = { "npc_ng_dt_09 03", "npc_ng_dt_09 04" }, paths = { "path_ng_dt_09_02" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_09 03", npcs = { "npc_ng_dt_09 05", "npc_ng_dt_09 06" }, paths = { "path_ng_dt_09_03" }, exp_factor = 0.1 },
},
},
dt_chase_ng_10 = {
name = "group_dt_chase_ng 10",
chase_vehicles = {
{ vehicle = "veh_ng_dt_10 01", npcs = { "npc_ng_dt_10 01", "npc_ng_dt_10 02" }, paths = { "path_ng_dt_10_01" }, exp_factor = 0.1 },
{ vehicle = "veh_ng_dt_10 02", npcs = { "npc_ng_dt_10 03", "npc_ng_dt_10 04" }, paths = { "path_ng_dt_10_02" }, exp_factor = 0.1 },
},
},
ng_bridge_roadblock = {
name = "group_ng_bridge_roadblock",
vehicles = {
{ vehicle = "veh_ng_roadblock_tank 01", npcs = { "npc_ng_roadblock 01", "npc_ng_roadblock 02" } },
{ vehicle = "veh_ng_roadblock_tank 02", npcs = { "npc_ng_roadblock 03", "npc_ng_roadblock 04" } },
{ vehicle = "veh_ng_roadblock_suv 01", npcs = { "npc_ng_roadblock 05", "npc_ng_roadblock 06" } },
{ vehicle = "veh_ng_roadblock_suv 02", npcs = { "npc_ng_roadblock 07", "npc_ng_roadblock 08" } },
{ vehicle = "veh_ng_roadblock_suv 03", npcs = { "npc_ng_roadblock 09", "npc_ng_roadblock 10" } },
{ vehicle = "veh_ng_roadblock_suv 04", npcs = { "npc_ng_roadblock 11", "npc_ng_roadblock 12" } },
{ vehicle = "veh_ng_roadblock_heli 01", npcs = { "npc_ng_roadblock 13", "npc_ng_roadblock 14" }, hover_nav = "nav_ng_roadblock_heli_pos 01" },
{ vehicle = "veh_ng_roadblock_heli 02", npcs = { "npc_ng_roadblock 15", "npc_ng_roadblock 16" }, hover_nav = "nav_ng_roadblock_heli_pos 02" },
},
},
ng_roadblock_pursuers = {
name = "group_ng_roadblock_pursuers",
chase_vehicles = {
{ vehicle = "veh_ng_roadblock_pursuer 01", npcs = { "npc_ng_roadblock_pursuer 01", "npc_ng_roadblock_pursuer 02" }, paths = { "path_ng_roadblock_pursuer 01" } },
{ vehicle = "veh_ng_roadblock_pursuer 02", npcs = { "npc_ng_roadblock_pursuer 03", "npc_ng_roadblock_pursuer 04" }, paths = { "path_ng_roadblock_pursuer 02" } },
},
},
alien_bridge_ambush = {
name = "group_nw_chase_alien 01",
vehicles = {
{ vehicle = "veh_alien_nw_01 01", npcs = { "npc_alien_nw_01 01", "npc_alien_nw_01 02" }, fly_to_nav = "nav_alien_nw_fly_to_01 001", target_nav = "nav_alien_nw_target_pos_01 01", paths = { "path_alien_ambush_01" }, follow_dist = 15.0, delay = 5.0, thread_id = -1, is_alien = true },
{ vehicle = "veh_alien_nw_01 02", npcs = { "npc_alien_nw_01 03", "npc_alien_nw_01 04" }, fly_to_nav = "nav_alien_nw_fly_to_01 002", target_nav = "nav_alien_nw_target_pos_01 02", paths = { "path_alien_ambush_02" }, follow_dist = 15.0, delay = 5.0, thread_id = -1, is_alien = true }, -- out of order so they attack in the correct order
},
},
nw_cameramen_01 = {
name = "group_nw_cameramen_01",
npcs = {
"npc_nw_cameraman_01", "npc_nw_cameraman_02", "npc_nw_cameraman_03", "npc_nw_cameraman_04", "npc_nw_cameraman_05",
"npc_nw_cameraman_06", "npc_nw_cameraman_07", "npc_nw_cameraman_08", "npc_nw_cameraman_09", "npc_nw_cameraman_10",
"npc_nw_cameraman_11", "npc_nw_cameraman_12", "npc_nw_cameraman_13",
},
},
nw_cameramen_02 = {
name = "group_nw_cameramen_02",
npcs = {
"npc_nw_cameraman_14", "npc_nw_cameraman_15", "npc_nw_cameraman_16", "npc_nw_cameraman_17", "npc_nw_cameraman_18",
"npc_nw_cameraman_19", "npc_nw_cameraman_20", "npc_nw_cameraman_21", "npc_nw_cameraman_22", "npc_nw_cameraman_23",
"npc_nw_cameraman_24", "npc_nw_cameraman_25", "npc_nw_cameraman_26", "npc_nw_cameraman_27", "npc_nw_cameraman_28",
},
},
alien_nw01_ambush = {
name = "group_nw_chase_alien_01",
chase_vehicles = {
{ vehicle = "veh_alien_nw01_001", npcs = { "npc_alien_nw01_001", "npc_alien_nw01_002" }, paths = { "path_alien_nw01_001"}, follow_dist = 10.0, orient = HELI_PF_FACE_TARGET, is_alien = true },
},
},
alien_nw02_ambush = {
name = "group_nw_chase_alien 02",
chase_vehicles = {
{ vehicle = "veh_alien_nw02_001", npcs = { "npc_alien_nw02_001", "npc_alien_nw02_002" }, paths = { "path_alien_nw02_001"}, follow_dist = 10.0, orient = HELI_PF_FACE_TARGET, is_alien = true},
},
},
alien_nw03_ambush = {
name = "group_nw_chase_alien 03",
chase_vehicles = {
{ vehicle = "veh_alien_nw03_001", npcs = { "npc_alien_nw03_001", "npc_alien_nw03_002" }, paths = { "path_alien_nw03_001"}, follow_dist = 10.0, is_alien = true},
},
},
alien_nw04_ambush = {
name = "group_nw_chase_alien 04",
chase_vehicles = {
{ vehicle = "veh_alien_nw04_001", npcs = { "npc_alien_nw04_001", "npc_alien_nw04_002" }, paths = { "path_alien_nw04_001"}, follow_dist = 15.0, is_alien = true},
},
},
alien_nw05_ambush = {
name = "group_nw_chase_alien 05",
chase_vehicles = {
{ vehicle = "veh_alien_nw05_001", npcs = { "npc_alien_nw05_001", "npc_alien_nw05_002" }, paths = { "path_alien_nw05_001"}, follow_dist = 10.0, is_alien = true},
},
},
alien_nw06_ambush = {
name = "group_nw_chase_alien 06",
chase_vehicles = {
{ vehicle = "veh_alien_nw06_001", npcs = { "npc_alien_nw06_001", "npc_alien_nw06_002" }, paths = { "path_alien_nw06_001"}, follow_dist = 10.0, is_alien = true},
},
},
alien_nw07_ambush = {
name = "group_nw_chase_alien 07",
chase_vehicles = {
{ vehicle = "veh_alien_nw07_001", npcs = { "npc_alien_nw07_001", "npc_alien_nw07_002" }, paths = { "path_alien_nw07_001"}, follow_dist = 10.0, is_alien = true},
},
},
alien_nw08_ambush = {
name = "group_nw_chase_alien 08",
chase_vehicles = {
{ vehicle = "veh_alien_nw08_001", npcs = { "npc_alien_nw08_001", "npc_alien_nw08_002" }, paths = { "path_alien_nw08_001"}, follow_dist = 10.0, is_alien = true},
},
},
alien_end_ambush_01 = {
name = "group_alien_end 01",
chase_vehicles = {
{ vehicle = "veh_alien_end_01 01", npcs = { "npc_alien_end_01 01", "npc_alien_end_01 02" }, paths = { "path_alien_end_01 01" }, follow_dist = 5.0, is_alien = true },
{ vehicle = "veh_alien_end_01 02", npcs = { "npc_alien_end_01 03", "npc_alien_end_01 04" }, paths = { "path_alien_end_01 02" }, follow_dist = 8.0, is_alien = true },
},
},
alien_end_ambush_02 = {
name = "group_alien_end 02",
chase_vehicles = {
{ vehicle = "veh_alien_end_02 01", npcs = { "npc_alien_end_02 01", "npc_alien_end_02 02" }, paths = { "path_alien_end_02 01" }, is_alien = true },
{ vehicle = "veh_alien_end_02 02", npcs = { "npc_alien_end_02 03", "npc_alien_end_02 04" }, paths = { "path_alien_end_02 02" }, is_alien = true },
},
},
alien_tunnel_ambush = {
name = "group_alien_tunnel 01",
chase_vehicles = {
{ vehicle = "veh_alien_bike_tunnel 01", npcs = { "npc_alient_bike_tunnel 01" }, paths = { "path_alien_bike_tunnel 01" }, follow_dist = 12.0, delay = 0.0, exp_factor = 0.1, is_alien = true },
{ vehicle = "veh_alien_bike_tunnel 02", npcs = { "npc_alient_bike_tunnel 02" }, paths = { "path_alien_bike_tunnel 02" }, follow_dist = 13.0, delay = 0.4, exp_factor = 0.1, is_alien = true },
{ vehicle = "veh_alien_bike_tunnel 03", npcs = { "npc_alient_bike_tunnel 03" }, paths = { "path_alien_bike_tunnel 03" }, follow_dist = 11.0, delay = 0.9, exp_factor = 0.1, is_alien = true },
{ vehicle = "veh_alien_bike_tunnel 04", npcs = { "npc_alient_bike_tunnel 04" }, paths = { "path_alien_bike_tunnel 04" }, follow_dist = 11.0, delay = 1.0, exp_factor = 0.1, is_alien = true },
{ vehicle = "veh_alien_bike_tunnel 05", npcs = { "npc_alient_bike_tunnel 05" }, paths = { "path_alien_bike_tunnel 05" }, follow_dist = 12.0, delay = 0.8, exp_factor = 0.1, is_alien = true },
{ vehicle = "veh_alien_bike_tunnel 06", npcs = { "npc_alient_bike_tunnel 06" }, paths = { "path_alien_bike_tunnel 06" }, follow_dist = 13.0, delay = 0.8, exp_factor = 0.1, is_alien = true },
},
},
}
-- Rail Sequence Ambushes --
Dlc2_m01_rail_ambushes = {
helipad_take1 = {
-- THESE ARE REFERENCED EXTERNALLY BY INDEX.
--
-- BE CAREFUL CHANGING THE ORDER (ADD NEW ENTRIES TO THE END IF IN DOUBT)
{
group = Dlc2_m01_groups.gate_gaurd_take_01,
create_trigger = nil,
activate_trigger = "tgr_heli_pad_gate",
behavior = "attack_region",
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.stair_guard_take_01,
create_trigger = nil,
activate_trigger = "tgr_stair_guard",
behavior = "retreat",
group_threads = { }, created = false, activated = false,
},
},
escape_start = {
{
group = Dlc2_m01_groups.armory_persue_heli,
create_trigger = "tgr_pursue_heli_create",
activate_trigger = "tgr_pursue_heli_activate",
behavior = "heli_path_retreat",
speed = 55.0,
group_threads = { }, create = false, activated = false,
},
},
dt_island = {
},
dt_island_02 = {
{
group = Dlc2_m01_groups.dt_chase_ng_04,
create_trigger = "tgr_ng_dt_create_04",
activate_trigger = "tgr_ng_dt_activate_04",
behavior = "heli_follow",
speed = -1,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.dt_chase_ng_05,
create_trigger = "tgr_ng_dt_create_05",
activate_trigger = "tgr_ng_dt_activate_05",
behavior = "path_navmesh",
speed = 75,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.dt_chase_ng_06,
create_trigger = "tgr_ng_dt_create_06",
activate_trigger = "tgr_ng_dt_activate_06",
behavior = "path_navmesh",
speed = 80,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.dt_chase_ng_07,
create_trigger = "tgr_ng_dt_create_07",
activate_trigger = "tgr_ng_dt_activate_07",
behavior = "chase",
speed = 85,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.dt_chase_ng_08,
create_trigger = "tgr_ng_dt_create_08",
activate_trigger = "tgr_ng_dt_activate_08",
behavior = "path_navmesh",
speed = 95,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.dt_chase_ng_09,
create_trigger = "tgr_ng_dt_create_09",
activate_trigger = "tgr_ng_dt_activate_09",
behavior = "path_navmesh",
speed = 75,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.dt_chase_ng_10,
create_trigger = "tgr_ng_dt_create_10",
activate_trigger = "tgr_ng_dt_activate_10",
behavior = "path_navmesh",
speed = 85,
group_threads = { }, created = false, activated = false,
},
},
alien_ambush = {
{
group = Dlc2_m01_groups.ng_roadblock_pursuers,
create_trigger = "tgr_ng_rb_pursuer_create",
activate_trigger = "tgr_ng_rb_pursuer_activate",
behavior = "path_navmesh_exit",
speed = -1,
group_threads = { }, created = false, activated = false,
},
},
nw_island = {
{
group = Dlc2_m01_groups.alien_nw01_ambush,
create_trigger = "tgr_al_create_01",
activate_trigger = "tgr_al_activate_01",
behavior = "heli_follow",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_nw02_ambush,
create_trigger = "tgr_al_create_02",
activate_trigger = "tgr_al_activate_02",
behavior = "heli_follow_explode",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_nw03_ambush,
create_trigger = "tgr_al_create_03",
activate_trigger = "tgr_al_activate_03",
behavior = "heli_follow_explode",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_nw04_ambush,
create_trigger = "tgr_al_create_04",
activate_trigger = "tgr_al_activate_04",
behavior = "heli_follow",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_nw05_ambush,
create_trigger = "tgr_al_create_05",
activate_trigger = "tgr_al_activate_05",
behavior = "heli_follow",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_nw06_ambush,
create_trigger = "tgr_al_create_06",
activate_trigger = "tgr_al_activate_06",
behavior = "heli_follow",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_nw07_ambush,
create_trigger = "tgr_al_create_07",
activate_trigger = "tgr_al_activate_07",
behavior = "heli_follow",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_nw08_ambush,
create_trigger = "tgr_al_create_08",
activate_trigger = "tgr_al_activate_08",
behavior = "heli_path",
speed = 100,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
},
take2 = {
{
group = Dlc2_m01_groups.alien_end_ambush_01,
create_trigger = "tgr_al_end_create_01",
activate_trigger = "tgr_al_end_activate_01",
behavior = "heli_path",
speed = 70,
hp_multiplier = 2,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_end_ambush_02,
create_trigger = "tgr_al_end_create_02",
activate_trigger = "tgr_al_end_activate_02",
behavior = "heli_path_explode",
speed = 57,
hp_multiplier = Dlc2_m01_tweak_values.alien_default_hp_mult,
group_threads = { }, created = false, activated = false,
},
{
group = Dlc2_m01_groups.alien_tunnel_ambush,
create_trigger = "tgr_alien_tunnel_create 01",
activate_trigger = "tgr_alien_tunnel_activate 01",
behavior = "heli_follow_explode",
speed = 75,
group_threads = { }, created = false, activated = false,
},
},
}
-- Objectives --
Dlc2_m01_objectives = {
get_in_car = { tag = "DLC2_M01_OBJ_GO_TO_VEHICLE", icon = OI_ASSET_USE },
go_to_armory = { tag = "DLC2_M01_OBJ_GO_TO_ARMORY", icon = OI_ASSET_LOCATION },
rescue_kwilanna = { tag = "DLC2_M01_OBJ_RESCUE_ALIEN", icon = OI_ASSET_USE },
breach_heliport = { tag = "DLC2_M01_OBJ_BREACH_HELIPORT", icon = OI_ASSET_LOCATION },
jump_from_heli = { tag = "DLC2_M01_OBJ_JUMP", icon = OI_ASSET_USE },
land_on_target = { tag = "DLC2_M01_OBJ_LAND_TARGET", icon = OI_ASSET_LOCATION },
get_in_helicopter = { tag = "DLC2_M01_OBJ_GO_TO_HELICOPTER", icon = OI_ASSET_USE },
get_in_escape_vehicle = { tag = "DLC2_M01_OBJ_GO_TO_VEHICLE", icon = OI_ASSET_USE },
escape_nat_guard = { tag = "DLC2_M01_OBJ_ESCAPE_NG", icon = OI_ASSET_LOCATION },
kill_nat_guard = { tag = "DLC2_M01_OBJ_KILL_NAT_GUARD", icon = OI_ASSET_KILL },
destroy_pursuers = { tag = "DLC2_M01_OBJ_DESTROY_PURSUERS", icon = OI_ASSET_KILL },
prepare_for_jump = { tag = "DLC2_M01_OBJ_PREPARE_JUMP", icon = OI_ASSET_LOCATION },
}
-- Characters --
Dlc2_m01_characters = {
kwilanna = Dlc2_m01_groups.kwilanna.kwilanna,
}
-- Navpoints --
Dlc2_m01_navpoints = {
mission_end = { "nav_player_start_chk01_01", "nav_player_start_chk01_02" },
armory_location = "nav_armory_location",
armory_waypoint = "nav_player_start_armory 02",
kwilanna_rescue_orient = "nav_kwilanna_resuce_orient",
kwilanna_rescue_anim_orient = "nav_kwilanna_rescue_anim_orient",
saints_hq = "nav_saints_hq",
player_vehicle_chk04 = "nav_player_vehicle_chk04",
player_vehicle_chk05 = "nav_player_vehicle_chk05",
player_vehicle_chk06 = "nav_player_vehicle_chk06",
player_vehicle_chk07 = "nav_player_vehicle_chk07",
player_vehicle_chk08 = "nav_player_vehicle_chk08",
alien_ambush_explosions = { "nav_alien_ambush_exp 001", "nav_alien_ambush_exp 002", "nav_alien_ambush_exp 003", "nav_alien_ambush_exp 004",
"nav_alien_ambush_exp 005", "nav_alien_ambush_exp 006", "nav_alien_ambush_exp 007", "nav_alien_ambush_exp 008" },
}
-- Triggers --
Dlc2_m01_triggers = {
armory_island = "tgr_armory_island_volume",
armory_parking_location = "tgr_armory_parking_spot",
heli_pad_area = "tgr_heli_pad_volume",
tgr_kwilanna_heli_radius = "tgr_kwilanna_heli_radius",
player_landing_area = "tgr_landing_area",
player_landing_bulls_eye = "tgr_landing_bulls_eye",
armory_cont_exp = "tgr_armory_cont_explosion",
rescue_kwilanna = "tgr_rescue_kwilanna",
call_out_helis = "tgr_escape_car_create",
player_heli_shot = "tgr_player_heli_shot",
player_heli_bail = "tgr_heli_bail_out",
player_heli_crash_area = "tgr_heli_crash_area",
convo_assault_drive_01 = "tgr_convo_assult_drive_01",
convo_assault_drive_02 = "tgr_convo_assult_drive_02",
convo_assault_drive_03 = "tgr_convo_assult_drive_03",
convo_tunnel_entrance = "tgr_tunnel_entrace_dialog",
tunnel_explosions = "tgr_alien_tunnel_explosions",
}
-- Movers --
Dlc2_m01_movers = {
armory_fence_to_remove = {
"mvr_armory_fence 001", "mvr_armory_fence 002", "mvr_armory_fence 003", "mvr_armory_fence 004", "mvr_armory_fence 005",
"mvr_armory_fence 006", "mvr_armory_fence 007", "mvr_armory_fence 008", "mvr_armory_fence 009", "mvr_armory_fence 010",
"mvr_armory_fence 011", "mvr_armory_fence 012", "mvr_armory_fence 013", "mvr_armory_fence 014", "mvr_armory_fence 015",
"mvr_armory_fence 016", "mvr_armory_fence 017", "mvr_armory_fence 018", "mvr_armory_fence 019", "mvr_armory_fence 020",
"mvr_armory_fence 021"
},
}
-- Rail Sequence Loops --
Dlc2_m01_rail_loops = {
dt_island_02 = {
segments = {
{
navs = {
"nav_player_rail_dt_02 000",
"nav_player_rail_dt_02 001", "nav_player_rail_dt_02 002", "nav_player_rail_dt_02 003", "nav_player_rail_dt_02 004",
"nav_player_rail_dt_02 005", "nav_player_rail_dt_02 006", "nav_player_rail_dt_02 007", "nav_player_rail_dt_02 008",
"nav_player_rail_dt_02 009", "nav_player_rail_dt_02 010"
},
navmesh = true,
delay = 1.0,
},
{
navs = {
"nav_player_rail_dt_02 011", "nav_player_rail_dt_02 012", "nav_player_rail_dt_02 013",
"nav_player_rail_dt_02 014", "nav_player_rail_dt_02 015", "nav_player_rail_dt_02 016", "nav_player_rail_dt_02 017",
"nav_player_rail_dt_02 018", "nav_player_rail_dt_02 019", "nav_player_rail_dt_02 020", "nav_player_rail_dt_02 021",
"nav_player_rail_dt_02 022", "nav_player_rail_dt_02 023", "nav_player_rail_dt_02 024", "nav_player_rail_dt_02 025",
"nav_player_rail_dt_02 026",
},
navmesh = true,
},
},
},
alien_ambush = {
segments = {
{
navs = {
"nav_player_rail_nw_01 000",
"nav_player_rail_nw_01 001", "nav_player_rail_nw_01 002", "nav_player_rail_nw_01 003", "nav_player_rail_nw_01 004",
"nav_player_rail_nw_01 005",
},
navmesh = true,
},
},
},
nw_island = {
segments = {
{
navs = {
"nav_player_rail_nw_01 006", "nav_player_rail_nw_01 007",
"nav_player_rail_nw_01 008", "nav_player_rail_nw_01 008", "nav_player_rail_nw_01 009", "nav_player_rail_nw_01 010",
"nav_player_rail_nw_01 011", "nav_player_rail_nw_01 012", "nav_player_rail_nw_01 013", "nav_player_rail_nw_01 014",
"nav_player_rail_nw_01 015", "nav_player_rail_nw_01 016", "nav_player_rail_nw_01 017", "nav_player_rail_nw_01 018",
"nav_player_rail_nw_01 019", "nav_player_rail_nw_01 020", "nav_player_rail_nw_01 021", "nav_player_rail_nw_01 022",
"nav_player_rail_nw_01 023", "nav_player_rail_nw_01 024", "nav_player_rail_nw_01 025", "nav_player_rail_nw_01 026",
"nav_player_rail_nw_01 027", "nav_player_rail_nw_01 028",
},
navmesh = true,
delay = 1.5,
},
{
navs = {
"nav_player_rail_nw_01 029", "nav_player_rail_nw_01 030",
},
navmesh = true,
delay = 1.5,
},
{
navs = {
"nav_player_rail_nw_01 031", "nav_player_rail_nw_01 032", "nav_player_rail_nw_01 033", "nav_player_rail_nw_01 034",
"nav_player_rail_nw_01 035", "nav_player_rail_nw_01 036", "nav_player_rail_nw_01 037", "nav_player_rail_nw_01 038",
"nav_player_rail_nw_01 039", "nav_player_rail_nw_01 040", "nav_player_rail_nw_01 041",
"nav_player_rail_nw_01 042", "nav_player_rail_nw_01 042",
"nav_player_rail_nw_01 043", "nav_player_rail_nw_01 044", "nav_player_rail_nw_01 045", "nav_player_rail_nw_01 046",
"nav_player_rail_nw_01 047", "nav_player_rail_nw_01 047", "nav_player_rail_nw_01 049", "nav_player_rail_nw_01 050",
"nav_player_rail_nw_01 051", "nav_player_rail_nw_01 052", "nav_player_rail_nw_01 053", "nav_player_rail_nw_01 054",
"nav_player_rail_nw_01 055", "nav_player_rail_nw_01 056", "nav_player_rail_nw_01 057", "nav_player_rail_nw_01 058",
"nav_player_rail_nw_01 059", "nav_player_rail_nw_01 060", "nav_player_rail_nw_01 061", "nav_player_rail_nw_01 062",
"nav_player_rail_nw_01 063", "nav_player_rail_nw_01 064", "nav_player_rail_nw_01 065", "nav_player_rail_nw_01 066",
"nav_player_rail_nw_01 067", "nav_player_rail_nw_01 068", "nav_player_rail_nw_01 069", "nav_player_rail_nw_01 070",
"nav_player_rail_nw_01 071",
},
navmesh = true,
},
},
},
jump = {
segments = {
{
navs = {
"nav_player_rail_nw_01 072", "nav_player_rail_nw_01 073", "nav_player_rail_nw_01 074",
},
navmesh = true,
},
},
},
rail_end = {
segments = {
{
navs = {
"nav_player_rail_nw_01 072", "nav_player_rail_nw_01 073",
},
navmesh = true,
},
{
navs = {
"nav_player_rail_end 001", "nav_player_rail_end 002", "nav_player_rail_end 003", "nav_player_rail_end 004",
"nav_player_rail_end 005", "nav_player_rail_end 006",
},
navmesh = true,
delay = 1.0,
},
},
},
finale = {
segments = {
{
navs = {
"nav_player_rail_end 007", "nav_player_rail_end 008",
"nav_player_rail_end 009", "nav_player_rail_end 010", "nav_player_rail_end 011", "nav_player_rail_end 012",
"nav_player_rail_end 013", "nav_player_rail_end 014",
"nav_player_rail_end 015", "nav_player_rail_end 016", "nav_player_rail_end 017", "nav_player_rail_end 018",
"nav_player_rail_end 019", "nav_player_rail_end 020", "nav_player_rail_end 021",
},
navmesh = true,
},
},
},
}
Dlc2_m01_vfx = {
car_husks = {
{ name = "vfx_car_husk 01", handle = -1 },
{ name = "vfx_car_husk 02", handle = -1 },
{ name = "vfx_car_husk 03", handle = -1 },
},
player_landing_flares = {
{ name = "vfx_landing_flare 01", handle = -1 },
{ name = "vfx_landing_flare 02", handle = -1 },
{ name = "vfx_landing_flare 03", handle = -1 },
{ name = "vfx_landing_flare 04", handle = -1 },
{ name = "vfx_landing_flare 05", handle = -1 },
{ name = "vfx_landing_flare 06", handle = -1 },
{ name = "vfx_landing_flare 07", handle = -1 },
{ name = "vfx_landing_flare 08", handle = -1 },
{ name = "vfx_landing_flare 09", handle = -1 },
},
player_heli_fire = { name = "vfx_player_heli_fire", handle = -1 },
bridge_smoke = {
{ name = "vfx_bridge_smoke 01", handle = -1 },
{ name = "vfx_bridge_smoke 02", handle = -1 },
},
tunnel_smoke = {
{ name = "vfx_tunnel_smoke 01", handle = -1 },
{ name = "vfx_tunnel_smoke 02", handle = -1 },
},
tunnel_explosions = {
{ name = "vfx_tunnel_exp 01", handle = -1 },
{ name = "vfx_tunnel_exp 02", handle = -1 },
{ name = "vfx_tunnel_exp 03", handle = -1 },
{ name = "vfx_tunnel_exp 04", handle = -1 },
},
}
Dlc2_m01_personas = {
--kwilanna = { name = "PAK2_Kwilanna", persona_id = INVALID_PERSONA_HANDLE, },
director = { name = "PAK2_Director", persona_id = INVALID_PERSONA_HANDLE, },
}
Dlc2_m01_conversations = {
mission_start = { name = "DLC2_M01_Mission_Start", load_direct = false, },
untie_kwilanna_take1 = { name = "DLC2_M01_Take_1_Untie_Alien", load_direct = false, },
armory_take1_wrap = { name = "DLC2_M01_Take_1_After_Cut", load_direct = false, },
untie_kwilanna_take2 = { name = "DLC2_M01_Take_2_Untie_Alien", load_direct = false, },
player_heli_escape_start = { name = "DLC2_M01_Take_2_Flying", load_direct = false, },
player_heli_crash = { name = "DLC2_M01_Heli_Crash", load_direct = false, },
player_heli_downed = { name = "DLC2_M01_Heli_Down", load_direct = false, },
director_cut_good = { name = "DLC2_M01_Take_2_Cut", load_direct = false, },
take_car = { name = "DLC2_M01_Get_in_Car", load_direct = false, },
humvee_driving_01 = { name = "DLC2_M01_Assault_Drive1", load_direct = false, },
humvee_driving_02 = { name = "DLC2_M01_Assault_Drive2", load_direct = false, },
humvee_driving_03 = { name = "DLC2_M01_Assault_Drive3", load_direct = false, },
--alien_roadblock_assault = {te name = "DLC2_M01_Alien_Assault", load_direct = false, },
jump_setup = { name = "DLC2_M01_Setting_Up_Jump", load_direct = false, },
jump_attempt = { name = "DLC2_M01_First_Jump_Attempt", load_direct = false, },
jump_fail = { name = "DLC2_M01_First_Jump_Fail", load_direct = false, },
jump_take2_start = { name = "DLC2_M01_Second_Jump_Begin", load_direct = false, },
jump_take2_skip = { name = "DLC2_M01_Second_Jump_Miss", load_direct = false, },
drive_to_tunnel = { name = "DLC2_M01_Drive_to_Tunnel_1", load_direct = false, },
stop_in_tunnel = { name = "DLC2_M01_Stop_In_Tunnel", load_direct = false, },
tunnel_jet_bikes = { name = "DLC2_M01_Ships_In_Tunnel", load_direct = false, },
}
Dlc2_m01_dialog_lines = {
start_action = { name = "pak2_m01_take_1_start_action", persona = Dlc2_m01_personas.director.name, },
armory_drive_start = { name = "pak2_m01_take_1_drive_begin", persona = LOCAL_PLAYER, },
armory_drive_end = { name = "pak2_m01_take_1_drive_ending", persona = LOCAL_PLAYER, },
armory_arrive = { name = "pak2_m01_take_1_heliport_setup", persona = Dlc2_m01_personas.director.name, },
armory_take1_cut = { name = "pak2_m01_take_1_cut_01", persona = Dlc2_m01_personas.director.name, },
armory_take2_action = { name = "pak2_m01_take_2_start_action", persona = Dlc2_m01_personas.director.name, },
player_parachute = { name = "pak2_m01_take_2_parachute", persona = LOCAL_PLAYER, },
director_parachute_obj = { name = "pak2_m01_hit_landing_target", persona = Dlc2_m01_personas.director.name, },
director_parachute_fail = { name = "pak2_m01_miss_landing", persona = Dlc2_m01_personas.director.name, },
player_exp_callout_01 = { name = "pak2_m01_take_1_explosions_01", persona = LOCAL_PLAYER, },
player_exp_callout_02 = { name = "pak2_m01_take_1_explosions_02", persona = LOCAL_PLAYER, },
player_exp_callout_03 = { name = "pak2_m01_take_1_explosions_03", persona = LOCAL_PLAYER, },
untie_kwilanna_take2_01 = { name = "pak2_m01_take_2_untie_alien_01", persona = LOCAL_PLAYER, },
untie_kwilanna_take2_02 = { name = "pak2_m01_take_2_untie_alien_02", persona = Dlc2_m01_characters.kwilanna, },
untie_kwilanna_take2_03 = { name = "pak2_m01_take_2_untie_alien_03", persona = LOCAL_PLAYER, },
player_heli_shot = { name = "pak2_m01_heli_crashed_into_01", persona = Dlc2_m01_characters.kwilanna },
heli_call_out = { name = "pak2_m01_assault_drive3_02", persona = LOCAL_PLAYER, },
car_chase_explosions = { name = "pak2_m01_car_chase_explosions", persona = LOCAL_PLAYER, },
bridge_roadblock = { name = "pak2_m01_bridge_blockade_01", persona = Dlc2_m01_characters.kwilanna, },
aliens_attack = { name = "pak2_m01_alien_assault_01", persona = Dlc2_m01_characters.kwilanna, },
reach_tunnel = { name = "pak2_m01_reaching_tunnel_01", persona = LOCAL_PLAYER, },
tunnel_ufo_crash_01 = { name = "pak2_m01_stop_in_tunnel_01", persona = LOCAL_PLAYER, },
tunnel_ufo_crash_02 = { name = "pak2_m01_ships_crash_inside_01", persona = Dlc2_m01_characters.kwilanna, },
jet_bikes = { name = "pak2_m01_ships_in_tunnel_01", persona = Dlc2_m01_characters.kwilanna, },
mission_end = { name = "pak2_m01_end_01", persona = LOCAL_PLAYER, },
mission_end_02 = { name = "pak2_m01_end_01", persona = Dlc2_m01_personas.director.name, },
director_generic_positive = { name = "pak2_generic_positives", persona = Dlc2_m01_personas.director.name, },
director_generic_action = { name = "pak2_generic_actions", persona = Dlc2_m01_personas.director.name, },
director_generic_camera = { name = "pak2_camera_comments", persona = Dlc2_m01_personas.director.name, },
director_generic_cut = { name = "pak2_generic_cuts", persona = Dlc2_m01_personas.director.name, },
director_generic_berating = { name = "pak2_generic_berating", persona = Dlc2_m01_personas.director.name, },
}
Dlc2_m01_dialog_queue = {
playing = {
thread_id = INVALID_THREAD_HANDLE,
dialog_handle = INVALID_CONVERSATION_HANDLE,
dialog_table = nil,
},
list = {},
size = 0,
}
-- Cutscenes --
Dlc2_m01_cutscenes = {
intro = "dlc2_gis_intro",
outro = "",
}
-- Threads --
Dlc2_m01_threads = {
process_dialog = INVALID_THREAD_HANDLE,
film_grain_load = INVALID_THREAD_HANDLE,
kwilanna_pos_process = INVALID_THREAD_HANDLE,
armory_explosion_dialog = INVALID_THREAD_HANDLE,
armory_heli_drop_off = INVALID_THREAD_HANDLE,
kwilanna_vehicle_enter = INVALID_THREAD_HANDLE,
heli_crash_area = INVALID_THREAD_HANDLE,
rail_loop_process = INVALID_THREAD_HANDLE,
parked_car_explosions = INVALID_THREAD_HANDLE,
alien_ambush_explosions = INVALID_THREAD_HANDLE,
player_heli_crash = INVALID_THREAD_HANDLE,
}
-- Achievement data
Dlc2_m01_acheivements = {
cameramen = {
name = "Cameramen Down",
slot_idx = 0,
current_count = 0,
target_goal = 15,
},
alien_ships = {
name = "Blowing the Budget",
slot_idx = 1,
current_count = 0,
target_goal = 20,
},
}
-- Runtime data --
Dlc2_m01_runtime = {
stag_lockdown_active = false,
current_checkpoint = nil,
kwilanna_rescued_by = nil,
armory_cont_exp_triggered_by = nil,
reached_armory_parking_area_by = nil,
num_players_in_heli_pad = 0,
local_player_had_backpack = false,
remote_player_had_backpack = false,
kwilanna_invulnerable = false,
kwilanna_damaged_by_player = false,
entered_coutesy_vehicle = false,
reached_armory_island = false,
entered_heli_pad = false,
player_jumped_from_heli = false,
take_2_music_trigger = false,
player_entered_landing_area = false,
local_player_entered_landing_area = false,
remote_player_entered_landing_area = false,
kwilanna_heli_radius_triggered = false,
gate_guards_triggered = false,
rescued_kwilanna = false,
called_out_helis = false,
heli_shot_down = false,
player_outside_crash_area = false,
played_to_bridge_music = false,
assult_drive_convo_01_triggered = false,
assult_drive_convo_02_triggered = false,
assult_drive_convo_03_triggered = false,
alien_ambush_triggered = false,
tunnel_explosions_triggered = false,
tunnel_explosions_triggered = false,
played_cameraman_line = false,
num_tower_guards_alive = 0,
}
-- List of players (can be used to iterate over for common setup in co-op games) --
Dlc2_m01_player_list = { LOCAL_PLAYER } -- REMOTE_PLAYER will be added on initialization if co-op is active
Dlc2_m01_chase_vehicle_cleanup_dist = 200
-- Conversation enums
DLC2_M01_CONVO_PLAY_LAST = 0
DLC2_M01_CONVO_PLAY_NEXT = 1
DLC2_M01_CONVO_PLAY_IMMEDIATE = 2
-- *************************
--
-- Standard Functions
--
-- *************************
-- This is the primary entry point for the mission, and is responsible for starting up the mission
-- at the specified checkpoint.
-- CALLED FROM CODE
--
-- checkpoint_name: The checkpoint the mission should begin at
-- is_restart: TRUE if the mission is restarting, FALSE otherwise
function dlc2_m01_start(checkpoint_name, is_restart)
Dlc2_m01_runtime.local_player_had_backpack = player_parachute_has_backpack(LOCAL_PLAYER)
if (coop_is_active() == true) then
Dlc2_m01_runtime.remote_player_had_backpack = player_parachute_has_backpack(REMOTE_PLAYER)
end
-- Put players in the custom outfit
customization_outfit_wear("GiS Mission One")
-- Dismiss all homies
party_dismiss_all()
-- Check if this mission starting from the beginning
if (checkpoint_name == Dlc2_m01_checkpoints.start.name) then
-- Clear all of the acievement counters
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_reset(achievement)
end
if (is_restart == false) then
-- First time playing mission
-- Play an intro cutscene???
if (Dlc2_m01_cutscenes.intro ~= "") then
cutscene_play(Dlc2_m01_cutscenes.intro, nil, Dlc2_m01_checkpoints.start.player_navs, false)
end
end
end
-- Initialize the mission for the current checkpoint
dlc2_m01_initialize(checkpoint_name, is_restart)
-- Run the mission from the current checkpoint
dlc2_m01_run(checkpoint_name)
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
function dlc2_m01_cleanup()
-- Call of the individual objective clean-up functions
dlc2_m01_get_in_courtesy_vehicle_take1_cleanup(true)
dlc2_m01_go_to_armory_take1_cleanup(true)
dlc2_m01_go_to_helipad_take1_cleanup(true)
dlc2_m01_rescue_kwilanna_take1_cleanup(true)
dlc2_m01_armory_take1_wrap_cleanup(true)
dlc2_m01_go_to_armory_take2_cleanup(true)
dlc2_m01_rescue_kwilanna_take2_cleanup(true)
dlc2_m01_get_in_escape_vehicle_cleanup(true)
dlc2_m01_escape_start_cleanup(true)
dlc2_m01_cleanup_armory_take2_wrap(true)
dlc2_m01_cleanup_steal_humvee(true)
dlc_m01_rail_sequence_dt_loop_02_cleanup(true)
dlc2_m01_alien_ambush_cleanup(true)
dlc_m01_rail_sequence_nw_loop_cleanup(true)
dlc2_m01_jump_take1_cleanup(true)
dlc2_m01_jump_take2_cleanup(true)
dlc2_m01_alien_finale_cleanup(true)
if (Dlc2_m01_runtime.stag_lockdown_active == true) then
city_zone_swap("lockdown", true)
end
-- Remove any callbacks we may have registered
on_death("", Dlc2_m01_characters.kwilanna)
on_dismiss("", Dlc2_m01_characters.kwilanna)
on_revived("", Dlc2_m01_characters.kwilanna)
on_incapacitated("", Dlc2_m01_characters.kwilanna)
on_vehicle_destroyed("", Dlc2_m01_groups.armory_get_away_car.vehicle)
dlc2_m01_helper_cleanup_camera_man(Dlc2_m01_groups.armory_camera_persue_heli.heli.npcs[2])
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
on_vehicle_destroyed("", vehicle_table.vehicle)
end
-- Clean-up all the script groups
for i, group in pairs(Dlc2_m01_groups) do
if (group_is_loaded(group.name) == true) then
group_destroy(group.name)
end
end
-- Clean-up any threads that might still be processing
for i, thread in pairs(Dlc2_m01_threads) do
if (thread_check_done(thread) == false) then
thread_kill(thread)
thread = INVALID_THREAD_HANDLE
end
end
-- Clean-up the players
for i, player in pairs(Dlc2_m01_player_list) do
set_player_can_enter_exit_vehicles(player, true)
hud_prompt_clear(player)
character_set_attack_multiplier(player, 1.0)
turn_vulnerable(player)
human_gravity_enable(player, true)
end
if (Dlc2_m01_runtime.local_player_had_backpack == false) then
player_parachute_wear_backpack(LOCAL_PLAYER, false)
end
if (coop_is_active() == true and Dlc2_m01_runtime.remote_player_had_backpack == false) then
player_parachute_wear_backpack(REMOTE_PLAYER, false)
end
-- Remove the Player(s) costumes
customization_item_revert()
-- Clean-up any looping VFX
for i, vfx in pairs(Dlc2_m01_vfx) do
if (vfx.name == nil) then
for j, vfx_sub in pairs(vfx) do
if (vfx_sub.handle ~= -1) then
effect_stop(vfx_sub.handle)
end
end
else
if (vfx.handle ~= -1) then
effect_stop(vfx.handle)
end
end
end
-- Kill the conversation thread
dlc2_m01_helper_dialog_kill_all()
if (thread_check_done(Dlc2_m01_threads.process_dialog) == false) then
thread_kill(Dlc2_m01_threads.process_dialog)
Dlc2_m01_threads.process_dialog = INVALID_THREAD_HANDLE
end
-- Unload any personas
for i, persona in pairs(Dlc2_m01_personas) do
if (persona.persona_id ~= INVALID_PERSONA_HANDLE) then
audio_persona_remove_2d(persona.persona_id)
persona.persona_id = INVALID_PERSONA_HANDLE
end
end
-- Remove Kwilanna from the player's party
party_dismiss(Dlc2_m01_characters.kwilanna)
-- Remove the film grain UI
dlc_gis_film_grain_unload(false)
-- Re-enable notoriety aircraft spawning
notoriety_force_no_air_spawn(false)
-- Reset notoriety
notoriety_reset("Police")
notoriety_reset("Luchadores")
notoriety_reset("Deckers")
notoriety_reset("Morningstar")
notoriety_force_no_spawn("STAG", false)
notoriety_force_no_spawn_group("police_tank", false)
-- Re-enable notoriety decay
notoriety_set_can_decay(true)
-- Re-eanbled restricted areas
notoriety_restricted_zones_enable(true)
team_make_unfriendly("Police", "Playas")
team_make_unfriendly("Playas", "Deckers")
team_make_unfriendly("Police", "Deckers")
-- Remove the fake notoriety HUD
hud_set_fake_notoriety("Police", false)
-- Re-enable parking spawns
parking_spot_disable_all(false)
-- Re-enable roadblocks
roadblocks_enable(true)
-- Re-eanbel flashpoints
flashpoints_enable(true)
-- Re-enable ambient gang spawns
ambient_gang_spawn_enable(true)
ambient_cop_spawn_enable(true)
-- Re-enable peds and vehicles
spawning_pedestrians(true)
spawning_vehicles(true)
-- Make sure to clean-up the HUD critical timer
hud_critical_timer_stop()
-- Re-enable car radios
radio_global_block(false)
continuous_explosion_stop()
character_ragdoll_clear_last_resort_position()
persona_clear_global_situation_override()
end
-- *************************
--
-- Local Functions
--
-- *************************
-- ***************************************************
-- Initilization Functions
-- ***************************************************
-- Initialize the mission for the specified checkpoint
--
-- checkpoint_name: Checkpoint to initialize the mission to
-- is_restart: Whether or not the mission is being restarted.
function dlc2_m01_initialize(checkpoint_name, is_restart)
-- Make sure the screen is completly faded out
mission_start_fade_out(0.0)
-- Set the mission author
set_mission_author("matt.gawalek")
-- Common initialization
dlc2_m01_initialize_common()
-- Checkpoint sepcific initialization
dlc2_m01_initialize_checkpoint(checkpoint_name, is_restart)
-- Start fading in
mission_start_fade_in()
end
-- Handle any common initialization necessary for all checkpoints
function dlc2_m01_initialize_common()
if (coop_is_active() == true) then
Dlc2_m01_player_list[2] = REMOTE_PLAYER
end
if (city_zone_swap_is_active("lockdown") == true) then
Dlc2_m01_runtime.stag_lockdown_active = true
city_zone_swap("lockdown", false)
end
-- Initialize the dialog lines
for i, convo in pairs(Dlc2_m01_conversations) do
convo.is_convo = true
convo.queued = false
convo.started = false
convo.completed = false
convo.ended = false
end
for i, line in pairs(Dlc2_m01_dialog_lines) do
line.is_convo = false
line.queued = false
line.started = false
line.completed = false
line.ended = false
end
-- Load any personas
for i, persona in pairs(Dlc2_m01_personas) do
if (persona.persona_id == INVALID_PERSONA_HANDLE) then
persona.persona_id = audio_persona_load_2d(persona.name)
end
end
-- Start the conversation thread
Dlc2_m01_threads.process_dialog = thread_new("dlc2_m01_thread_process_dialog")
-- Disable gang notoriety
notoriety_set_min_and_max("Luchadores", 0, 0)
notoriety_set_min_and_max("Deckers", 0, 0)
notoriety_set_min_and_max("morningstar", 0, 0)
-- Disable notoriety decay and notoriety aircraft spawning
notoriety_set_can_decay(false)
notoriety_force_no_air_spawn(true)
-- Disable STAG notoriety
notoriety_force_no_spawn("STAG", true)
-- Disable tank notoriety spawns
notoriety_force_no_spawn_group("police_tank", true)
-- Disable restricted areas
notoriety_restricted_zones_enable(false)
-- Make the Deckers Gang and Playa teams allies (camera men are set to Deckers)
team_make_allies("Playas", "Deckers")
team_make_allies("Police", "Deckers")
-- Disable car radios
radio_global_block(true)
-- Disable roadblocks
roadblocks_enable(false)
-- Disable ambient gang spawns
ambient_gang_spawn_enable(false)
-- Disable peds and vehicles
spawning_pedestrians(false)
spawning_vehicles(false)
-- Re-eanbel flashpoints
flashpoints_enable(false)
-- Setup Kwilanna
group_create(Dlc2_m01_groups.kwilanna.name, true)
npc_combat_enable(Dlc2_m01_characters.kwilanna, false) -- disable combat for Kwilanna
set_suppress_synced_attacks_flag(Dlc2_m01_characters.kwilanna, true) -- Kwillanna cannot be synced attacked
on_death("dlc2_m01_kwilanna_died_cb", Dlc2_m01_characters.kwilanna)
on_revived("dlc2_m01_kwilanna_revived_cb", Dlc2_m01_characters.kwilanna)
on_incapacitated("dlc2_m01_kwilanna_downed_cb", Dlc2_m01_characters.kwilanna)
persona_set_global_situation_override(9)
-- Read the achievement data from the checkpoint
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_read_checkpoint(achievement)
end
-- Set the waypoints to teleport the player if they cancel this mission (necessary because of the potential zone swaps)
mission_set_cancel_warp_location(Dlc2_m01_checkpoints.start.player_navs[1], Dlc2_m01_checkpoints.start.player_navs[2])
end
-- Handle any checkpoint specific initialization
--
-- checkpoint_name: Checkpoint to initialize the mission to
-- is_restart: Whether or not the mission is being restarted.
function dlc2_m01_initialize_checkpoint(checkpoint_name, is_restart)
if (checkpoint_name == Dlc2_m01_checkpoints.start.name) then
dlc2_m01_go_to_armory_take1_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.armory_take1.name) then
dlc2_m01_armory_take1_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.armory_take2.name) then
dlc2_m01_go_to_armory_take2_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.escape_start.name) then
dlc2_m01_escape_start_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.rail_dt_02.name) then
dlc2_m01_rail_dt_02_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.alien_ambush.name) then
dlc2_m01_alien_ambush_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.rail_nw_01.name) then
dlc2_m01_rail_nw_01_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.jump_take2.name) then
dlc2_m01_jump_take2_initialize() -- player teleport happens internally
elseif (checkpoint_name == Dlc2_m01_checkpoints.finale.name) then
dlc2_m01_finale_initialize() -- player teleport happens internally
end
end
-- ***************************************************
-- Process Functions
-- ***************************************************
-- Main mission processing function
--
-- checkpoint_name: Name of the checkpoint to run the mission from
function dlc2_m01_run(checkpoint_name)
Dlc2_m01_runtime.current_checkpoint = checkpoint_name
-- make sure player personas are set to dlc2
persona_set_dlc_bundle(2)
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.start.name) then
dlc2_m01_get_in_courtesy_vehicle_take1_process()
dlc2_m01_go_to_armory_take1_process()
-- Set the next checkpoint
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.armory_take1.name
mission_set_checkpoint(Dlc2_m01_runtime.current_checkpoint, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_write_checkpoint(achievement)
end
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.armory_take1.name) then
dlc2_m01_go_to_helipad_take1()
dlc2_m01_rescue_kwilanna_take1_process()
dlc2_m01_armory_take1_wrap()
-- Set the next checkpoint
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.armory_take2.name
mission_set_checkpoint(Dlc2_m01_runtime.current_checkpoint, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_write_checkpoint(achievement)
end
-- Do the transition into the second take of the Armory
mission_start_fade_out()
-- Clean-up the first take
if (group_is_loaded(Dlc2_m01_groups.courtesy_veh_01.name) == true) then
group_destroy(Dlc2_m01_groups.courtesy_veh_01.name)
end
if (group_is_loaded(Dlc2_m01_groups.kwilanna_heli.name) == true) then
group_destroy(Dlc2_m01_groups.kwilanna_heli.name)
end
if (group_is_loaded(Dlc2_m01_groups.armory_take_01.name) == true) then
group_destroy(Dlc2_m01_groups.armory_take_01.name)
end
if (group_is_loaded(Dlc2_m01_groups.armory_camera_men.name) == true) then
group_destroy(Dlc2_m01_groups.armory_camera_men.name)
end
if (group_is_loaded(Dlc2_m01_groups.armory_car_husks.name) == true) then
group_destroy(Dlc2_m01_groups.armory_car_husks.name)
end
-- Remove Kwilanna from the player's party and make her vulnerable again
party_dismiss(Dlc2_m01_characters.kwilanna)
dlc2_m01_helper_set_kwilanna_invulnerable(true, true)
thread_yield()
-- Initialize the second take
dlc2_m01_go_to_armory_take2_initialize()
mission_start_fade_in()
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.armory_take2.name) then
dlc2_m01_go_to_armory_take2_process()
dlc2_m01_rescue_kwilanna_take2_process()
dlc2_m01_get_in_escape_vehicle_process()
-- Set the next checkpoint
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.escape_start.name
mission_set_checkpoint(Dlc2_m01_runtime.current_checkpoint, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_write_checkpoint(achievement)
end
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.escape_start.name) then
dlc2_m01_escape_start_process()
dlc2_m01_process_armory_take2_wrap()
dlc2_m01_process_steal_humvee()
-- Set the next checkpoint
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.rail_dt_02.name
mission_set_checkpoint(Dlc2_m01_runtime.current_checkpoint, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_write_checkpoint(achievement)
end
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.rail_dt_02.name) then
dlc_m01_rail_sequence_dt_loop_02_process()
-- Set the next checkpoint (DEBUG checkpoint so don't call mission_set_checkpoint)
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.alien_ambush.name
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.alien_ambush.name) then
dlc2_m01_alien_ambush_process()
-- Set the next checkpoint
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.rail_nw_01.name
mission_set_checkpoint(Dlc2_m01_runtime.current_checkpoint, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_write_checkpoint(achievement)
end
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.rail_nw_01.name) then
dlc_m01_rail_sequence_nw_loop_process()
dlc2_m01_jump_take1_process()
-- Set the next checkpoint
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.jump_take2.name
mission_set_checkpoint(Dlc2_m01_runtime.current_checkpoint, true)
-- Write the achievement data for the checkpoint
for i, achievement in pairs(Dlc2_m01_acheivements) do
dlc2_m01_helper_achievement_write_checkpoint(achievement)
end
-- Do the transition into the second take of the jump
mission_start_fade_out()
-- Clean-up all the ambush groups
for i, ambush_group in pairs(Dlc2_m01_rail_ambushes) do
for j, ambush in pairs(ambush_group) do
dlc2_m01_cleanup_rail_ambush(ambush)
end
end
-- Destroy any script groups that may be aroudn
for i, group in pairs(Dlc2_m01_groups) do
if (group_is_loaded(group.name) == true) then
group_destroy(group.name)
end
end
thread_yield()
-- Initialize the second take
dlc2_m01_initialize_common()
dlc2_m01_initialize_checkpoint(Dlc2_m01_checkpoints.jump_take2.name, false)
mission_start_fade_in()
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.jump_take2.name) then
dlc2_m01_jump_take2_process()
-- Set the next checkpoint (DEBUG checkpoint so don't call mission_set_checkpoint)
Dlc2_m01_runtime.current_checkpoint = Dlc2_m01_checkpoints.finale.name
end
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.finale.name) then
dlc2_m01_alien_finale_process()
end
delay(1.0)
-- Fade-out and teleport the players back to the mission start navpoints
fade_out(1.0)
fade_out_block()
teleport_coop(Dlc2_m01_navpoints.mission_end[1], Dlc2_m01_navpoints.mission_end[2], true)
-- Call mission success
mission_end_success("dlc2_m01", Dlc2_m01_cutscenes.outro, Dlc2_m01_navpoints.mission_end)
end
--[[
Checkpoint 01 - Rescue Kwilanna from the Armory (Take1)
--]]
-- Initialization for the "go to the armory" objective
function dlc2_m01_go_to_armory_take1_initialize()
dlc2_m01_go_to_armory_initialize_common()
dlc2_m01_armory_take1_initialize_common()
-- Create the courtesy vehicle for the players
group_create(Dlc2_m01_groups.courtesy_veh_01.name, true) -- wait for the group to load
-- Hide the second courtesy vehicle if this isn't coop
if (coop_is_active() == false) then
vehicle_hide(Dlc2_m01_groups.courtesy_veh_01.vehicles[2])
end
-- Teleport the player's to the start navs
teleport_coop(Dlc2_m01_checkpoints.start.player_navs[1], Dlc2_m01_checkpoints.start.player_navs[2], true)
-- Teleport Kwilanna
--teleport(Dlc2_m01_characters.kwilanna, Dlc2_m01_navpoints.kwilanna_rescue_orient, true, false, 0.0, 0.0, 0.0, false)
-- Set the objective text and add an object indicator at the Armory
objective_text(0, Dlc2_m01_objectives.get_in_car.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.get_in_car.icon)
marker_add(Dlc2_m01_groups.courtesy_veh_01.vehicles[1], MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
end
-- Process the "get in a vehicle" objective
function dlc2_m01_get_in_courtesy_vehicle_take1_process()
-- Register a callback on the coutesy vehicle with the marker, so we can remove the marker if the vehicle is destroyed
on_vehicle_destroyed("dlc2_m01_courtest_vehicle_destroyed_cb", Dlc2_m01_groups.courtesy_veh_01.vehicles[1])
-- Register a callback for when any player enter's a vehicle, and set the player damage multipliers
for i, player in pairs(Dlc2_m01_player_list) do
on_vehicle_enter("dlc2_m01_entered_courtesy_vehicle_cb", player)
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.armory_player_atk_mult_take1)
end
delay(0.5)
-- Play the intro conversation
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.mission_start, DLC2_M01_CONVO_PLAY_IMMEDIATE, 1.0)
-- Wait until the player gets into a vehicle
while(Dlc2_m01_runtime.entered_coutesy_vehicle == false) do
thread_yield()
end
dlc2_m01_get_in_courtesy_vehicle_take1_cleanup(false)
end
-- Clean-up the "get into vehicle" objective
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_get_in_courtesy_vehicle_take1_cleanup(exiting)
on_vehicle_destroyed("", Dlc2_m01_groups.courtesy_veh_01.vehicles[1])
-- Remove callback for when any player enter's a vehicle
for i, player in pairs(Dlc2_m01_player_list) do
on_vehicle_enter("", player)
end
-- Remove the marker
marker_remove(Dlc2_m01_groups.courtesy_veh_01.vehicles[1])
end
-- Callback for when the courtest vehicle with the marker on it is destroyed
function dlc2_m01_courtest_vehicle_destroyed_cb()
-- Remove the marker
marker_remove(Dlc2_m01_groups.courtesy_veh_01.vehicles[1])
end
-- Callback for when a player enters a vehicle
function dlc2_m01_entered_courtesy_vehicle_cb()
Dlc2_m01_runtime.entered_coutesy_vehicle = true
end
-- Process the "go to the armory" objective
function dlc2_m01_go_to_armory_take1_process()
-- Set the objective text and add an object indicator at the Armory
objective_text(0, Dlc2_m01_objectives.go_to_armory.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.go_to_armory.icon)
marker_add(Dlc2_m01_navpoints.armory_waypoint, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
waypoint_add(Dlc2_m01_navpoints.armory_waypoint, SYNC_ALL)
-- Enable the trigger for the parking location
on_trigger("dlc2_m01_armory_parking_triggered_cb", Dlc2_m01_triggers.armory_parking_location)
trigger_enable(Dlc2_m01_triggers.armory_parking_location, true)
-- Enable the trigger for the Armory Island
on_trigger("dlc2_m01_armory_island_entered_take1_cb", Dlc2_m01_triggers.armory_island)
on_trigger_exit("dlc2_m01_armory_island_exited_cb", Dlc2_m01_triggers.armory_island)
trigger_enable(Dlc2_m01_triggers.armory_island, true)
-- Wait until the player has reached the Armory
Dlc2_m01_runtime.reached_armory_parking_area_by = nil
while(Dlc2_m01_runtime.reached_armory_parking_area_by == nil) do
thread_yield()
end
dlc2_m01_go_to_armory_take1_cleanup(false)
end
-- Clean-up the "go to the armory" objective
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_go_to_armory_take1_cleanup(exiting)
-- Remove the marker at the Armory
marker_remove(Dlc2_m01_navpoints.armory_waypoint)
waypoint_remove(SYNC_ALL)
if (exiting == true) then
if (group_is_loaded(Dlc2_m01_groups.courtesy_veh_01.name) == true) then
-- If a player is in any of the courtesy vehicles, release that vehicle to the world
for i, vehicle in pairs(Dlc2_m01_groups.courtesy_veh_01.vehicles) do
for j, player in pairs(Dlc2_m01_player_list) do
if (character_is_in_vehicle(player, vehicle) == true) then
release_to_world(vehicle)
break
end
end
end
-- Destroy the courtesy vehicle group
group_destroy(Dlc2_m01_groups.courtesy_veh_01.name)
end
end
end
-- Initialization for the "resuce Kwilanna" objective (take1)
function dlc2_m01_armory_take1_initialize()
-- No longer required to reach parking area, so mark that as completed
Dlc2_m01_runtime.reached_armory_parking_area_by = LOCAL_PLAYER
dlc2_m01_go_to_armory_initialize_common()
dlc2_m01_armory_take1_initialize_common()
-- Disable parking spots
parking_spot_disable_all(true)
-- Disable Police notoriety
notoriety_force_no_spawn("Police", true)
-- Teleport the player's to the start navs
teleport_coop(Dlc2_m01_checkpoints.armory_take1.player_navs[1], Dlc2_m01_checkpoints.armory_take1.player_navs[2], true)
-- Load the film grain UI
dlc2_m01_load_film_grain()
-- Teleport Kwilanna
teleport(Dlc2_m01_characters.kwilanna, Dlc2_m01_navpoints.kwilanna_rescue_orient, true, false, 0.0, 0.0, 0.0, false)
end
-- Process the "go to the helipad" objective
function dlc2_m01_go_to_helipad_take1()
-- Set the objective text and add an object indicator at the Heliport
objective_text(0, Dlc2_m01_objectives.breach_heliport.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.breach_heliport.icon)
-- Add the marker at the helipad
marker_add(Dlc2_m01_navpoints.armory_location, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Play some dialog
Dlc2_m01_dialog_lines.armory_drive_end.persona = Dlc2_m01_runtime.reached_armory_parking_area_by
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.armory_drive_end, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.armory_arrive, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
-- Update the music
audio_object_post_event("Take_One")
-- Disable peds and vehicles
--spawning_pedestrians(false)
--spawning_vehicles(false)
-- Setup all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.helipad_take1) do
dlc2_m01_setup_rail_ambush(ambush)
end
-- Wait until the player reaches the Heli Pad
while(Dlc2_m01_runtime.entered_heli_pad == false) do
thread_yield()
end
dlc2_m01_go_to_helipad_take1_cleanup()
end
-- Clean-up the "go to the helipad" objective
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_go_to_helipad_take1_cleanup(exiting)
-- Remove the marker
marker_remove(Dlc2_m01_navpoints.armory_location)
-- Disable the Armory trigger volume
on_trigger("", Dlc2_m01_triggers.heli_pad_area)
on_trigger_exit("", Dlc2_m01_triggers.heli_pad_area)
trigger_enable(Dlc2_m01_triggers.heli_pad_area, false)
-- Disable the trigger for the parking location
on_trigger("", Dlc2_m01_triggers.armory_parking_location)
trigger_enable(Dlc2_m01_triggers.armory_parking_location, false)
-- Remove on_death callbacks for the tower guards
for i, guard in pairs(Dlc2_m01_groups.armory_take_01.tower_guards) do
on_death("", guard)
end
end
-- Process the "rescue Kwilanna" objective
function dlc2_m01_rescue_kwilanna_take1_process()
-- Set the objective text and add an object indicator at the Armory
objective_text(0, Dlc2_m01_objectives.rescue_kwilanna.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.rescue_kwilanna.icon)
marker_add(Dlc2_m01_characters.kwilanna, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
-- Enable the trigger to resuce Kwilanna
Dlc2_m01_runtime.rescued_kwilanna = false
trigger_enable(Dlc2_m01_triggers.rescue_kwilanna, true)
on_trigger("dlc2_m01_resuce_kwilanna_cb", Dlc2_m01_triggers.rescue_kwilanna)
-- Enable the trigger around kwilanna
Dlc2_m01_runtime.kwilanna_heli_radius_triggered = false
trigger_enable(Dlc2_m01_triggers.tgr_kwilanna_heli_radius, true)
on_trigger("dlc2_m01_kwilanna_heli_radius_cb", Dlc2_m01_triggers.tgr_kwilanna_heli_radius)
-- Register a callback for when the guards at the top of the stairs are damaged
for i, npc_table in pairs(Dlc2_m01_groups.stair_guard_take_01.chase_npcs) do
on_take_damage("dlc2_m01_stair_guard_damaged_cb", npc_table.npc)
end
-- Wait until a player triggers the resuce Kwilanna animation
while(Dlc2_m01_runtime.rescued_kwilanna == false) do
thread_yield()
end
dlc2_m01_rescue_kwilanna_take1_cleanup()
end
-- Clean-up the "rescue Kwilanna" objective
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_rescue_kwilanna_take1_cleanup(exiting)
-- Remove the marker
marker_remove(Dlc2_m01_characters.kwilanna)
-- Disable the trigger to rescue Kwilanna
on_trigger("", Dlc2_m01_triggers.rescue_kwilanna)
trigger_enable(Dlc2_m01_triggers.rescue_kwilanna, false)
-- Disable the trigger for the radius around Kwilanna's helicopter
on_trigger("", Dlc2_m01_triggers.tgr_kwilanna_heli_radius)
trigger_enable(Dlc2_m01_triggers.tgr_kwilanna_heli_radius, false)
-- Remove a callback for when the guards at the top of the stairs are damaged
for i, npc_table in pairs(Dlc2_m01_groups.stair_guard_take_01.chase_npcs) do
on_take_damage("", npc_table.npc)
end
end
-- Callback for when one of the guards at the top of the stairs is damaged
function dlc2_m01_stair_guard_damaged_cb(victim)
-- Activate the ambush callback for the stair guard group
dlc2_m01_ambush_activate_triggered_cb(LOCAL_PLAYER, Dlc2_m01_rail_ambushes.helipad_take1[2].activate_trigger)
end
-- Process the "take1 wrap" sequence, where the directory yells "Cut!" to reshoot this sequence
function dlc2_m01_armory_take1_wrap()
-- Wait for the conversation to finish (director yells cut at the end of the conversation
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_conversations.untie_kwilanna_take1) == false) do
thread_yield()
end
delay(0.5)
objective_text_clear(0)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.armory_take1_cut, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.armory_take1_wrap, DLC2_M01_CONVO_PLAY_LAST, 0.0)
-- Remove the film grain UI
dlc_gis_film_grain_unload()
delay(0.5)
-- Update the music
audio_object_post_event("Take_One_Cut")
-- Wipe all police notoriety
notoriety_reset("Police")
notoriety_set("Police", 0)
notoriety_set_max("Police", 0)
-- Make all NPCs idle, and make the Police team friendly with the Playas team
ai_force_team_idle("None")
team_make_allies("Police", "Playas")
-- Set Kwilanna's animation state
npc_combat_enable(Dlc2_m01_characters.kwilanna, false)
npc_leash_to_object(Dlc2_m01_characters.kwilanna, Dlc2_m01_runtime.kwilanna_rescued_by, 5.0)
-- Make Everyone Invulnerable
dlc2_m01_helper_set_kwilanna_invulnerable(true, false)
-- Manually update all the NPCs we directly spawning in the mission
for i, npc in pairs(Dlc2_m01_groups.armory_take_01.npcs) do
dlc2_m01_make_npc_idle(npc)
end
for i, npc_table in pairs(Dlc2_m01_groups.gate_gaurd_take_01.chase_npcs) do
dlc2_m01_make_npc_idle(npc_table.npc)
end
for i, npc_table in pairs(Dlc2_m01_groups.stair_guard_take_01.chase_npcs) do
dlc2_m01_make_npc_idle(npc_table.npc)
end
for i, npc in pairs(Dlc2_m01_groups.armory_camera_men.npcs) do
dlc2_m01_make_npc_idle(npc)
end
dlc2_m01_make_npc_idle(Dlc2_m01_groups.kwilanna_heli.heli.pilot)
-- Make the player's invulnerable and revive them if they're downed
for i, player in pairs(Dlc2_m01_player_list) do
if (human_is_downed(player) == true) then
player_revive(player)
end
turn_invulnerable(player)
end
-- Wait for the conversation to finish
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_conversations.armory_take1_wrap) == false) do
thread_yield()
end
-- Make sure kwilanna isn't downed
if (human_is_downed(Dlc2_m01_characters.kwilanna) == true) then
npc_revive(Dlc2_m01_characters.kwilanna)
end
-- Make sure none of the players are downed
for i, player in pairs(Dlc2_m01_player_list) do
if (human_is_downed(player) == true) then
player_revive(player)
end
end
delay(2.0)
dlc2_m01_armory_take1_wrap_cleanup(false)
end
-- Clean-up the "take1 wrap" sequence, where the directory yells "Cut!" to reshoot this sequence
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_armory_take1_wrap_cleanup(exiting)
-- Disable the trigger for the Armory Island
on_trigger("", Dlc2_m01_triggers.armory_island)
on_trigger_exit("", Dlc2_m01_triggers.armory_island)
trigger_enable(Dlc2_m01_triggers.armory_island, false)
-- Clean-up all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.helipad_take1) do
dlc2_m01_cleanup_rail_ambush(ambush)
end
-- Clean-up the cameramen
for i, npc in pairs(Dlc2_m01_groups.armory_camera_men.npcs) do
dlc2_m01_helper_cleanup_camera_man(npc)
end
npc_leash_remove(Dlc2_m01_characters.kwilanna)
-- Remove the players weapon load-out
dlc2_m01_helper_remove_temp_weapons(Dlc2_m01_tweak_values.armory_inventory_take1)
-- Clear the animation state
set_script_animation_state(Dlc2_m01_characters.kwilanna, nil)
end
function dlc2_m01_make_npc_idle(npc)
if (human_is_downed(npc) == true) then
npc_revive(npc)
end
--turn_invulnerable(npc)
npc_combat_enable(npc, false)
local behavior_idx = rand_int(1, 3)
if (behavior_idx == 1) then
wander_start(npc, nil, 50.0)
elseif (behavior_idx == 2) then
set_script_animation_state(npc, "bus loiter a")
elseif (behavior_idx == 3) then
set_script_animation_state(npc, "bus loiter d")
elseif (behavior_idx == 4) then
set_script_animation_state(npc, "cellphone c")
end
end
--[[
Checkpoint 02 - Rescue Kwilanna from the Armory (Take2)
--]]
-- Initialize the second take of the Armory seuqence
function dlc2_m01_go_to_armory_take2_initialize()
dlc2_m01_go_to_armory_initialize_common()
-- Create the script group for the second take
group_create(Dlc2_m01_groups.armory_take_02.name, true)
-- Put the gunners in all the manned vehicles
for i, manned_vehicle in pairs(Dlc2_m01_groups.armory_take_02.manned_vehicles) do
vehicle_suppress_npc_exit(manned_vehicle.vehicle, true)
vehicle_enter_teleport(manned_vehicle.gunner, manned_vehicle.vehicle, 1, true)
end
-- Lock all the helicopters
for i, heli in pairs(Dlc2_m01_groups.armory_take_02.helis) do
set_unjackable_flag(heli, true)
set_unenterable_for_player(heli, true)
end
-- Create the player's heli
group_create_hidden(Dlc2_m01_groups.armory_player_heli.name, true)
-- Create the escape vehicle
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints_hc
end
dlc2_m01_setup_escape_vehicle(veh_hitpoints)
set_unjackable_flag(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
set_unenterable_for_player(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
turn_invulnerable(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Setup the get away car drop off group
dlc2_m01_setup_get_away_car_drop_off_group()
-- Create the camera men helicopter
dlc2_m01_setup_heli_cameramen()
-- Setup the downtown camera men
dlc2_m01_setup_downtown_camera_men_01()
-- Disable gravity on the players
for i, player in pairs(Dlc2_m01_player_list) do
human_gravity_enable(player, false)
end
-- Teleport the player's to the start navs
teleport_coop(Dlc2_m01_checkpoints.armory_take2.player_navs[1], Dlc2_m01_checkpoints.armory_take2.player_navs[2], true)
-- Give the players weapon load-out
dlc2_m01_helper_give_temp_weapons(Dlc2_m01_tweak_values.armory_inventory_take2)
-- Setup the player's helicopter
vehicle_set_keyframed_physics(Dlc2_m01_groups.armory_player_heli.heli.vehicle, true)
turn_invulnerable(Dlc2_m01_groups.armory_player_heli.heli.vehicle)
turn_invulnerable(Dlc2_m01_groups.armory_player_heli.heli.pilot)
vehicle_suppress_npc_exit(Dlc2_m01_groups.armory_player_heli.heli.vehicle, true)
vehicle_enter_teleport(Dlc2_m01_groups.armory_player_heli.heli.pilot, Dlc2_m01_groups.armory_player_heli.heli.vehicle, 0, true)
set_ignore_ai_flag(Dlc2_m01_groups.armory_player_heli.heli.pilot, true)
set_dont_attack_me_on_sight_flag(Dlc2_m01_groups.armory_player_heli.heli.pilot, true)
radio_block(Dlc2_m01_groups.armory_player_heli.heli.vehicle)
set_unjackable_flag(Dlc2_m01_groups.armory_player_heli.heli.vehicle, true)
set_unenterable_for_player(Dlc2_m01_groups.armory_player_heli.heli.vehicle, true)
-- Show the helicopter and make it fly to it's hover navpoint
group_show(Dlc2_m01_groups.armory_player_heli.name)
thread_yield()
vehicle_enter_teleport(LOCAL_PLAYER, Dlc2_m01_groups.armory_player_heli.heli.vehicle, 5, true)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
if (coop_is_active() == true) then
vehicle_enter_teleport(REMOTE_PLAYER, Dlc2_m01_groups.armory_player_heli.heli.vehicle, 3, true)
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
end
-- Re-enable gravity on the players
for i, player in pairs(Dlc2_m01_player_list) do
human_gravity_enable(player, true)
end
-- Teleport Kwilanna
teleport(Dlc2_m01_characters.kwilanna, Dlc2_m01_navpoints.kwilanna_rescue_orient, true, false, 0.0, 0.0, 0.0, false)
-- Make sure all the world settings are correct
notoriety_reset("Police")
-- No longer required to reach parking area, so mark that as completed
Dlc2_m01_runtime.reached_armory_parking_area_by = LOCAL_PLAYER
end
-- Process the "go to the armory" objective (take2)
function dlc2_m01_go_to_armory_take2_process()
-- Enable the trigger for the Armory Island
on_trigger("dlc2_m01_armory_island_entered_take2_cb", Dlc2_m01_triggers.armory_island)
on_trigger_exit("dlc2_m01_armory_island_exited_cb", Dlc2_m01_triggers.armory_island)
trigger_enable(Dlc2_m01_triggers.armory_island, true)
-- Enable the trigger for the landing area
on_trigger("dlc2_m01_landing_area_cb", Dlc2_m01_triggers.player_landing_area)
trigger_enable(Dlc2_m01_triggers.player_landing_area, true)
-- Enable the trigger for the landing bulls eye (no on-enter callback)
trigger_enable(Dlc2_m01_triggers.player_landing_bulls_eye, true)
-- Enabled the trigger for the continuous explosion region
on_trigger("dlc2_m01_armory_cont_exp_entered_cb", Dlc2_m01_triggers.armory_cont_exp)
on_trigger_exit("dlc2_m01_armory_cont_exp_exited_cb", Dlc2_m01_triggers.armory_cont_exp)
trigger_enable(Dlc2_m01_triggers.armory_cont_exp, true)
-- Start continuous explosion
continuous_explosion_start("Dlc2_m01_armory", Dlc2_m01_navpoints.armory_location)
continuous_explosion_avoid_object_add(Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
for i, player in pairs(Dlc2_m01_player_list) do
continuous_explosion_avoid_object_add(player)
end
-- Play some dialog and wait for it to finish
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_parachute_obj, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.armory_take2_action, DLC2_M01_CONVO_PLAY_LAST, 0.0)
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_dialog_lines.armory_take2_action) == false) do
thread_yield()
end
-- Create the flares to guide the player
for i, vfx in pairs(Dlc2_m01_vfx.player_landing_flares) do
vfx.handle = effect_play(vfx.name, true)
end
-- Make the players vulnerable again
for i, player in pairs(Dlc2_m01_player_list) do
turn_vulnerable(player)
end
-- Load the film grain UI
dlc2_m01_load_film_grain()
delay(0.8)
-- Update the music
audio_object_post_event("Take_Two_Intro")
-- Set the player damage multipliers
for i, player in pairs(Dlc2_m01_player_list) do
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.armory_player_atk_mult_take2)
end
-- Prompt the players to jump out of the heli
hud_prompt(LOCAL_PLAYER, "DLC2_M01_HUD_JUMP", "dlc2_m01_player_jumped_local_cb")
player_supress_falling_scream(LOCAL_PLAYER)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
if (coop_is_active() == true) then
hud_prompt(REMOTE_PLAYER, "DLC2_M01_HUD_JUMP", "dlc2_m01_player_jumped_remote_cb")
player_supress_falling_scream(REMOTE_PLAYER)
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
end
-- Set the objective text and add an object indicator at the Armory
objective_text(0, Dlc2_m01_objectives.jump_from_heli.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.jump_from_heli.icon)
-- Disable peds and vehicles
--spawning_pedestrians(false)
--spawning_vehicles(false)
-- Wait until the player has reached the Heli Pad
Dlc2_m01_runtime.entered_heli_pad = false
while(Dlc2_m01_runtime.entered_heli_pad == false) do
thread_yield()
end
dlc2_m01_go_to_armory_take2_cleanup(false)
end
-- Clean-up the "go to the armory' objective (take2)
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_go_to_armory_take2_cleanup(exiting)
-- Remove the marker at the Armory
marker_remove(Dlc2_m01_navpoints.armory_location)
marker_remove(Dlc2_m01_vfx.player_landing_flares[1])
-- Disable the Armory trigger volume
on_trigger("", Dlc2_m01_triggers.heli_pad_area)
on_trigger_exit("", Dlc2_m01_triggers.heli_pad_area)
trigger_enable(Dlc2_m01_triggers.heli_pad_area, false)
-- Disable the trigger for the continuous explosion region
on_trigger("", Dlc2_m01_triggers.armory_cont_exp)
on_trigger_exit("", Dlc2_m01_triggers.armory_cont_exp)
trigger_enable(Dlc2_m01_triggers.armory_cont_exp, false)
-- Kill the armory explosion dialog thread
if (thread_check_done(Dlc2_m01_threads.armory_explosion_dialog) == false) then
thread_kill(Dlc2_m01_threads.armory_explosion_dialog)
Dlc2_m01_threads.armory_explosion_dialog = INVALID_THREAD_HANDLE
end
-- Stop the continuous explosion
continuous_explosion_stop()
end
-- Callback for when the local players jumps from the starting helicopter
function dlc2_m01_player_jumped_local_cb()
dlc2_m01_player_jumped_process(LOCAL_PLAYER)
end
-- Callback for when the remote players jumps from the starting helicopter
function dlc2_m01_player_jumped_remote_cb()
dlc2_m01_player_jumped_process(REMOTE_PLAYER)
end
function dlc2_m01_player_jumped_process(player)
if (Dlc2_m01_runtime.take_2_music_trigger == false) then
Dlc2_m01_runtime.take_2_music_trigger = true
-- Update the music
audio_object_post_event("Take_Two")
end
hud_prompt_clear(player)
vehicle_exit(player)
if (Dlc2_m01_runtime.player_jumped_from_heli == false) then
Dlc2_m01_runtime.player_jumped_from_heli = true
-- Set the objective text to land on the target
objective_text(0, Dlc2_m01_objectives.land_on_target.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.land_on_target.icon)
marker_add(Dlc2_m01_vfx.player_landing_flares[1], MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
delay(0.5)
Dlc2_m01_dialog_lines.player_parachute.persona = player
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.player_parachute, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
-- Callback for when the player enters the landing area for the second take at the armory
--
-- player: Name of the player that triggered this trigger
-- trigger: Name of the trigger
function dlc2_m01_landing_area_cb(player, trigger)
local landing_area_entered_prev = Dlc2_m01_runtime.player_entered_landing_area
Dlc2_m01_runtime.player_entered_landing_area = true
-- If this player has already triggered this trigger, then just return
if (player == LOCAL_PLAYER) then
if (Dlc2_m01_runtime.local_player_entered_landing_area == true) then
return
end
Dlc2_m01_runtime.local_player_entered_landing_area = true
else
if (Dlc2_m01_runtime.remote_player_entered_landing_area == true) then
return
end
Dlc2_m01_runtime.remote_player_entered_landing_area = true
end
-- Wait to see if the player enter's the landing area bulls eye
local elapsed_time = 0.0
while(elapsed_time < 5.0) do
-- If the player enters the bulls eye trigger, give them the achievement
if (object_is_in_trigger(Dlc2_m01_triggers.player_landing_bulls_eye, player) == true) then
hud_achievement_show_progress("No Stuntman Required", 1, 1, sync_from_player(player))
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_positive, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
break
end
elapsed_time = elapsed_time + get_frame_time()
thread_yield()
end
-- If this is the first time in the landing area, move the objective and marker
if (landing_area_entered_prev == false) then
-- Set enemeis to always see the player
for i, npc in pairs(Dlc2_m01_groups.armory_take_02.npcs) do
set_always_sees_player_flag(npc, true)
end
-- Set the objective text and add an object indicator at the Heliport
objective_text(0, Dlc2_m01_objectives.breach_heliport.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.breach_heliport.icon)
-- Move the marker
marker_remove(Dlc2_m01_vfx.player_landing_flares[1])
marker_add(Dlc2_m01_navpoints.armory_location, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
delay(3.0)
tutorial_start("weap_alt_fire", 5.0, true, true)
end
-- If there are no other players left to land, then remove the flares and tell the helicopter to fly off
if (landing_area_entered_prev == true or coop_is_active() == false) then
for i, vfx in pairs(Dlc2_m01_vfx.player_landing_flares) do
if (vfx.handle ~= -1) then
effect_stop(vfx.handle)
end
end
-- Disable the keyframe for the escape helicopter, and have it fly off
vehicle_set_keyframed_physics(Dlc2_m01_groups.armory_player_heli.heli.vehicle, false)
helicopter_enter_retreat(Dlc2_m01_groups.armory_player_heli.heli.vehicle)
release_to_world(Dlc2_m01_groups.armory_player_heli.heli.vehicle)
end
end
-- Callback when a player enters the armory cont explosoin trigger
function dlc2_m01_armory_cont_exp_entered_cb(player, trigger)
if (Dlc2_m01_runtime.armory_cont_exp_triggered_by == nil) then
Dlc2_m01_runtime.armory_cont_exp_triggered_by = player
-- Play some dialog
Dlc2_m01_threads.armory_explosion_dialog = thread_new("dlc2_m01_process_armory_explosion_dialog_thread", player)
end
continuous_explosion_follow_target_add(player)
end
-- Callback when a player exits the armory cont explosoin trigger
function dlc2_m01_armory_cont_exp_exited_cb(player, trigger)
continuous_explosion_follow_target_remove(player)
if (Dlc2_m01_runtime.armory_cont_exp_triggered_by == player) then
if (thread_check_done(Dlc2_m01_threads.armory_explosion_dialog) == false) then
thread_kill(Dlc2_m01_threads.armory_explosion_dialog)
Dlc2_m01_threads.armory_explosion_dialog = INVALID_THREAD_HANDLE
end
Dlc2_m01_runtime.armory_cont_exp_triggered_by = nil
end
end
-- Thread to process dialog for the armory continuous explosions
function dlc2_m01_process_armory_explosion_dialog_thread(player)
delay(3.0)
if (Dlc2_m01_dialog_lines.player_exp_callout_02.ended ~= true) then
Dlc2_m01_dialog_lines.player_exp_callout_02.persona = player
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.player_exp_callout_02, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
delay(8.0)
end
if (Dlc2_m01_dialog_lines.player_exp_callout_03.ended ~= true) then
Dlc2_m01_dialog_lines.player_exp_callout_03.persona = player
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.player_exp_callout_03, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
delay(12.0)
end
end
-- Process the "rescue Kwilanna" objective (take2)
function dlc2_m01_rescue_kwilanna_take2_process()
-- Set the objective text and add an object indicator at the Armory
objective_text(0, Dlc2_m01_objectives.rescue_kwilanna.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.rescue_kwilanna.icon)
marker_add(Dlc2_m01_characters.kwilanna, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
-- Enable the trigger to resuce Kwilanna
trigger_enable(Dlc2_m01_triggers.rescue_kwilanna, true)
on_trigger("dlc2_m01_resuce_kwilanna_cb", Dlc2_m01_triggers.rescue_kwilanna)
-- Enable the trigger around kwilanna
Dlc2_m01_runtime.kwilanna_heli_radius_triggered = false
trigger_enable(Dlc2_m01_triggers.tgr_kwilanna_heli_radius, true)
on_trigger("dlc2_m01_kwilanna_heli_radius_cb", Dlc2_m01_triggers.tgr_kwilanna_heli_radius)
-- Kick off a thread to process the helicopter drop off at the armory heli pad
Dlc2_m01_threads.armory_heli_drop_off = thread_new("dlc2_m01_process_helicopter_drop_off_thread", Dlc2_m01_groups.armory_drop_off)
-- Wait until a player triggers the resuce Kwilanna animation
Dlc2_m01_runtime.rescued_kwilanna = false
Dlc2_m01_runtime.kwilanna_rescued_by = nil
while(Dlc2_m01_runtime.rescued_kwilanna == false) do
thread_yield()
end
dlc2_m01_rescue_kwilanna_take2_cleanup()
end
-- Clean-up the "rescue Kwilanna" objective (take2)
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_rescue_kwilanna_take2_cleanup(exiting)
-- Remove the marker
marker_remove(Dlc2_m01_characters.kwilanna)
-- Remove the marker at the Armory
marker_remove(Dlc2_m01_navpoints.armory_location)
marker_remove(Dlc2_m01_vfx.player_landing_flares[1])
-- Disable the trigger to rescue Kwilanna
on_trigger("", Dlc2_m01_triggers.rescue_kwilanna)
trigger_enable(Dlc2_m01_triggers.rescue_kwilanna, false)
-- Disable the trigger for the radius around Kwilanna's helicopter
on_trigger("", Dlc2_m01_triggers.tgr_kwilanna_heli_radius)
trigger_enable(Dlc2_m01_triggers.tgr_kwilanna_heli_radius, false)
-- Clear the Jump prompt, if one of the players is still in the helicopter
for i, player in pairs(Dlc2_m01_player_list) do
hud_prompt_clear(player)
end
if (exiting == true) then
-- Remove the players weapon load-out
dlc2_m01_helper_remove_temp_weapons(Dlc2_m01_tweak_values.armory_inventory_take2)
end
end
-- Process the "get into the escape vehicle" objective (take2)
function dlc2_m01_get_in_escape_vehicle_process()
-- Set the objective text
objective_text(0, Dlc2_m01_objectives.get_in_helicopter.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.get_in_helicopter.icon)
-- Clear enemeis to always seeing the player
for i, npc in pairs(Dlc2_m01_groups.armory_take_02.npcs) do
set_always_sees_player_flag(npc, false)
end
-- Get the gang into the helicopter
dlc2_m01_helper_get_gang_into_vehicle(Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
-- Turn off police notoriety again
notoriety_force_no_spawn("Police", true)
-- Clean-up
dlc2_m01_get_in_escape_vehicle_cleanup(false)
end
-- Clean-up the "get into the escape vehicle" objective (take2)
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_get_in_escape_vehicle_cleanup(exiting)
-- Remove the marker
marker_remove(Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
-- Disable the trigger for the Armory Island
on_trigger("", Dlc2_m01_triggers.armory_island)
on_trigger_exit("", Dlc2_m01_triggers.armory_island)
trigger_enable(Dlc2_m01_triggers.armory_island, false)
-- Disable the trigger for the landing area
on_trigger("", Dlc2_m01_triggers.player_landing_area)
trigger_enable(Dlc2_m01_triggers.player_landing_area, false)
-- Disable the trigger for the landing bulls eye
trigger_enable(Dlc2_m01_triggers.player_landing_bulls_eye, false)
-- Enable peds and vehicles
--spawning_pedestrians(true)
--spawning_vehicles(true)
-- Unregister our callback for vehicle entry
on_vehicle_enter("", Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
on_vehicle_exit("", Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
end
--[[
Checkpoint 03 - Escape Sequence Rail Start
--]]
-- Initialize the escape start sequence
function dlc2_m01_escape_start_initialize()
-- Disable parking spots
parking_spot_disable_all(true)
-- Create some guys at the Armory helipad
group_create(Dlc2_m01_groups.kwilanna_heli.name, true)
group_create(Dlc2_m01_groups.armory_take_02, true)
-- Create the escape car (will be used when the heli crashes)
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints_hc
end
dlc2_m01_setup_escape_vehicle(veh_hitpoints)
-- Setup the get away car drop off group
dlc2_m01_setup_get_away_car_drop_off_group()
-- Setup the downtown camera men
dlc2_m01_setup_downtown_camera_men_01()
-- Create the camera men helicopter
dlc2_m01_setup_heli_cameramen()
-- Hide some characters at the armory, as they don't make sense when starting from the checkpoint
character_hide("npc_armory_take2_19")
-- Teleport the player's to the start navs
teleport_coop(Dlc2_m01_checkpoints.escape_start.player_navs[1], Dlc2_m01_checkpoints.escape_start.player_navs[2], true)
-- Make Kwilanna a homie
party_add(Dlc2_m01_characters.kwilanna, LOCAL_PLAYER)
on_dismiss("dlc2_m01_kwilanna_dismissed_cb", Dlc2_m01_characters.kwilanna)
-- Put eveyone into the helicopter
vehicle_suppress_npc_exit(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
vehicle_enter_teleport(Dlc2_m01_characters.kwilanna, Dlc2_m01_groups.kwilanna_heli.heli.vehicle, 0, true)
for i, player in pairs(Dlc2_m01_player_list) do
-- Clear the Jump prompt, if one of the players is still in the helicopter
hud_prompt_clear(player)
-- i starts at index 1, which coincidently is the seat we want to put the first player in
vehicle_enter_teleport(player, Dlc2_m01_groups.kwilanna_heli.heli.vehicle, i, true)
set_player_can_enter_exit_vehicles(player, false)
end
-- Set fake notoriety
hud_set_fake_notoriety("Police", true, Dlc2_m01_tweak_values.fake_notoriety_level)
-- Give the players weapon load-out
dlc2_m01_helper_give_temp_weapons(Dlc2_m01_tweak_values.armory_inventory_take2)
-- Load the film grain UI
dlc2_m01_load_film_grain()
-- Start music and say action
audio_object_post_event("Take_Two")
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_action, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
end
-- Process the escape start sequence
function dlc2_m01_escape_start_process()
-- Set the objective text and add an object indicator at the Saints HQ
objective_text(0, Dlc2_m01_objectives.escape_nat_guard.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.escape_nat_guard.icon)
marker_add(Dlc2_m01_navpoints.saints_hq, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_ALL)
-- Dont' allow anyone in the get away car to be pulled out
set_unjackable_flag(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
vehicle_set_keyframed_physics(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, false)
-- Make everyone in the car invulnerable, and set the player damage multipliers
dlc2_m01_helper_set_kwilanna_invulnerable(true, false)
for i, player in pairs(Dlc2_m01_player_list) do
turn_invulnerable(player)
if (difficulty_get_level() == 2) then
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_start_hc)
else
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_start)
end
character_ragdoll_set_last_valid_position(player, "nav_armory_get_away_stop", true)
end
character_ragdoll_set_last_resort_position("nav_armory_get_away_stop")
-- Enable the trigger for when the player's heli gets shot and when the player's should bail
trigger_enable(Dlc2_m01_triggers.player_heli_shot, true)
on_trigger("dlc2_m01_player_heli_shot_cb", Dlc2_m01_triggers.player_heli_shot)
-- Enable the trigger for when the players bail out of the heli
trigger_enable(Dlc2_m01_triggers.player_heli_bail, true)
on_trigger("dlc2_m01_player_heli_bail_cb", Dlc2_m01_triggers.player_heli_bail)
-- Enable trigger to call out helis
trigger_enable(Dlc2_m01_triggers.call_out_helis, true)
on_trigger("dlc2_m01_call_out_helis_cb", Dlc2_m01_triggers.call_out_helis)
-- Disable the armory island exit trigger
on_trigger_exit("", Dlc2_m01_triggers.armory_island)
-- Disable parking spawns
parking_spot_disable_all(true)
-- Setup all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.escape_start) do
dlc2_m01_setup_rail_ambush(ambush)
end
-- Set the armory camera persue heli going
thread_new("dlc2_m01_process_ambush_vehicle_thread", Dlc2_m01_groups.armory_camera_persue_heli.heli, "heli_path", -1, false, 1.0, true, Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
-- Disable Police notoriety
notoriety_force_no_spawn("Police", true)
-- Make the helicopter and escape humvee invulnerable
turn_invulnerable(Dlc2_m01_groups.armory_get_away_car.vehicle)
turn_invulnerable(Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
-- Play some dialog
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.player_heli_escape_start, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
-- Fly the helicopter path
helicopter_set_dont_use_constraints(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, false)
helicopter_fly_to_direct_dont_stop(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, 100, "path_player_rail_heli_01")
helicopter_fly_to_direct_dont_stop(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, 100, "path_player_rail_heli_02")
-- Make it crash
Dlc2_m01_threads.player_heli_crash = thread_new("dlc2_m01_process_play_heli_crash_thread")
-- Cleanup
dlc2_m01_escape_start_cleanup(false)
end
-- Cleanup the escape start seqeunce
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_escape_start_cleanup(exiting)
-- Remove the marker
marker_remove(Dlc2_m01_navpoints.saints_hq)
-- Clean-up the cameramen
for i, npc in pairs(Dlc2_m01_groups.armory_camera_men.npcs) do
dlc2_m01_helper_cleanup_camera_man(npc)
end
-- The players are now outside of the armory, so it's safe to clean up some script groups to make room for more awesome
if (group_is_loaded(Dlc2_m01_groups.courtesy_veh_01.name) == true) then
group_destroy(Dlc2_m01_groups.courtesy_veh_01.name)
end
if (group_is_loaded(Dlc2_m01_groups.armory_take_02.name) == true) then
group_destroy(Dlc2_m01_groups.armory_take_02.name)
end
if (group_is_loaded(Dlc2_m01_groups.armory_drop_off.name) == true) then
group_destroy(Dlc2_m01_groups.armory_drop_off.name)
end
if (group_is_loaded(Dlc2_m01_groups.armory_camera_men.name) == true) then
group_destroy(Dlc2_m01_groups.armory_camera_men.name)
end
if (group_is_loaded(Dlc2_m01_groups.armory_car_husks.name) == true) then
group_destroy(Dlc2_m01_groups.armory_car_husks.name)
end
-- Clean-up the car husk VFX
for i, vfx in pairs(Dlc2_m01_vfx.car_husks) do
if (vfx.handle ~= -1) then
effect_stop(vfx.handle)
vfx.handle = -1
end
end
-- Clean-up all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.escape_start) do
dlc2_m01_cleanup_rail_ambush(ambush)
end
-- Disable the trigger for when the player's heli gets shot
trigger_enable(Dlc2_m01_triggers.player_heli_shot, false)
on_trigger("", Dlc2_m01_triggers.player_heli_shot)
trigger_enable(Dlc2_m01_triggers.player_heli_bail, false)
on_trigger("", Dlc2_m01_triggers.player_heli_bail)
-- Disable trigger to call out helis
trigger_enable(Dlc2_m01_triggers.call_out_helis, false)
on_trigger("", Dlc2_m01_triggers.call_out_helis)
end
-- Callback when the player's helicopter enter's the trigger where the helicopter is shot down
function dlc2_m01_player_heli_shot_cb()
if (Dlc2_m01_runtime.heli_shot_down == false) then
Dlc2_m01_runtime.heli_shot_down = true
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true, false)
Dlc2_m01_vfx.player_heli_fire.handle = effect_play_on_script_object(Dlc2_m01_vfx.player_heli_fire.name, Dlc2_m01_groups.kwilanna_heli.heli.vehicle, "exhaust", true)
-- Update the music
audio_object_post_event("Heli_Crash")
delay(0.5)
-- Play some dialog
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.player_heli_shot, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
thread_yield()
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.player_heli_crash, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
delay(25.0)
effect_stop(Dlc2_m01_vfx.player_heli_fire.handle)
end
end
-- Callback when the players should bail from the escape helicopter
function dlc2_m01_player_heli_bail_cb()
trigger_enable(Dlc2_m01_triggers.player_heli_bail, false)
for i, player in pairs(Dlc2_m01_player_list) do
set_player_can_enter_exit_vehicles(player, true)
vehicle_exit_do(player, false, true, true)
character_ragdoll(player, 1500)
turn_vulnerable(player)
end
end
-- Callback when the trigger to call out helis is it
function dlc2_m01_call_out_helis_cb()
if (Dlc2_m01_runtime.called_out_helis == false) then
Dlc2_m01_runtime.called_out_helis = true
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.heli_call_out, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
-- Thread to process the helicopter crash
function dlc2_m01_process_play_heli_crash_thread()
-- Make everyone bail from the helicopter
vehicle_suppress_npc_exit(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, false)
vehicle_exit_do(Dlc2_m01_characters.kwilanna, false, true, true)
character_set_never_catch_fire(Dlc2_m01_characters.kwilanna, true)
character_ragdoll(Dlc2_m01_characters.kwilanna, 2000)
delay(3.0)
turn_vulnerable(Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true, true)
delay(5.0)
character_set_never_catch_fire(Dlc2_m01_characters.kwilanna, false)
dlc2_m01_helper_set_kwilanna_invulnerable(false)
end
-- Process the armory take2 wrap
function dlc2_m01_process_armory_take2_wrap()
-- Clear objective text
objective_text_clear(0)
-- Enable the trigger to keep the player at the crash site
trigger_enable(Dlc2_m01_triggers.player_heli_crash_area, true)
Dlc2_m01_threads.heli_crash_area = thread_new("dlc2_m01_keep_players_in_crash_area_thread")
npc_combat_enable(Dlc2_m01_characters.kwilanna, false)
-- Add the radius to the minimap
minimap_icon_add_radius("nav_armory_get_away_stop", trigger_get_radius(Dlc2_m01_triggers.player_heli_crash_area))
delay(3.0)
character_ragdoll_clear_last_resort_position()
-- Play some dialog
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.player_heli_downed, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_conversations.player_heli_downed) == false) do
thread_yield()
end
-- Director yells cut
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.director_cut_good, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
delay(1.0)
dlc_gis_film_grain_unload()
audio_object_post_event("Cut")
-- Make Kwilanna invulnerable
dlc2_m01_helper_set_kwilanna_invulnerable(true, false)
-- Manually update all the NPCs we directly spawning in the mission
for i, npc in pairs(Dlc2_m01_groups.dt_camera_men_01.npcs) do
dlc2_m01_make_npc_idle(npc)
end
-- Make the player's invulnerable and revive them if they're downed
for i, player in pairs(Dlc2_m01_player_list) do
if (human_is_downed(player) == true) then
player_revive(player)
end
turn_invulnerable(player)
end
delay(0.5)
-- Wait for the dialog to finish
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_conversations.director_cut_good) == false) do
thread_yield()
end
while(Dlc2_m01_runtime.player_outside_crash_area == true) do
thread_yield()
end
dlc2_m01_cleanup_armory_take2_wrap()
end
-- Clean-up the armory take 2 wrap
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_cleanup_armory_take2_wrap(exiting)
-- Disable the trigger for the crash area
trigger_enable(Dlc2_m01_triggers.player_heli_crash_area, false)
if (thread_check_done(Dlc2_m01_threads.heli_crash_area) == false) then
thread_kill(Dlc2_m01_threads.heli_crash_area)
end
minimap_icon_remove_radius("nav_armory_get_away_stop")
end
-- Thread to process the critical timer if either player leaves the heli crash area
function dlc2_m01_keep_players_in_crash_area_thread()
Dlc2_m01_runtime.player_outside_crash_area = false
while(true) do
if (object_is_in_trigger(Dlc2_m01_triggers.player_heli_crash_area, LOCAL_PLAYER) == true and (coop_is_active() == false or object_is_in_trigger(Dlc2_m01_triggers.player_heli_crash_area, REMOTE_PLAYER) == true) ) then
if (Dlc2_m01_runtime.player_outside_crash_area == true) then
hud_critical_timer_stop()
Dlc2_m01_runtime.player_outside_crash_area = false
end
else
if (Dlc2_m01_runtime.player_outside_crash_area == false) then
hud_critical_timer_set(10000, "DLC2_M02_OBJ_MISSION_START", "dlc2_m01_player_disobey_failure_cb")
Dlc2_m01_runtime.player_outside_crash_area = true
end
end
thread_yield()
end
end
-- Process stealing the Humvee
function dlc2_m01_process_steal_humvee()
-- Load the film grain
delay(1.0)
dlc2_m01_load_film_grain()
delay(0.8)
-- Update the music
audio_object_post_event("Action_02")
-- Mark Kwilanna vulnerable again
dlc2_m01_helper_set_kwilanna_invulnerable(false)
npc_combat_enable(Dlc2_m01_characters.kwilanna, true)
-- Make all the cameramen active again
for i, npc in pairs(Dlc2_m01_groups.dt_camera_men_01.npcs) do
npc_combat_enable(npc, true)
turn_vulnerable(npc)
set_script_animation_state(npc, nil)
end
-- Make the player's invulnerable and revive them if they're downed
for i, player in pairs(Dlc2_m01_player_list) do
turn_vulnerable(player)
end
vehicle_show(Dlc2_m01_groups.armory_get_away_car.vehicle)
group_show(Dlc2_m01_groups.dt_get_away_car_drop_off.name)
-- Drive the Humvee to the helicopter crash site
set_unenterable_for_player(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_pathfind_to(Dlc2_m01_groups.armory_get_away_car.vehicle, Dlc2_m01_groups.dt_get_away_car_drop_off.path, true, true) -- navmesh pathfind, stop at goal
ai_add_enemy_target(Dlc2_m01_characters.kwilanna, Dlc2_m01_groups.dt_get_away_car_drop_off.npcs[1], ATTACK_NOW_NEVER_LOSE)
-- Make eveyone vulnerable
for i, npc in pairs(Dlc2_m01_groups.dt_get_away_car_drop_off.npcs) do
set_ignore_ai_flag(npc, false)
turn_vulnerable(npc)
end
-- Play some dialog about stealing the humvee
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.take_car, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
vehicle_exit_group(Dlc2_m01_groups.dt_get_away_car_drop_off.npcs)
-- Set the objective text and make the enemies in the humvee mission targets (objective)
objective_text(0, Dlc2_m01_objectives.kill_nat_guard.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.kill_nat_guard.icon)
process_enemy_set(Dlc2_m01_groups.dt_get_away_car_drop_off.npcs)
delay(1.0)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_positive, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
-- Set the objective text to get into the Humvee
objective_text(0, Dlc2_m01_objectives.get_in_escape_vehicle.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.get_in_escape_vehicle.icon)
-- Make everyone get into the Humvee
dlc2_m01_helper_get_gang_into_vehicle(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Make the Humvee vulnerable
turn_vulnerable(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Disable combat for Kwilanna again
npc_combat_enable(Dlc2_m01_characters.kwilanna, false)
-- Clean-up
dlc2_m01_cleanup_steal_humvee(false)
end
-- Cleanup the escape start seqeunce
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_cleanup_steal_humvee(exiting)
-- Remove the callback and marker on the humvee
marker_remove(Dlc2_m01_groups.armory_get_away_car.vehicle)
on_vehicle_enter("", Dlc2_m01_groups.armory_get_away_car.vehicle)
on_vehicle_exit("", Dlc2_m01_groups.armory_get_away_car.vehicle)
end
function dlc2_m01_setup_get_away_car_drop_off_group()
vehicle_hide(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Create the NG enemies and place them in the escape vehicle
group_create_hidden(Dlc2_m01_groups.dt_get_away_car_drop_off.name, true)
vehicle_enter_group_teleport(Dlc2_m01_groups.dt_get_away_car_drop_off.npcs, Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Show the vehicle and character and make the characters invulnerable
for i, npc in pairs(Dlc2_m01_groups.dt_get_away_car_drop_off.npcs) do
set_ignore_ai_flag(npc, true)
turn_invulnerable(npc)
end
end
--[[
Checkpoint 04 - Downtown Rail Sequence 02 (north island)
--]]
-- Initialize the second downtown rail section (north island)
function dlc2_m01_rail_dt_02_initialize()
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints_hc
end
-- Do common rail setup
dlc2_m01_setup_rail_common(Dlc2_m01_checkpoints.rail_dt_02.player_navs, Dlc2_m01_navpoints.player_vehicle_chk04, true, veh_hitpoints)
-- Update the music
audio_object_post_event("To_The_Bridge")
Dlc2_m01_runtime.played_to_bridge_music = true
-- Yell action
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_action, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
end
-- Process the second downtown rail section (north island)
function dlc_m01_rail_sequence_dt_loop_02_process()
-- Change the objective text
objective_text(0, Dlc2_m01_objectives.destroy_pursuers.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.destroy_pursuers.icon)
-- Setup all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.dt_island_02) do
dlc2_m01_setup_rail_ambush(ambush)
end
-- Set the player attack multiplier
for i, player in pairs(Dlc2_m01_player_list) do
if (difficulty_get_level() == 2) then
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_dt2_hc)
else
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_dt2)
end
end
-- Setup the two conversation triggers
on_trigger("dlc2_m01_assault_drive_01_cb", Dlc2_m01_triggers.convo_assault_drive_01)
trigger_enable(Dlc2_m01_triggers.convo_assault_drive_01, true)
on_trigger("dlc2_m01_assault_drive_02_cb", Dlc2_m01_triggers.convo_assault_drive_02)
trigger_enable(Dlc2_m01_triggers.convo_assault_drive_02, true)
-- Kick of a thread to process the player's rail path
Dlc2_m01_threads.rail_loop_process = thread_new("dlc2_m01_process_rail_loop", Dlc2_m01_rail_loops.dt_island_02)
delay(3.0)
-- Enable parking spawns
parking_spot_disable_all(false)
-- Destroy the dt cameramen 01 group (cannot be release to world since they have a mission only wepaon equipped)
for i, npc in pairs(Dlc2_m01_groups.dt_camera_men_01.npcs) do
dlc2_m01_helper_cleanup_camera_man(npc)
end
if (group_is_loaded(Dlc2_m01_groups.dt_camera_men_01.name) == true) then
group_destroy(Dlc2_m01_groups.dt_camera_men_01.name)
end
-- Create the dt camera men 02 group
group_create(Dlc2_m01_groups.dt_camera_men_02.name, true)
for i, npc in pairs(Dlc2_m01_groups.dt_camera_men_02.npcs) do
dlc2_m01_helper_setup_camera_man(npc)
end
delay(12.0)
-- Delay a little bit and then start notoriety spawning
notoriety_force_no_spawn("Police", false)
notoriety_set_min_and_max("Police", Dlc2_m01_tweak_values.dt_police_notoriety, Dlc2_m01_tweak_values.dt_police_notoriety)
-- Start the rail explosions
dlc2_m01_helper_setup_rail_explosions()
-- Wait for the rail pathfind to finish
while(thread_check_done(Dlc2_m01_threads.rail_loop_process) == false) do
thread_yield()
end
-- Clean-up this portion of the mission
dlc_m01_rail_sequence_dt_loop_02_cleanup(false)
end
-- Clean-up the second downtown rail section (north island)
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc_m01_rail_sequence_dt_loop_02_cleanup(exiting)
-- Clean-up all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.dt_island_02) do
dlc2_m01_cleanup_rail_ambush(ambush)
end
-- Destroy the dt cameramen 01 group (cannot be release to world since they have a mission only wepaon equipped)
for i, npc in pairs(Dlc2_m01_groups.dt_camera_men_01.npcs) do
dlc2_m01_helper_cleanup_camera_man(npc)
end
if (group_is_loaded(Dlc2_m01_groups.dt_camera_men_01.name) == true) then
group_destroy(Dlc2_m01_groups.dt_camera_men_01.name)
end
-- Disable the two conversation triggers
on_trigger("", Dlc2_m01_triggers.convo_assault_drive_01)
trigger_enable(Dlc2_m01_triggers.convo_assault_drive_01, false)
on_trigger("", Dlc2_m01_triggers.convo_assault_drive_02)
trigger_enable(Dlc2_m01_triggers.convo_assault_drive_02, false)
end
-- Callback for the assault drive convo trigger 01
function dlc2_m01_assault_drive_01_cb()
if (Dlc2_m01_runtime.assult_drive_convo_01_triggered == false) then
Dlc2_m01_runtime.assult_drive_convo_01_triggered = true
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.humvee_driving_01, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
-- Callback for the assault drive convo trigger 02
function dlc2_m01_assault_drive_02_cb()
if (Dlc2_m01_runtime.assult_drive_convo_02_triggered == false) then
Dlc2_m01_runtime.assult_drive_convo_02_triggered = true
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.humvee_driving_02, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
--[[
Checkpoint 05 - Alien ambush and NW rail section
--]]
-- Initialize the alien ambush
function dlc2_m01_alien_ambush_initialize()
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_hitpoints_hc
end
-- Do common rail setup
dlc2_m01_setup_rail_common(Dlc2_m01_checkpoints.alien_ambush.player_navs, Dlc2_m01_navpoints.player_vehicle_chk05, true, veh_hitpoints)
end
-- Process the alien ambush
function dlc2_m01_alien_ambush_process()
-- Disable police notoriety spawns
notoriety_force_no_spawn("Police", true)
-- Setup all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.alien_ambush) do
dlc2_m01_setup_rail_ambush(ambush)
end
-- Kick of a thread to process the player's rail path
Dlc2_m01_threads.rail_loop_process = thread_new("dlc2_m01_process_rail_loop", Dlc2_m01_rail_loops.alien_ambush)
-- Create the NG roadblock
group_create_hidden(Dlc2_m01_groups.ng_bridge_roadblock.name, true)
for i, vehicle_table in pairs(Dlc2_m01_groups.ng_bridge_roadblock.vehicles) do
vehicle_suppress_npc_exit(vehicle_table.vehicle, true)
vehicle_enter_group_teleport(vehicle_table.npcs, vehicle_table.vehicle)
vehicle_disable_chase(vehicle_table.vehicle, true)
vehicle_disable_flee(vehicle_table.vehicle, true)
vehicle_prevent_explosion_fling(vehicle_table.vehicle, true)
turn_invulnerable(vehicle_table.vehicle, true)
-- If this is a helicopter, make it go idle (so it won't fall)
if (get_vehicle_type(vehicle_table.vehicle) == VT_HELICOPTER) then
helicopter_fly_to_do(vehicle_table.vehicle, -1, true, "", false, vehicle_table.hover_nav)
end
end
group_show(Dlc2_m01_groups.ng_bridge_roadblock.name)
-- Create the Alien Ambush group
group_create_hidden(Dlc2_m01_groups.alien_bridge_ambush.name, true)
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
vehicle_suppress_npc_exit(vehicle_table.vehicle, true)
vehicle_enter_group_teleport(vehicle_table.npcs, vehicle_table.vehicle)
vehicle_disable_chase(vehicle_table.vehicle, true)
vehicle_disable_flee(vehicle_table.vehicle, true)
turn_invulnerable(vehicle_table.vehicle, true)
for i, npc in pairs(vehicle_table.npcs) do
turn_invulnerable(npc, true)
end
end
-- Create the camera men
group_create(Dlc2_m01_groups.nw_cameramen_01.name, false) -- don't block
group_create(Dlc2_m01_groups.nw_cameramen_02.name, false) -- don't block
-- Wait until the alien ambush has been triggered
while(thread_check_done(Dlc2_m01_threads.rail_loop_process) == false) do
thread_yield()
end
dlc2_m01_helper_stop_rail_explosions()
-- Stop the player's vehicle and make it invulnerable
vehicle_speed_cancel(Dlc2_m01_groups.armory_get_away_car.vehicle)
vehicle_stop(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
turn_invulnerable(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- because the player is not driving, vehicle_stop is not clearing the accelerator,
-- causing audio squeals. Make sure it is stopped.
vehicle_freeze(Dlc2_m01_groups.armory_get_away_car.vehicle)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.bridge_roadblock, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
delay(1.0)
-- If the player's vehicle is on fire, then just blow them up now (it's weird if they die in the camera cut)
local smoking, fire = vehicle_get_smoke_and_fire_state(Dlc2_m01_groups.armory_get_away_car.vehicle)
if (fire == true) then
turn_vulnerable(Dlc2_m01_groups.armory_get_away_car.vehicle)
vehicle_detonate(Dlc2_m01_groups.armory_get_away_car.vehicle)
while(true) do
thread_yield()
end
else
-- Repair the player's vehicle (if they're not already on fire)
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints_hc
end
set_max_hit_points(Dlc2_m01_groups.armory_get_away_car.vehicle, veh_hitpoints, true)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.armory_get_away_car.vehicle, false, false)
end
camera_look_through("nav_camera_look_through", 1.0)
delay(4.0)
-- Make all of the alien spacecraft fade in and fire at their target navpoints
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
-- Fade in the vehicle and show the NPCs
vehicle_show(vehicle_table.vehicle, true, 1.0)
for j, npc in pairs(vehicle_table.npcs) do
character_show(npc)
end
-- Fly towards the player
helicopter_fly_to_do(vehicle_table.vehicle, 5, true, "", false, vehicle_table.fly_to_nav)
-- Wait just a tad to stagger the planes warping in
delay(0.5)
end
-- Teleport the player's vehicle so it is orientated correctly
teleport_vehicle(Dlc2_m01_groups.armory_get_away_car.vehicle, "nav_player_rail_nw_01 005")
-- Update the music
audio_object_post_event("Alien_Invasion")
-- Process all the explosions for alien ambush
Dlc2_m01_threads.alien_ambush_explosions = thread_new("dlc2_m01_alien_ambush_process_explosions")
while(thread_check_done(Dlc2_m01_threads.alien_ambush_explosions) == false) do
thread_yield()
end
delay(2.0)
-- Go hostile towards the player
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
turn_vulnerable(vehicle_table.vehicle)
for j, npc in pairs(vehicle_table.npcs) do
set_attack_player_flag(npc, true)
ai_add_enemy_target(npc, LOCAL_PLAYER, ATTACK_NOW_NEVER_LOSE)
turn_vulnerable(npc)
end
thread_new("dlc2_m01_alien_ambush_process_alien_fire", vehicle_table.vehicle, Dlc2_m01_groups.armory_get_away_car.vehicle, 4.0)
vehicle_disable_chase(vehicle_table.vehicle, false)
end
delay(1.0)
camera_end_look_through(false)
--Make the alien spacecraft fly their chase paths
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
vehicle_table.thread_id = thread_new("dlc2_m01_process_ambush_vehicle_thread", vehicle_table, "heli_follow", -1, false, Dlc2_m01_tweak_values.alien_default_hp_mult, true)
end
delay(1.0)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_positive, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
turn_vulnerable(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Play some dialog
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.aliens_attack, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
-- Clean-up the alien ambush
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_alien_ambush_cleanup(exiting)
-- Clean-up all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.alien_ambush) do
dlc2_m01_cleanup_rail_ambush(ambush)
end
-- Destroy the DT camera men group (cannot be release to world since they have a mission only wepaon equipped)
for i, npc in pairs(Dlc2_m01_groups.dt_camera_men_02.npcs) do
dlc2_m01_helper_cleanup_camera_man(npc)
end
if (group_is_loaded(Dlc2_m01_groups.dt_camera_men_02.name) == true) then
group_destroy(Dlc2_m01_groups.dt_camera_men_02.name)
end
camera_end_look_through(true)
-- Release the NG roadblock groups to the world
release_to_world(Dlc2_m01_groups.ng_bridge_roadblock.name)
end
-- Process the alien spacecraft firing
function dlc2_m01_alien_ambush_process_alien_fire(alien_vehicle, target_veh, fire_time, radius, shot_delay, pulse_time, pulse_delay)
if (radius == nil) then
radius = 3.5
end
if (shot_delay == nil) then
shot_delay = 0.1
end
if (pulse_time == nil) then
pulse_time = 1.0
end
if (pulse_delay == nil) then
pulse_delay = 0.5
end
local elapsed_time = 0.0
while(elapsed_time < fire_time and vehicle_is_destroyed(alien_vehicle) == false) do
local pulse_elapsed_time = 0.0
while(pulse_elapsed_time < pulse_time and vehicle_is_destroyed(alien_vehicle) == false) do
helicopter_shoot_vehicle(alien_vehicle, target_veh, true, radius, true)
pulse_elapsed_time = pulse_elapsed_time + get_frame_time()
elapsed_time = elapsed_time + get_frame_time()
delay(shot_delay)
end
delay(pulse_delay)
end
end
-- Thread to proces all the things that go boom at the NG roadblock on the bridge
function dlc2_m01_alien_ambush_process_explosions()
-- Make all of the alien craft fire at their target navpoints
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
thread_new("dlc2_m01_alien_ambush_process_alien_fire", vehicle_table.vehicle, Dlc2_m01_groups.ng_bridge_roadblock.vehicles[i].vehicle, 8.0)
delay(0.15)
end
delay(0.25)
-- Start some smoke
Dlc2_m01_vfx.bridge_smoke[1].handle = effect_play(Dlc2_m01_vfx.bridge_smoke[1].name, true)
Dlc2_m01_vfx.bridge_smoke[2].handle = effect_play(Dlc2_m01_vfx.bridge_smoke[2].name, true)
-- Make a heli crash and burn
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[8].vehicle)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[8].vehicle, true, true)
-- Pause before first explosion
delay(1.75)
-- First explosion flings SUV 04
vehicle_prevent_explosion_fling(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[6].vehicle, false)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[6].vehicle, true, true)
delay(0.1)
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[6].vehicle)
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[1], nil, false)
delay(0.3)
-- Create the second explosions
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[2], nil, false)
-- Create the third explosion which detontates SUV 02
vehicle_prevent_explosion_fling(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle, false)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle, true, true)
delay(0.1)
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle)
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[3], nil, false)
delay(0.1)
-- Make a heli crash and burn
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[7].vehicle)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[7].vehicle, true, true)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.car_chase_explosions, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
-- Explosion 4 kills tank2
vehicle_prevent_explosion_fling(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[2].vehicle, false)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[2].vehicle, true, true)
delay(0.1)
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[2].vehicle)
vehicle_detonate(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[2].vehicle)
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[4], nil, false)
delay(0.3)
-- Hide the tank corpse
vehicle_hide(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[2].vehicle)
-- Explosion 5 kills tank1 and other SUV
vehicle_prevent_explosion_fling(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[1].vehicle, false)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[1].vehicle, true, true)
delay(0.1)
vehicle_prevent_explosion_fling(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle, false)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle, true, true)
delay(0.1)
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[1].vehicle)
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle)
vehicle_detonate(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[1].vehicle)
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[5], nil, false)
delay(0.2)
-- Explosion 6
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[6], nil, false)
delay(0.1)
-- Hide the tank corpse
vehicle_hide(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[1].vehicle)
-- Explosion 7 kills lsat SUV
vehicle_prevent_explosion_fling(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[5].vehicle, false)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[5].vehicle, true, true)
delay(0.1)
turn_vulnerable(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[5].vehicle)
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[7], nil, false)
delay(0.2)
-- Explosion 8
explosion_create("Medium Bang", Dlc2_m01_navpoints.alien_ambush_explosions[8], nil, false)
end
-- Callback for when the alien ambush trigger is triggered
function dlc2_m01_alien_ambush_triggered_cb()
Dlc2_m01_runtime.alien_ambush_triggered = true
end
-- Initialize the alien ambush
function dlc2_m01_rail_nw_01_initialize()
-- Create the roadblock group
group_create_hidden(Dlc2_m01_groups.ng_bridge_roadblock.name, true)
-- Setup the alein abmush group
group_create_hidden(Dlc2_m01_groups.alien_bridge_ambush.name, true)
-- Create the camera men
group_create(Dlc2_m01_groups.nw_cameramen_01.name, true)
group_create(Dlc2_m01_groups.nw_cameramen_02.name, true)
-- Start some smoke
Dlc2_m01_vfx.bridge_smoke[1].handle = effect_play(Dlc2_m01_vfx.bridge_smoke[1].name, true)
Dlc2_m01_vfx.bridge_smoke[2].handle = effect_play(Dlc2_m01_vfx.bridge_smoke[2].name, true)
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints_hc
end
-- Do common rail setup
dlc2_m01_setup_rail_common(Dlc2_m01_checkpoints.rail_nw_01.player_navs, Dlc2_m01_navpoints.player_vehicle_chk06, true, veh_hitpoints)
-- Unhide a few of the roadblock vehicles and turn them to corpses
vehicle_show(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[2].vehicle)
vehicle_make_corpse(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[2].vehicle, true)
vehicle_show(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle)
vehicle_make_corpse(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[3].vehicle, true)
vehicle_show(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[5].vehicle)
vehicle_make_corpse(Dlc2_m01_groups.ng_bridge_roadblock.vehicles[5].vehicle, true)
-- Make the aliens fly at the player
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
vehicle_table.delay = 0 -- override the delay to 0
teleport_vehicle(vehicle_table.vehicle, vehicle_table.fly_to_nav)
vehicle_table.thread_id = thread_new("dlc2_m01_process_ambush_vehicle_thread", vehicle_table, "heli_follow", -1, false, Dlc2_m01_tweak_values.alien_default_hp_mult)
end
-- Release the NG roadblock groups to the world
release_to_world(Dlc2_m01_groups.ng_bridge_roadblock.name)
-- Update the music
audio_object_post_event("Alien_Invasion")
-- Say action
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_action, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
end
-- Process the alien ambush
function dlc_m01_rail_sequence_nw_loop_process()
-- Setup all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.nw_island) do
dlc2_m01_setup_rail_ambush(ambush)
end
notoriety_force_no_spawn("Police", true)
ambient_cop_spawn_enable(false)
-- Set the player attack multiplier
for i, player in pairs(Dlc2_m01_player_list) do
if (difficulty_get_level() == 2) then
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_nw_hc)
else
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_nw)
end
end
-- Enable the trigger for the assault drive conversation
on_trigger("dlc2_m01_assault_drive_03_cb", Dlc2_m01_triggers.convo_assault_drive_03)
trigger_enable(Dlc2_m01_triggers.convo_assault_drive_03, true)
-- Kick of a thread to process the player's rail path
Dlc2_m01_threads.rail_loop_process = thread_new("dlc2_m01_process_rail_loop", Dlc2_m01_rail_loops.nw_island)
-- Setup the camera men
while (group_create_check_done(Dlc2_m01_groups.nw_cameramen_01.name) == false) do
thread_yield()
end
for i, npc in pairs(Dlc2_m01_groups.nw_cameramen_01.npcs) do
dlc2_m01_helper_setup_camera_man(npc)
end
-- Setup the camera men
while (group_create_check_done(Dlc2_m01_groups.nw_cameramen_02.name) == false) do
thread_yield()
end
for i, npc in pairs(Dlc2_m01_groups.nw_cameramen_02.npcs) do
dlc2_m01_helper_setup_camera_man(npc)
end
-- Wait until the player has reached the end of the path
while(thread_check_done(Dlc2_m01_threads.rail_loop_process) == false) do
thread_yield()
end
-- Clean-up this section
dlc_m01_rail_sequence_nw_loop_cleanup(false)
end
-- Clean-up the alien ambush
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc_m01_rail_sequence_nw_loop_cleanup(exiting)
-- Disable the conversation trigger
on_trigger("", Dlc2_m01_triggers.convo_assault_drive_03)
trigger_enable(Dlc2_m01_triggers.convo_assault_drive_03, false)
end
-- Callback for the assault drive convo trigger 03
function dlc2_m01_assault_drive_03_cb()
if (Dlc2_m01_runtime.assult_drive_convo_03_triggered == false) then
Dlc2_m01_runtime.assult_drive_convo_03_triggered = true
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.humvee_driving_03, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
-- Process the first attempt at the jump
function dlc2_m01_jump_take1_process()
objective_text_clear(0)
-- Stop the player's vehicle and make it invulnerable
vehicle_speed_cancel(Dlc2_m01_groups.armory_get_away_car.vehicle)
vehicle_stop(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
turn_invulnerable(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- vehicle audio is squealing while car is stopped. Make sure vehicle is stopped with no acceleration.
vehicle_freeze(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Play some dialog (director yells cut)
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.jump_setup, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
-- Unload the film grain
delay(1.5)
dlc_gis_film_grain_unload()
delay(0.5)
-- Update the music
audio_object_post_event("Alien_Invasion_Cut")
-- Make all the alien VTOLs retreat
for i, ambush in pairs(Dlc2_m01_rail_ambushes.nw_island) do
for j, vehicle_table in pairs(ambush.group.chase_vehicles) do
dlc2_m01_force_alien_ship_idle(vehicle_table)
end
end
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_bridge_ambush.vehicles) do
dlc2_m01_force_alien_ship_idle(vehicle_table)
end
-- Update the objective text
objective_text(0, Dlc2_m01_objectives.prepare_for_jump.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.prepare_for_jump.icon)
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_conversations.jump_setup) == false) do
thread_yield()
end
-- Kick of a thread to process the player's rail path
Dlc2_m01_threads.rail_loop_process = thread_new("dlc2_m01_process_rail_loop", Dlc2_m01_rail_loops.jump)
-- Play some dialog (director yells action)
delay(1.5)
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.jump_attempt, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
delay(1.0)
dlc2_m01_load_film_grain()
delay(0.8)
-- Update the music
audio_object_post_event("Action_03_Fail_Jump")
-- Wait until the player has reached the end of the path
while(thread_check_done(Dlc2_m01_threads.rail_loop_process) == false) do
thread_yield()
end
-- Remove the on destroyed callback on the player's vehicle (since it will be destroyed by the water)
on_vehicle_destroyed("", Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Wait until the get away car lands into the water
while(vehicle_in_water(Dlc2_m01_groups.armory_get_away_car.vehicle) == false) do
thread_yield()
end
-- Play some dialog (director yells cut)
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.jump_fail, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
-- Force Kwilanna out of the vehicle
vehicle_suppress_npc_exit(Dlc2_m01_groups.armory_get_away_car.vehicle, false)
vehicle_exit(Dlc2_m01_characters.kwilanna, true)
-- Turn off warp to shore for the players
for i, player in pairs(Dlc2_m01_player_list) do
player_warp_to_shore_disable(player)
end
-- Unload the film grain
delay(1.5)
dlc_gis_film_grain_unload()
delay(0.5)
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_conversations.jump_fail) == false) do
thread_yield()
end
delay(2.0)
dlc2_m01_jump_take1_cleanup(false)
end
function dlc2_m01_jump_take1_cleanup(exiting)
-- Clean-up all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.nw_island) do
dlc2_m01_cleanup_rail_ambush(ambush)
end
-- Re-enable warp to shore for the players
for i, player in pairs(Dlc2_m01_player_list) do
player_warp_to_shore_enable(player)
end
-- Remove the NW cameramen
if (group_is_loaded(Dlc2_m01_groups.nw_cameramen_01.name) == true) then
for i, npc in pairs(Dlc2_m01_groups.nw_cameramen_01.npcs) do
dlc2_m01_helper_cleanup_camera_man(npc)
end
group_destroy(Dlc2_m01_groups.nw_cameramen_01.name)
end
if (group_is_loaded(Dlc2_m01_groups.nw_cameramen_02.name) == true) then
for i, npc in pairs(Dlc2_m01_groups.nw_cameramen_02.npcs) do
dlc2_m01_helper_cleanup_camera_man(npc)
end
group_destroy(Dlc2_m01_groups.nw_cameramen_02.name)
end
-- Remove the player's temp weapons
dlc2_m01_helper_remove_temp_weapons(Dlc2_m01_tweak_values.armory_inventory_take2)
end
-- Make an alien ship go idle
function dlc2_m01_force_alien_ship_idle(vehicle_table)
if (vehicle_exists(vehicle_table.vehicle) == true and vehicle_is_destroyed(vehicle_table.vehicle) == false) then
if (thread_check_done(vehicle_table.fire_thread_id) == false) then
thread_kill(vehicle_table.fire_thread_id)
end
for i, npc in pairs(vehicle_table.npcs) do
npc_combat_enable(npc, false)
ai_clear_priority_target(npc)
set_attack_player_flag(npc, false)
set_attack_enemies_flag(npc, false)
end
helicopter_enter_retreat(vehicle_table.vehicle)
vehicle_set_weapons_disarmed(vehicle_table.vehicle, true)
end
end
--[[
Checkpoint 06 - Jump Second Take
--]]
-- Initialize the second take of the jump
function dlc2_m01_jump_take2_initialize()
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints_hc
end
-- Do common rail setup
dlc2_m01_setup_rail_common(Dlc2_m01_checkpoints.jump_take2.player_navs, Dlc2_m01_navpoints.player_vehicle_chk07, false, veh_hitpoints)
-- Stop the player's vehicle and make it invulnerable
vehicle_speed_cancel(Dlc2_m01_groups.armory_get_away_car.vehicle)
vehicle_stop(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
-- because the player is not driving, vehicle_stop is not clearing the accelerator,
-- causing audio squeals. Make sure it is stopped.
vehicle_freeze(Dlc2_m01_groups.armory_get_away_car.vehicle)
end
-- Process the second take of the jump
function dlc2_m01_jump_take2_process()
-- Setup all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.take2) do
dlc2_m01_setup_rail_ambush(ambush)
end
-- Set the player attack multiplier
for i, player in pairs(Dlc2_m01_player_list) do
if (difficulty_get_level() == 2) then
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_end_hc)
else
character_set_attack_multiplier(player, Dlc2_m01_tweak_values.rail_player_atk_mult_end)
end
end
-- Play some dialog (director yells action) and wait for it to finish
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.jump_take2_start, DLC2_M01_CONVO_PLAY_IMMEDIATE, 2.5)
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.jump_take2_skip, DLC2_M01_CONVO_PLAY_LAST, 1.0)
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.drive_to_tunnel, DLC2_M01_CONVO_PLAY_LAST, 1.0)
delay(5.0)
-- Kick of a thread to process the player's rail path
Dlc2_m01_threads.rail_loop_process = thread_new("dlc2_m01_process_rail_loop", Dlc2_m01_rail_loops.rail_end)
delay(1.0)
dlc2_m01_load_film_grain()
-- Change the objective text
objective_text(0, Dlc2_m01_objectives.destroy_pursuers.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.destroy_pursuers.icon)
delay(0.8)
-- Update the music
audio_object_post_event("Final_Sequence")
-- Wait for the rail pathfind to finish
while(thread_check_done(Dlc2_m01_threads.rail_loop_process) == false) do
thread_yield()
end
dlc2_m01_jump_take2_cleanup(false)
end
-- Clean-up the second take of the jump
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_jump_take2_cleanup(exiting)
-- NOTHING TO DO HERE
end
-- Initialize the finale in the tunnel
function dlc2_m01_finale_initialize()
local veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints
if (difficulty_get_level() == 2) then
veh_hitpoints = Dlc2_m01_tweak_values.player_veh_nw_hitpoints_hc
end
-- Do common rail setup
dlc2_m01_setup_rail_common(Dlc2_m01_checkpoints.finale.player_navs, Dlc2_m01_navpoints.player_vehicle_chk08, true, veh_hitpoints)
-- Setup all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.take2) do
dlc2_m01_setup_rail_ambush(ambush)
end
-- Create the alien group (the player starts after the create trigger for this ambush)
dlc2_m01_ambush_create_triggered_cb(LOCAL_PLAYER, Dlc2_m01_rail_ambushes.take2[2].create_trigger)
end
-- Process the alien finale
function dlc2_m01_alien_finale_process()
-- Kick of a thread to process the player's rail path
Dlc2_m01_threads.rail_loop_process = thread_new("dlc2_m01_process_rail_loop", Dlc2_m01_rail_loops.finale)
-- Setup the trigger for the tunnel conversation and explosions
on_trigger("dlc2_m01_tunnel_entrace_triggered_cb", Dlc2_m01_triggers.convo_tunnel_entrance)
trigger_enable(Dlc2_m01_triggers.convo_tunnel_entrance, true)
on_trigger("dlc2_m01_tunnel_explosions_triggered_cb", Dlc2_m01_triggers.tunnel_explosions)
trigger_enable(Dlc2_m01_triggers.tunnel_explosions, true)
-- Disable ambient vehicles
spawning_vehicles(false)
-- Wait for the rail pathfind to finish
while(thread_check_done(Dlc2_m01_threads.rail_loop_process) == false) do
thread_yield()
end
-- Stop the player's vehicle
vehicle_speed_cancel(Dlc2_m01_groups.armory_get_away_car.vehicle)
vehicle_stop(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
-- because the player is not driving, vehicle_stop is not clearing the accelerator,
-- causing audio squeals. Make sure it is stopped.
vehicle_freeze(Dlc2_m01_groups.armory_get_away_car.vehicle)
-- Play the final dialog
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.mission_end, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_dialog_lines.mission_end) == false) do
thread_yield()
end
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.mission_end_02, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
delay(0.5)
dlc_gis_film_grain_unload()
delay(0.5)
--audio_object_post_event("GIS_M01_Stop_All")
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_dialog_lines.mission_end_02) == false) do
thread_yield()
end
dlc2_m01_alien_finale_cleanup(false)
end
-- Clean-up the second take of the jump
--
-- exiting: TRUE if the cleanup is called as a result of mission exit, FALSE if the objective was completed
function dlc2_m01_alien_finale_cleanup(exiting)
-- Clean-up all of the ambushes
for i, ambush in pairs(Dlc2_m01_rail_ambushes.take2) do
dlc2_m01_cleanup_rail_ambush(ambush)
end
-- Re-enable ambient vehicles
spawning_vehicles(true)
-- Clean-up the trigger for the tunnel explosions
on_trigger("", Dlc2_m01_triggers.convo_tunnel_entrance)
trigger_enable(Dlc2_m01_triggers.convo_tunnel_entrance, false)
on_trigger("", Dlc2_m01_triggers.tunnel_explosions)
trigger_enable(Dlc2_m01_triggers.tunnel_explosions, false)
end
function dlc2_m01_tunnel_entrace_triggered_cb()
if (Dlc2_m01_runtime.tunnel_entrace_triggered == false) then
Dlc2_m01_runtime.tunnel_explosions_triggered = true
continuous_explosion_stop()
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.reach_tunnel, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
end
end
-- Callback when the player enters the trigger for the tunnel explosions
function dlc2_m01_tunnel_explosions_triggered_cb()
if (Dlc2_m01_runtime.tunnel_explosions_triggered == false) then
Dlc2_m01_runtime.tunnel_explosions_triggered = true
for i, vfx in pairs(Dlc2_m01_vfx.tunnel_smoke) do
vfx.handle = effect_play(vfx.name, true)
end
for i, vfx in pairs(Dlc2_m01_vfx.tunnel_explosions) do
vfx.handle = effect_play(vfx.name, false)
delay(rand_float(0.2, 0.3))
end
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.tunnel_ufo_crash_01, DLC2_M01_CONVO_PLAY_IMMEDIATE, 1.0)
delay(0.6)
vehicle_max_speed(Dlc2_m01_groups.armory_get_away_car.vehicle, 10.0)
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_dialog_lines.tunnel_ufo_crash_01) == false) do
thread_yield()
end
-- Activate the jet bikes
dlc2_m01_ambush_activate_triggered_cb(LOCAL_PLAYER, Dlc2_m01_rail_ambushes.take2[3].activate_trigger)
vehicle_max_speed(Dlc2_m01_groups.armory_get_away_car.vehicle, 60.0)
delay(0.1)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.jet_bikes, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
end
end
-- ***************************************************
-- General Helper Functions
-- ***************************************************
-- Common initialization for the armory objective for both Take1 & Take2
function dlc2_m01_go_to_armory_initialize_common()
-- Setup the helicopter next to Kwilanna
group_create(Dlc2_m01_groups.kwilanna_heli.name, true) -- wait for the group to load
vehicle_enter_teleport(Dlc2_m01_groups.kwilanna_heli.heli.pilot, Dlc2_m01_groups.kwilanna_heli.heli.vehicle, 0, true)
vehicle_suppress_npc_exit(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
vehicle_disable_chase(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
vehicle_disable_flee(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
set_unjackable_flag(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
set_unenterable_for_player(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
vehicle_prevent_explosion_fling(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
vehicle_set_keyframed_physics(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, true)
turn_invulnerable(Dlc2_m01_groups.kwilanna_heli.heli.vehicle)
-- Setup Kwilanna
set_dont_attack_me_on_sight_flag(Dlc2_m01_characters.kwilanna, true)
character_allow_ragdoll(Dlc2_m01_characters.kwilanna, false)
character_prevent_flinching(Dlc2_m01_characters.kwilanna, true)
character_prevent_bumping(Dlc2_m01_characters.kwilanna, true)
set_ignore_ai_flag(Dlc2_m01_characters.kwilanna, true)
set_current_hit_points(Dlc2_m01_characters.kwilanna, get_max_hit_points(Dlc2_m01_characters.kwilanna))
set_script_animation_state(Dlc2_m01_characters.kwilanna, "hostage idle")
npc_suppress_persona(Dlc2_m01_characters.kwilanna, true)
dlc2_m01_helper_set_kwilanna_invulnerable(true, true)
-- Kick off a thread to process Kwilanna's position, and kill her if she moves too far away from her tied up position
--Dlc2_m01_threads.kwilanna_pos_process = thread_new("dlc2_m01_process_kwilanna_pos_thread")
-- Create the armory car husks
group_create(Dlc2_m01_groups.armory_car_husks.name, true)
for i, vehicle in pairs(Dlc2_m01_groups.armory_car_husks.vehicles) do
turn_invulnerable(vehicle)
set_unenterable_for_player(vehicle, false)
end
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.armory_car_husks.vehicles[1], true, true)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.armory_car_husks.vehicles[3], true, false)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.armory_car_husks.vehicles[4], true, true)
vehicle_set_smoke_and_fire_state(Dlc2_m01_groups.armory_car_husks.vehicles[5], true, false)
-- Create the camera men
group_create(Dlc2_m01_groups.armory_camera_men.name, true)
for i, npc in pairs(Dlc2_m01_groups.armory_camera_men.npcs) do
dlc2_m01_helper_setup_camera_man(npc)
end
-- Remove the movers for some fence around the armory helipad
for i, mover in pairs(Dlc2_m01_movers.armory_fence_to_remove) do
mesh_mover_hide(mover)
end
-- Enable the trigger at the Armory
on_trigger("dlc2_m01_heli_pad_triggered_cb", Dlc2_m01_triggers.heli_pad_area)
on_trigger_exit("dlc2_m01_heli_pad_exited_cb", Dlc2_m01_triggers.heli_pad_area)
trigger_enable(Dlc2_m01_triggers.heli_pad_area, true)
-- Play the VFX for the car husks
--[[
for i, vfx in pairs(Dlc2_m01_vfx.car_husks) do
if (vfx.handle == -1) then
vfx.handle = effect_play(vfx.name, true)
end
end
--]]
end
-- Common function for armory take 1 initialization
function dlc2_m01_armory_take1_initialize_common()
-- Create the script group for the first take
group_create(Dlc2_m01_groups.armory_take_01.name, true)
-- Lock all the helicopters
for i, heli in pairs(Dlc2_m01_groups.armory_take_01.helis) do
set_unjackable_flag(heli, true)
set_unenterable_for_player(heli, false)
end
-- Register on_death callbacks for the tower guards (and get the num of guards)
Dlc2_m01_runtime.num_tower_guards_alive = 0
for i, guard in pairs(Dlc2_m01_groups.armory_take_01.tower_guards) do
on_death("dlc2_m01_take1_tower_guard_killed_cb", guard)
Dlc2_m01_runtime.num_tower_guards_alive = Dlc2_m01_runtime.num_tower_guards_alive + 1
end
-- Set the players weapon load-out
dlc2_m01_helper_give_temp_weapons(Dlc2_m01_tweak_values.armory_inventory_take1)
end
-- Common function for creating and initializing the escape vehicle
function dlc2_m01_setup_escape_vehicle(vehicle_hitpoints)
group_create(Dlc2_m01_groups.armory_get_away_car, true)
vehicle_disable_chase(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_disable_flee(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_ignore_repulsors(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_infinite_mass(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_never_flatten_tires(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_prevent_explosion_fling(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_prevent_transition_to_ambient(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_prevent_vehicle_collision_damage(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_set_allow_ram_ped(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_set_crazy(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_set_ignore_rail_obstacles(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_set_obey_traffic_lights(Dlc2_m01_groups.armory_get_away_car.vehicle, false)
vehicle_set_script_hard_goto(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_suppress_flipping(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
vehicle_suppress_npc_exit(Dlc2_m01_groups.armory_get_away_car.vehicle, true)
set_max_hit_points(Dlc2_m01_groups.armory_get_away_car.vehicle, vehicle_hitpoints, true)
vehicle_speed_override(Dlc2_m01_groups.armory_get_away_car.vehicle, Dlc2_m01_tweak_values.player_veh_pathfind_speed)
vehicle_max_speed(Dlc2_m01_groups.armory_get_away_car.vehicle, Dlc2_m01_tweak_values.player_veh_pathfind_speed)
on_vehicle_destroyed("dlc2_m01_get_away_vehicle_destroyed_cb", Dlc2_m01_groups.armory_get_away_car.vehicle)
end
-- Setup the downtown camera men
function dlc2_m01_setup_downtown_camera_men_01()
-- Create the camera men
group_create(Dlc2_m01_groups.dt_camera_men_01.name, true)
for i, npc in pairs(Dlc2_m01_groups.dt_camera_men_01.npcs) do
dlc2_m01_helper_setup_camera_man(npc)
end
end
-- Common setup for the rail sequence checkpoints
function dlc2_m01_setup_rail_common(player_navs, car_nav, load_film_grain, veh_hitpoints)
if (load_film_grain == nil) then
load_film_grain = true
end
-- Create the get away car
dlc2_m01_setup_escape_vehicle(veh_hitpoints)
-- Teleport the get away car to the navpoint for this checkpoint
if (car_nav ~= nil) then
teleport_vehicle(Dlc2_m01_groups.armory_get_away_car.vehicle, car_nav)
end
-- Make Everyone in the car invulnerable
dlc2_m01_helper_set_kwilanna_invulnerable(true, false)
for i, player in pairs(Dlc2_m01_player_list) do
turn_invulnerable(player)
end
-- Teleport the player's to the start navs
teleport_coop(player_navs[1], player_navs[2], true)
-- Put eveyone into the car
vehicle_enter_teleport(Dlc2_m01_characters.kwilanna, Dlc2_m01_groups.armory_get_away_car.vehicle, 0, true)
for i, player in pairs(Dlc2_m01_player_list) do
-- i starts at index 1, which coincidently is the seat we want to put the first player in
vehicle_enter_teleport(player, Dlc2_m01_groups.armory_get_away_car.vehicle, i, true)
set_player_can_enter_exit_vehicles(player, false)
end
-- Make Kwilanna a homie
party_add(Dlc2_m01_characters.kwilanna, LOCAL_PLAYER)
on_dismiss("dlc2_m01_kwilanna_dismissed_cb", Dlc2_m01_characters.kwilanna)
-- Set fake notoriety
hud_set_fake_notoriety("Police", true, Dlc2_m01_tweak_values.fake_notoriety_level)
-- Load the film grain UI
if (load_film_grain == true) then
dlc2_m01_load_film_grain()
end
-- Give the players weapon load-out
dlc2_m01_helper_give_temp_weapons(Dlc2_m01_tweak_values.armory_inventory_take2)
-- Change the objective text
objective_text(0, Dlc2_m01_objectives.destroy_pursuers.tag, nil, nil, SYNC_ALL, Dlc2_m01_objectives.destroy_pursuers.icon)
end
-- Loop-up a rail ambush trigger Lua table by trigger name
--
-- trigger_name: Name of the trigger to look for in rail ambush Lua tables
function dlc2_m01_find_rail_ambush_by_trigger(trigger_name)
-- Look through all the ambush groups looking for any ambushes that use the specified trigger
for i, ambush_group in pairs(Dlc2_m01_rail_ambushes) do
for j, ambush in pairs(ambush_group) do
if (ambush.create_trigger == trigger_name or ambush.activate_trigger == trigger_name) then
-- Found it, return the ambush table
return ambush
end
end
end
-- If we didn't already return an ambush, then we didn't find it... return nil
return nil
end
-- Function to setup a rail sequence ambush
--
-- ambush: Lua table defining the ambush (see Dlc2_m01_rail_ambushes)
function dlc2_m01_setup_rail_ambush(ambush)
ambush.created = false
ambush.activated = false
-- If there's a create trigger, activate it. Otherwise, create the group immediately
if (ambush.create_trigger ~= nil) then
trigger_enable(ambush.create_trigger, true)
on_trigger("dlc2_m01_ambush_create_triggered_cb", ambush.create_trigger)
else
group_create(ambush.group.name, false)
ambush.created = true
end
-- Enable the activate trigger
trigger_enable(ambush.activate_trigger, true)
on_trigger("dlc2_m01_ambush_activate_triggered_cb", ambush.activate_trigger)
end
-- Function to cleanup a rail sequence ambush
--
-- ambush: Lua table defining the ambush (see Dlc2_m01_rail_ambushes)
function dlc2_m01_cleanup_rail_ambush(ambush)
-- Cleanup the triggers
if (ambush.create_trigger ~= nil) then
on_trigger("", ambush.create_trigger)
trigger_enable(ambush.create_trigger, false)
end
on_trigger("", ambush.activate_trigger)
trigger_enable(ambush.activate_trigger, false)
-- Remove any vehicle callbacks
if (ambush.group.chase_vehicles ~= nil) then
for i, vehicle_table in pairs(ambush.group.chase_vehicles) do
on_take_damage("", vehicle_table.vehicle)
-- Cleanup the on destroyed callbacks for the alien vehicles
if (vehicle_table.is_alien == true) then
on_vehicle_destroyed("", vehicle_table.vehicle)
end
end
end
-- Release the group to the world
release_to_world(ambush.group.name)
-- Clean-up any threads we spawned to process the scripted object
for i, thread in pairs(ambush.group_threads) do
if (thread_check_done(thread) == false) then
thread_kill(thread)
end
thread = nil
end
end
-- Callback for when an ambush create trigger is entered
--
-- triggerer: Name of the player that triggered this trigger
-- trigger: Name of the trigger
function dlc2_m01_ambush_create_triggered_cb(triggerer, trigger)
-- Find the ambush table from the trigger name
local ambush = dlc2_m01_find_rail_ambush_by_trigger(trigger)
if (ambush == nil) then
-- Couldn't find it? Just return
return
end
-- Check if this ambush has already been created
if (ambush.created == true) then
return
end
ambush.created = true
-- Create the script group for this ambush
group_create_hidden(ambush.group.name, false)
end
-- Callback for when an ambush activate trigger is entered
--
-- triggerer: Name of the player that triggered this trigger
-- trigger: Name of the trigger
function dlc2_m01_ambush_activate_triggered_cb(triggerer, trigger)
-- Find the ambush table from the trigger name
local ambush = dlc2_m01_find_rail_ambush_by_trigger(trigger)
if (ambush == nil) then
-- Couldn't find it? Just return
return
end
-- Check if this ambush has already been activated
if (ambush.activated == true) then
return
end
ambush.activated = true
-- Make sure the group is loaded
if (group_is_loaded(ambush.group.name) == false) then
-- If the group failed to load, check to see if there were any Alien vehicles in it. We want to still give the player credit for those
for i, vehicle_table in pairs(ambush.group.chase_vehicles) do
dlc2_m01_alien_spaceship_destroyed_cb(vehicle_table.vehicle)
end
return
end
-- Make sure the group has finished being created
if (group_create_check_done(ambush.group.name) == false) then
-- If it hasn't already loaded, we're going to bail on this ambush. Destroy the group
group_destroy(ambush.group.name)
return
end
-- Setup any chase vehicles
if (ambush.group.chase_vehicles ~= nil) then
for i, vehicle in pairs(ambush.group.chase_vehicles) do
ambush.group_threads[#ambush.group_threads + 1] = thread_new("dlc2_m01_process_ambush_vehicle_thread", vehicle, ambush.behavior, ambush.speed, ambush.invulnerable, ambush.hp_multiplier)
end
end
-- Setup any chase NPCs
if (ambush.group.chase_npcs ~= nil) then
for i, npc in pairs(ambush.group.chase_npcs) do
ambush.group_threads[#ambush.group_threads + 1] = thread_new("dlc2_m01_process_ambush_npc_thread", npc, ambush.behavior, ambush.invulnerable)
end
end
end
-- Helper function to process Kwilanna and both players getting into a required vehicle
--
-- vehicle_name: Name of the vehicle
function dlc2_m01_helper_get_gang_into_vehicle(vehicle_name)
-- Add a marker on the vehicle
marker_add(vehicle_name, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_ALL)
-- Call out the player's seat
for i, player in pairs(Dlc2_m01_player_list) do
-- i starts at index 1, which coincidently is the seat we want to put the first player in
player_force_vehicle_seat(player, i, vehicle_name)
end
-- Unlock the vehicle and register a callback for when it is entered
set_unjackable_flag(vehicle_name, false)
set_unenterable_for_player(vehicle_name, false)
on_vehicle_enter("dlc2_m01_get_away_car_entered_cb", vehicle_name)
on_vehicle_exit("dlc2_m01_get_away_car_exited_cb", vehicle_name)
-- Make it so that AI cannot pull anyone out of the vehicle
set_unjackable_by_ai_flag(vehicle_name, true)
vehicle_suppress_npc_exit(vehicle_name, true)
delay(0.5)
Dlc2_m01_threads.kwilanna_vehicle_enter = thread_new("dlc2_m01_thread_kwilanna_get_in_vehicle", vehicle_name)
-- Wait until all the players are in the get away car
local ready = false
while(ready == false) do
ready = true
-- Check if any players are not in the vehicle
for i, player in pairs(Dlc2_m01_player_list) do
if (character_is_in_vehicle(LOCAL_PLAYER, vehicle_name) == false) then
ready = false
end
end
-- If Kwilanna goes down, wait for her to be revived
if (human_is_downed(Dlc2_m01_characters.kwilanna) == true) then
ready = false
end
thread_yield()
end
-- Make Kwilanna invulnerable
dlc2_m01_helper_set_kwilanna_invulnerable(true, false)
-- Lock the player's into the car
for i, player in pairs(Dlc2_m01_player_list) do
set_player_can_enter_exit_vehicles(player, false)
end
-- Update the music if this is the escape start checkpoing
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.escape_start.name) then
audio_object_post_event("To_The_Bridge")
end
-- If Kwilanna isn't in the vehicle by now, teleport her in
if (character_is_in_vehicle(Dlc2_m01_characters.kwilanna, vehicle_name) == false) then
if (human_is_downed(Dlc2_m01_characters.kwilanna) == true) then
npc_revive(Dlc2_m01_characters.kwilanna)
end
dlc2_m01_helper_set_kwilanna_invulnerable(true, false)
delay(3.0)
end
-- Make sure eveyone's in the car
for i, player in pairs(Dlc2_m01_player_list) do
vehicle_enter_teleport(player, vehicle_name, i, true, true)
end
vehicle_enter_teleport(Dlc2_m01_characters.kwilanna, vehicle_name, 0, true)
-- Loop until everyone is actually in the car (fixes Bug #1949)
ready = false
while(ready == false) do
ready = true
-- Check if any players are not in the vehicle
for i, player in pairs(Dlc2_m01_player_list) do
if (character_is_in_vehicle(LOCAL_PLAYER, vehicle_name) == false) then
ready = false
end
end
-- Check if Kwilanna is not in the vehicle
if (character_is_in_vehicle(Dlc2_m01_characters.kwilanna, vehicle_name) == false) then
ready = false
end
thread_yield()
end
follower_make_independent(Dlc2_m01_characters.kwilanna, false)
set_unjackable_flag(vehicle_name, true)
on_vehicle_enter("", vehicle_name)
on_vehicle_exit("", vehicle_name)
marker_remove(vehicle_name)
end
-- Callback for when someone enter's the get-away car during the "get into the escape vehicle" objective
--
-- human_name: Name of the character entering the vehicle (not necessarily a player)
-- vehicle_name: Name of the vehicle entered
-- seat: Seat index (driver == 0, passenger1 == 1, etc.)
function dlc2_m01_get_away_car_entered_cb(human_name, vehicle_name, seat)
turn_invulnerable(human_name, false)
end
-- Callback for when someone enter's the get-away car during the "get into the escape vehicle" objective
--
-- human_name: Name of the character exiting the vehicle (not necessarily a player)
-- vehicle_name: Name of the vehicle exited
-- seat: Seat index (driver == 0, passenger1 == 1, etc.)
function dlc2_m01_get_away_car_exited_cb(human_name, vehicle_name, seat)
turn_vulnerable(human_name)
end
-- Thread to process Kwilanna getting into the vehicle
function dlc2_m01_thread_kwilanna_get_in_vehicle(vehicle_name)
-- Wait until the local player is close to the vehicle
while(get_dist(Dlc2_m01_characters.kwilanna, vehicle_name) > 20.0) do
thread_yield()
end
-- Tell Kwilanna to get into the vehicle
follower_make_independent(Dlc2_m01_characters.kwilanna, true)
vehicle_enter(Dlc2_m01_characters.kwilanna, vehicle_name, 0)
-- Wait a bit for Kwilanna to get into the car (we'll teleport her into the car down below if she doesn't make it in there)
while(true) do
if (character_is_in_vehicle(Dlc2_m01_characters.kwilanna, vehicle_name) == true) then
break
else
-- Check to see if Kwilanna aborted the vehicle enter
if (vehicle_enter_check_done(Dlc2_m01_characters.kwilanna, false, vehicle_name) == 2) then
-- Try restarting the vehicle enter
vehicle_enter(Dlc2_m01_characters.kwilanna, vehicle_name, 0)
end
end
-- If Kwilanna goes down, wait for her to be revived
while(human_is_downed(Dlc2_m01_characters.kwilanna) == true) do
thread_yield()
end
thread_yield()
end
end
-- Helper function for giving the players a temporary weapon loadout
--
-- weapon_list: List of weapons to give the player
function dlc2_m01_helper_give_temp_weapons(weapon_list)
-- Disable all slots but melee
inv_weapon_disable_slot(WEAPON_SLOT_PISTOL, true, SYNC_ALL)
inv_weapon_disable_slot(WEAPON_SLOT_SMG, true, SYNC_ALL)
inv_weapon_disable_slot(WEAPON_SLOT_SHOTGUN, true, SYNC_ALL)
inv_weapon_disable_slot(WEAPON_SLOT_RIFLE, true, SYNC_ALL)
inv_weapon_disable_slot(WEAPON_SLOT_EXPLOSIVE, true, SYNC_ALL)
inv_weapon_disable_slot(WEAPON_SLOT_SPECIAL, true, SYNC_ALL)
for i, weapon_table in pairs(weapon_list) do
if (weapon_table.is_grenade == nil or weapon_table.is_grenade == false) then
-- Enable this weapon's slot for all players
inv_weapon_disable_slot(inv_item_get_weapon_slot(weapon_table.weapon), false, SYNC_ALL)
end
-- If this is the last weapon in the list, it should be equipped now
local equip_now = false
if (i == #weapon_list) then
equip_now = true
end
-- Add the weapon to each player's inventory
for j, player in pairs(Dlc2_m01_player_list) do
inv_weapon_add_temporary(player, weapon_table.weapon, 1, true, equip_now, false, true, weapon_table.upgrade_lvl)
end
end
end
-- Helper function for removing temporary weapons given to the players
--
-- weapon_list: List of weapons to give the player
function dlc2_m01_helper_remove_temp_weapons(weapon_list)
inv_weapon_disable_all_slots(false, SYNC_ALL)
for i, weapon_table in pairs(weapon_list) do
-- Add the weapon to each player's inventory
for j, player in pairs(Dlc2_m01_player_list) do
inv_weapon_remove_temporary(player, weapon_table.weapon)
end
end
end
-- Helper function to setup a camera man to bahave like a camera man
--
-- npc: Name of the NPC to setup as a camera man
function dlc2_m01_helper_setup_camera_man(npc)
ai_set_action_delay(npc, "melee", 99999)
ai_set_action_delay(npc, "move rush to melee", 99999)
set_team(npc, "Deckers")
set_cant_cower_flag(npc, true)
set_cant_flee_flag(npc, true)
set_always_sees_player_flag(npc, true)
set_attack_player_flag(npc, true)
inv_item_add("Special-CameraProp", 1, npc, true)
npc_dont_drop_weapon_on_death(npc, true)
npc_dont_auto_equip_or_unequip_weapons(npc, true)
character_set_always_combat_ready(npc, true)
-- Register an on-death callback
on_death("dlc2_m01_camera_man_died_cb", npc)
end
-- Helper function to cleanup a camera man
--
-- npc: Name of the NPC to cleanup
function dlc2_m01_helper_cleanup_camera_man(npc)
on_death("", npc)
end
-- Callback for when a cameraman dies
function dlc2_m01_camera_man_died_cb(victim, attacker)
on_death("", victim)
dlc2_m01_helper_achievement_increment(Dlc2_m01_acheivements.cameramen)
if (thread_check_done(Dlc2_m01_dialog_queue.playing.thread_id) == true) then
if (Dlc2_m01_runtime.played_cameraman_line == false or rand_int(1, 2) == 1) then
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_camera, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
Dlc2_m01_runtime.played_cameraman_line = true
end
end
end
-- Setup rail explosions
function dlc2_m01_helper_setup_rail_explosions()
-- Start continuous explosion
if (Dlc2_m01_threads.parked_car_explosions == INVALID_THREAD_HANDLE) then
Dlc2_m01_threads.parked_car_explosions = thread_new("dlc2_m01_process_parked_car_explosions")
-- Start continuous explosion
continuous_explosion_start("Dlc2_m01_rail", Dlc2_m01_navpoints.armory_location)
for i, player in pairs(Dlc2_m01_player_list) do
continuous_explosion_follow_target_add(player)
continuous_explosion_avoid_object_add(player)
end
--dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.car_chase_explosions, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
-- Stop rail explosions
function dlc2_m01_helper_stop_rail_explosions()
-- Stop the park car explosions
if (thread_check_done(Dlc2_m01_threads.parked_car_explosions) == false) then
thread_kill(Dlc2_m01_threads.parked_car_explosions)
Dlc2_m01_threads.parked_car_explosions = INVALID_THREAD_HANDLE
continuous_explosion_stop()
end
end
-- Set Kwilanna's invulnerability flag
function dlc2_m01_helper_set_kwilanna_invulnerable(invulnerable, allow_player_dmg)
if (allow_player_dmg == nil) then
allow_player_dmg = false
end
if (invulnerable) then
-- Make Kwilanna invulnerable
if (human_is_downed(Dlc2_m01_characters.kwilanna) == true) then
npc_revive(Dlc2_m01_characters.kwilanna)
end
turn_invulnerable(Dlc2_m01_characters.kwilanna, allow_player_dmg)
else
turn_vulnerable(Dlc2_m01_characters.kwilanna)
end
Dlc2_m01_runtime.kwilanna_invulnerable = invulnerable
Dlc2_m01_runtime.kwilanna_damaged_by_player = allow_player_dmg
end
-- Process the film grain action
function dlc2_m01_helper_start_film_grain_thread()
-- Load the film grain UI
dlc_gis_film_grain_load()
audio_object_post_event("Action")
delay(5.0)
audio_object_post_event("Action_Fade")
end
-- Load the film grain
function dlc2_m01_load_film_grain()
if (thread_check_done(Dlc2_m01_threads.film_grain_load) == false) then
thread_kill(Dlc2_m01_threads.film_grain_load)
end
Dlc2_m01_threads.film_grain_load = thread_new("dlc2_m01_helper_start_film_grain_thread")
end
-- Check if a particular conversation is done (Originally written by Matt Gawalek for Mission 02)
--
-- dialog_table: Conversation Lua table (see Dlc2_m01_conversations)
function dlc2_m01_helper_dialog_check_done(dialog_table)
if (dialog_table.queued == false and dialog_table.started == false) then
return true
else
return dialog_table.ended
end
end
-- Helper to play conversations, by adding them to the cue (Originally written by Matt Gawalek for Mission 02)
--
-- dialog_table: Conversation Lua table (see Dlc2_m01_conversations)
-- priority: Desired priority for the conversation
-- delay: Amonut of time to dalya after this conversation before playing the next conversation (in seconds)
-- player: Player to play the line on if in coop (if player speaks in dialog), or nil to play on the HOST (defaults to nil)
function dlc2_m01_helper_dialog_play(dialog_table, priority, delay, player)
dialog_table.queued = true
dialog_table.delay = delay
dialog_table.player = player
if (priority == DLC2_M01_CONVO_PLAY_LAST) then
-- Insert this entry at the end of hte lsit
Dlc2_m01_dialog_queue.list[Dlc2_m01_dialog_queue.size] = dialog_table
Dlc2_m01_dialog_queue.size = Dlc2_m01_dialog_queue.size + 1
elseif (priority == DLC2_M01_CONVO_PLAY_NEXT) then
-- Shift the list to the right
for i = Dlc2_m01_dialog_queue.size - 1, 0, -1 do
Dlc2_m01_dialog_queue.list[i + 1] = Dlc2_m01_dialog_queue.list[i]
end
Dlc2_m01_dialog_queue.list[0] = dialog_table
Dlc2_m01_dialog_queue.size = Dlc2_m01_dialog_queue.size + 1
elseif (priority == DLC2_M01_CONVO_PLAY_IMMEDIATE) then
-- Stop any actively playing conversations, and start this one immediatly
dlc2_m01_helper_dialog_cleanup_playing()
Dlc2_m01_dialog_queue.playing.thread_id = thread_new("dlc2_m01_thread_play_dialog", dialog_table)
end
end
-- Kill any active dialog, and clear out the dialog queue (Originally written by Matt Gawalek for Mission 02)
function dlc2_m01_helper_dialog_kill_all()
-- Stop any active conversation
dlc2_m01_helper_dialog_cleanup_playing()
-- Clear out the queue
for i = 0, Dlc2_m01_dialog_queue.size - 1 do
Dlc2_m01_dialog_queue.list[i].ended = true
end
Dlc2_m01_dialog_queue.size = 0
end
-- Cleanup any playing dialog (Originally written by Matt Gawalek for Mission 02)
function dlc2_m01_helper_dialog_cleanup_playing()
-- Stop the thread processing a playing dialog
if (Dlc2_m01_dialog_queue.playing.thread_id ~= INVALID_THREAD_HANDLE) then
thread_kill(Dlc2_m01_dialog_queue.playing.thread_id)
Dlc2_m01_dialog_queue.playing.thread_id = INVALID_THREAD_HANDLE
end
-- Cleanup any dialog data for a playing dialog
if (Dlc2_m01_dialog_queue.playing.dialog_handle ~= INVALID_CONVERSATION_HANDLE) then
if (Dlc2_m01_dialog_queue.playing.dialog_table.is_convo == true) then
audio_conversation_end(Dlc2_m01_dialog_queue.playing.dialog_handle)
else
audio_stop(Dlc2_m01_dialog_queue.playing.dialog_handle)
end
Dlc2_m01_dialog_queue.playing.dialog_handle = INVALID_CONVERSATION_HANDLE
end
-- Mark the playing dialog as ended
if (Dlc2_m01_dialog_queue.playing.dialog_table ~= nil) then
Dlc2_m01_dialog_queue.playing.dialog_table.ended = true
end
end
-- Thread to process playing a single converation or dialog line (Originally written by Matt Gawalek for Mission 02)
function dlc2_m01_thread_play_dialog(dialog_table)
-- Add this conversatin to the playing dialog data
Dlc2_m01_dialog_queue.playing.dialog_table = dialog_table
dialog_table.started = true -- it has now started
dialog_table.queued = false
-- Play the dialog
if (dialog_table.is_convo == true) then
-- Load the conversation data
if (dialog_table.load_direct == false) then
if (dialog_table.player ~= nil) then
Dlc2_m01_dialog_queue.playing.dialog_handle = audio_conversation_load_player(dialog_table.name, dialog_table.player)
else
Dlc2_m01_dialog_queue.playing.dialog_handle = audio_conversation_load(dialog_table.name)
end
else
Dlc2_m01_dialog_queue.playing.dialog_handle = audio_conversation_load_direct(dialog_table.name)
end
-- Play the conversation and wait for it to end
audio_conversation_play(Dlc2_m01_dialog_queue.playing.dialog_handle)
audio_conversation_wait_for_end(Dlc2_m01_dialog_queue.playing.dialog_handle)
audio_conversation_end(Dlc2_m01_dialog_queue.playing.dialog_handle)
Dlc2_m01_dialog_queue.playing.dialog_handle = INVALID_CONVERSATION_HANDLE
else
-- Find the persona ID for this line
local persona_id = INVALID_PERSONA_HANDLE
for i, persona in pairs (Dlc2_m01_personas) do
if (persona.name == dialog_table.persona) then
persona_id = persona.persona_id
break
end
end
if (persona_id ~= INVALID_PERSONA_HANDLE) then
-- Play the line
Dlc2_m01_dialog_queue.playing.dialog_handle = audio_play_persona_line_2d(persona_id, dialog_table.name)
else
-- Assume the persona listed is an actual character
Dlc2_m01_dialog_queue.playing.dialog_handle = audio_play_persona_line(dialog_table.persona, dialog_table.name)
end
-- Wait for the line to end
while(audio_is_playing(Dlc2_m01_dialog_queue.playing.dialog_handle) == true) do
thread_yield()
end
end
delay(0.1)
delay(dialog_table.delay)
-- Do some book-keeping
Dlc2_m01_dialog_queue.playing.dialog_handle = INVALID_CONVERSATION_HANDLE
dialog_table.completed = true
dialog_table.ended = true
end
-- Process the dialog queue (should be running the duration of the mission) (Originally written by Matt Gawalek for Mission 02)
function dlc2_m01_thread_process_dialog()
-- Loop forever
while(true) do
-- Wait until something is added to the queue
while(Dlc2_m01_dialog_queue.size == 0 or thread_check_done(Dlc2_m01_dialog_queue.playing.thread_id) == false) do
thread_yield()
end
-- Play the first dialog from the queue, and then remove it from the qeue
Dlc2_m01_dialog_queue.playing.thread_id = thread_new("dlc2_m01_thread_play_dialog", Dlc2_m01_dialog_queue.list[0])
for i = 1, Dlc2_m01_dialog_queue.size do
Dlc2_m01_dialog_queue.list[i - 1] = Dlc2_m01_dialog_queue.list[i]
end
Dlc2_m01_dialog_queue.size = Dlc2_m01_dialog_queue.size - 1
-- Wait for the active dialog thread to end
while(thread_check_done(Dlc2_m01_dialog_queue.playing.thread_id) == false) do
thread_yield()
end
Dlc2_m01_dialog_queue.playing.thread_id = INVALID_THREAD_HANDLE
delay(0.2)
end
end
-- ***************************************************
-- General Thread Functions
-- ***************************************************
-- Process vehicle pathfinds through a segment for the rail sequence
--
-- segment: segment of vehicle navs as defined in Dlc2_m01_rail_loops
function dlc2_m01_process_rail_loop(loop)
local max_pathfind_attempts = 2
-- Process all of the segments in this loop
local curr_segment_idx = 1
while(curr_segment_idx <= #(loop.segments)) do
local segment = loop.segments[curr_segment_idx]
-- Loop over all the navs in the segment
local curr_path_idx = 1
while(curr_path_idx <= #(segment.navs)) do
-- Do the vehicle pathfind
local success = false
local attempts = 0
while (success == false and attempts < max_pathfind_attempts) do
if (segment.navmesh == true) then
vehicle_pathfind_navmesh_do(Dlc2_m01_groups.armory_get_away_car.vehicle, segment.navs[curr_path_idx], false, false, false, 0)
else
vehicle_pathfind_to_do(Dlc2_m01_groups.armory_get_away_car.vehicle, segment.navs[curr_path_idx], false, false)
end
-- Wait for the pathfind to complete
while(true) do
local pathfind_complete = vehicle_pathfind_check_done(Dlc2_m01_groups.armory_get_away_car.vehicle)
if (pathfind_complete == 2) then
success = false
break
elseif (pathfind_complete == 1) then
success = true
break
end
local dist_to_node = get_dist(Dlc2_m01_groups.armory_get_away_car.vehicle, segment.navs[curr_path_idx])
if (dist_to_node <= Dlc2_m01_tweak_values.player_veh_pathfind_dist) then
success = true
break
end
thread_yield()
end
-- If the pathfind failed, wait a second and try again
if (success == false) then
if (character_is_in_vehicle(Dlc2_m01_characters.kwilanna, Dlc2_m01_groups.armory_get_away_car.vehicle) == false) then
vehicle_enter_teleport(Dlc2_m01_characters.kwilanna, Dlc2_m01_groups.armory_get_away_car.vehicle, 0, true, true)
while(character_is_in_vehicle(Dlc2_m01_characters.kwilanna, Dlc2_m01_groups.armory_get_away_car.vehicle) == false) do
thread_yield()
end
end
delay(1.0)
end
attempts = attempts + 1
end
-- If the pathfind fails, teleport the vehicle to the destination navpoint
if (attempts == max_pathfind_attempts) then
teleport_vehicle(Dlc2_m01_groups.armory_get_away_car.vehicle, segment.navs[curr_path_idx])
end
-- Move to the next path
curr_path_idx = curr_path_idx + 1
thread_yield()
end
-- Do any delay for the segment
if (segment.delay ~= nil) then
delay(segment.delay)
end
curr_segment_idx = curr_segment_idx + 1
end
end
-- Thread to process an NPC doing a pathfind, and then chasing the LOCAL_PLAYER
--
-- npc_table: NPC table
-- path: Name of the path to follow
function dlc2_m01_process_ambush_npc_thread(npc_table, behavior, invulnerable)
if (npc_table.delay ~= nil) then
delay(npc_table.delay)
end
if (invulnerable == true) then
turn_invulnerable(npc_table.npc)
end
-- Show the character
character_show(npc_table.npc)
if (behavior == "attack_region") then
-- Add the player as an attack target
ai_add_enemy_target(npc_table.npc, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, false)
-- Move to the attack region
ai_attack_region(npc_table.npc, npc_table.nav, npc_table.leash)
elseif (behavior == "retreat") then
-- Rush to the navpoint and leash them there
npc_leash_to_nav(npc_table.npc, npc_table.nav, npc_table.leash)
ai_do_scripted_rush(npc_table.npc, npc_table.nav)
end
while(true) do
delay(1.5)
-- Check if the npc has been killed or is too far away from the player
local dist = get_dist_closest_player_to_object(npc_table.npc)
if (character_is_dead(npc_table.npc) == true or dist > Dlc2_m01_chase_vehicle_cleanup_dist) then
-- Release the NPC to the world
release_to_world(npc_table.npc)
-- We're done processing here
return
end
end
end
-- Thread to process a vehicle doing a pathfind, and then chasing the LOCAL_PLAYER
--
-- vehicle_table: Vehicle table
-- path: Name of the path to follow
function dlc2_m01_process_ambush_vehicle_thread(vehicle_table, behavior, speed, invulnerable, hp_multiplier, no_entry, follow_target)
if (speed == nil) then
speed = -1
end
if (no_entry == nil) then
no_entry = false
end
if (follow_target == nil) then
follow_target = Dlc2_m01_groups.armory_get_away_car.vehicle
end
-- If this is an alien vehicle, register a callback for when it's destroyed so we can track the achievement
if (vehicle_table.is_alien == true) then
on_vehicle_destroyed("dlc2_m01_alien_spaceship_destroyed_cb", vehicle_table.vehicle)
end
-- Put all of the NPCs into the vehicle
if (no_entry == false) then
vehicle_enter_group_teleport(vehicle_table.npcs, vehicle_table.vehicle)
vehicle_suppress_npc_exit(vehicle_table.vehicle, true)
end
if (vehicle_table.delay ~= nil) then
delay(vehicle_table.delay)
end
if (vehicle_table.exp_factor ~= nil) then
vehicle_set_explosion_damage_multiplier(vehicle_table.vehicle, vehicle_table.exp_factor)
end
if (invulnerable == true) then
turn_invulnerable(vehicle_table.vehicle)
for i, npc in pairs(vehicle_table.npcs) do
turn_invulnerable(npc)
end
end
-- Show the vehicle and all NPCs
vehicle_show(vehicle_table.vehicle)
for i, npc in pairs(vehicle_table.npcs) do
character_show(npc)
end
-- Setup the vehicle
local veh_type = get_vehicle_type(vehicle_table.vehicle)
vehicle_suppress_npc_exit(vehicle_table.vehicle, true)
if (veh_type == VT_AUTOMOBILE or veh_type == VT_MOTORCYCLE) then
vehicle_ignore_repulsors(vehicle_table.vehicle, true)
vehicle_set_ignore_rail_obstacles(vehicle_table.vehicle, true)
vehicle_set_script_hard_goto(vehicle_table.vehicle, true)
end
if (speed ~= nil and speed ~= -1) then
vehicle_max_speed(vehicle_table.vehicle, speed)
vehicle_speed_override(vehicle_table.vehicle, speed)
end
if (hp_multiplier ~= nil) then
set_max_hit_points(vehicle_table.vehicle, hp_multiplier * get_max_hit_points(vehicle_table.vehicle))
end
-- Add the player as an attack target
for i, npc in pairs(vehicle_table.npcs) do
ai_add_enemy_target(npc, CLOSEST_PLAYER, ATTACK_NOW_NEVER_LOSE, true)
end
if (vehicle_table.orient ~= nil) then
helicopter_set_path_orientation(vehicle_table.vehicle, vehicle_table.orient, LOCAL_PLAYER)
end
-- Kick off a thread to force fire the lasers on the alien spaceships
if (vehicle_table.is_alien == true) then
vehicle_table.fire_thread_id = thread_new("dlc2_m01_alien_ambush_process_alien_fire", vehicle_table.vehicle, follow_target, 99999.0, 2.2, 0.0, 1.0, 0.5)
end
-- Do the requested behavior
if (behavior == "chase") then
-- Nothing to do up front, just do the chase setup below
elseif (behavior == "path_navmesh") then
-- Do the vehicle pathfind
local path_idx = 1
while(path_idx <= #vehicle_table.paths) do
vehicle_pathfind_to(vehicle_table.vehicle, vehicle_table.paths[path_idx], true, false) -- navmesh pathfind, don't stop at goal
path_idx = path_idx + 1
end
elseif (behavior == "path_navmesh_stop" or behavior == "path_navmesh_exit") then
-- Do the vehicle pathfind
local path_idx = 1
while(path_idx <= #vehicle_table.paths) do
local stop = false
if (path_idx == #vehicle_table.paths) then
stop = true
end
vehicle_pathfind_to(vehicle_table.vehicle, vehicle_table.paths[path_idx], true, stop) -- navmesh pathfind, stop at goal
path_idx = path_idx + 1
end
-- If they should exit, do that now
if (behavior == "path_navmesh_exit") then
vehicle_exit_group(vehicle_table.npcs)
end
elseif (behavior == "heli_follow" or behavior == "heli_follow_explode") then
local follow_above = false
if (vehicle_table.above == true) then
follow_above = true
end
-- Do heli pathfind
local path_idx = 1
while(path_idx <= #vehicle_table.paths) do
helicopter_fly_to_internal(vehicle_table.vehicle, speed, true, follow_target, true, vehicle_table.paths[path_idx], vehicle_table.follow_dist, false, follow_above, true, false)
path_idx = path_idx + 1
end
elseif (behavior == "heli_path" or "heli_path_explode" or "heli_path_retreat") then
-- Do heli pathfind
local path_idx = 1
while(path_idx <= #vehicle_table.paths) do
helicopter_fly_to_internal(vehicle_table.vehicle, speed, true, "", true, vehicle_table.paths[path_idx], vehicle_table.follow_dist, false, false, true, false)
path_idx = path_idx + 1
end
elseif (behavior == "heli_path_stop") then
local path_idx = 1
while(path_idx <= #vehicle_table.paths) do
local continue = (path_idx ~= #vehicle_table.paths)
helicopter_fly_to_internal(vehicle_table.vehicle, speed, true, "", continue, vehicle_table.paths[path_idx], vehicle_table.follow_dist, false, false, true, false)
path_idx = path_idx + 1
end
--helicopter_fly_to_stop(vehicle_table.vehicle)
end
-- Now chase the local player
if (behavior == "heli_follow_explode" or behavior == "heli_path_explode") then
vehicle_set_smoke_and_fire_state(vehicle_table.vehicle, true, true)
on_take_damage("dlc2_m01_destroy_vehicle_on_collision_cb", vehicle_table.vehicle)
elseif (behavior == "heli_path_stop") then
-- DO NOTHING
elseif (behavior == "heli_path_retreat") then
helicopter_enter_retreat(vehicle_table.vehicle)
else
vehicle_chase(vehicle_table.vehicle, CLOSEST_PLAYER)
vehicle_max_speed(vehicle_table.vehicle, Dlc2_m01_tweak_values.ng_vehicle_chase_speed)
vehicle_speed_override(vehicle_table.vehicle, Dlc2_m01_tweak_values.ng_vehicle_chase_speed)
end
-- Process this vehicle until it is destroyed or gets too far from the player
while(true) do
delay(1.5)
-- If this isn't an alien vehicle, then check the distance (we don't want aliens to be deactived by distance since they count towards an achievement)
local dist = 0
if (vehicle_table.is_alien == false) then
dist = get_dist_closest_player_to_object(vehicle_table.vehicle)
end
-- Check if the vehicle has been destroyed or too far away from the player
if (vehicle_is_destroyed(vehicle_table.vehicle) == true or dist > Dlc2_m01_chase_vehicle_cleanup_dist) then
-- If the vehicle was destroyed, maybe play a positive director voice line
if (vehicle_is_destroyed(vehicle_table.vehicle) == true) then
if (rand_int(1, 5) == 1 and thread_check_done(Dlc2_m01_dialog_queue.playing.thread_id) == true) then
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.director_generic_positive, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
-- Release the vehicle and any NPCs to the world
release_to_world(vehicle_table.vehicle)
for i, npc in pairs(vehicle_table.npcs) do
release_to_world(npc)
end
-- We're done processing here
return
end
end
end
-- Thread to process a helicopter droping some soldier off
function dlc2_m01_process_helicopter_drop_off_thread(heli_group)
-- Create the group
group_create_hidden(heli_group.name, true)
-- Load up the pilots and soldiers into the helicopter
local seat_idx = 0
for i, pilot in pairs(heli_group.heli.pilots) do
vehicle_enter_teleport(pilot, heli_group.heli.vehicle, seat_idx, true)
seat_idx = seat_idx + 1
end
for i, soldier in pairs(heli_group.heli.soldiers) do
vehicle_enter_teleport(soldier, heli_group.heli.vehicle, seat_idx, true)
seat_idx = seat_idx + 1
end
-- Unhide the group and start following the path
group_show(heli_group.name)
helicopter_fly_to_direct(heli_group.heli.vehicle, heli_group.heli.speed, heli_group.heli.path)
-- Wait a bit and then force the soldiers out
delay(0.5)
vehicle_exit_group(heli_group.heli.soldiers)
-- Wait a bit and then make the helicopter retreat
delay(2.0)
helicopter_enter_retreat(heli_group.heli.vehicle)
-- Release the helicopter and pilots to the world
release_to_world(heli_group.heli.vehicle)
for i, pilot in pairs(heli_group.heli.pilots) do
release_to_world(pilot)
end
end
-- Spin and randomly detonate parker cars
function dlc2_m01_process_parked_car_explosions()
while(true) do
delay(rand_float(Dlc2_m01_tweak_values.parked_car_exp_cooldown_min, Dlc2_m01_tweak_values.parked_car_exp_cooldown_max))
vehicle_detonate_random_parked_car(Dlc2_m01_groups.armory_get_away_car.vehicle, 110, 180, 20, 80)
end
end
--[[
-- Process Kwilanna's position to kill her if she gets pushed away from where she should be tied up
function dlc2_m01_process_kwilanna_pos_thread()
while(true) do
delay(1.0)
if (get_dist(Dlc2_m01_characters.kwilanna, Dlc2_m01_navpoints.kwilanna_rescue_orient) > 1.5) then
character_kill(Dlc2_m01_characters.kwilanna, true)
break
end
end
end
--]]
-- ***************************************************
-- General Script Callback Functions
-- ***************************************************
-- Callback for when a player enters the trigger surrounding the National Guard Island
--
-- player_name: Name of the player that entered the trigger
-- trigger: Name of the trigger volume
function dlc2_m01_armory_island_entered_take1_cb(player_name, trigger)
-- Disable Police notoriety
notoriety_force_no_spawn("Police", true)
-- Disable parking spots (since we want to spawn our own vehicles)
parking_spot_disable_all(true)
if (Dlc2_m01_runtime.reached_armory_island == false) then
Dlc2_m01_runtime.reached_armory_island = true
-- Director yells action
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.start_action, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
while(dlc2_m01_helper_dialog_check_done(Dlc2_m01_dialog_lines.start_action) == false) do
thread_yield()
end
-- Load the film grain UI
dlc2_m01_load_film_grain()
delay(0.8)
audio_object_post_event("Action_01")
delay(1.0)
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.armory_drive_start, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
-- Callback for when a player enters the trigger surrounding the National Guard Island (on the second take)
--
-- player_name: Name of the player that entered the trigger
-- trigger: Name of the trigger volume
function dlc2_m01_armory_island_entered_take2_cb(player_name, trigger)
-- Disable Police notoriety
notoriety_force_no_spawn("Police", true)
-- Disable parking spots (since we want to spawn our own vehicles)
parking_spot_disable_all(true)
end
-- Callback for when a player exits the trigger surrounding the National Guard Island
--
-- player_name: Name of the player that entered the trigger
-- trigger: Name of the trigger volume
function dlc2_m01_armory_island_exited_cb(player_name, trigger)
-- If we're in coop, check to make sure the other player isn't still in the trigger before restoring the ambient spawning levels
if (coop_is_active() == true) then
for i, player in pairs(Dlc2_m01_player_list) do
if (object_is_in_trigger(trigger, player) == true) then
return
end
end
end
-- Re-enable parking spawns
parking_spot_disable_all(false)
end
-- Callback for when a player enters the trigger volume at the parking area next to the heli pad
--
-- player_name: Name of the player that entered the trigger
-- trigger: Name of the trigger volume
function dlc2_m01_armory_parking_triggered_cb(player_name, trigger)
if (Dlc2_m01_runtime.reached_armory_parking_area_by == nil) then
Dlc2_m01_runtime.reached_armory_parking_area_by = player_name
end
-- If the player's in a vehicle, stop the vehicle and force the player on foot
if (Dlc2_m01_runtime.current_checkpoint ~= Dlc2_m01_checkpoints.armory_take2.name) then
if (character_is_in_vehicle(player_name) == true) then
if (character_is_in_a_driver_seat(player_name) == true) then
vehicle_stop_do(player_name)
end
set_unenterable_for_player(player_name, true)
vehicle_exit(player_name)
end
end
end
-- Callback for when a player enters the trigger volume around the Armory
--
-- player_name: Name of the player that entered the trigger
-- trigger: Name of the trigger volume
function dlc2_m01_heli_pad_triggered_cb(player_name, trigger)
if (Dlc2_m01_runtime.reached_armory_parking_area_by ~= nil) then
Dlc2_m01_runtime.entered_heli_pad = true
else
if (Dlc2_m01_runtime.num_players_in_heli_pad == 0) then
-- Disable the trigger for the parking area
trigger_enable(Dlc2_m01_triggers.armory_parking_location, false)
-- Put up a HUD critical timer
hud_critical_timer_set(Dlc2_m01_tweak_values.heli_pad_evacuate_time, "DLC2_M01_HUD_LEAVE_HELI_AREA", "dlc2_m01_player_disobey_failure_cb", SYNC_ALL)
end
Dlc2_m01_runtime.num_players_in_heli_pad = Dlc2_m01_runtime.num_players_in_heli_pad + 1
end
end
-- Callback for when a player exits the trigger volume around the Armory
--
-- player_name: Name of the player that entered the trigger
-- trigger: Name of the trigger volume
function dlc2_m01_heli_pad_exited_cb(player_name, trigger)
if (Dlc2_m01_runtime.reached_armory_parking_area_by == nil) then
Dlc2_m01_runtime.num_players_in_heli_pad = Dlc2_m01_runtime.num_players_in_heli_pad - 1
if (Dlc2_m01_runtime.num_players_in_heli_pad == 0) then
-- Remove the HUD critical timer
hud_critical_timer_stop()
-- Enable the trigger for the parking area
trigger_enable(Dlc2_m01_triggers.armory_parking_location, true)
end
end
end
-- Callback for when Kwilanna is killed
function dlc2_m01_kwilanna_died_cb()
-- Fail the mission
mission_end_failure("dlc2_m01", "DLC2_M01_FAIL_KWILANNA_DIED")
end
-- Callback for when Kwilanna is dismissed
function dlc2_m01_kwilanna_dismissed_cb()
-- Fail the mission
mission_end_failure("dlc2_m01", "DLC2_M01_FAIL_KWILANNA_DISMISSED")
end
-- Callback for when Kwilanna is revived
function dlc2_m01_kwilanna_revived_cb()
-- Hack to restore invulnerable flag, since human_revive is dumb and clears the flag
if (Dlc2_m01_runtime.kwilanna_invulnerable == true) then
turn_invulnerable(Dlc2_m01_characters.kwilanna, Dlc2_m01_runtime.kwilanna_damaged_by_player)
end
end
-- Callback for when Kwilanna is downed
function dlc2_m01_kwilanna_downed_cb()
-- If Kwilanna is supposed to be invulnerable, then instantly revive her
if (Dlc2_m01_runtime.kwilanna_invulnerable == true) then
npc_revive(Dlc2_m01_characters.kwilanna)
end
end
-- Callback for when the player doesn't follow the directors direction
function dlc2_m01_player_disobey_failure_cb()
mission_end_failure("dlc2_m01", "DLC2_M01_FAIL_DIRECTOR_UNHAPPY")
end
-- Callback for when player triggers the "rescue Kwilanna" trigger
-- player_name: Name of the player that activated the trigger
-- trigger: Name of the trigger
function dlc2_m01_resuce_kwilanna_cb(player_name, trigger)
-- Don't allow this to be triggered more than once
if (Dlc2_m01_runtime.kwilanna_rescued_by ~= nil) then
return
end
-- Mark the trigger as triggered, and store off the player that activated the trigger
Dlc2_m01_runtime.kwilanna_rescued_by = player_name
-- Disable the trigger to rescue Kwilanna
on_trigger("", Dlc2_m01_triggers.rescue_kwilanna)
trigger_enable(Dlc2_m01_triggers.rescue_kwilanna, false)
-- Re-enable her persona lines
npc_suppress_persona(Dlc2_m01_characters.kwilanna, false)
--[[
-- Kill the thread that processes Kwilanna's position
if (thread_check_done(Dlc2_m01_threads.kwilanna_pos_process) == false) then
thread_kill(Dlc2_m01_threads.kwilanna_pos_process)
Dlc2_m01_threads.kwilanna_pos_process = INVALID_THREAD_HANDLE
end
--]]
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.armory_take1.name) then
dlc2_m01_helper_dialog_play(Dlc2_m01_conversations.untie_kwilanna_take1, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
elseif (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.armory_take2.name) then
Dlc2_m01_dialog_lines.untie_kwilanna_take2_01.persona = player_name
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.untie_kwilanna_take2_01, DLC2_M01_CONVO_PLAY_IMMEDIATE, 0.0)
end
-- Play the synced animation
set_script_animation_state(Dlc2_m01_characters.kwilanna, nil)
action_play_synced(Dlc2_m01_runtime.kwilanna_rescued_by, Dlc2_m01_characters.kwilanna, "Hostage Release", Dlc2_m01_navpoints.kwilanna_rescue_anim_orient)
set_ignore_ai_flag(Dlc2_m01_characters.kwilanna, false) -- clear the ignore AI flag
if (Dlc2_m01_runtime.current_checkpoint == Dlc2_m01_checkpoints.armory_take2.name) then
notoriety_force_no_spawn("Police", false)
notoriety_force_no_air_spawn(true)
notoriety_set_min_and_max("Police", Dlc2_m01_tweak_values.armory_notoriety_rescue_kwilanna, Dlc2_m01_tweak_values.armory_notoriety_rescue_kwilanna)
Dlc2_m01_dialog_lines.untie_kwilanna_take2_01.persona = player_name
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.untie_kwilanna_take2_03, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
Dlc2_m01_dialog_lines.untie_kwilanna_take2_01.persona = player_name
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.untie_kwilanna_take2_02, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
-- Make Kwilanna a homie
party_add(Dlc2_m01_characters.kwilanna, LOCAL_PLAYER)
follower_make_independent(Dlc2_m01_characters.kwilanna, true)
on_dismiss("dlc2_m01_kwilanna_dismissed_cb", Dlc2_m01_characters.kwilanna)
npc_combat_enable(Dlc2_m01_characters.kwilanna, true)
dlc2_m01_helper_set_kwilanna_invulnerable(false) -- no longer invulnerable
Dlc2_m01_runtime.rescued_kwilanna = true
end
-- Callback when the player enters the radius near Kwilanna's helicopter
function dlc2_m01_kwilanna_heli_radius_cb()
if (Dlc2_m01_runtime.kwilanna_heli_radius_triggered == false) then
Dlc2_m01_runtime.kwilanna_heli_radius_triggered = true
-- Make the pilot leave the helicopter
local dist, closest_player = get_dist_closest_player_to_object(Dlc2_m01_groups.kwilanna_heli.heli.pilot)
vehicle_suppress_npc_exit(Dlc2_m01_groups.kwilanna_heli.heli.vehicle, false)
vehicle_exit(Dlc2_m01_groups.kwilanna_heli.heli.pilot, true)
end
end
-- Callback for when one of the tower guards at the armory (take1) is killed
--
-- victim: Name of the guard that was killed
-- attacker: Name of the person who killed the guard
function dlc2_m01_take1_tower_guard_killed_cb(victim, attacker)
Dlc2_m01_runtime.num_tower_guards_alive = Dlc2_m01_runtime.num_tower_guards_alive - 1
on_death("", victim)
-- Check if enough tower guards have been killed to trigger the gate guards to move up
if (Dlc2_m01_runtime.num_tower_guards_alive <= Dlc2_m01_tweak_values.num_tower_guards_to_trigger_gate) then
dlc2_m01_ambush_activate_triggered_cb(LOCAL_PLAYER, Dlc2_m01_rail_ambushes.helipad_take1[1].activate_trigger)
end
end
-- Callback when an alien spaceship is destroyed
function dlc2_m01_alien_spaceship_destroyed_cb(victim)
on_vehicle_destroyed("", victim)
local num_jetbikes_alive = 0
local victim_is_jetbike = false
for i, vehicle_table in pairs(Dlc2_m01_groups.alien_tunnel_ambush.chase_vehicles) do
if (vehicle_exists(vehicle_table.vehicle) == true and vehicle_is_destroyed(vehicle_table.vehicle) == false) then
num_jetbikes_alive = num_jetbikes_alive + 1
end
if (victim == vehicle_table.vehicle) then
victim_is_jetbike = true
end
end
local show_progress = true
if (victim_is_jetbike == true and num_jetbikes_alive > 0) then
show_progress = false
end
dlc2_m01_helper_achievement_increment(Dlc2_m01_acheivements.alien_ships, show_progress)
end
-- Callback for a vehicle to explode when it takes damage from the world
--
-- victim: The vehicle that was damaged
-- attacker: The character that caused the damage
function dlc2_m01_destroy_vehicle_on_collision_cb(victim, attacker)
if (attacker == nil) then
vehicle_detonate(victim)
delay(1.0)
if (rand_int(1, 3) == 1 and thread_check_done(Dlc2_m01_dialog_queue.playing.thread_id) == true) then
dlc2_m01_helper_dialog_play(Dlc2_m01_dialog_lines.car_chase_explosions, DLC2_M01_CONVO_PLAY_NEXT, 0.0)
end
end
end
function dlc2_m01_setup_heli_cameramen()
group_create_hidden(Dlc2_m01_groups.armory_camera_persue_heli.name, true)
vehicle_enter_teleport(Dlc2_m01_groups.armory_camera_persue_heli.heli.npcs[1], Dlc2_m01_groups.armory_camera_persue_heli.heli.vehicle, 0, true)
vehicle_enter_teleport(Dlc2_m01_groups.armory_camera_persue_heli.heli.npcs[2], Dlc2_m01_groups.armory_camera_persue_heli.heli.vehicle, 5, true)
dlc2_m01_helper_setup_camera_man(Dlc2_m01_groups.armory_camera_persue_heli.heli.npcs[2])
end
-- Callback when the player's get away vehicle is destroyed
function dlc2_m01_get_away_vehicle_destroyed_cb()
mission_end_failure("dlc2_m01", "DLC2_M01_FAIL_ESCAPE_CAR_DESTROYED")
end
-- Reset the acheivement count for mission start
function dlc2_m01_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_m01_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_m01_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_m01_helper_achievement_increment(achievement_table, show_progress)
if (show_progress == nil) then
show_progress = true
end
-- 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
if (show_progress == true) then
hud_achievement_show_progress(achievement_table.name, achievement_table.current_count, achievement_table.target_goal)
end
end