--[[
m03.lua
SR3 Mission Script
DATE: 5/18/10
AUTHOR: Nick Heilmann
]]--
M03_DEBUG = {
infinity = 999999999,
large_cash_sum = 100,
message_handle = INVALID_MESSAGE_HANDLE,
}
M03_cte = {
name = "m03_cte_01",
}
M03_status = {
convo_is_playing = false,
item_purchased = false,
warehouse_objective = false,
satellite_timer_elapsed = false,
helis_destroyed = 0,
fly_home_played = false,
}
M03_weapon = {
satellite_drone_weapon = "Special-Drone",
helicopter_ride = "Rifle-Gang",
cleanup = { "Rifle-Gang", "Special-Drone" },
}
M03_start_inventory = {
{
name = "Pistol-Gang",
reserve_ammo = 16,
},
{
name = "SMG-Gang",
reserve_ammo = 39,
},
}
M03_navpoint = {
heli_landing_pos = "Nav Heli Landing Pos",
shaundi_house = "Nav Shaundi House",
heli_blow_up = "Nav Blow Up",
end_local = "Nav End Local Player",
end_remote = "Nav End Remote Player",
}
M03_FlytoPoint = { "Flyto Point 001", "Flyto Point 002", "Flyto Point 003", "Flyto Point 004",
"Flyto Point 005", "Flyto Point 006" }
M03_scripted_path = {
fly_home_pierce = { "Fly Home Pierce 001", "Fly Home Pierce 002", "Fly Home Pierce 003", "Fly Home Pierce 004" },
fly_home_bomb = { "Fly Home Bomb 001", "Fly Home Bomb 002", "Fly Home Bomb 003", "Fly Home Bomb 004"},
fly_home_backup = { "Fly Home Backup 001", "Fly Home Backup 002", "Fly Home Backup 003", "Fly Home Backup 004" },
fly_home_enemy1 = { "Fly Home Enemy1 001", "Fly Home Enemy1 002", "Fly Home Enemy1 003", "Fly Home Enemy1 004" },
fly_home_enemy2 = { "Fly Home Enemy2 001", "Fly Home Enemy2 002", "Fly Home Enemy2 003", "Fly Home Enemy2 004" },
fly_home_enemy3 = { "Fly Home Enemy3 001", "Fly Home Enemy3 002", "Fly Home Enemy3 003", "Fly Home Enemy3 004" },
fly_home_enemy4 = { "Fly Home Enemy4 001", "Fly Home Enemy4 002", "Fly Home Enemy4 003", "Fly Home Enemy4 004" },
fly_home_enemy5 = { "Fly Home Enemy5 002", "Fly Home Enemy5 003", "Fly Home Enemy5 004" },
fly_home_enemy6 = { "Fly Home Enemy6 002", "Fly Home Enemy6 003", "Fly Home Enemy6 004" },
fly_home_enemy7 = { "Fly Home Enemy7 003", "Fly Home Enemy7 004" },
fly_home_enemy8 = { "Fly Home Enemy8 003", "Fly Home Enemy8 004" },
fly_home_enemy9 = { "Fly Home Enemy9 004" },
fly_home_enemy10 = { "Fly Home Enemy10 004" },
fly_home_secondary_enemies = { "Fly Home SE 001", "Fly Home SE 002" },
}
M03_trigger = {
weapon_store = {
name = "Trigger Weapon Store",
triggered = false
},
weapon_store2 = {
name = "Trigger Weapon Store2",
triggered = false
},
armory_entrance = {
name = "Trigger Armory Entrance",
triggered = false
},
armory_warehouse = {
name = "Trigger Armory Warehouse",
triggered = false
},
armory_warehouse_door = {
name = "Trigger Warehouse Door",
triggered = false
},
armory_warehouse_inside = {
name = "Trigger Warehouse Inside",
triggered = false
},
weapons_cache = {
name = "Trigger Weapons Cache",
triggered = false
},
satellite_weapon = {
name = "Trigger Satellite Weapon",
triggered = false
},
enter_heli = {
name = "Enter_Heli_trigger",
triggered = false
},
fly_home_secondary_enemies = {
name = "Trigger Fly Home SE",
triggered = false
},
blow_up_helis = {
name = "Trigger Blow Up Helis",
triggered = false
},
callout1 = {
name = "Trigger Callout 1",
triggered = false
},
callout2 = {
name = "Trigger Callout 2",
triggered = false
},
callout3 = {
name = "Trigger Callout 3",
triggered = false
},
callout4 = {
name = "Trigger Callout 4",
triggered = false
},
traffic = {
name = "Trigger Traffic",
triggered = false
},
traffic1 = {
name = "Trigger Traffic<001>",
triggered = false
},
}
M03_char = {
shaundi = "NPC Shaundi",
pierce = "NPC Pierce",
fly_home_enemies = {
{ "NPC Fly Home Enemy 001", "NPC Fly Home Enemy 002" },
{ "NPC Fly Home Enemy 003", "NPC Fly Home Enemy 004" },
{ "NPC Fly Home Enemy 005", "NPC Fly Home Enemy 006" },
{ "NPC Fly Home Enemy 007", "NPC Fly Home Enemy 008" },
{ "NPC Fly Home Enemy 009", "NPC Fly Home Enemy 010" },
{ "NPC Fly Home Enemy 011", "NPC Fly Home Enemy 012" },
{ "NPC Fly Home Enemy 013", "NPC Fly Home Enemy 014" },
{ "NPC Fly Home Enemy 015", "NPC Fly Home Enemy 016" },
{ "NPC Fly Home Enemy 017", "NPC Fly Home Enemy 018" },
{ "NPC Fly Home Enemy 019", "NPC Fly Home Enemy 020" },
},
fly_home_secondary_enemies = {
{ "NPC Fly Home Secondary Enemy 001", "NPC Fly Home Secondary Enemy 002" },
{ "NPC Fly Home Secondary Enemy 003", "NPC Fly Home Secondary Enemy 004" },
},
}
M03_vehicle = {
fly_home_enemies = { "Veh Fly Home Enemy 001", "Veh Fly Home Enemy 002", "Veh Fly Home Enemy 003", "Veh Fly Home Enemy 004",
"Veh Fly Home Enemy 005", "Veh Fly Home Enemy 006", "Veh Fly Home Enemy 007", "Veh Fly Home Enemy 008",
"Veh Fly Home Enemy 009", "Veh Fly Home Enemy 010" },
fly_home_secondary_enemies = { "Veh Fly Home Secondary Enemy 001", "Veh Fly Home Secondary Enemy 002" },
}
M03_item = {
satellite_weapon = "Item Satellite Weapon",
}
M03_group = {
shaundi = {
name = "GRP Shaundi",
chars = { M03_char.shaundi }
},
starting_vehicle = {
name = "GRP Starting Veh",
vehicle = "Veh Starting Veh"
},
vehicle_get_the_goods = {
name = "GRP Get The Goods Veh"
},
guns = {
name = "Guns_group"
},
armory_guards = {
name = "GRP Armory Guards",
-- group A
group_a_members = { "group_a_guard<001>", "group_a_guard<002>", "group_a_guard<003>",
"group_a_guard<004>", "group_a_guard<005>", "group_a_guard<006>" },
group_a_navs = { "group_a_nav<001>", "group_a_nav<002>", "group_a_nav<003>" },
-- group B
group_b_members = { "group_b_guard<001>", --"group_b_guard<002>", --"group_b_guard<003>",
"group_b_guard<004>", --"group_b_guard<005>", "group_b_guard<006>",
"group_b_guard<007>", "group_b_guard<008>" },
group_b_navs = { "group_b_nav<001>", --"group_b_nav<002>", "group_b_nav<003>",
"group_b_nav<004>", "group_b_nav<005>", "group_b_nav<006>"},
-- "group_b_nav<007>", --[["group_b_nav<008>"]]-- },
-- group C
group_c_members = { "group_c_guard<001>", "group_c_guard<002>", --"group_c_guard<003>",
-- too many "group_c_guard<004>",
"group_c_guard<005>", "group_c_guard<006>",
--"group_c_guard<007>",
-- too many "group_c_guard<008>"
},
group_c_navs = { "group_c_nav<001>",-- "group_c_nav<002>",
"group_c_nav<003>",
"group_c_nav<004>",
"group_c_nav<005>", --"group_c_nav<006>",
--"group_c_nav<007>",
--"group_c_nav<008>"
},
},
warehouse_cover_vehicles = {
name = "GRP Warehouse Cover Vehicles"
},
the_army = {
name = "GRP The Army",
squad1 = {
members = { "Squad1<001>", "Squad1<002>", "Squad1<003>", }, -- "Squad1<004>", },
dest = "Squad1_dest",
thread = INVALID_THREAD_HANDLE
},
squad2 = {
members = { "Squad2<001>", "Squad2<002>", "Squad2<003>", }, -- "Squad2<004>", },
dest = "Squad2_dest",
thread = INVALID_THREAD_HANDLE
},
squad3 = {
members = { "Squad3<001>", "Squad3<002>", "Squad3<003>", }, -- "Squad3<004>", },
dest = "Squad3_dest",
thread = INVALID_THREAD_HANDLE
},
squad4 = {
members = { "Squad4<001>", "Squad4<002>", "Squad4<003>", }, -- "Squad4<004>", },
dest = "Squad4_dest",
thread = INVALID_THREAD_HANDLE
},
squad5 = {
members = { "Squad5<001>", "Squad5<002>", "Squad5<003>", }, -- "Squad5<004>", },
dest = "Squad5_dest",
thread = INVALID_THREAD_HANDLE
},
squad6 = {
members = { "Squad6<001>", "Squad6<002>", "Squad6<003>", }, -- "Squad6<004>", },
dest = "Squad6_dest",
thread = INVALID_THREAD_HANDLE
},
},
tank1 = {
name = "Tank1_group",
vehicle = "Tank1_tank",
members = { "Tank1_guard<001>", "Tank1_guard<002>" },
dest = "Tank1_path",
move_thread = INVALID_THREAD_HANDLE,
delay_gunner_thread = INVALID_THREAD_HANDLE
},
tank2 = {
name = "Tank2_group",
vehicle = "Tank2_tank",
members = { "Tank2_guard<001>", "Tank2_guard<002>" },
dest = "Tank2_path",
move_thread = INVALID_THREAD_HANDLE,
delay_gunner_thread = INVALID_THREAD_HANDLE
},
tank3 = {
name = "Tank3_group",
vehicle = "Tank3_tank",
members = { "Tank3_guard<001>", "Tank3_guard<002>" },
dest = "Tank3_path",
move_thread = INVALID_THREAD_HANDLE,
delay_gunner_thread = INVALID_THREAD_HANDLE
},
satellite_weapon = {
name = "GRP Item Satellite Weapon",
items = { M03_item.satellite_weapon }
},
satellite_attack1 = {
name = "GRP CS Satellite Attack 001",
members = { "NPC Satellite Attack 001", "NPC Satellite Attack 002" },
vehicle = "Veh Satellite Attack 001",
dest = "APC_path01",
thread = INVALID_THREAD_HANDLE
},
satellite_attack2 = {
name = "GRP CS Satellite Attack 002",
members = { "NPC Satellite Attack 003", "NPC Satellite Attack 004" },
vehicle = "Veh Satellite Attack 002",
dest = "APC_path02",
thread = INVALID_THREAD_HANDLE
},
satellite_attack3 = {
name = "GRP CS Satellite Attack 003",
members = { "NPC Satellite Attack 005", "NPC Satellite Attack 006" },
vehicle = "Veh Satellite Attack 003",
dest = "APC_path03",
thread = INVALID_THREAD_HANDLE
},
satellite_attack4 = {
name = "GRP CS Satellite Attack 004",
members = { "NPC Satellite Attack 007", "NPC Satellite Attack 008" },
vehicle = "Veh Satellite Attack 004",
dest = "APC_path04",
thread = INVALID_THREAD_HANDLE
},
satellite_attack5 = {
name = "GRP CS Satellite Attack 005",
members = { "NPC Satellite Attack 009", "NPC Satellite Attack 010" },
vehicle = "Veh Satellite Attack 005",
dest = "APC_path05",
thread = INVALID_THREAD_HANDLE
},
satellite_attack6 = {
name = "GRP CS Satellite Attack 006",
members = { "NPC Satellite Attack 011", "NPC Satellite Attack 012" },
vehicle = "Veh Satellite Attack 006",
dest = "APC_path06",
thread = INVALID_THREAD_HANDLE
},
satellite_attack7 = {
name = "GRP CS Satellite Attack 007",
members = { "NPC Satellite Attack 013", "NPC Satellite Attack 014" },
vehicle = "Veh Satellite Attack 007",
dest = "APC_path07",
thread = INVALID_THREAD_HANDLE
},
satellite_attack8 = {
name = "GRP CS Satellite Attack 008",
members = { "NPC Satellite Attack 015", "NPC Satellite Attack 016" },
vehicle = "Veh Satellite Attack 008",
dest = "APC_path08",
thread = INVALID_THREAD_HANDLE
},
satellite_attack9 = {
name = "GRP CS Satellite Attack 009",
members = { "NPC Satellite Attack 017", "NPC Satellite Attack 018" },
vehicle = "Veh Satellite Attack 009",
dest = "APC_path09",
thread = INVALID_THREAD_HANDLE
},
satellite_attack10 = {
name = "GRP CS Satellite Attack 010",
members = { "NPC Satellite Attack 019", "NPC Satellite Attack 020" },
vehicle = "Veh Satellite Attack 010",
dest = "APC_path10",
thread = INVALID_THREAD_HANDLE
},
target_practice = {
name = "GRP Target Practice",
members = { "npc_NG_target 001", "npc_NG_target 002", "npc_NG_target 003",
"npc_NG_target 004", "npc_NG_target 005", "npc_NG_target 006",
"npc_NG_target 007", "npc_NG_target 008", "npc_NG_target 009" },
vehicles = { "veh_NG_target 001", "veh_NG_target 002", "veh_NG_target 003" },
},
choppers = {
name = "GRP Choppers",
pierce = {
vehicle = "Veh Chopper Pierce Normal", -- NOTE: not actually in the group
pilots = { "NPC Pierce" }, --[[, "NPC Pierce Copilot"]]--
float_nav = "Nav Heli Float Pos Pierce",
thread = INVALID_THREAD_HANDLE
},
bomb = {
vehicle = "Veh Chopper Bomb",
pilots = { "NPC Bomb Pilot 001" },--[[, "NPC Bomb Pilot 002"]]--
float_nav = "Nav Heli Float Pos Bomb",
pickup_nav = { "Bomb_pickup<001>", "Bomb_pickup<002>" },
thread = INVALID_THREAD_HANDLE
},
backup = {
vehicle = "Veh Chopper Backup",
pilots = { "NPC Backup Pilot 001", "NPC Backup Pilot 002" },
float_nav = "Nav Heli Float Pos Backup",
thread = INVALID_THREAD_HANDLE
},
},
chopper_pierce_normal = {
name = "GRP Chopper Pierce Normal",
vehicles = { "Veh Chopper Pierce Normal" }
},
fly_home_enemies = {
name = "GRP Fly Home Enemies",
chars = M03_char.fly_home_enemies,
vehicles = M03_vehicle.fly_home_enemies
},
fly_home_secondary_enemies = {
name = "GRP Fly Home Secondary Enemies",
chars = M03_char.fly_home_secondary_enemies,
vehicles = M03_vehicle.fly_home_secondary_enemies
},
cte_shaundi_group = {
name = "m3_cte_shaundi_01",
},
cte_soldier_group = {
name = "m3_cte_soldiers_01",
},
cte_apc_group = {
name = "m3_cte_apcs_01",
},
initial_guard = {
name = "GRP Initial Guard",
members = { "npc_InitialGuard1", "npc_InitialGuard2" },
vehicles = { "veh_Initial Guard1", "veh_Initial Guard2" },
},
}
M03_choppers = { M03_group.choppers.pierce, M03_group.choppers.bomb, M03_group.choppers.backup }
-- Guards running around as you enter the warehouse (required kills)
M03_warehouse_guard_wave = {
outside = {
trigger = M03_trigger.armory_warehouse,
members = M03_group.armory_guards.group_a_members,
locations = M03_group.armory_guards.group_a_navs
},
door = {
trigger = M03_trigger.armory_warehouse_door,
members = M03_group.armory_guards.group_b_members,
locations = M03_group.armory_guards.group_b_navs
},
inside = {
trigger = M03_trigger.armory_warehouse_inside,
members = M03_group.armory_guards.group_c_members,
locations = M03_group.armory_guards.group_c_navs
},
}
M03_tanks = { M03_group.tank1, M03_group.tank2, M03_group.tank3 }
M03_tank_attack1 = { M03_group.tank1 }
M03_tank_attack2 = { M03_group.tank2 }
M03_tank_attack3 = { M03_group.tank1, M03_group.tank3 }
M03_tank_attacks = { M03_tank_attack1, M03_tank_attack2, M03_tank_attack3 }
M03_all_satellite_groups = { M03_group.satellite_attack1, M03_group.satellite_attack2, M03_group.satellite_attack3,
M03_group.satellite_attack4, M03_group.satellite_attack5, M03_group.satellite_attack6,
M03_group.satellite_attack7, M03_group.satellite_attack8, M03_group.satellite_attack9,
M03_group.satellite_attack10 }
M03_num_satellite_attackers = 3
M03_satellite_attack1 = { M03_group.satellite_attack1, M03_group.satellite_attack2, M03_group.satellite_attack3 }
M03_satellite_attack2 = { M03_group.satellite_attack1, M03_group.satellite_attack2, M03_group.satellite_attack3,
M03_group.satellite_attack4, M03_group.satellite_attack5 }
M03_satellite_attack3 = M03_all_satellite_groups
M03_satellite_attack = { M03_satellite_attack1, M03_satellite_attack2, M03_satellite_attack3 }
M03_text = {
steal_a_car = "M03_OBJ_STEAL_A_CAR",
set_gps = "M03_OBJ_ACCESS_MAP", --"M03_OBJ_SET_GPS",
go_to_weapon_store = "M03_OBJ_GO_TO_WEAPON_STORE",
purchase_an_upgrade = "M03_OBJ_PURCHASE_AN_UPGRADE",
go_to_armory = "M03_OBJ_GO_TO_ARMORY",
go_to_warehouse = "M03_OBJ_GO_TO_WAREHOUSE",
find_weapons_cache = "M03_OBJ_FIND_WEAPONS_CACHE",
kill_guards = "M03_OBJ_KILL_GUARDS",
cutscene_found_weapons_cache = "M03_OBJ_CUTSCENE_FOUND_WEAPONS_CACHE",
hold_your_position = "M03_OBJ_HOLD_YOUR_POSITION",
eliminate_reinforcements = "M03_OBJ_ELIMINATE_REINFORCEMENTS",
use_satellite_weapon = "M03_OBJ_USE_SATELLITE_WEAPON",
protect_the_stash = "M03_OBJ_PROTECT_THE_STASH",
go_to_chopper = "M03_OBJ_GO_TO_CHOPPER",
protect_the_bomb = "M03_OBJ_PROTECT_THE_BOMB",
current_handle = INVALID_MESSAGE_HANDLE,
failure_bomb_destroyed = "m03_failure_bomb_destroyed",
failure_heli_destroyed = "m03_failure_heli_destroyed",
failure_pierce_destroyed = "m03_failure_pierce_destroyed",
}
M03_convo = {
phillipe_call = {
name = "m03_phillipe_call",
handle = INVALID_CONVERSATION_HANDLE,
persona_name = "Phillipe",
persona_id = INVALID_PERSONA_HANDLE,
call_complete = false
},
mission_start = {
name = "m03_convo_1",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false,
thread = INVALID_THREAD_HANDLE
},
set_gps = {
name = "M03_GPS_Tutorial_For_FF",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
to_gun_store1 = {
name = "M03_To_Gun_Store_1",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
to_gun_store2 = {
name = "M03_To_Gun_Store_2",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
to_armory = {
name = "M03_To_Armory",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
armory_arrival = {
name = "M03_Arrive_Warehouse",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
armory_combat = {
name = "M03_Arrive_Combat",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
bomb_found = {
name = "m03_convo_4",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
cavalry = {
name = "m03_convo_5",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false,
-- added persona info in standard format
persona_name = "Pierce",
persona_id = INVALID_PERSONA_HANDLE
},
defend_area = {
name = "M03_Defend_Area",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
satellite_start = {
name = "m03_convo_6",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
drone_operator1 = {
name = "M03_Drone_Operator_1",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = true
},
drone_operator2 = {
name = "M03_Drone_Operator_2",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = true
},
stash_combat1 = {
name = "M03_Stash_Combat_1",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
stash_combat2 = {
name = "M03_Stash_Combat_2",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
get_in_chopper = {
name = "M03_Get_In_Chopper",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
protect_bomb = {
name = "M03_Protect_Bomb",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
fly_home = {
name = "M03_Arrive_Studio",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
callout1 = {
name = "M03_Calling_Out_Places_1",
handle = INVALID_CONVERSATION_HANDLE,
load_direct = false
},
}
M03_attack_info = {
situation = "M03_attack",
delay = 10.0,
callback = "m03_process_attack_cb",
timer = INVALID_THREAD_HANDLE
}
M03_see_saints_info = {
situation = "M03_defend_bomb",
delay = 10.0,
callback = "m03_process_see_saints_cb",
timer = INVALID_THREAD_HANDLE
}
-- 2d voices
M03_drone_voices = {
operator1 = {
persona_name = "Interrogation",
persona_id = INVALID_PERSONA_HANDLE
},
}
M03_drone_operators = {
{
is_conversation = true,
conversation = M03_convo.drone_operator1,
spoken = false
},
{
is_conversation = true,
conversation = M03_convo.drone_operator2,
spoken = false
},
{
is_conversation = false,
speaker = M03_drone_voices.operator1,
line = "M03_Drone_Operator_03",
spoken = false
},
{
is_conversation = false,
speaker = M03_drone_voices.operator1,
line = "M03_Drone_Operator_04",
spoken = false
},
}
M03_heli_shot_down = {
hit1 = {
speaker = M03_char.shaundi,
line = "M03_Nice_Hit_01",
spoken = false
},
hit2 = {
speaker = M03_char.pierce,
line = "M03_Nice_Hit_02",
spoken = false
},
hit1 = {
speaker = M03_char.shaundi,
line = "M03_Nice_Hit_03",
spoken = false
},
}
M03_radio_chatter = {
line1 = {
speaker = M03_char.pierce,
line = "M03_Radio_Chatter_01",
spoken = false
},
line2 = {
speaker = M03_char.pierce,
line = "M03_Radio_Chatter_02",
spoken = false
},
line3 = {
speaker = M03_char.pierce,
line = "M03_Radio_Chatter_03",
spoken = false
},
line4 = {
speaker = M03_char.pierce,
line = "M03_Radio_Chatter_04",
spoken = false
},
}
M03_chopper_combat = {
line1 = {
speaker = M03_char.shaundi,
line = "M03_Chopper_Combat_01",
spoken = false
},
line2 = {
speaker = M03_char.shaundi,
line = "M03_Chopper_Combat_02",
spoken = false
},
line3 = {
speaker = M03_char.shaundi,
line = "M03_Chopper_Combat_03",
spoken = false
},
}
M03_thread = {
start_conversation = INVALID_THREAD_HANDLE,
drive_conversations = INVALID_THREAD_HANDLE,
gps_tutorial = INVALID_THREAD_HANDLE,
weapon_upgrade_purchased = INVALID_THREAD_HANDLE,
warehouse_approach = INVALID_THREAD_HANDLE,
fly_home_convo = INVALID_THREAD_HANDLE,
satellite_attack = INVALID_THREAD_HANDLE,
satellite_convos = INVALID_THREAD_HANDLE,
chatter = INVALID_THREAD_HANDLE,
chatter_timer = INVALID_THREAD_HANDLE,
move_to_float = { },
fly_home = { },
fly_home_enemy_chase = { },
fly_home_secondary_enemy_chase = { },
fly_home_enemy_setup = { },
landing = INVALID_THREAD_HANDLE,
pierce_float = INVALID_THREAD_HANDLE,
}
M03_checkpoint = {
start = {
name = MISSION_START_CHECKPOINT, -- defined in ug_lib.lua
player_local = "Nav CP Start Local",
player_remote = "Nav CP Start Remote"
},
get_the_goods = {
name = "get the goods",
player_local = "Nav CP Get The Goods Local",
player_remote = "Nav CP Get The Goods Remote"
},
hold_your_ground = {
name = "hold your ground",
player_local = "Nav CP Protect The Stash Local",
player_remote = "Nav CP Protect The Stash Remote"
},
protect_the_stash = {
name = "protect the stash",
player_local = "Nav CP Protect The Stash Local",
player_remote = "Nav CP Protect The Stash Remote"
},
helicopter_ride = {
name = "helicopter ride",
player_local = "Nav CP Helicopter Ride Local",
player_remote = "Nav CP Helicopter Ride Remote"
},
}
M03_teleport = {
weapon_local = "Nav Weapon Store Local",
weapon_remote = "Nav Weapon Store Remote",
}
M03_cutscene = {
mission_intro = nil,
found_weapons_cache = nil,
pierce_entrance = "03_Z01",
mission_outro = "03_out",
}
M03_warehouse_guards_alive = 0
M03_warehouse_guards_killed = 0
M03_warehouse_triggers_left = 0
M03_bomb_mover = "DaBomb"
-- Stuff to kill the helis (don't know where to put this)
M03_Kill_Heli_Navs = { "nav_Heli_Kill 001", "nav_Heli_Kill 002", "nav_Heli_Kill 003", "nav_Heli_Kill 004" }
M03_kill_heli = ""
-- Stuff to track the weapon store objective in coop
Weapon_store_completion = { }
Weapon_store_completion[LOCAL_PLAYER] = false
Weapon_store_completion[REMOTE_PLAYER] = not coop_is_active()
M03_given_drone = false
M03_riding_helicopter = false
--------------------------------------------------------------------------------------------------
--[[********************]]--
--[[ ]]--
--[[ Standard functions ]]--
--[[ ]]--
--[[********************]]--
-- This is the primary entry point for the mission, and is responsible for starting up the mission
-- at the specified checkpoint.
-- CALLED FROM CODE
--
-- m03_checkpoint: (string) The checkpoint the mission should begin at
-- is_restart: (bool) TRUE if the mission is restarting, FALSE otherwise
--
function m03_start(m03_checkpoint, is_restart)
-- Check if this mission starting from the beginning
if (m03_checkpoint == M03_checkpoint.start.name) then
set_ped_override_density(1)
if (not is_restart) then
-- First time playing mission
-- Play an intro cutscene???
if (M03_cutscene.mission_intro ~= nil) then
cutscene_play(M03_cutscene.mission_intro)
end
end
end
-- Handle mission initialization for the current checkpoint
m03_initialize(m03_checkpoint)
-- Run the mission from the current checkpoint
m03_run(m03_checkpoint)
end
-- Initialize the mission for the specified checkpoint
--
-- checkpoint: Checkpoint to initialize the mission to
--
function m03_initialize(checkpoint)
-- Make sure the screen is completly faded out
mission_start_fade_out(0.0)
-- Set the mission author
set_mission_author("Neil Ryan")
-- Common initialization
m03_initialize_common()
-- Checkpoint specific initialization
m03_initialize_checkpoint(checkpoint)
-- Start fading in
mission_start_fade_in()
end
-- Handle any common initialization
--
function m03_initialize_common()
-- ignore clerk state for this mission
shop_ignore_clerk(true)
-- don't play newsbreak unless we say so
radio_newsbreak_clear()
M03_given_drone = false
notoriety_force_no_spawn("luchadores", true)
notoriety_force_no_spawn("deckers", true)
notoriety_force_no_spawn("morningstar", true)
notoriety_force_no_spawn("police", true)
-- TEST
--notoriety_set_min_and_max("police", 0, 0)
--notoriety_set_min_and_max("luchadores", 0, 0)
--notoriety_set_min_and_max("morningstar", 0, 0)
--notoriety_set_min_and_max("deckers", 0, 0)
-- Set the persona situation override for Pierce
persona_set_global_situation_override(PS_OVERRIDE_MISSION03)
-- Turn traffic splines around the armory off
m03_traffic_off()
mesh_mover_reset(M03_bomb_mover)
mesh_mover_show(M03_bomb_mover)
end
-- Checkpoint specific initialization
--
-- checkpoint: The checkpoint to be initialized
--
function m03_initialize_checkpoint(checkpoint)
if (checkpoint == M03_checkpoint.start.name) then
m03_initialize_start()
elseif (checkpoint == M03_checkpoint.get_the_goods.name) then
m03_initialize_get_the_goods()
elseif (checkpoint == M03_checkpoint.hold_your_ground.name) then
group_create(M03_group.guns, true)
m03_initialize_hold_your_ground()
elseif (checkpoint == M03_checkpoint.protect_the_stash.name) then
mesh_mover_hide(M03_bomb_mover)
group_create(M03_group.guns, true)
m03_initialize_protect_the_stash()
elseif (checkpoint == M03_checkpoint.helicopter_ride.name) then
mesh_mover_hide(M03_bomb_mover)
m03_initialize_helicopter_ride()
end
end
-- This is the primary function responsible for running the entire mission from start to finish.
--
-- first_checkpoint: (string) The first checkpoint to begin running the mission at
--
function m03_run(first_checkpoint)
local current_checkpoint = first_checkpoint
local ignore_vehicles = false
-- Run the mission from the beginning
if (current_checkpoint == M03_checkpoint.start.name) then
-- Prevent player from being able to get notoriety
notoriety_set_min_and_max("police", 0, 0)
notoriety_set_min_and_max("morningstar", 0, 0)
m03_steal_a_car()
m03_go_to_weapon_store()
m03_weapon_upgrade_tutorial()
-- Now move on to the next checkpoint
current_checkpoint = M03_checkpoint.get_the_goods.name
mission_set_checkpoint(M03_checkpoint.get_the_goods.name, ignore_vehicles)
end
-- Allow the player to get some notoriety now
notoriety_set_min_and_max("police", 0, 3)
notoriety_set_min_and_max("morningstar", 0, 3)
ignore_vehicles = true
if (current_checkpoint == M03_checkpoint.get_the_goods.name) then
m03_go_to_armory()
m03_objective_find_the_weapons()
m03_cutscene_approach_stash()
-- Now move on to the next checkpoint
current_checkpoint = M03_checkpoint.hold_your_ground.name
mission_set_checkpoint(M03_checkpoint.hold_your_ground.name, ignore_vehicles)
end
if (current_checkpoint == M03_checkpoint.hold_your_ground.name) then
zscene_prep(M03_cutscene.pierce_entrance)
m03_objective_hold_your_ground()
m03_cutscene_pierce_entrance()
-- Now move on to the next checkpoint
current_checkpoint = M03_checkpoint.protect_the_stash.name
mission_set_checkpoint(M03_checkpoint.protect_the_stash.name, ignore_vehicles)
end
if (current_checkpoint == M03_checkpoint.protect_the_stash.name) then
m03_objective_protect_the_stash()
-- Now move on to the next checkpoint
current_checkpoint = M03_checkpoint.helicopter_ride.name
mission_set_checkpoint(M03_checkpoint.helicopter_ride.name, ignore_vehicles)
end
if (current_checkpoint == M03_checkpoint.helicopter_ride.name) then
M03_riding_helicopter = true
m03_objective_helicopter_ride()
M03_riding_helicopter = false
end
-- Call mission success??
local end_navs = {M03_navpoint.end_local, M03_navpoint.end_remote}
mission_end_success("m03", M03_cutscene.mission_outro, end_navs)
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATELY+++)
--
function m03_cleanup()
-- make sure nothing is running first (or we may create things after they are cleaned up)
cleanup_threads(M03_thread)
if M03_riding_helicopter then
-- set a cancel teleport so we don't fall when we fail
teleport(LOCAL_PLAYER, M03_checkpoint.helicopter_ride.player_local, true)
teleport(REMOTE_PLAYER, M03_checkpoint.helicopter_ride.player_remote, true)
end
-- set ped density back to normal levels
set_ped_override_density(-1)
-- kill guards and their callbacks
m03_cleanup_warehouse_guards()
-- kill hud prompt callback
hud_prompt_clear()
-- cleanup cell phone call
m03_call_complete_cb()
-- stupid tutorial thing
tutorial_vehicle_controls_enabled(true)
-- no more GPS tutorial
pause_map_tutorial_mode(false)
-- re-enable clerk checks for stores
shop_ignore_clerk(false)
-- done with this
set_cops_shooting_from_vehicles(false)
notoriety_force_no_spawn("luchadores", false)
notoriety_force_no_spawn("deckers", false)
notoriety_force_no_spawn("morningstar", false)
notoriety_force_no_spawn("police", false)
-- TEST
notoriety_set_min_and_max("police", 0, MAX_NOTORIETY_LEVEL)
notoriety_set_min_and_max("luchadores", 0, MAX_NOTORIETY_LEVEL)
notoriety_set_min_and_max("morningstar", 0, MAX_NOTORIETY_LEVEL)
notoriety_set_min_and_max("deckers", 0, MAX_NOTORIETY_LEVEL)
-- END TEST
-- njr - no longer care about teleporting them. There is no exit except success for this mission.
---- Teleport them to a safe location
--teleport(LOCAL_PLAYER, M03_navpoint.end_local, true)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
if (coop_is_active()) then
-- teleport(REMOTE_PLAYER, M03_navpoint.end_remote, true)
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
end
-- Stop the situation override.
persona_clear_global_situation_override()
-- no more callbacks
on_attack_performed("", LOCAL_PLAYER)
if coop_is_active() then
on_attack_performed("", REMOTE_PLAYER)
end
m03_cleanup_army_callbacks()
m03_forced_satellite_end()
-- Unload personas
m03_unload_persona(M03_convo.cavalry)
m03_unload_persona(M03_drone_voices.operator1)
cleanup_callbacks( { M03_char, M03_vehicle, M03_item } )
cleanup_callbacks( { M03_group.choppers.pierce.vehicle, M03_group.choppers.bomb.vehicle, M03_group.choppers.backup.vehicle } )
cleanup_groups(M03_group)
m03_clear_trigger_table()
on_purchase("")
cleanup_conversations(M03_convo)
inv_weapon_disable_all_slots(false)
-- Turn traffic splines around the armory back on
m03_traffic_on()
-- skip this if we gave the player the drone in success
if not M03_given_drone then
cleanup_temporary_weapons(M03_weapon.cleanup)
end
end
-- Called when the mission has ended with success
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function m03_success()
-- clean up temp weapons before we give the weapon
cleanup_temporary_weapons(M03_weapon.cleanup)
-- give the sat-drone weapon
inv_item_add(M03_weapon.satellite_drone_weapon, 1, LOCAL_PLAYER)
if (coop_is_active() == true) then
inv_item_add(M03_weapon.satellite_drone_weapon, 1, REMOTE_PLAYER)
end
M03_given_drone = true
m03_coop_skip( ) -- do the stuff we'd do in the skip case
end
--------------------------------------------------------------------------------------------------
--[[**************************]]--
--[[ ]]--
--[[ m03_run Helper Functions ]]--
--[[ ]]--
--[[**************************]]--
--[[ ]]--
--[[ FIRST CHECKPOINT (START OF MISSION) ]]--
--[[ ]]--
function m03_initialize_start()
teleport_coop(M03_checkpoint.start.player_local, M03_checkpoint.start.player_remote, true)
-- a bit of hackery to make sure the transition from mission 02 has happened ok
repeat
thread_yield()
until (get_dist(LOCAL_PLAYER, M03_checkpoint.start.player_local) < 10)
group_create(M03_group.shaundi.name, true)
thread_yield()
group_create(M03_group.starting_vehicle.name, true)
--teleport(M03_char.shaundi, M03_checkpoint.start.player_remote, true)
tutorial_vehicle_controls_enabled(false)
m03_give_players_weapons()
-- Player look cool GO!
-- set_ped_override_density(1) -- more peds during walk through red light district
local anim_name = "M03 Player Mission Start"
local morph_name = "M03 Player Mission Start"
local force_play = false
local percentage = 0.0
local stand_still = true
local zero_movement = true
action_play(LOCAL_PLAYER, anim_name, morph_name, force_play, percentage, stand_still, zero_movement)
end
-- Have the player steal a car
--
function m03_steal_a_car()
m03_add_shaundi()
M03_trigger.weapon_store.triggered = false
M03_trigger.weapon_store2.triggered = false
repeat
thread_yield()
until action_play_is_finished(LOCAL_PLAYER, 1.0)
-- Mark the car to steal
marker_add(M03_group.starting_vehicle.vehicle, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL)
-- Tell the player to steal a car
objective_text(0, M03_text.steal_a_car, nil, nil, SYNC_ALL, OI_ASSET_USE)
-- phillipe phone call timing
M03_convo.phillipe_call.call_complete = false
m03_load_persona(M03_convo.phillipe_call)
audio_play_for_mission_cellphone(M03_convo.phillipe_call.name, true, true, nil, "m03_call_complete_cb", M03_convo.phillipe_call.persona_id)
while not M03_convo.phillipe_call.call_complete do
thread_yield()
end
delay(2.5)
M03_thread.start_conversation = thread_new("m03_convo", M03_convo.mission_start)
local redisplay = true
local infinite_duration = true
tutorial_start("vehicle entry", 10000, false, redisplay, infinite_duration)
-- Wait till the player is in a car
repeat
thread_yield()
until (character_is_in_vehicle(LOCAL_PLAYER) or (coop_is_active() and character_is_in_vehicle(REMOTE_PLAYER)))
-- Take the marker off the car
marker_remove(M03_group.starting_vehicle.vehicle)
-- Ped density down
set_ped_override_density(-1)
-- Don't care if this is the vehicle anymore
release_to_world(M03_group.starting_vehicle.name)
tutorial_stop("vehicle entry")
M03_thread.drive_conversations = thread_new("m03_start_convos_thread")
objective_text_clear(0)
end
-- Direct the player to a weapon store so we can do the upgrade tutorial
--
function m03_go_to_weapon_store()
local add_waypoint = false
local add_marker = false
-- no waypoint or marker for this one because we want the player to set the GPS
m03_set_trigger(M03_trigger.weapon_store.name, "m03_weapon_store_trigger_cb", add_waypoint, add_marker)
marker_add_trigger(M03_trigger.weapon_store.name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT)
M03_thread.gps_tutorial = thread_new("m03_gps_tutorial_thread")
thread_yield()
-- Set up callout triggers
m03_set_trigger(M03_trigger.callout1.name, "m03_callout_1_cb", add_waypoint, add_marker)
m03_set_trigger(M03_trigger.callout2.name, "m03_callout_2_cb", add_waypoint, add_marker)
m03_set_trigger(M03_trigger.callout3.name, "m03_callout_3_cb", add_waypoint, add_marker)
m03_set_trigger(M03_trigger.callout4.name, "m03_callout_4_cb", add_waypoint, add_marker)
repeat
thread_yield()
until (M03_trigger.weapon_store2.triggered)
-- kill tutorial thread
thread_kill(M03_thread.gps_tutorial)
-- make sure tutorials are done
tutorial_stop("pause_map")
tutorial_stop("minimap")
tutorial_vehicle_controls_enabled(true)
objective_text_clear(0)
end
-- Do the weapon upgrade tutorial
--
function m03_weapon_upgrade_tutorial()
-- Set objective
objective_text(0, M03_text.purchase_an_upgrade, nil, nil, SYNC_ALL, OI_ASSET_USE)
on_purchase("m03_item_purchased_cb")
--tutorial_start("weapon_upgrades")
-- Wait for player to buy something
repeat thread_yield() until (M03_status.item_purchased)
-- Wait for player to get out of the interface before continuing
while (store_interface_is_active())do
thread_yield()
end
objective_text_clear(0)
end
-- Placeholder processing for making sure the player has money for upgrades
--
function m03_check_player_funds_for_upgrade()
-- Check if the player has enough money for an upgrade, if not, do the following
audio_play_persona_line(M03_char.shaundi, "M03_Out_Of_Cash")
thread_yield()
while audio_persona_line_playing(M03_char.shaundi) do
thread_yield()
end
-- Give him the cash he needs...
cash_add(M03_DEBUG.large_cash_sum)
if(coop_is_active())then
cash_add(M03_DEBUG.large_cash_sum, "#PLAYER2#")
end
end
--[[ ]]--
--[[ SECOND CHECKPOINT (GET THE GOODS) ]]--
--[[ ]]--
function m03_initialize_get_the_goods()
group_create(M03_group.shaundi.name, true)
teleport_coop(M03_checkpoint.get_the_goods.player_local, M03_checkpoint.get_the_goods.player_remote, true)
-- teleport Shaundi to where you are going to be
teleport(M03_char.shaundi, M03_checkpoint.get_the_goods.player_local, nil, nil, 0.0, 0.0, 1.4)
group_create(M03_group.vehicle_get_the_goods.name, true)
-- NOW add Shaundi and she won't go through a bunch of bad teleports
m03_add_shaundi()
end
function m03_go_to_armory()
M03_thread.weapon_upgrade_purchased = thread_new("m03_convo", M03_convo.to_armory)
objective_text(0, M03_text.go_to_armory, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
M03_trigger.armory_entrance.triggered = false
-- Clean up callout triggers
m03_clear_trigger(M03_trigger.callout1.name)
m03_clear_trigger(M03_trigger.callout2.name)
m03_clear_trigger(M03_trigger.callout3.name)
m03_clear_trigger(M03_trigger.callout4.name)
-- Create barricade guards
group_create_hidden(M03_group.initial_guard.name, true)
-- Direct them to the entrance of the armory
local add_waypoint = false
local add_marker = true
m03_set_trigger(M03_trigger.armory_entrance.name, "m03_armory_entrance_trigger_cb", add_waypoint, add_marker)
-- fake out gps a little
mission_waypoint_add("Tank1_dest")
local played_news = false
repeat
thread_yield()
if (not played_news) and (not M03_status.convo_is_playing) then
radio_newsbreak("m02")
played_news = true
end
until (M03_trigger.armory_entrance.triggered)
M03_thread.warehouse_approach = thread_new("m03_convo", M03_convo.armory_arrival)
objective_text_clear(0)
local add_waypoint = false
objective_text(0, M03_text.go_to_warehouse, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
m03_set_trigger(M03_trigger.weapons_cache.name, "m03_weapons_cache_trigger_cb", add_waypoint)
-- still direct to the front of warehouse
mission_waypoint_add("Tank1_dest")
group_create(M03_group.warehouse_cover_vehicles.name, true)
-- m03_warehouse_advance_cb
m03_setup_warehouse_guards()
local completed_takeover = false
local played_conversation = false
while not completed_takeover do
thread_yield()
if (M03_warehouse_guards_alive == 0) then
if (M03_warehouse_triggers_left == 0) then
completed_takeover = true
else
-- set objective go inside
m03_set_enter_warehouse_objective()
end
end
if (not played_conversation) and (M03_warehouse_guards_killed > 0) then
M03_thread.warehouse_approach = thread_new("m03_convo", M03_convo.armory_combat)
played_conversation = true
end
end
objective_text_clear(0)
end
function m03_objective_find_the_weapons()
objective_text(0, M03_text.find_weapons_cache, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
M03_trigger.weapons_cache.triggered = false
local add_waypoint = false
m03_set_trigger(M03_trigger.weapons_cache.name, "m03_weapons_cache_trigger_cb", add_waypoint)
-- This conversation should be done by now. If not, kill it with FIRE!!!
if not thread_check_done(M03_thread.warehouse_approach) then
cleanup_conversations(M03_convo)
end
-- Whenever the conversation is done, wait until they've reached the weapons cache
repeat
thread_yield()
until (M03_trigger.weapons_cache.triggered)
objective_text_clear(0)
end
function m03_cutscene_approach_stash()
local teleport_navs = {M03_checkpoint.hold_your_ground.player_local, M03_checkpoint.hold_your_ground.player_remote}
-- cutscene_in()
-- group_create_hidden( M03_group.cte_shaundi_group.name, true )
-- group_create_hidden( M03_group.cte_soldier_group.name, true )
-- group_create( M03_group.cte_apc_group.name, true )
-- cutscene_play(M03_cte.name, nil, teleport_navs)
-- group_destroy( M03_group.cte_shaundi_group.name )
-- group_destroy( M03_group.cte_soldier_group.name )
-- group_destroy( M03_group.cte_apc_group.name )
-- This should also bring Shaundi in with us...
--teleport_coop(M03_checkpoint.hold_your_ground.player_local, M03_checkpoint.hold_your_ground.player_remote, true)
objective_text_clear(0)
-- spawn a shitload of guys to (try to) hold you in the warehouse
group_create(M03_group.the_army.name, true)
m03_spawn_tanks()
group_create(M03_group.guns, true)
-- cutscene_out()
end
-----------------------------------------------
--[[ ]]--
--[[ THIRD CHECKPOINT (HOLD YOUR GROUND) ]]--
--[[ ]]--
function m03_initialize_hold_your_ground()
group_create(M03_group.shaundi.name, true)
-- Put everybody in their place
teleport_coop(M03_checkpoint.hold_your_ground.player_local, M03_checkpoint.hold_your_ground.player_remote, true)
-- teleport Shaundi to where you are going to be
teleport(M03_char.shaundi, M03_checkpoint.hold_your_ground.player_local, nil, nil, 0.0, 0.0, 1.4)
group_create(M03_group.warehouse_cover_vehicles.name, true)
-- spawn a shitload of guys to (try to) hold you in the warehouse
group_create(M03_group.the_army.name, true)
m03_spawn_tanks()
-- NOW add Shaundi and she won't go through a bunch of bad teleports
m03_add_shaundi()
end
function m03_objective_hold_your_ground()
-- marker_add(M03_bomb_mover, MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND)
objective_text(0, M03_text.hold_your_position, nil, nil, SYNC_ALL, OI_ASSET_DEFEND)
thread_new("m03_convo", M03_convo.defend_area)
-- keep Shaundi in the back of the warehouse
npc_leash_to_nav( M03_char.shaundi, M03_checkpoint.hold_your_ground.player_local, 25.0 )
-- send in the tanks
m03_deploy_tanks()
local advance = false
-- deploy the troops
M03_group.the_army.squad1.thread = thread_new("m03_deploy_troops_thread", M03_group.the_army.squad1, advance)
M03_group.the_army.squad2.thread = thread_new("m03_deploy_troops_thread", M03_group.the_army.squad2, advance)
M03_group.the_army.squad5.thread = thread_new("m03_deploy_troops_thread", M03_group.the_army.squad5, advance)
delay(2.0)
advance = true
M03_group.the_army.squad3.thread = thread_new("m03_deploy_troops_thread", M03_group.the_army.squad3, advance)
delay(6.0)
advance = false
M03_group.the_army.squad4.thread = thread_new("m03_deploy_troops_thread", M03_group.the_army.squad4, advance)
delay(2.0)
M03_group.the_army.squad6.thread = thread_new("m03_deploy_troops_thread", M03_group.the_army.squad6, advance)
delay(2.0)
-- squad 3 has riot shields - They should enter first (offensive AI)
-- squad 4 and half of squad 2 can go in (normal ai). The rest stay defensive
-- just wait for now, but go ahead and load pierce's persona
m03_load_persona(M03_convo.cavalry)
delay(60.0)
-- Pierce needs a 2d persona loaded for this conversation
m03_convo(M03_convo.cavalry)
-- Unload persona
m03_unload_persona(M03_convo.cavalry)
objective_text_clear(0)
-- Shaundi is free again
npc_leash_remove( M03_char.shaundi )
m03_nuke_tanks()
if human_is_downed( M03_char.shaundi)then
npc_revive( M03_char.shaundi)
end
delay(2.0)
end
function m03_cutscene_pierce_entrance()
local fade_in_after = false
local teleport_navs = { M03_checkpoint.protect_the_stash.player_local, M03_checkpoint.protect_the_stash.player_remote }
cutscene_play(M03_cutscene.pierce_entrance, nil, teleport_navs, fade_in_after)
-- hack to bring Shaundi back after cutscene due to teleporting everyone to the slate
teleport(M03_char.shaundi, "m3_cte_playerteleport", true)
group_create(M03_group.choppers.name, true)
group_create(M03_group.chopper_pierce_normal.name, true)
on_vehicle_destroyed("m03_chopper_destroyed_cb", M03_group.choppers.pierce.vehicle)
on_vehicle_destroyed("m03_bomb_destroyed_cb", M03_group.choppers.bomb.vehicle)
-- Start three separate vehicle entry threads so they are all entering at the same time
for i,chopper in pairs(M03_choppers) do
chopper.thread = thread_new("m03_wrapper_thread", vehicle_enter_group_teleport, chopper.pilots, chopper.vehicle)
end
for i,chopper in pairs(M03_choppers) do
threads_wait_for_completion(chopper.thread)
end
-- Put the choppers in their starting positions
m03_float_choppers()
-- marker_remove(M03_bomb_mover)
-- Hide the giant bomb
mesh_mover_hide("DaBomb")
if group_is_loaded(M03_group.the_army.name) then
m03_cleanup_army_callbacks()
group_destroy(M03_group.the_army.name)
end
--objective_text_clear(0)
mission_start_fade_in()
end
-----------------------------------------------
--[[ ]]--
--[[ FOURTH CHECKPOINT (PROTECT THE STASH) ]]--
--[[ ]]--
function m03_initialize_protect_the_stash()
group_create(M03_group.shaundi.name, true)
group_create(M03_group.warehouse_cover_vehicles.name, true)
-- Put everybody in their place
teleport_coop(M03_checkpoint.protect_the_stash.player_local, M03_checkpoint.protect_the_stash.player_remote, true)
-- teleport Shaundi to where you are going to be
teleport(M03_char.shaundi, M03_checkpoint.protect_the_stash.player_local, nil, nil, 0.0, 0.0, 1.4)
group_create(M03_group.choppers.name, true)
group_create(M03_group.chopper_pierce_normal.name, true)
on_vehicle_destroyed("m03_chopper_destroyed_cb", M03_group.choppers.pierce.vehicle)
on_vehicle_destroyed("m03_heli_destroyed_cb", M03_group.choppers.bomb.vehicle)
on_vehicle_destroyed("m03_heli_destroyed_cb", M03_group.choppers.backup.vehicle)
-- Start three separate vehicle entry threads so they are all entering at the same time
for i,chopper in pairs(M03_choppers) do
chopper.thread = thread_new("m03_wrapper_thread", vehicle_enter_group_teleport, chopper.pilots, chopper.vehicle)
end
for i,chopper in pairs(M03_choppers) do
threads_wait_for_completion(chopper.thread)
end
-- Put the choppers in their starting positions
m03_float_choppers()
-- NOW add Shaundi and she won't go through a bunch of bad teleports
m03_add_shaundi()
end
function m03_objective_protect_the_stash()
-- keep Shaundi in the back of the warehouse
npc_leash_to_nav( M03_char.shaundi, M03_checkpoint.hold_your_ground.player_local, 5.0 )
-- let cops shoot from turrets
set_cops_shooting_from_vehicles(true)
-- send choppers in loops
helicopter_fly_to_direct_loop(M03_group.choppers.pierce.vehicle, 15, "heli_loop<001>")
helicopter_fly_to_direct_loop(M03_group.choppers.backup.vehicle, 5, "heli_loop<002>")
-- load personas for pred-drone conversations
m03_load_persona(M03_drone_voices.operator1)
-- set callbacks so we know if the pred-drone has been fired
on_attack_performed("m03_player_fired_weapon_cb", LOCAL_PLAYER)
if coop_is_active() then
on_attack_performed("m03_player_fired_weapon_cb", REMOTE_PLAYER)
end
thread_new("m03_convo", M03_convo.satellite_start)
-- Play some awesome audio SP: shifted to here to try getting some audio going during the drone sequence to see how it feels
audio_object_post_event("M03_Heli_Intro_Score", nil, nil, LOCAL_PLAYER)
-- Send the player(s) to the satellite weapon
M03_trigger.satellite_weapon.triggered = false
--objective_text(0, M03_text.protect_the_stash, nil, nil, SYNC_ALL, OI_ASSET_DEFEND)
objective_text(0, M03_text.use_satellite_weapon, nil, nil, SYNC_ALL, OI_ASSET_USE)
group_create(M03_group.satellite_weapon.name, true)
thread_yield()
marker_add(M03_item.satellite_weapon, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL)
local add_waypoint = false
local add_marker = false
m03_set_trigger(M03_trigger.satellite_weapon.name, "m03_satellite_weapon_used_cb", add_waypoint, add_marker)
repeat
thread_yield()
until (M03_trigger.satellite_weapon.triggered)
-- Put both players into satellite weapon mode
-- njr: let players put themselves in sat mode -- satellite_weapon_mode_enter(M03_checkpoint.helicopter_ride.player_local)
-- Once one player has started using the satellite weapon, clear the objective
objective_text_clear(0)
objective_text(0, M03_text.protect_the_stash, nil, nil, SYNC_ALL, OI_ASSET_DEFEND)
-- slowly move the helicopter into position
marker_add(M03_group.choppers.bomb.vehicle, MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND)
marker_add(M03_group.choppers.pierce.vehicle, MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND)
marker_add(M03_group.choppers.backup.vehicle, MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND)
M03_group.choppers.bomb.thread = thread_new("m03_pickup_bomb_thread")
M03_num_satellite_attackers = 5 -- start out light
-- M03_all_satellite_groups
M03_thread.satellite_attack = thread_new("m03_satellite_attackers_thread", M03_all_satellite_groups)
-- a few seconds to play with the attackers
delay(10.0)
-- stop spawning
M03_status.satellite_timer_elapsed = true
while not thread_check_done(M03_thread.satellite_attack) do
thread_yield()
end
-- start the grunts again
M03_thread.satellite_attack = thread_new("m03_satellite_attackers_thread", M03_all_satellite_groups)
-- send in some tanks
for i,tank_groups in pairs(M03_tank_attacks) do
-- pause for dramatic effect
delay(2.0)
for tank_index,group in pairs(tank_groups) do
-- send in a tank (only target for a few seconds)
group_create(group.name, true)
vehicle_enter_group_teleport(group.members, group.vehicle)
-- put a kill marker on it
marker_add(group.vehicle, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAG_STICKY)
on_vehicle_destroyed("m03_satellite_tank_killed_cb", group.vehicle)
group.move_thread = thread_new( "m03_wrapper_thread", vehicle_pathfind_to, group.vehicle, group.dest, true )
-- tell them who to attack
ai_add_enemy_target(group.members[1], M03_group.choppers.bomb.pilots[1], ATTACK_NOW_NEVER_LOSE, true)
ai_add_enemy_target(group.members[2], M03_group.choppers.bomb.pilots[1], ATTACK_NOW_NEVER_LOSE, true)
-- and tell them not to attack for a bit
group.delay_gunner_thread = thread_new( "m03_tank_delay_gunner_thread", group )
end
objective_text(0, "M03_OBJ_DESTROY_TANKS", nil, nil, SYNC_ALL, OI_ASSET_KILL)
-- A Tank! OMG!
-- wait for tank(s) to be destroyed
for tank_index,group in pairs(tank_groups) do
while not vehicle_is_destroyed(group.vehicle) do
thread_yield()
end
marker_remove(group.vehicle)
release_to_world(group.name)
end
objective_text(0, M03_text.protect_the_stash, nil, nil, SYNC_ALL, OI_ASSET_DEFEND)
-- more attackers! -- AC TEST: These #s were 7 and 10
if i == 1 then
M03_num_satellite_attackers = 5
else
M03_num_satellite_attackers = 5
end
---- stop spawning
--M03_status.satellite_timer_elapsed = true
--while not thread_check_done(M03_thread.satellite_attack) do
-- thread_yield()
--end
if i == 1 then
M03_thread.satellite_convos = thread_new("m03_convo", M03_convo.stash_combat1)
end
if i == 2 then
if M03_status.convo_is_playing then
audio_conversation_end(M03_convo.stash_combat1.handle)
end
M03_thread.satellite_convos = thread_new("m03_convo", M03_convo.stash_combat2)
end
end
-- we can stop spawning new dudes now
M03_status.satellite_timer_elapsed = true
-- a little pause for the fallen tanks
delay(3.0)
-- kill attack thread and remove any leftover markers
m03_forced_satellite_end()
delay(1)
-- no more satellite for U!
if group_is_loaded(M03_group.satellite_weapon.name) then
group_destroy(M03_group.satellite_weapon.name)
end
-- done talking
cleanup_conversations(M03_convo)
-- If the players haven't left satellite weapon mode yet, force them out of it
satellite_weapon_mode_exit()
-- done with these callbacks
on_attack_performed("", LOCAL_PLAYER)
if coop_is_active() then
on_attack_performed("", REMOTE_PLAYER)
end
-- Shaundi is free again
npc_leash_remove( M03_char.shaundi )
-- done with the drone operators
m03_unload_persona(M03_drone_voices.operator1)
m01_restore_heli(M03_group.choppers.bomb.vehicle)
m01_restore_heli(M03_group.choppers.pierce.vehicle)
m01_restore_heli(M03_group.choppers.backup.vehicle)
-- Turn helicopters invulnerable till you get in them
turn_invulnerable(M03_group.choppers.bomb.vehicle)
turn_invulnerable(M03_group.choppers.pierce.vehicle)
turn_invulnerable(M03_group.choppers.backup.vehicle)
objective_text_clear(0)
end
-----------------------------------------------
--[[ ]]--
--[[ FIFTH CHECKPOINT (HELICOPTER RIDE) ]]--
--[[ ]]--
function m03_initialize_helicopter_ride()
group_create(M03_group.shaundi.name, true)
group_create(M03_group.warehouse_cover_vehicles.name, true)
teleport_coop(M03_checkpoint.helicopter_ride.player_local, M03_checkpoint.helicopter_ride.player_remote, true)
-- teleport Shaundi to where you are going to be
teleport(M03_char.shaundi, M03_checkpoint.helicopter_ride.player_local, nil, nil, 0.0, 0.0, 1.4)
group_create(M03_group.choppers.name, true)
group_create(M03_group.chopper_pierce_normal.name, true)
on_vehicle_destroyed("m03_chopper_destroyed_cb", M03_group.choppers.pierce.vehicle)
on_vehicle_destroyed("m03_bomb_destroyed_cb", M03_group.choppers.bomb.vehicle)
-- Start three separate vehicle entry threads so they are all entering at the same time
for i,chopper in pairs(M03_choppers) do
chopper.thread = thread_new("m03_wrapper_thread", vehicle_enter_group_teleport, chopper.pilots, chopper.vehicle)
end
for i,chopper in pairs(M03_choppers) do
threads_wait_for_completion(chopper.thread)
end
vehicle_suppress_npc_exit(M03_group.choppers.pierce.vehicle, true)
-- Put the choppers in their starting positions
m03_float_choppers()
-- NOW add Shaundi and she won't go through a bunch of bad teleports
m03_add_shaundi()
inv_weapon_add_temporary(LOCAL_PLAYER, M03_weapon.satellite_drone_weapon, 1, true)
if (coop_is_active()) then
inv_weapon_add_temporary(REMOTE_PLAYER, M03_weapon.satellite_drone_weapon, 1, true)
end
-- Play some awesome audio
audio_object_post_event("M03_Heli_Intro_Score", nil, nil, LOCAL_PLAYER)
end
function m03_objective_helicopter_ride()
-- no more drone gun for you
group_create_hidden(M03_group.fly_home_enemies.name, true)
for i,chopper in pairs(M03_vehicle.fly_home_enemies) do
M03_thread.fly_home_enemy_setup[i] = thread_new("m03_fly_home_enemy_setup_thread", i, chopper)
end
thread_new("m03_convo", M03_convo.get_in_chopper)
tutorial_start("sprint", 2000) --SP: tell the player how to sprint to get to the chopper fast!
-- TEST
--notoriety_set_min("police", 5)
notoriety_set_min_and_max("police", 3, 3)
-- END TEST
objective_text(0, M03_text.go_to_chopper, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
M03_thread.landing = thread_new("m03_wrapper_thread", helicopter_fly_to_direct, M03_group.choppers.pierce.vehicle, -1, M03_navpoint.heli_landing_pos)
repeat
thread_yield()
until (get_dist(M03_group.choppers.pierce.vehicle, M03_navpoint.heli_landing_pos) < 5)
thread_kill(M03_thread.landing)
-- This line was not recorded
-- audio_play_persona_line(M03_char.pierce, "M03_Heli_Rail_Start")
marker_add(M03_group.choppers.pierce.vehicle, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL)
-- Wait until the player gets close to the chopper before moving on
M03_trigger.enter_heli.triggered = false
local add_waypoint = false
local add_marker = false
m03_set_trigger(M03_trigger.enter_heli.name, "m03_enter_heli_cb", add_waypoint, add_marker)
repeat
thread_yield()
until (M03_trigger.enter_heli.triggered == true)
marker_remove(M03_group.choppers.pierce.vehicle)
objective_text_clear(0)
-- Here's what will happen when you get to the trigger:
fade_out(0.5)
fade_out_block()
-- Stop the awesome audio
audio_object_post_event("M03_Heli_Intro_Score_Stop", nil, nil, LOCAL_PLAYER)
-- don't be in satellite mode
satellite_weapon_mode_exit()
-- make sure Shaundi stays alive
npc_revive(M03_char.shaundi)
if character_is_in_vehicle(M03_char.shaundi) then
vehicle_exit(M03_char.shaundi)
end
if character_is_in_vehicle(LOCAL_PLAYER) then
vehicle_exit(LOCAL_PLAYER)
end
if coop_is_active() and character_is_in_vehicle(REMOTE_PLAYER) then
vehicle_exit(REMOTE_PLAYER)
while character_is_in_vehicle(REMOTE_PLAYER) do
thread_yield()
end
end
cleanup_callbacks({ M03_group.choppers.pierce.vehicle })
-- make sure everyone is out of their vehicles
while character_is_in_vehicle(LOCAL_PLAYER) or character_is_in_vehicle(M03_char.shaundi) do
thread_yield()
end
-- make sure everyone has the right weapons
local ammo = 1
local equip_now = true
local unlimited_ammo = true
local dual_wielding = false
local force_override = false
inv_item_add(M03_weapon.helicopter_ride, ammo, M03_char.shaundi, equip_now)
if (coop_is_active()) then
inv_weapon_add_temporary(REMOTE_PLAYER, M03_weapon.helicopter_ride, 1, unlimited_ammo, equip_now, dual_wielding, force_override, 0x7)
end
inv_weapon_add_temporary(LOCAL_PLAYER, M03_weapon.helicopter_ride, 1, unlimited_ammo, equip_now, dual_wielding, force_override, 0x7)
inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_RIFLE)
-- get in the damn heli Shaundi
follower_make_independent(M03_char.shaundi, true)
-- Put the player(s) into Pierce's chopper and lock them there
-- (Note: Seat 0 is the driver's seat, seat 1 is the passenger's seat, 2 and 3 are the gunner seats)
local shaundi_seat = 3
local block = true
if (coop_is_active()) then
shaundi_seat = 1
while not vehicle_enter_teleport(REMOTE_PLAYER, M03_group.choppers.pierce.vehicle, 3, block) do
thread_yield()
end
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
end
-- seat Shaundi first so she doesn't follow the player in
while not vehicle_enter_teleport(M03_char.shaundi, M03_group.choppers.pierce.vehicle, shaundi_seat, block) do
thread_yield()
end
while not vehicle_enter_teleport(LOCAL_PLAYER, M03_group.choppers.pierce.vehicle, 2, block) do
thread_yield()
end
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
-- put it in the air
m03_float_chopper(M03_group.choppers.pierce, M03_group.choppers.pierce.float_nav)
-- no more destroying your heli
turn_invulnerable(M03_group.choppers.pierce.vehicle)
turn_invulnerable(M03_char.shaundi)
-- The other helicopters can be damaged now
turn_vulnerable(M03_group.choppers.bomb.vehicle)
turn_vulnerable(M03_group.choppers.backup.vehicle)
fade_in(0.5)
M03_status.helis_destroyed = 0
-- Now have all the helicopters rise up, and Pierce will fly to Shaundi's house while the player fights off the attacking choppers
objective_text(0, M03_text.protect_the_bomb, nil, nil, SYNC_ALL, OI_ASSET_DEFEND)
-- Show the player(s) which vehicle (the one carrying the bomb) they need to protect
marker_add(M03_group.choppers.bomb.vehicle, MINIMAP_ICON_PROTECT_ACQUIRE, OI_ASSET_DEFEND, OI_FLAGS_FULL)
-- Post an audio event to reduce the helicopter audio complexity
audio_object_post_event("M03_Heli_Rail_Sequence", nil, nil, LOCAL_PLAYER)
-- Post an audio event to start the Rail Music
audio_object_post_event("M03_Heli_Rail_Score_Start", nil, nil, LOCAL_PLAYER)
group_show(M03_group.fly_home_enemies.name)
-- Keep the helicopter somewhat level
helicopter_set_max_bank_angle(M03_group.choppers.pierce.vehicle, 0.25)
local leader_speed = 20
local follower_speed = 50
-- DEBUG: TAKE THIS OUT, or shaundi will be standing up in the helicopter
-- inv_item_remove_all(M03_char.shaundi)
M03_trigger.fly_home_secondary_enemies.triggered = false
add_waypoint = false
add_marker = false
M03_status.fly_home_played = false
--m03_set_trigger(M03_trigger.fly_home_secondary_enemies.name, "m03_spawn_secondary_enemies_cb", add_waypoint, add_marker)
M03_trigger.blow_up_helis.triggered = false
m03_set_trigger(M03_trigger.blow_up_helis.name, "m03_blow_up_helis_cb", add_waypoint, add_marker)
M03_kill_heli = M03_Kill_Heli_Navs[1]
-- Saints
M03_thread.fly_home[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_dont_stop, M03_group.choppers.bomb.vehicle, 50, M03_scripted_path.fly_home_bomb[1])
M03_thread.fly_home[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.pierce.vehicle, 70, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_pierce[1], 3)
M03_thread.fly_home[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.backup.vehicle, 70, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_backup[1], 0)
-- Give the player a few secs to look around
--delay(3.0)
-- Set up so that helicopters are hovering
thread_new("m03_secondary_heli_hover_setup")
-- Enemies
M03_thread.fly_home_enemy_chase[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[1], 90, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy1[1], 4)
M03_thread.fly_home_enemy_chase[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct, M03_vehicle.fly_home_enemies[2], 70, M03_scripted_path.fly_home_enemy2[1])
M03_thread.fly_home_enemy_chase[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[3], 90, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy3[1], 6)
M03_thread.fly_home_enemy_chase[4] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[4], 70, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy4[1], 4)
-- Add Object indicators
marker_add(M03_vehicle.fly_home_enemies[1], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
marker_add(M03_vehicle.fly_home_enemies[2], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
marker_add(M03_vehicle.fly_home_enemies[3], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
marker_add(M03_vehicle.fly_home_enemies[4], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
-- For when they are almost dead and when they are destroyed
for i, chopper in pairs (M03_vehicle.fly_home_enemies) do
on_damage("m03_crash_heli", M03_vehicle.fly_home_enemies[i], 0.22)
on_vehicle_destroyed("m03_heli_enemy_destroyed_cb", M03_vehicle.fly_home_enemies[i])
end
M03_thread.fly_home_convo = thread_new("m03_convo", M03_convo.protect_bomb)
-- get chatty
on_take_damage("m03_heli_chatter_cb", M03_group.choppers.bomb.vehicle)
on_take_damage("m03_heli_chatter_cb", M03_group.choppers.pierce.vehicle)
on_take_damage("m03_heli_chatter_cb", M03_group.choppers.backup.vehicle)
M03_thread.chatter = thread_new("m03_heli_chatter_thread")
threads_wait_for_completion(M03_thread.fly_home[1])
-- Allow helis to shoot again
for i,chopper in pairs(M03_vehicle.fly_home_enemies) do
npc_combat_enable(M03_char.fly_home_enemies[i][1], true)
npc_combat_enable(M03_char.fly_home_enemies[i][2], true)
ai_add_enemy_target(M03_char.fly_home_enemies[i][1], M03_group.choppers.bomb.pilots[1], ATTACK_NOW, true)
ai_add_enemy_target(M03_char.fly_home_enemies[i][2], M03_group.choppers.bomb.pilots[1], ATTACK_NOW, true)
end
M03_kill_heli = M03_Kill_Heli_Navs[2]
-- Saints
M03_thread.fly_home[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_dont_stop, M03_group.choppers.bomb.vehicle, leader_speed, M03_scripted_path.fly_home_bomb[2])
M03_thread.fly_home[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.pierce.vehicle, follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_pierce[2], 3)
M03_thread.fly_home[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.backup.vehicle, follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_backup[2], 0)
--Enemies
M03_thread.fly_home_enemy_chase[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[1], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy1[2], 6)
M03_thread.fly_home_enemy_chase[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[2], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy2[2], 3)
M03_thread.fly_home_enemy_chase[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[3], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy3[2], 1)
M03_thread.fly_home_enemy_chase[4] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[4], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy4[2], 4)
M03_thread.fly_home_enemy_chase[5] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[5], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy5[1], 2)
M03_thread.fly_home_enemy_chase[6] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[6], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy6[1], 5)
-- New OI
marker_add(M03_vehicle.fly_home_enemies[5], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
marker_add(M03_vehicle.fly_home_enemies[6], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
threads_wait_for_completion(M03_thread.fly_home[1])
M03_kill_heli = M03_Kill_Heli_Navs[3]
-- Saints
M03_thread.fly_home[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_dont_stop, M03_group.choppers.bomb.vehicle, 50, M03_scripted_path.fly_home_bomb[3])
M03_thread.fly_home[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.pierce.vehicle, 70, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_pierce[3], 3)
M03_thread.fly_home[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.backup.vehicle, 70, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_backup[3], 0)
-- Enemies
M03_thread.fly_home_enemy_chase[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[1], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy1[3], 4)
M03_thread.fly_home_enemy_chase[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[2], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy2[3], 1)
M03_thread.fly_home_enemy_chase[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[3], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy3[3], 2)
M03_thread.fly_home_enemy_chase[4] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[4], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy4[3], 6)
M03_thread.fly_home_enemy_chase[5] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[5], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy5[2], 4)
M03_thread.fly_home_enemy_chase[6] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[6], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy6[2], 3)
M03_thread.fly_home_enemy_chase[7] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[7], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy7[1], 6)
M03_thread.fly_home_enemy_chase[8] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[8], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy8[1], 5)
-- New OI
marker_add(M03_vehicle.fly_home_enemies[7], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
marker_add(M03_vehicle.fly_home_enemies[8], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
threads_wait_for_completion(M03_thread.fly_home[1])
M03_kill_heli = M03_Kill_Heli_Navs[4]
-- Saints
M03_thread.fly_home[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_dont_stop, M03_group.choppers.bomb.vehicle, leader_speed, M03_scripted_path.fly_home_bomb[4])
M03_thread.fly_home[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.pierce.vehicle, follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_pierce[4], 3)
M03_thread.fly_home[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_group.choppers.backup.vehicle, follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_backup[4], 4)
-- Enemies
M03_thread.fly_home_enemy_chase[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[1], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy1[4], 3)
M03_thread.fly_home_enemy_chase[2] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[2], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy2[4], 5)
M03_thread.fly_home_enemy_chase[3] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[3], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy3[4], 4)
M03_thread.fly_home_enemy_chase[4] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[4], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy4[4], 2)
M03_thread.fly_home_enemy_chase[5] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[5], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy5[3], 3)
M03_thread.fly_home_enemy_chase[6] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[6], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy6[3], 4)
M03_thread.fly_home_enemy_chase[7] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[7], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy7[2], 6)
M03_thread.fly_home_enemy_chase[8] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[8], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy8[2], 4)
M03_thread.fly_home_enemy_chase[9] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[9], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy9[1], 2)
M03_thread.fly_home_enemy_chase[10] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, M03_vehicle.fly_home_enemies[10], follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_enemy10[1], 5)
-- New OI
marker_add(M03_vehicle.fly_home_enemies[9], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
marker_add(M03_vehicle.fly_home_enemies[10], MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_DEFAULT, SYNC_ALL)
threads_wait_for_completion(M03_thread.fly_home[1])
-- Switch music
audio_object_post_event("M03_Heli_Rail_Sequence_Fade", nil, nil, LOCAL_PLAYER)
-- Move this convo to happen earlier
-- M03_thread.fly_home_convo = thread_new("m03_convo", M03_convo.fly_home)
repeat
thread_yield()
until (get_dist(M03_group.choppers.bomb.vehicle, M03_navpoint.shaundi_house) < 25)
threads_wait_for_completion(M03_thread.fly_home[1])
M03_thread.fly_home[1] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct, M03_group.choppers.bomb.vehicle, -1, M03_navpoint.shaundi_house)
repeat
thread_yield()
until (get_dist(M03_group.choppers.bomb.vehicle, M03_navpoint.shaundi_house) < 20)
-- This line is now obsolete
-- audio_play_persona_line(M03_char.shaundi, "M03_Arrive")
-- This delay will be replaced with animations or a cutscene of the bomb being removed from the helicopter
delay(5)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
if (coop_is_active()) then
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
end
turn_vulnerable(M03_char.shaundi)
inv_weapon_disable_all_slots(false)
-- Post an audio event to stop the custom heli audio
audio_object_post_event("M03_Heli_Rail_Sequence_Stop", nil, nil, LOCAL_PLAYER)
end
--------------------------------------------------------------------------------------------------
--[[************************************]]--
--[[ ]]--
--[[ Miscellaneous m03 Helper Functions ]]--
--[[ ]]--
--[[************************************]]--
-- The player that finished m02 will have these weapons.
-- The coop client that just joined will not, so we give them again.
-- Just need to give at the first checkpoint. Afterwards they should be saved
--
function m03_give_players_weapons()
for i, weapon in pairs(M03_start_inventory) do
inv_item_add(weapon.name, weapon.reserve_ammo, LOCAL_PLAYER)
inv_item_add(weapon.name, weapon.reserve_ammo, REMOTE_PLAYER)
end
end
-- Set a trigger enabled with a mission marker
--
-- trigger: (string) Name of the trigger
-- trigger_callback: (string) Function name to call when trigger is activated
-- add_waypoint: (bool, optional) true to add a waypoint, false otherwise (defaults to true)
-- add_marker: (bool, optional) true to add a marker, false otherwise (defaults to true)
--
function m03_set_trigger(trigger, trigger_callback, add_waypoint, add_marker)
trigger_enable(trigger, true)
if (add_waypoint ~= false) then
mission_waypoint_add(trigger)
end
if (add_marker ~= false) then
marker_add_trigger(trigger, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
end
on_trigger(trigger_callback, trigger)
end
-- Disable trigger
--
-- trigger: (string) Name of the trigger
--
function m03_clear_trigger(trigger)
on_trigger("", trigger)
trigger_enable(trigger, false)
marker_remove_trigger(trigger, SYNC_ALL)
mission_waypoint_remove()
end
-- Disable all m03 triggers
function m03_clear_trigger_table()
for i,trigger_table in pairs(M03_trigger) do
m03_clear_trigger(trigger_table.name)
end
end
function m03_continuous_spawns_stop(spawn_group)
call_function_on_each_member(continuous_spawn_stop, spawn_group)
end
-- Add a Shaundi as a crew member with all associated goodness
--
function m03_add_shaundi()
party_add(M03_char.shaundi, LOCAL_PLAYER)
follower_set_can_abandon( M03_char.shaundi, true )
on_dismiss("m03_failure_dismissed_cb", M03_char.shaundi)
on_death("m03_shaundi_killed_cb", M03_char.shaundi)
end
-- Play an audio conversation
--
-- convo: (table) the conversation to play - contains a name, handle, and table of non-player speakers
--
function m03_convo(convo)
if (convo == nil) then
return
end
-- If another conversation is already playing, wait for it to finish
if (M03_status.convo_is_playing) then
repeat
thread_yield()
until (not M03_status.convo_is_playing)
end
M03_status.convo_is_playing = true
-- Load the conversation
if (convo.load_direct) then
convo.handle = audio_conversation_load_direct(convo.name)
else
convo.handle = audio_conversation_load(convo.name)
end
-- Play the conversation
audio_conversation_play(convo.handle)
delay(1)
-- Wait for the conversation to end
audio_conversation_wait_for_end(convo.handle)
convo.handle = INVALID_CONVERSATION_HANDLE
M03_status.convo_is_playing = false
end
-- float a chopper at a given navpoint
--
-- chopper_table: (table) chopper information
-- float_nav: (string) name of navpoint to float the chopper at
--
function m03_float_chopper(chopper_table, float_nav)
teleport_vehicle(chopper_table.vehicle, float_nav)
thread_yield()
-- tell choppers to move there so they stay in place
chopper_table.thread = thread_new( "m03_wrapper_thread", helicopter_fly_to_direct, chopper_table.vehicle, -1, float_nav)
end
-- make sure choppers are at the floating positions
--
function m03_float_choppers()
-- teleport choppers into position
for i,chopper in pairs(M03_choppers) do
m03_float_chopper(chopper, chopper.float_nav)
end
end
-- if we don't have guards left to kill, set the objective to go to warehouse
--
function m03_set_enter_warehouse_objective()
if (M03_warehouse_guards_alive == 0) then
objective_text(0, M03_text.find_weapons_cache, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
if not M03_status.warehouse_objective then
-- mark trigger so you know where to go
local add_waypoint = false
m03_set_trigger(M03_trigger.weapons_cache.name, "m03_weapons_cache_trigger_cb", add_waypoint)
M03_status.warehouse_objective = true
end
end
end
-- if we have guards left to kill, set the objective to kill guards
--
function m03_set_kill_warehouse_guards_objective()
if (M03_warehouse_guards_alive > 0) then
objective_text(0, M03_text.kill_guards, "", "", SYNC_ALL, OI_ASSET_KILL)
-- clear trigger stuff
m03_clear_trigger(M03_trigger.weapons_cache.name)
M03_status.warehouse_objective = false
end
end
-- setup the waves of toops and triggers to move them around
function m03_setup_warehouse_guards()
-- Spawn the National Guard guys
group_create(M03_group.armory_guards.name, true)
M03_warehouse_guards_alive = 0
M03_warehouse_guards_killed = 0
M03_warehouse_triggers_left = 0
local add_waypoint = false
local add_marker = false
for i,wave_table in pairs(M03_warehouse_guard_wave) do
wave_table.trigger.triggered = false
-- set trigger to make them move and add to the killing
m03_set_trigger(wave_table.trigger.name, "m03_warehouse_advance_cb", add_waypoint, add_marker)
-- mark this trigger as 'armed'
M03_warehouse_triggers_left = M03_warehouse_triggers_left + 1
end
end
-- cleanup the waves of toops and triggers to move them around
function m03_cleanup_warehouse_guards()
if group_is_loaded(M03_group.armory_guards.name) then
for i,wave_table in pairs(M03_warehouse_guard_wave) do
for j,guard in pairs(wave_table.members) do
on_death("", guard)
on_detection("", guard)
on_attack_performed("", guard)
end
end
group_destroy(M03_group.armory_guards.name)
end
end
-- Spawn tanks and get the guards in them
--
function m03_spawn_tanks()
for i,group in pairs(M03_tanks) do
group_create(group.name, true)
vehicle_enter_group_teleport(group.members, group.vehicle)
vehicle_disable_chase(group.vehicle, true) -- Stay. Good tank.
end
-- await further orders
end
-- Roll tanks to their destinations
--
function m03_deploy_tanks()
for i,group in pairs(M03_tanks) do
group.move_thread = thread_new( "m03_wrapper_thread", vehicle_pathfind_to, group.vehicle, group.dest, true )
end
-- await further orders
end
-- destroy all of the tanks
--
function m03_nuke_tanks()
for i,group in pairs(M03_tanks) do
-- destroy each tank
vehicle_detonate(group.vehicle)
-- release to world so we can respawn them
release_to_world(group.name)
end
end
-- remove markers and repair the helicopter
--
-- heli_name: (string) helicopter to restore
function m01_restore_heli(heli_name)
-- if the vehicle blew up this frame (don't laugh, it has happened), then it can't be repaired
while vehicle_is_destroyed(heli_name) do
-- stall until the callbacks kick in
thread_yield()
end
marker_remove(heli_name)
vehicle_repair(heli_name)
end
-- load a 2d persona
--
-- persona_data: (table) table containing persona_name and persona_id to load
function m03_load_persona(persona_data)
persona_data.persona_id = audio_persona_load_2d(persona_data.persona_name)
end
-- unload persona
--
-- persona_data: (table) table containing the persona_id to unload
function m03_unload_persona(persona_data)
if (persona_data.persona_id ~= INVALID_PERSONA_HANDLE) then
audio_persona_remove_2d(persona_data.persona_id)
persona_data.persona_id = INVALID_PERSONA_HANDLE
end
end
-- kill satellite reinforcemetns thread and supporting threads
-- Remove any markers and free groups to world
--
function m03_forced_satellite_end()
-- kill the main thread
thread_kill(M03_thread.satellite_attack)
-- clean up any leftover groups
for sa_index,spawn_group in pairs(M03_all_satellite_groups) do
-- remove callback
on_vehicle_destroyed("", spawn_group.vehicle)
-- don't need this marker anymore
marker_remove(spawn_group.vehicle)
-- release the whole group
release_to_world(spawn_group.name)
-- kill the thread
thread_kill(spawn_group.thread)
end
-- make sure tanks don't have leftover markers/callbacks
for tank_index,tank in pairs(M03_tanks) do
on_vehicle_destroyed("", tank.vehicle)
marker_remove(tank.vehicle)
end
end
-- Turn off traffic splines around the armory
--
function m03_traffic_off()
sidewalk_disable_nodes(M03_trigger.traffic.name, true)
traffic_disable_lanes(M03_trigger.traffic.name, true)
sidewalk_disable_nodes(M03_trigger.traffic1.name, true)
traffic_disable_lanes(M03_trigger.traffic1.name, true)
end
-- Turn traffic splines around the armory
--
function m03_traffic_on()
sidewalk_disable_nodes(M03_trigger.traffic.name, false)
traffic_disable_lanes(M03_trigger.traffic.name, false)
sidewalk_disable_nodes(M03_trigger.traffic1.name, false)
traffic_disable_lanes(M03_trigger.traffic1.name, false)
end
--------------------------------------------------------------------------------------------------
--[[********************]]--
--[[ ]]--
--[[ Callback functions ]]--
--[[ ]]--
--[[********************]]--
-- Callback when Phillipe's phone call is complete (also works as a mission cleanup for call)
--
function m03_call_complete_cb()
-- flag it as complete
M03_convo.phillipe_call.call_complete = true
-- kill persona
m03_unload_persona(M03_convo.phillipe_call)
-- kill any leftovers
audio_remove_mission_cellphone(M03_convo.phillipe_call.name)
end
-- Callback for hud prompt
--
function m03_hud_prompt_cb()
-- nop
end
-- Callback for player getting to the weapon store
--
function m03_weapon_store_trigger_cb()
-- Clear the trigger
m03_clear_trigger(M03_trigger.weapon_store.name)
-- Set secondary trigger for breadcrumbing
m03_set_trigger(M03_trigger.weapon_store2.name, "m03_weapon_store2_trigger_cb", true, true)
-- Reset notoriety
notoriety_reset("police")
notoriety_reset("Morningstar")
-- Notify script that weapon store was reached
M03_trigger.weapon_store.triggered = true
end
-- Callback for the player reaching the second weapon store trigger
--
function m03_weapon_store2_trigger_cb()
-- Clear the trigger
m03_clear_trigger(M03_trigger.weapon_store2.name)
m03_set_trigger(M03_trigger.weapon_store2.name, "m03_weapon_store2_trigger2_cb", false, false)
marker_add_trigger(M03_trigger.weapon_store2.name, MINIMAP_ICON_USE)
--marker_add(M03_trigger.weapon_store2.name, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAG_NONE)
-- Notify script that weapon store was reached
M03_trigger.weapon_store2.triggered = true
m03_check_player_funds_for_upgrade()
fade_out(0.5)
fade_out_block()
teleport_coop(M03_teleport.weapon_local, M03_teleport.weapon_remote, true)
if human_is_downed( M03_char.shaundi)then
npc_revive( M03_char.shaundi)
end
hud_push_screen("store_common", SYNC_ALL)
hud_push_screen("store_weapon", SYNC_ALL)
fade_in(0.5)
fade_in_block()
end
-- Secondary callback for when the player reaches the second weapon store trigger
-- This is to prevent the player from getting lost if they don't make a purchase
--
function m03_weapon_store2_trigger2_cb()
m03_clear_trigger(M03_trigger.weapon_store2.name)
end
-- Callback for player reaching the armory entrance
--
function m03_armory_entrance_trigger_cb()
-- Clear the trigger
m03_clear_trigger(M03_trigger.armory_entrance.name)
-- Notify script that the entrance was reached
M03_trigger.armory_entrance.triggered = true
-- Unhide barricade guys
group_show(M03_group.initial_guard.name)
end
-- Callback for advancing into the warehouse
-- Mark enemies to kill and add to kill list
--
-- player: (string) name of character triggering the trigger
-- trigger: (string) name of the trigger that was triggered
--
function m03_warehouse_advance_cb(player, trigger)
-- which trigger is this?
local wave_table
local found = false
for i,guard_wave_table in pairs(M03_warehouse_guard_wave) do
if (guard_wave_table.trigger.name == trigger) then
wave_table = guard_wave_table
found = true
end
end
if not found then
return
end
if wave_table.triggered then
return
end
wave_table.triggered = true
-- clear trigger
m03_clear_trigger(wave_table.trigger.name)
M03_warehouse_triggers_left = M03_warehouse_triggers_left - 1
for i,guard in pairs(wave_table.members) do
if (not character_is_dead(guard)) then
-- set callback
on_death("m03_warehouse_guard_killed_cb", guard)
on_detection(M03_see_saints_info.callback, guard)
on_attack_performed(M03_attack_info.callback, guard)
-- turn ai on
set_ignore_ai_flag( guard, false )
-- add marker
marker_add(guard, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL)
-- add count
M03_warehouse_guards_alive = M03_warehouse_guards_alive + 1
end
end
-- send guards to their navpoint
-- Note: we may have more guards than navpoints. Guards without navs will just not move
local should_run = true
local should_fire = false
for i,mark in pairs(wave_table.locations) do
if (not character_is_dead(wave_table.members[i])) then
ai_do_scripted_move(wave_table.members[i], mark, should_run, should_fire)
npc_leash_remove(wave_table.members[i])
end
end
m03_set_kill_warehouse_guards_objective()
if M03_warehouse_triggers_left == 1 then
m03_convo(M03_convo.bomb_found)
end
end
-- Handle playing the attack lines
--
-- name: (string) name of character
-- weapon: (string) name of weapon
-- attack: (string) type of attack performed
--
function m03_process_attack_cb(name, weapon, attack)
-- don't play this if we have done this recently
if (not thread_check_done(M03_attack_info.timer)) then
return
end
-- start timer
M03_attack_info.timer = thread_new("delay", M03_attack_info.delay)
-- play situation
if not audio_play_persona_line(name, M03_attack_info.situation) then
-- line didn't play, kill our timer
thread_kill(M03_attack_info.timer)
M03_attack_info.timer = INVALID_THREAD_HANDLE
end
end
-- Handle playing the attack lines
--
-- name: (string) name of character
-- weapon: (string) name of weapon
-- attack: (string) type of attack performed
--
function m03_process_see_saints_cb(name, weapon, attack)
-- don't play this if we have done this recently
if (not thread_check_done(M03_see_saints_info.timer)) then
return
end
-- start timer
M03_see_saints_info.timer = thread_new("delay", M03_see_saints_info.delay)
-- play situation
if not audio_play_persona_line(name, M03_see_saints_info.situation) then
-- line didn't play, kill our timer
thread_kill(M03_see_saints_info.timer)
M03_see_saints_info.timer = INVALID_THREAD_HANDLE
end
end
-- Report warhouse guard killed
--
-- guard: (string) name of guard killed
--
function m03_warehouse_guard_killed_cb(guard)
on_death("", guard)
on_detection("", guard)
on_attack_performed("", guard)
marker_remove(guard)
M03_warehouse_guards_alive = M03_warehouse_guards_alive - 1
M03_warehouse_guards_killed = M03_warehouse_guards_killed + 1
end
-- tell an attacker to advance on the player
--
-- attacker: (string) name of attacker
--
function m03_advance_cb(attacker)
on_ai_do_action_complete("", attacker)
ai_do_scripted_advance(attacker)
end
-- tell an attacker to take cover
--
-- attacker: (string) name of attacker
--
function m03_take_cover_cb(attacker)
on_ai_do_action_complete("", attacker)
ai_do_scripted_take_cover(attacker)
end
-- Callback for player purchasing an item at a store
--
-- item_type: (string) type of item that was purchased
-- player_name: (string) name of the player who purchased the item
--
function m03_item_purchased_cb(item_type, player_name)
if (item_type ~= "weapon" and item_type ~= "weapon-ammo") then
return
end
-- Clear the callback
on_purchase("")
m03_weapon_store2_trigger2_cb()
-- Notify script that item was purchased
M03_status.item_purchased = true
end
-- Callback for player reaching the weapons cache
function m03_weapons_cache_trigger_cb()
-- Clear the trigger
m03_clear_trigger(M03_trigger.weapons_cache.name)
-- Notify script that the weapons cache was reached
M03_trigger.weapons_cache.triggered = true
end
-- Callback for a player using the satellite weapon via trigger
--
-- player_user: (string) the player that triggered the satellite weapon
-- trigger: (string) the trigger that was activated
--
function m03_satellite_weapon_used_cb(player_user, trigger)
-- Note: We need to put both players into satellite weapon mode
--satellite_weapon_mode_set(true)--, sync_type)
--on_pickup("", M03_item.satellite_weapon)
marker_remove(M03_item.satellite_weapon)
m03_clear_trigger(M03_trigger.satellite_weapon.name)
inv_weapon_add_temporary(LOCAL_PLAYER, M03_weapon.satellite_drone_weapon, 1, true, true)
--inv_item_remove_in_slot("special", LOCAL_PLAYER)
--inv_item_add(M03_weapon.satellite_drone_weapon, 1, LOCAL_PLAYER, true)
if (coop_is_active()) then
inv_weapon_add_temporary(REMOTE_PLAYER, M03_weapon.satellite_drone_weapon, 1, true, true)
--inv_item_remove_in_slot("special", REMOTE_PLAYER)
--inv_item_add(M03_weapon.satellite_drone_weapon, 1, REMOTE_PLAYER, true)
end
-- destroy the item
if group_is_loaded(M03_group.satellite_weapon.name) then
group_destroy(M03_group.satellite_weapon.name)
end
-- If we are in coop, make sure the player that didn't trigger the weapon is nearby
if coop_is_active() then
local other_player = REMOTE_PLAYER
if player_user == REMOTE_PLAYER then
other_player = LOCAL_PLAYER
end
local nearby = 30.0
if get_dist(other_player, M03_checkpoint.protect_the_stash.player_remote) > nearby then
-- you are too far away. We are going to bring you both back, so we are going to bite the bullet and fade out
mission_start_fade_out()
-- surprise! back you go
teleport_coop(M03_checkpoint.protect_the_stash.player_local, M03_checkpoint.protect_the_stash.player_remote, true)
mission_start_fade_in()
end
end
-- Yield, just to make sure the players actually have the weapon equipped before trying to put them in satellite mode
thread_yield()
M03_trigger.satellite_weapon.triggered = true
-- let's use some drones! I'll show you. Here!
satellite_weapon_mode_set(true)
end
-- Callback for entering trigger near Pierce's helicopter
--
function m03_enter_heli_cb()
m03_clear_trigger(M03_trigger.enter_heli.name)
M03_trigger.enter_heli.triggered = true
end
-- Callback for the helicopter carrying the bomb being destroyed
--
-- vehicle_name: (string) name of the helicopter
--
function m03_bomb_destroyed_cb(vehicle_name)
on_vehicle_destroyed("", vehicle_name)
mission_end_failure("m03", M03_text.failure_bomb_destroyed)
end
-- Callback for the helicopter picking up the bomb being destroyed
--
-- vehicle_name: (string) name of the helicopter
--
function m03_heli_destroyed_cb(vehicle_name)
on_vehicle_destroyed("", vehicle_name)
mission_end_failure("m03", M03_text.failure_heli_destroyed)
end
-- Callback for Pierce's chopper being destroyed
--
-- vehicle_name: (string) name of the helicopter
--
function m03_chopper_destroyed_cb(vehicle_name)
on_vehicle_destroyed("", vehicle_name)
mission_end_failure("m03", M03_text.failure_pierce_destroyed)
end
-- Callback for an enemy chopper being destroyed during the fly home sequence
--
-- chopper: (string) name of the chopper
--
function m03_heli_enemy_destroyed_cb(chopper)
marker_remove(chopper)
on_vehicle_destroyed("", chopper)
-- not required, no marker -- marker_remove(chopper)
M03_status.helis_destroyed = M03_status.helis_destroyed + 1
if M03_status.helis_destroyed == 1 then
audio_play_persona_line(M03_char.shaundi, "M03_Nice_Hit_01")
end
if M03_status.helis_destroyed == 3 then
audio_play_persona_line(M03_char.pierce, "M03_Nice_Hit_02")
end
if M03_status.helis_destroyed == 5 then
audio_play_persona_line(M03_char.shaundi, "M03_Nice_Hit_03")
end
end
-- Cause the helicopter to fly away from the player when dying
--
-- heli_name: (string) name of the vehicle that reached the hitpoint threshold
-- killer: (string) name of the character or vehicle responsible for causing the damage
--
function m03_crash_heli(heli_name, killer)
on_damage("", heli_name, 0.20)
-- go to the navpoint away from the player
helicopter_fly_to_direct(heli_name, 80.0, M03_kill_heli)
delay(1.0)
vehicle_detonate(heli_name)
end
-- Callback to determine if a player just fired the satellite weapon
--
-- attacker: (string) name of attacker
-- weapon: (string) name of weapon used or "unarmed" if melee
-- attack: (string) "melee", "firearm" or "thrown"
function m03_player_fired_weapon_cb(attacker, weapon, attack)
-- we only set this callback for the players, so I don't care who the attacker is
-- is this the pred-drone?
if weapon == M03_weapon.satellite_drone_weapon then
-- maybe say something
-- if a conversation is going, don't talk
if M03_status.convo_is_playing then
return
end
-- if we chatted recently, don't talk
if (not thread_check_done(M03_thread.chatter_timer)) then
return
end
local playing_line = false
-- find something to say
for i,chat in pairs(M03_drone_operators) do
if (not playing_line) and (not chat.spoken) then
chat.spoken = true
playing_line = true
if chat.is_conversation then
m03_convo(chat.conversation)
else
audio_play_persona_line_2d(chat.speaker.persona_id, chat.line)
end
-- set the timer so someone else doesn't try to talk
M03_thread.chatter_timer = thread_new("delay", 5.0)
end
end
end
end
-- Callback for a vehicle being killed during the satellite attack portion
--
-- vehicle_name: (string) name of the vehicle
--
function m03_satellite_vehicle_killed_cb(vehicle_name)
-- clear our callback
on_vehicle_destroyed("", vehicle_name)
-- find our vehicle
for i,sat_group in pairs(M03_all_satellite_groups) do
if sat_group.vehicle == vehicle_name then
-- don't need this marker anymore
marker_remove(sat_group.vehicle)
-- release the whole group
release_to_world(sat_group.name)
-- kill the thread
thread_kill(sat_group.thread)
-- we're done here
return
end
end
end
-- Callback for an attacker being killed during the satellite attack portion
--
-- attacker: (string) name of the attacker
--
function m03_satellite_attacker_killed_cb(attacker)
on_death("", attacker)
marker_remove(attacker)
end
-- Callback for a tank being killed during the satellite attack portion
--
-- tank: (string) name of the tank
--
function m03_satellite_tank_killed_cb(tank)
on_vehicle_destroyed("", tank)
marker_remove(tank)
end
-- Shaundi is killed and you lose
--
function m03_shaundi_killed_cb()
mission_end_failure("m03", "m03_failure_shaundi_killed")
end
-- Abandoned Shaundi, you lose
--
function m03_failure_dismissed_cb()
mission_end_failure("m03", "m03_failure_homie_dismissed")
end
-- Handle Pierce talking when getting shot
--
function m03_heli_chatter_cb()
-- if a conversation is going, don't talk
if M03_status.convo_is_playing then
return
end
-- if we chatted recently, don't talk
if (not thread_check_done(M03_thread.chatter_timer)) then
return
end
local playing_line = false
-- find something to say
for i,chat in pairs(M03_radio_chatter) do
if (not playing_line) and (not chat.spoken) then
audio_play_persona_line(chat.speaker, chat.line)
chat.spoken = true
playing_line = true
-- set the timer so someone else doesn't try to talk
M03_thread.chatter_timer = thread_new("delay", 5.0)
end
end
end
-- Callback for spawning a second set of enemy choppers when the player reaches a certain point in the fly home portion
--
function m03_spawn_secondary_enemies_cb()
-- Make them fast so they can get in position behind the bomb chopper
local follower_speed = 50
group_create(M03_group.fly_home_secondary_enemies.name, true)
for i,chopper in pairs(M03_vehicle.fly_home_secondary_enemies) do
vehicle_enter_group_teleport(M03_char.fly_home_secondary_enemies[i], chopper)
vehicle_suppress_npc_exit(chopper, true)
end
for i,chopper in pairs(M03_vehicle.fly_home_secondary_enemies) do
M03_thread.fly_home_secondary_enemy_chase[i] = thread_new("m03_wrapper_thread", helicopter_fly_to_direct_follow, chopper, follower_speed, M03_group.choppers.bomb.vehicle, M03_scripted_path.fly_home_secondary_enemies[i], 5)
-- not required, no marker -- marker_add(chopper, MINIMAP_ICON_KILL, OI_ASSET_KILL)
on_vehicle_destroyed("m03_heli_enemy_destroyed_cb", chopper)
end
-- Make sure they don't hit the player or the bomb when they die
on_damage("m03_crash_heli", M03_vehicle.fly_home_secondary_enemies[1], 0.20)
on_damage("m03_crash_heli", M03_vehicle.fly_home_secondary_enemies[2], 0.20)
for i,npc_group in pairs(M03_char.fly_home_enemies) do
for j,npc in pairs(npc_group) do
ai_add_enemy_target(npc, M03_group.choppers.bomb.pilots[1], ATTACK_NOW_NEVER_LOSE, true)
end
end
M03_trigger.fly_home_secondary_enemies.triggered = true
end
-- Callback for when an NPC enters the "blow up helis" trigger
--
-- npc: (string) name of the NPC that entered the trigger
--
function m03_blow_up_helis_cb(npc)
-- If an ambient ped activates the trigger, the callback is called with an empty string for the NPC name
if (npc == nil or npc == "") then
return
end
local vehicle_name = get_char_vehicle_name(npc)
-- Just in case the NPC is somehow not in a vehicle...
if (vehicle_name == nil or vehicle_name == "") then
return
end
-- Don't destroy any of the good guys
if (vehicle_name == M03_group.choppers.bomb.vehicle) then
return
end
if (vehicle_name == M03_group.choppers.backup.vehicle) then
return
end
if (vehicle_name == M03_group.choppers.pierce.vehicle) then
if M03_status.fly_home_played then
return
end
--Have Shaundi point out ex bf's apartment
M03_thread.fly_home_convo = thread_new("m03_convo", M03_convo.fly_home)
M03_status.fly_home_played = true
-- Switch music
audio_object_post_event("M03_Heli_Rail_Score_Finish", nil, nil, LOCAL_PLAYER)
return
end
local smoke, fire = vehicle_get_smoke_and_fire_state(vehicle_name)
-- Make sure they're smoking and on fire
if ((smoke and fire) == false) then
helicopter_fly_to_direct(vehicle_name, 80.0, M03_navpoint.heli_blow_up)
vehicle_set_smoke_and_fire_state(vehicle_name, true, true)
end
M03_trigger.blow_up_helis.triggered = true
end
-- Callback for when player enters the "callout 1" trigger
--
function m03_callout_1_cb()
-- message("Convo trigger 1")
if (M03_trigger.callout1.triggered) then
return
end
M03_trigger.callout1.triggered = true
on_trigger("", M03_trigger.callout1.name)
trigger_enable(M03_trigger.callout1.name, false)
m03_convo(M03_convo.callout1)
end
-- Callback for when player enters the "callout 2" trigger
--
function m03_callout_2_cb()
-- message("Convo trigger 2")
if (M03_trigger.callout2.triggered)then
return
end
M03_trigger.callout2.triggered = true
on_trigger("", M03_trigger.callout2.name)
trigger_enable(M03_trigger.callout2.name, false)
audio_play_persona_line(M03_char.shaundi, "M03_Calling_Out_Places_02")
end
-- Callback for when player enters the "callout 3" trigger
--
function m03_callout_3_cb()
-- message("Convo trigger 3")
if (M03_trigger.callout3.triggered)then
return
end
M03_trigger.callout3.triggered = true
on_trigger("", M03_trigger.callout3.name)
trigger_enable(M03_trigger.callout3.name, false)
audio_play_persona_line(M03_char.shaundi, "M03_Calling_Out_Places_03")
end
-- Callback for when player enters the "callout 4" trigger
--
function m03_callout_4_cb()
-- message("Convo trigger 4")
if(M03_trigger.callout4.triggered)then
return
end
M03_trigger.callout4.triggered = true
on_trigger("", M03_trigger.callout4.name)
trigger_enable(M03_trigger.callout4.name, false)
audio_play_persona_line(M03_char.shaundi, "M03_Calling_Out_Places_04")
end
-- Callback for when a player leaves the weapon store
--
function m03_weapon_store_complete(screen_name, player_name)
if (screen_name ~= "store_weapon") then
return
end
-- flag the player as completed
Weapon_store_completion[player_name] = true
-- TODO: if one finished first, figure out what to do here, maybe just have a wait objective
--if(not(Weapon_store_completion[LOCAL_PLAYER] and Weapon_store_completion[REMOTE_PLAYER]))then
--end
end
--------------------------------------------------------------------------------------------------
--[[******************]]--
--[[ ]]--
--[[ Thread functions ]]--
--[[ ]]--
--[[******************]]--
-- Handle playing all of the conversations on the drive to the weapons shop
-- Exit if weapons shop trigger is hit
--
function m03_start_convos_thread()
--M03_convo.mission_start.thread = thread_new("m03_convo", M03_convo.mission_start)
--delay(1.0)
repeat
thread_yield()
until (not M03_status.convo_is_playing) or (M03_trigger.weapon_store.triggered)
if M03_status.convo_is_playing then
audio_conversation_end(M03_convo.mission_start.handle)
end
if (not M03_trigger.weapon_store.triggered) then
delay(2.0)
end
if (not M03_trigger.weapon_store.triggered) then
M03_convo.mission_start.thread = thread_new("m03_convo", M03_convo.set_gps)
delay(1.0)
repeat
thread_yield()
until (not M03_status.convo_is_playing) or (M03_trigger.weapon_store2.triggered)
if M03_status.convo_is_playing then
audio_conversation_end(M03_convo.set_gps.handle)
end
end
if (not M03_trigger.weapon_store.triggered) then
delay(2.0)
end
if (not M03_trigger.weapon_store.triggered) then
M03_convo.mission_start.thread = thread_new("m03_convo", M03_convo.to_gun_store1)
delay(1.0)
repeat
thread_yield()
until (not M03_status.convo_is_playing) or (M03_trigger.weapon_store2.triggered)
if M03_status.convo_is_playing then
audio_conversation_end(M03_convo.to_gun_store1.handle)
end
end
if (not M03_trigger.weapon_store.triggered) then
delay(3.0)
end
if (not M03_trigger.weapon_store.triggered) then
M03_convo.mission_start.thread = thread_new("m03_convo", M03_convo.to_gun_store2)
delay(1.0)
repeat
thread_yield()
until (not M03_status.convo_is_playing) or (M03_trigger.weapon_store2.triggered)
if M03_status.convo_is_playing then
audio_conversation_end(M03_convo.to_gun_store2.handle)
end
end
if (not M03_trigger.weapon_store.triggered) then
radio_newsbreak("m01")
end
end
-- Handle the GPS tutorial
-- People miss this, so set this up as a separate thread that will let the player continue
-- if they can't figure this out.
--
function m03_gps_tutorial_thread()
-- set the objective to set the GPS
objective_text(0, M03_text.set_gps, nil, nil, SYNC_ALL, OI_ASSET_USE)
-- SP: display the hud prompt TO THE LOCAL PLAYER to pull up the cell phone/map. NEIL - you'll need to change this to happen on the player who got into a car and not the other player, or some such logic, to cover co-op variations
hud_prompt(LOCAL_PLAYER, "M03_OBJ_ACCESS_MAP_USE_MSG", "m03_hud_prompt_cb")
if coop_is_active() then
hud_prompt(REMOTE_PLAYER, "M03_OBJ_ACCESS_MAP_USE_MSG", "m03_hud_prompt_cb")
end
-- Tell the player to place a waypoint
local redisplay = true
local infinite_duration = true
tutorial_start("pause_map", 0,false,redisplay, infinite_duration)
-- prep the map
pause_map_tutorial_mode(true)
repeat
thread_yield()
until (waypoint_is_placed() or M03_trigger.weapon_store.triggered)
pause_map_tutorial_mode(false)
tutorial_stop("pause_map")
hud_prompt_clear() --SP: remove the HUD prompt when the waypoint is placed
if not M03_trigger.weapon_store.triggered then
-- clear the trigger and set it with proper marker
marker_remove_trigger(M03_trigger.weapon_store.name, SYNC_ALL)
marker_add_trigger(M03_trigger.weapon_store.name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Tell the player to drive to the weapon store.
objective_text(0, M03_text.go_to_weapon_store, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
tutorial_vehicle_controls_enabled(true)
-- if we are still in the car, maybe start the tutorial
if character_is_in_vehicle(LOCAL_PLAYER) then
tutorial_start("np_car_controls")
end
-- queue up the minimap tutorial
tutorial_start("minimap")
end
tutorial_vehicle_controls_enabled(true)
end
-- Send troops to their post
--
-- squad: (table) squad members and destination
-- advance: {boolean) if true, guards will advance on the player
--
function m03_deploy_troops_thread(squad, advance)
local should_run = true
local should_fire = false
for i,guard in pairs(squad.members) do
if (not character_is_dead(guard)) then
ai_add_enemy_target(guard, LOCAL_PLAYER, ATTACK_NOW_NEVER_LOSE)
if (coop_is_active()) then
ai_add_enemy_target(guard, REMOTE_PLAYER, ATTACK_NOW_NEVER_LOSE)
end
ai_do_scripted_move(guard, squad.dest, should_run, should_fire)
if advance then
on_ai_do_action_complete("m03_advance_cb", guard)
else
on_ai_do_action_complete("m03_take_cover_cb", guard)
end
end
end
end
-- Thread for setting up an enemy chopper and its pilots for the fly home portion
--
-- index: (number) index of the group we are setting up
-- chopper: (string) name of the chopper in the group
--
function m03_fly_home_enemy_setup_thread(index, chopper)
vehicle_enter_group_teleport(M03_char.fly_home_enemies[index], chopper)
npc_combat_enable(M03_char.fly_home_enemies[index][1], false)
npc_combat_enable(M03_char.fly_home_enemies[index][2], false)
vehicle_suppress_npc_exit(chopper, true)
end
-- Move the bomb heli in to 'pickup' the bomb
--
function m03_pickup_bomb_thread()
local speed = 4.0
helicopter_fly_to_direct(M03_group.choppers.bomb.vehicle, speed, M03_group.choppers.bomb.pickup_nav[1])
-- really slow for lowering to pick up
speed = 2.0
helicopter_fly_to_direct(M03_group.choppers.bomb.vehicle, speed, M03_group.choppers.bomb.pickup_nav[2])
-- just stay here when done so we can be shot up
end
-- Thread for processing one group of attackers in the satellite portion
--
-- spawn_group: (table) group attackers information
--
function m03_satellite_attacker_thread(spawn_group)
group_create(spawn_group.name, true)
vehicle_enter_group_teleport(spawn_group.members, spawn_group.vehicle)
vehicle_ignore_repulsors(spawn_group.vehicle, true)
marker_add(spawn_group.vehicle, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL)
vehicle_suppress_npc_exit(spawn_group.vehicle)
vehicle_speed_override(spawn_group.vehicle, 30)
on_vehicle_destroyed("m03_satellite_vehicle_killed_cb", spawn_group.vehicle)
-- make driver dumb
local driver = vehicle_get_driver(spawn_group.vehicle, false)
set_ignore_ai_flag( driver, true )
local use_navmesh = true
local stop_at_goal = true
local force_path = false
local suppress_errors = false
vehicle_pathfind_to(spawn_group.vehicle, spawn_group.dest, use_navmesh, stop_at_goal, force_path, suppress_errors)
-- NOBODY gets out, because killing specs on foot is kinda dull
----- vehicle is no longer the threat
---marker_remove(spawn_group.vehicle)
---on_vehicle_destroyed("", spawn_group.vehicle)
---vehicle_exit_group(spawn_group.members)
vehicle_freeze(spawn_group.vehicle, true)
-- For fuck's sake, don't drive your car into the water!
character_kill(driver)
--vehicle_max_speed(spawn_group.vehicle, 0.0)
--vehicle_disable_chase(spawn_group.vehicle, true)
--vehicle_disable_flee(spawn_group.vehicle, true)
for npc_index,npc in pairs(spawn_group.members) do
if (character_exists(npc) and not character_is_dead(npc)) then
-- force_fire(npc, "group_a_nav<002>")
--- marker_add(npc, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL)
ai_add_enemy_target(npc, M03_group.choppers.bomb.pilots[1], ATTACK_NOW_NEVER_LOSE)
--- ai_add_enemy_target(npc, M03_group.choppers.pierce.pilots[1], ATTACK_NOW_NEVER_LOSE)
--- ai_add_enemy_target(npc, M03_group.choppers.backup.pilots[1], ATTACK_NOW_NEVER_LOSE)
--- on_death("m03_satellite_attacker_killed_cb", npc)
end
end
-- when the vehicle is destroyed, this thread will be killed
while true do
if vehicle_in_water(spawn_group.vehicle) then
vehicle_detonate(spawn_group.vehicle)
end
thread_yield()
end
--[[
-- Wait until all the NPCs in this group have died
for npc_index,npc in pairs(spawn_group.members) do
repeat
thread_yield()
until (not character_exists(npc) or character_is_dead(npc))
end
delay(2.0)
-- Release them to the world, so they can be respawned
release_to_world(spawn_group.name)
delay(2.0)
]]--
end
-- Continuously respawn attackers and send them to attack positions until we are told to stop
--
-- spawn_table: (table) table of group information for attackers
--
function m03_satellite_attackers_thread(spawn_table)
-- flag that tells us to go/stop
M03_status.satellite_timer_elapsed = false
while not M03_status.satellite_timer_elapsed do
-- respawn where necessary
for sa_index,spawn_group in pairs(spawn_table) do
if sa_index <= M03_num_satellite_attackers then
if thread_check_done(spawn_group.thread) then
spawn_group.thread = thread_new("m03_satellite_attacker_thread", spawn_group)
delay(0.5)
end
end
end
-- at least one yield
thread_yield()
end
-- wait for all of the spawns to be done
for sa_index,spawn_group in pairs(spawn_table) do
while not thread_check_done(spawn_group.thread) do
thread_yield()
end
end
end
-- Since tanks are so uber powerful, delay attacking until some time to blow them up has passed
--
-- group_table: (table) information about the tank group
--
function m03_tank_delay_gunner_thread( group_table )
-- nobody in the tank attacks...yet
npc_combat_enable(group_table.members[1], false)
npc_combat_enable(group_table.members[2], false)
-- wait some time and enable the machine gunner
delay(10.0)
npc_combat_enable(group_table.members[2], true)
delay(5.0)
-- let the main gunner go (you are the dead)
npc_combat_enable(group_table.members[1], true)
end
-- If noone is speaking, say something
--
function m03_heli_chatter_thread()
for i,chat in pairs(M03_chopper_combat) do
local playing_line = false
while (not playing_line) do
if M03_status.convo_is_playing then
-- if a conversation is going, don't talk
thread_yield()
elseif (not thread_check_done(M03_thread.chatter_timer)) then
-- if we chatted recently, don't talk
thread_yield()
elseif (not playing_line) and (not chat.spoken) then
audio_play_persona_line(chat.speaker, chat.line)
chat.spoken = true
playing_line = true
-- set the timer so someone else doesn't try to talk
M03_thread.chatter_timer = thread_new("delay", 5.0)
end
end
delay(10.0) -- wait before trying to say one of these lines again
end
end
function m03_wrapper_thread(function_ref, ...)
function_ref(unpack(arg))
end
-- Set it up so that secondary enemies hover in the air prior to the player getting near
--
function m03_secondary_heli_hover_setup()
helicopter_fly_to(M03_vehicle.fly_home_enemies[5], 80, M03_FlytoPoint[1])
helicopter_fly_to(M03_vehicle.fly_home_enemies[6], 80, M03_FlytoPoint[2])
helicopter_fly_to(M03_vehicle.fly_home_enemies[7], 80, M03_FlytoPoint[3])
helicopter_fly_to(M03_vehicle.fly_home_enemies[8], 80, M03_FlytoPoint[4])
helicopter_fly_to(M03_vehicle.fly_home_enemies[9], 80, M03_FlytoPoint[5])
helicopter_fly_to(M03_vehicle.fly_home_enemies[10], 80, M03_FlytoPoint[6])
end
-- Cleanup any callback on army guys if the mission is ended while they are still active
--
function m03_cleanup_army_callbacks()
if(group_is_loaded(M03_group.the_army.name))then
for i,guard in pairs(M03_group.the_army.squad1.members) do
on_ai_do_action_complete("", guard)
end
for i,guard in pairs(M03_group.the_army.squad2.members) do
on_ai_do_action_complete("", guard)
end
for i,guard in pairs(M03_group.the_army.squad3.members) do
on_ai_do_action_complete("", guard)
end
for i,guard in pairs(M03_group.the_army.squad4.members) do
on_ai_do_action_complete("", guard)
end
for i,guard in pairs(M03_group.the_army.squad5.members) do
on_ai_do_action_complete("", guard)
end
for i,guard in pairs(M03_group.the_army.squad6.members) do
on_ai_do_action_complete("", guard)
end
end
end