--[[
SH04.lua
SR3 Mission Script
DATE: 11/1/2010
AUTHOR: David Bowring, Jimmy Cross
]]
-- Debug flags --
-- Tweakable Parameters --
sh04_status = {
convo_is_playing = false,
}
-- Characters --
ANGEL_NO_MASK = "Angel"
ANGEL_WITH_MASK = "Angel_Mask"
MOVING_DOWN_CHARACTERS = { "Moving Down 001", "Moving Down 002", "Moving Down 003" }
MOVING_DOWN_LEADER = MOVING_DOWN_CHARACTERS[1]
-- Groups --
SH04_group = {
homies = {
name = "Homies Group",
members = { "Angel", "Angel_Mask" },
thread = INVALID_THREAD_HANDLE
},
initial_luchadors = {
name = "Initial Luchadors",
members = { "First Floor 002", "First Floor 005",
"Second Floor 001", "Second Floor 002", "Second Floor 003",
"Second Floor 006", "Second Floor 010",}
},
right_door =
{
name = "right_door_grp",
members = { "First Floor 003", "First Floor 011" },
thread = { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE },
navs = { "rdest", "rdest01" }
},
left_door =
{
name = "left_door_grp",
members = { "First Floor 001", "First Floor 006", "First Floor 009" },
thread = { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE },
navs = {"ldest01", "ldest02", "ldest03" }
},
first_specialist = {
name = "first_specialist",
members = "init_specialist",
dest = "spec_dest"
},
coop_initial_luchadors = {
name = "coop_init",
members = { "coop_first_floor", "coop_first_floor<001>", "coop_first_floor<002>", "coop_first_floor<003>", "coop_first_floor<004>", "coop_first_floor<005>", "coop_first_floor<006>", }
},
backroom_guards = {
name = "Backroom Guards",
members = { "Backroom Back 002", "Backroom Back 003", "Backroom Back 004" }
},
back_left = {
name = "Back_Left",
members = {"Backroom Left 001", "Backroom Left 002"},
navs = { "lback01", "lback02", "lback03", "lback04" }
},
back_right = {
name = "Back_Right",
members = { "Backroom Right 002", "Backroom Right 003" },
navs = { "rback01","rback02","rback03","rback04", }
},
backroom_specialist = {
name = "Backroom Specialist Group",
members = "Backroom Specialist"
},
backroom_specialist_coop = {
name = "Backroom Specialist Coop",
members = "Backroom_Specialist_Coop"
},
alpha_squad = {
name = "Alpha Team",
members = { "Alpha 003", "Alpha 006" },
},
beta_squad = {
name = "Beta Team",
members = { "Beta 001", "Beta 005"},
},
right_room = {
name = "right room",
members = { "Right guard 001","Right guard 002" },
},
brute_g01 = {
name = "brute_01",
members = "brute01"
},
brute_g02 = {
name = "brute_02",
members = { "brute02", "brute03" }
},
brute_g03 = {
name = "brute_03",
members = {"brute04"}
},
post_mask_attackers = {
name = "Post Mask Attackers",
members = { "Post Mask 001", "Post Mask 002", "Post Mask 003", "Post Mask 004", "Post Mask 005" }
},
casino_manager = {
name = "manager",
members = "sh04_manager",
dest = "angel_dest",
id = -1,
thread = INVALID_THREAD_HANDLE
},
cont_spawn_a = {
name = "spawngroup_a",
members = "spawn_a"
},
cont_spawn_b = {
name = "spawngroup_b",
members = "spawn_b",
},
cont_spawn_c = {
name = "spawngroup_c",
members = "spawn_c", "spawn_c<001>"
},
cont_spawn_d = {
name = "spawngroup_d",
members = "spawn_d",
},
--[[
cont_spawn_spec = {
name = "spawngroup_c",
members = "spawn_c",
},
]]--
ambush = {
name = "post_statue",
members = { "Post Statue", "Post Statue 001", "Post Statue 002", "Post Statue 003" }
},
peds = {
name = "sh04_peds",
members = { "bartender 001", "bartender 002", "dealer", "dealer<003>",
"gambler<001>", "gambler<003>", "gambler<004>" },
bartenders = { "bartender 001", "bartender 002" },
dealers = { "dealer", "dealer<003>" }
},
CTE_cutscene = {
name = "CTE Cutscene",
members = { "CTE Angel (No Mask)" }
},
CTE_angel_mask = {
name = "CTE_AngelWMask",
members = { "CTE Angel Mask" },
},--[[,
= {
name = "next group name"
},]]
}
sh04_objectives = {
statues =
{
members = { "statue_trigger", "statue_trigger<001>", "statue_trigger<002>", "statue_trigger<003>", "statue_trigger<004>", "statue_trigger<005>"},
status = {false, false, false, false, false, false},
active = {false, false, false, false, false, false},
nav = { "statue_nav", "statue_nav<001>", "statue_nav<002>", "statue_nav<003>", "statue_nav<004>", "statue_nav<005>" }
},
}
-- Navpoints --
sh04_navs = {
post_cte = { "checkpoint_cte_local", "checkpoint_cte_remote" },
tele = {
plocal = "teleport_local",
premote = "teleport_remote"
},
cp_start = { "Checkpoint Warp Start", "P2 Checkpoint Warp Start" }
}
START_WARP_LOCATIONS = { [LOCAL_PLAYER] = "Checkpoint Warp Start", [REMOTE_PLAYER] = "P2 Checkpoint Warp Start" }
POST_MASK_CHECKPOINT_WARP_LOCATIONS = { [LOCAL_PLAYER] = "checkpoint_cte_local", [REMOTE_PLAYER] = "checkpoint_cte_remote" }
NAVPOINT_ANGEL_POST_MASK = "CTE Angel Location"
NAVPOINT_TO_VAULT_001 = "To Vault 001"
NAVPOINT_TO_VAULT_002 = "To Vault 002"
NAVPOINT_MASK_CUTSCENE = "Mask Cutscene Location"
NAVPOINT_PICK_UP_MASK_LOCATION = "CTE Mask Pickup Point"
NAVPOINT_POST_CTE_PLAYER_WARP = "CTE Player Location"
NAVPOINT_POST_CTE_REMOTE_PLAYER_WARP = "CTE Angel Location"
NAVPOINTS_DOWN_STAIRS_PATH = { "Down Stairs Path 001", "Down Stairs Path 002" }
SH04_BRUTE_DEST = "brute_dest"
-- Triggers --
SH04_TRIGGER_UPSTAIRS = "Spawn_upstairs"
SH04_TRIGGER_ALPHA = "trigger_alpha"
SH04_TRIGGER_BETA = "trigger_beta"
SH04_TRIGGER_ATTACK = "attack_trigger"
--SH04_TRIGGER_ALARM = "Alarm_Trigger"
SH04_TRIGGER_AMBUSH = "ambush_trigger"
SH04_TRIGGER_CONT_SPAWN = "trig_activate_cont_spawn"
TRIGGER_BOTTOM_FLOOR = "Bottom Floor"
TRIGGER_TO_VAULT_001 = "To Vault Trigger 001"
TRIGGER_TO_VAULT_002 = "To Vault Trigger 002"
TRIGGER_MASK_CUTSCENE = "Mask Cutscene"
TRIGGER_MISSION_AREA_001 = "Mission Area 001"
-- Vehicles --
-- Mesh Movers --
SH04_killbane_statues = { "SM Killbane Statue 1F SE", "SM Killbane Statue 1F NW", "SM Killbane Statue 1F SW",
"SM Killbane Statue 2F NE", "SM Killbane Statue 2F NW", "SM Killbane Statue 2F SE" } --"SM Killbane Statue 2F SW", "SM Killbane Statue 1F NE",
-- Text --
HELPTEXT_FAILURE_ANGEL_DIED = "sh04_failure_angel_died"
HELPTEXT_FAILURE_ANGEL_ABANDONED = "sh04_failure_angel_abandoned"
HELPTEXT_FAILURE_LEFT_MISSION = "sh04_failure_left_casino"
SH04_HELPTEXT_GET_BACK_TO_THE_CASINO = "sh04_get_back_to_the_casino"
HELPTEXT_HEAD_TO_CASINO = "sh04_obj_head_to_casino"
HELPTEXT_GO_TO_THE_STATUE = "sh04_obj_go_to_the_statue"
HELPTEXT_FIND_THE_VAULT = "sh04_obj_find_the_vault"
HELPTEXT_DESTROY_STATUES = "sh04_obj_destroy_statues"
HELPTEXT_DESTROY_LUCHADORES = "SH04_OBJ_DESTROY_LUCHADORES"
SH04_DAMAGE = "SH04_DAMAGE"
SH04_TOTAL_DAMAGE = 125
SH04_MANAGER = "SH04_OBJ_MGR"
SH04_BRUTES = "SH04_OBJ_BRUTES"
-- Threads --
sh04_threads = {
attack_line_timer = INVALID_THREAD_HANDLE
}
SH04_THREAD_SPAWN_SECOND_SQUAD = INVALID_THREAD_HANDLE
SH04_THREAD_SPAWN_SECOND_SQUAD = INVALID_THREAD_HANDLE
SH04_THREAD_ANGEL_WATCHER = INVALID_THREAD_HANDLE
SH04_THREAD_CONVO = INVALID_THREAD_HANDLE
-- Checkpoints --
CHECKPOINT_START = MISSION_START_CHECKPOINT -- defined in ug_lib.lua
SH04_CHECKPOINT_MASK = "sh04_checkpoint_mask"
-- Cutscenes --
CUTSCENE_MISSION_INTRO = ""
CUTSCENE_MISSION_OUTRO = ""
CUTSCENE_ENTRANCE = "ld_sh01"
CUTSCENE_TAKE_MASK = "cte_s04_angel_gets_mask"
-- Conversations --
SH04_convo = {
start_convo = {
name = "SH04_Mission_Start",
handle = INVALID_CONVERSATION_HANDLE
}
,
fake_convo = {
name = "SH04_Fake_Mask",
handle = INVALID_CONVERSATION_HANDLE
}
,
vault_convo = {
name = "SH04_Vault_Mask",
handle = INVALID_CONVERSATION_HANDLE
}
,
destroy_statues_convo = {
name = "SH04_Destroy_Statues",
handle = INVALID_CONVERSATION_HANDLE
}
,
see_manager = {
name = "SH04_See_Manager",
handle = INVALID_CONVERSATION_HANDLE
}
,
threaten_manager = {
name = "SH04_Threaten_Manager_New",
handle = INVALID_CONVERSATION_HANDLE
}
,
interrogate_manager = {
name = "SH04_Manager_Interrogation",
handle = INVALID_CONVERSATION_HANDLE
}
,
fight2vault = {
name = "SH04_Fights_To_The_Vault",
handle = INVALID_CONVERSATION_HANDLE
}
}
SH04_dialog_lines = {
pre_mask = "sh04_pre_mask_combat",
post_mask = "sh04_post_mask_combat",
brute01 = "sh04_brute_comment_01",
brute02 = "sh04_brute_comment_02",
specialist01 = "sh04_luchadore_specialist_01",
specialist02 = "sh04_luchadore_specialist_02",
clean_house = "SH04_Finish_Clearing_Guys_01",
put_on_mask = "sh04_puts_on_mask",
do_damage = "SH04_Do_Damage",
statue_destroyed = {
"SH04_Statue_Destroyed_01",
"SH04_Statue_Destroyed_02",
"SH04_Statue_Destroyed_03",
"SH04_Statue_Destroyed_04",
"SH04_Statue_Destroyed_05",
"SH04_Statue_Destroyed_06"
},
}
-- Other --
CONTINUOUS_SPAWN_POINTS = { "Spawn 2F E", "Spawn 2F W", "Spawn N", "Spawn NE", "Spawn SE" }
SH04_INIT_SPAWN_POINTS = { "init_spawn_1", "init_spawn_2" }
SH04_INT_CONT_SPAWN_TIME = 6
SH04_SPECIALIST_SPAWN_DELAY_SECONDS = 10.0
SH04_NORMAL_SQUAD_RESPAWN_DELAY_SECONDS = 15.0
SH04_SPECIALIST_SQUAD_SPAWN_DELAY_SECONDS = 20.0
SH04_COOP_SCALE = 5.0
--SH04_NUM_STATUES_REMAINING_BRUTE_SPAWN_TRIGGER = 2
SH04_OUT_OF_AREA_FAILURE_TIME_MS = 15000
SH04_MIN_NOTORIETY = 4
SH04_GO_HOSTILE = false
SH04_TIMER_ACTIVE = false
SH04_LEAVE_AREA_FAILURE_ENABLED = false
SH04_INTERROGATION = false
SH04_INTERROGATION_COMPLETE = false
SH04_INTERROGATE_PLAYER = LOCAL_PLAYER
local IS_RESTART = false
SH04_ANGEL_RADIUSS = 10
ANIMATION_EXAMINE_FAKE_MASK = "react Surprised"
ANIMATION_FINISH_PUTTING_ON_MASK = "react Surprised"
FAIL_TIMER_INDICES = { [LOCAL_PLAYER] = 1, [REMOTE_PLAYER] = 2 }
SH04_NUMBER_LUCHADORES = 0
SH04_DEAD_BRUTES = 0
SH04_Players = { LOCAL_PLAYER, REMOTE_PLAYER }
sh04_queue = {}
sh04_queue_size = 0
sh04_spawn_brutes = true
-- Set by default to "true" since mission is started within the trigger regions
Players_in_mission_area_triggers = { [TRIGGER_MISSION_AREA_001] = { [LOCAL_PLAYER] = true, [REMOTE_PLAYER] = true }}
Players_in_mission_area = { [LOCAL_PLAYER] = true, [REMOTE_PLAYER] = true }
Entrance_cutscene_triggered = false
Hit_vault_one_trigger = false
Hit_mask_cutscene = false
Wait_on_Angel_timer_expired = false
SH04_slot_obj = false
sh04_hostage_taken = false
SH04_num_remaining_luchadors = 0
SH04_num_remaining_statues = 0
SH04_original_num_statues = 0
SH04_destroyed_slots = 0
SH04_total_slots = 380
Mission_successful = false
---AUDIO---
SH04_START_CONVERSATION_PLAYER = "SH04_Mission_Start_02"
SH04_START_CONVERSATION_ANGEL = "SH04_Mission_Start_01"
-- *************************
--
-- 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
--
-- sh04_checkpoint: The checkpoint the mission should begin at
-- is_restart: TRUE if the mission is restarting, FALSE otherwise
--
function sh04_start(sh04_checkpoint, is_restart)
IS_RESTART = is_restart
-- Check if this mission starting from the beginning
if (sh04_checkpoint == CHECKPOINT_START) then
if (is_restart == false) then
-- First time playing mission
-- Play an intro cutscene???
if (CUTSCENE_ENTRANCE ~= "") then
zscene_prep( CUTSCENE_ENTRANCE )
cutscene_play( CUTSCENE_ENTRANCE, nil, sh04_navs.cp_start, false )
--sh04_play_entrance_cutscene()
end
else --is a restart, need to make sure all movers are reset
mesh_mover_reset_by_zone("3count_interior")
end
fade_out(0)
sh04_setup_slots()
end
character_ragdoll_set_last_resort_position( sh04_navs.cp_start[1] )
-- Handle mission initialization for the current checkpoint
sh04_initialize(sh04_checkpoint)
-- Run the mission from the current checkpoint
sh04_run(sh04_checkpoint)
end
-- This is the primary function responsible for running the entire mission from start to finish.
--
-- first_checkpoint: The first checkpoint to begin running the mission at
--
function sh04_run(first_checkpoint)
local current_checkpoint = first_checkpoint
-- Run the mission from the beginning
if current_checkpoint == CHECKPOINT_START then
sh04_initial_cont_spawn() --set up continuous spawn guys during the damage portion
sh04_convo(SH04_convo.start_convo)
delay(.5)
--delay so we don't play the dialog line on top of the convo
repeat
thread_yield()
until (sh04_status.convo_is_playing == false)
--if there have been no slots killed yet, remind the player with a voice line
if SH04_destroyed_slots == 0 then
audio_play_persona_line( LOCAL_PLAYER, SH04_dialog_lines.do_damage )
end
--delay(1)
--tell angel to throw a grenade
force_throw(ANGEL_NO_MASK, "gren_throw" )
--sh04_attack_trigger() --spawn initial enemies and have them file in
sh04_wait_for_slots()
--talk to pit boss
sh04_obj_manager()
sh04_setup_vault_destination()
sh04_wait_on_reach_vault()
sh04_play_mask_cutscene()
mission_set_checkpoint( SH04_CHECKPOINT_MASK )
current_checkpoint = SH04_CHECKPOINT_MASK
end
if current_checkpoint == SH04_CHECKPOINT_MASK then
--sh04_convo(SH04_convo.vault_convo)
--audio_play_persona_line( ANGEL_WITH_MASK, SH04_dialog_lines.put_on_mask ) --angel is complete!
--make sure the doors are open
door_open("left_door")
door_open("right_door")
sh04_mark_statues()
sh04_create_backroom_guards()
--sh04_create_post_cutscene_attack()
delay(3.5)
--sh04_convo(SH04_convo.destroy_convo)
--ai_suggest_action(ANGEL_WITH_MASK , "follow player" ) --have ANgel follow the player because he gets lost
trigger_enable( SH04_TRIGGER_CONT_SPAWN, true )
on_trigger( "sh04_cont_spawn", SH04_TRIGGER_CONT_SPAWN )
sh04_wait_on_statues_destroyed()
sh04_activate_continuous_spawns( false )
if( coop_is_active() == true ) then
--create the mini gun brute in co=op only
group_create( SH04_group.brute_g03.name )
marker_add_script_group( SH04_group.brute_g03.name, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL )
for i, enemy in pairs(SH04_group.brute_g03.members) do
on_death( "sh04_remaining_luchador_died", enemy )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
move_to( enemy, SH04_BRUTE_DEST)
end
end
sh04_mark_remaining_luchadors()
--sh04_setup_ambush()
sh04_wait_on_leftovers_killed()
if Mission_successful == false then
objective_text( 0, SH04_BRUTES, nil, nil, SYNC_ALL, OI_ASSET_KILL )
end
while( Mission_successful == false ) do
thread_yield()
end
objective_text_clear( 0 )
end
-- Call mission success
mission_end_success( "sh04" )
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function sh04_cleanup()
--enable special slot if it was disabled due to having a sonic gun
inv_weapon_disable_slot(WEAPON_SLOT_SPECIAL, false, SYNC_ALL)
on_death( "", ANGEL_NO_MASK )
on_dismiss( "", ANGEL_NO_MASK )
on_death( "", ANGEL_WITH_MASK )
on_dismiss( "", ANGEL_WITH_MASK )
on_attack_performed("", ANGEL_NO_MASK)
on_attack_performed("", ANGEL_WITH_MASK)
on_character_grabbed("", SH04_group.casino_manager.members)
sh04_remove_markers()
sh04_clear_triggers()
--sh04_end_conversations()
sh04_stop_spawns()
sh04_kill_threads()
sh04_stop_failure_timers()
sh04_cleanup_groups( Mission_successful )
cleanup_statues()
notoriety_set_min( "luchadores", 0 )
notoriety_set_max( "police", 5 )
notoriety_set_can_decay( true )
on_random_mover_killed( "", "sh04")
on_random_human_killed( "", "sh04")
character_ragdoll_clear_last_resort_position()
if SH04_group.casino_manager.id ~= -1 then
audio_persona_remove_2d(SH04_group.casino_manager.id)
SH04_group.casino_manager.id = -1
end
hud_prompt_clear(LOCAL_PLAYER)
hud_prompt_clear(REMOTE_PLAYER)
set_player_can_take_human_shields(LOCAL_PLAYER, true )
if coop_is_active() == true then
set_player_can_take_human_shields(REMOTE_PLAYER, true )
end
end
-- Called when the mission has ended with success
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function sh04_success()
--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]--
Mission_successful = true
local skip_teleport = true
sh04_coop_skip(skip_teleport)
teleport( LOCAL_PLAYER, sh04_navs.tele.plocal )
if coop_is_active() == true then
teleport( REMOTE_PLAYER, sh04_navs.tele.premote )
end
-- mission_successful = true
end
-- *************************
--
-- Local functions
--
-- *************************
-- Initialize the mission for the specified checkpoint
--
-- checkpoint: Checkpoint to initialize the mission to
--
function sh04_initialize(checkpoint)
-- Make sure the screen is completly faded out
mission_start_fade_out(0.0)
-- Set the mission author
set_mission_author("Jimmy Cross")
-- Common initialization
sh04_initialize_common()
-- Checkpoint specific initialization
sh04_initialize_checkpoint(checkpoint)
-- Start fading in
mission_start_fade_in()
end
-- ***************************************************
-- sh04_run Helper Functions
-- ***************************************************
-- this function adds a conversation to the conversation queue. the conversation is played by the play convo thread
--
function sh04_convo( convo )
if (convo == nil) then
return
end
--convo is good, add it to the queue
sh04_queue[sh04_queue_size] = convo
sh04_queue_size = sh04_queue_size + 1
end
-- This function doesn't continue until the entrance cutscene trigger is hit.
--
function sh04_wait_until_entrance_cutscene_triggered()
while( Entrance_cutscene_triggered == false ) do
thread_yield()
end
end
-- Plays the entrance cutscene and has the Luchadors attack the player after it runs.
--
function sh04_play_entrance_cutscene()
zscene_prep( CUTSCENE_ENTRANCE )
cutscene_play( CUTSCENE_ENTRANCE )
end
-- Enables, adds a callback, and adds a marker to the specified trigger.
--
-- callback: Function that the trigger should call when it's triggered.
-- trigger_name: Name of trigger to mark, enable, etc.
--
function sh04_set_trigger_as_destination( callback, trigger_name )
trigger_enable( trigger_name, true )
on_trigger( callback, trigger_name )
marker_add_trigger( trigger_name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
end
function sh04_set_trigger(trigger, trigger_callback)
trigger_enable(trigger, true)
on_trigger(trigger_callback, trigger)
end
function sh04_disable_trigger(trigger)
on_trigger("", trigger)
trigger_enable(trigger, false)
end
function sh04_cont_spawn()
--activate continuois spawns
sh04_activate_continuous_spawns( true )
--spawn the various attackers that should file in from the stairs
sh04_create_post_cutscene_attack()
--tell Angel to move to a point on the casino floor then make him independent
move_to_safe( ANGEL_WITH_MASK, SH04_group.casino_manager.dest, 3, false, false )
--follower_make_independent(ANGEL_WITH_MASK, true)
trigger_enable( SH04_TRIGGER_CONT_SPAWN, false )
on_trigger( "", SH04_TRIGGER_CONT_SPAWN )
end
-- Activate the trigger that causes Angel to mention that he sees his mask.
--
function sh04_activate_dialog_trigger()
trigger_enable( SH04_TRIGGER_UPSTAIRS, true )
on_trigger( "sh04_setup_upstairs", SH04_TRIGGER_UPSTAIRS )
end
function sh04_create_backroom_guards()
group_create( SH04_group.backroom_guards.name )
group_create( SH04_group.back_left.name )
group_create( SH04_group.back_right.name )
end
function sh04_trigger_specialist_spawn()
if (group_is_loaded( SH04_group.backroom_specialist.name ) == false ) then
group_create( SH04_group.backroom_specialist.name )
end
if coop_is_active() == true then
if (group_is_loaded( SH04_group.backroom_specialist_coop.name ) == false ) then
group_create( SH04_group.backroom_specialist_coop.name )
end
end
end
-- Sets up the Vault as the next destination. (Marks the entrance to the backroom and activates guidance and messages)
--
function sh04_setup_vault_destination()
objective_text_clear(0)
objective_text( 0, HELPTEXT_FIND_THE_VAULT, "", "", SYNC_ALL, OI_ASSET_LOCATION )
if SH04_group.casino_manager.thread ~= INVALID_THREAD_HANDLE then
thread_kill(SH04_group.casino_manager.thread)
SH04_group.casino_manager.thread = INVALID_THREAD_HANDLE
end
if SH04_group.homies.thread ~= INVALID_THREAD_HANDLE then
thread_kill(SH04_group.homies.thread)
SH04_group.homies.thread = INVALID_THREAD_HANDLE
end
character_set_can_take_human_shield( ANGEL_NO_MASK, true )
--set_player_can_take_human_shields(ANGEL_NO_MASK, true)
set_player_can_take_human_shields(LOCAL_PLAYER, true )
if coop_is_active() == true then
set_player_can_take_human_shields(REMOTE_PLAYER, true )
end
-- Activate the beginning of the guidance trigger chain
if( Hit_mask_cutscene == false ) then
trigger_enable( TRIGGER_TO_VAULT_001, true )
on_trigger( "sh04_to_vault_001", TRIGGER_TO_VAULT_001 )
marker_add( NAVPOINT_TO_VAULT_001, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
-- Activate the end of the guidance chain in case the player skips ahead (but don't mark it)
trigger_enable( TRIGGER_TO_VAULT_002, true )
on_trigger( "sh04_to_vault_002", TRIGGER_TO_VAULT_002 )
end
end
-- This function delays until the vault has been reached.
--
function sh04_wait_on_reach_vault()
delay(2)
--sh04_convo(SH04_convo.fight2vault)
SH04_convo.fight2vault.handle = audio_conversation_load(SH04_convo.fight2vault.name)
-- Play the conversation
audio_conversation_play(SH04_convo.fight2vault.handle)
-- Wait for the conversation to end
audio_conversation_wait_for_end(SH04_convo.fight2vault.handle)
SH04_convo.fight2vault.handle = INVALID_CONVERSATION_HANDLE
sh04_status.convo_is_playing = false
while ( Hit_mask_cutscene == false ) do
thread_yield()
end
-- We've reached the vault, so stop the objective text
objective_text_clear( 0 )
end
function sh04_wait_for_slots()
while( SH04_slot_obj == false ) do
thread_yield()
end
hud_bar_off( 0 )
end
-- This function sets up the cutscene, plays it, and sets up the situation afterward.
--
function sh04_play_mask_cutscene()
fade_out(0)
fade_out_block()
cutscene_in()
group_create( SH04_group.CTE_cutscene.name)
group_create( SH04_group.CTE_angel_mask.name)
--inv_item_remove_all( SH04_group.CTE_cutscene.members[1] )
--inv_item_remove_all( SH04_group.CTE_angel_mask.members[1] )
--inv_item_remove_all( ANGEL_NO_MASK )
follower_set_can_abandon( ANGEL_NO_MASK, false )
on_dismiss( "", ANGEL_NO_MASK )
party_dismiss( ANGEL_NO_MASK )
character_hide( ANGEL_NO_MASK )
cutscene_play( CUTSCENE_TAKE_MASK, nil, sh04_navs.post_cte, false )
--teleport_coop( POST_MASK_CHECKPOINT_WARP_LOCATIONS[LOCAL_PLAYER], POST_MASK_CHECKPOINT_WARP_LOCATIONS[REMOTE_PLAYER], true )
character_show( ANGEL_WITH_MASK )
party_add( ANGEL_WITH_MASK, LOCAL_PLAYER )
--teleport( ANGEL_WITH_MASK, NAVPOINT_PICK_UP_MASK_LOCATION )
group_destroy( SH04_group.CTE_cutscene.name )
group_destroy( SH04_group.CTE_angel_mask.name )
cutscene_out()
fade_in(0)
fade_in_block()
--action_play( ANGEL_WITH_MASK, ANIMATION_FINISH_PUTTING_ON_MASK )
follower_set_can_abandon( ANGEL_WITH_MASK, true )
end
function sh04_setup_ambush()
if group_is_loaded( SH04_group.initial_luchadors.members ) == true then
for index, member in pairs( SH04_group.initial_luchadors.members ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.coop_initial_luchadors.name ) ) then
for index, member in pairs( SH04_group.coop_initial_luchadors.members ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
if group_is_loaded( SH04_group.right_room.name ) == true then
for index, member in pairs( SH04_group.right_room.name ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.alpha_squad.name ) ) then
for index, member in pairs( SH04_group.alpha_squad.members ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.beta_squad.name ) ) then
for index, member in pairs( SH04_group.beta_squad.members ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.post_mask_attackers.name ) ) then
for index, member in pairs( SH04_group.post_mask_attackers.members ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.back_left.name ) ) then
for index, member in pairs( SH04_group.back_left.members ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.back_right.name ) ) then
for index, member in pairs( SH04_group.back_right.members ) do
if ( character_is_dead( member ) == false ) then
--npc_leash_remove( member )
set_always_sees_player_flag( member, true )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
--ai_do_scripted_move( member, LOCAL_PLAYER, true, true )
set_attack_player_flag( member, true )
end
end
end
end
-- This function marks the initial luchadors as targets and adds death callbacks to them.
-- Something of a misunderstanding, but I decided to leave it in.
--
function sh04_mark_remaining_luchadors()
-- SH04_num_remaining_luchadors = 0
if( group_is_loaded( SH04_group.initial_luchadors.name ) ) then
for index, member in pairs( SH04_group.initial_luchadors.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
--marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.coop_initial_luchadors.name ) ) then
for index, member in pairs( SH04_group.coop_initial_luchadors.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
--marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if ( character_is_dead( SH04_group.brute_g01.members ) == false ) then
marker_add( SH04_group.brute_g01.members, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", SH04_group.brute_g01.members )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
end
if ( character_is_dead( SH04_group.backroom_specialist.members ) == false ) then
marker_add( SH04_group.backroom_specialist.members, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", SH04_group.backroom_specialist.members )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( SH04_group.backroom_specialist.members, true )
set_attack_player_flag( SH04_group.backroom_specialist.members, true )
end
if( group_is_loaded( SH04_group.backroom_specialist_coop.name ) ) then
if ( character_is_dead( SH04_group.backroom_specialist_coop.members ) == false ) then
marker_add( SH04_group.backroom_specialist_coop.members, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", SH04_group.backroom_specialist_coop.members )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( SH04_group.backroom_specialist_coop.members, true )
set_attack_player_flag( SH04_group.backroom_specialist_coop.members, true )
end
end
if( group_is_loaded( SH04_group.right_door.name ) ) then
for index, member in pairs( SH04_group.right_door.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
--marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.left_door.name ) ) then
for index, member in pairs( SH04_group.left_door.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
--marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.alpha_squad.name ) ) then
for index, member in pairs( SH04_group.alpha_squad.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
--marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.beta_squad.name ) ) then
for index, member in pairs( SH04_group.beta_squad.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.post_mask_attackers.name ) ) then
for index, member in pairs( SH04_group.post_mask_attackers.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.back_left.name ) ) then
for index, member in pairs( SH04_group.back_left.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.back_right.name ) ) then
for index, member in pairs( SH04_group.back_right.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
if( group_is_loaded( SH04_group.ambush.name ) ) then
for index, member in pairs( SH04_group.ambush.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
set_always_sees_player_flag( member, true )
set_attack_player_flag( member, true )
end
end
end
--[[
for index, member in pairs( SH04_group.cont_spawn_a.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
end
end
for index, member in pairs( SH04_group.cont_spawn_b.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
end
end
for index, member in pairs( SH04_group.cont_spawn_c.members ) do
if ( character_is_dead( member ) == false ) then
marker_add( member, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_DEFAULT, SYNC_ALL )
on_death( "sh04_remaining_luchador_died", member )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors + 1
end
end
]]--
SH04_NUMBER_LUCHADORES = SH04_num_remaining_luchadors
objective_text( 0, HELPTEXT_DESTROY_LUCHADORES, nil, nil, SYNC_ALL, OI_ASSET_KILL )
audio_play_persona_line( LOCAL_PLAYER, SH04_dialog_lines.clean_house )
end
-- Creates the group that waits at the exit of the vault before the continuous spawn has had a
-- chance to start.
--
function sh04_create_post_cutscene_attack()
group_create( SH04_group.post_mask_attackers.name )
for index, char in pairs( SH04_group.post_mask_attackers.members ) do
on_attack_performed("sh04_attack_line_cb", char)
end
end
-- Marks statues of Killbane as targets and adds destruction callbacks and number tracking to them.
--
function sh04_mark_statues()
SH04_num_remaining_statues = 0
sh04_convo( SH04_convo.destroy_statues_convo )
--marker_add_script_group( SH04_killbane_statues, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL )
--[[
for i, trigger in pairs(sh04_objectives.statues.members) do
if sh04_objectives.statues.status[i] == false then
sh04_set_trigger( trigger, "sh04_hit_trigger" )
end
end
]]--
for index, statue in pairs( SH04_killbane_statues ) do
marker_add( statue, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL ) --OI_FLAGS_DEFAULT + OI_FLAG_FADE
mesh_mover_set_invulnerable( statue, false )
on_mover_destroyed( "sh04_statue_died", statue )
SH04_num_remaining_statues = SH04_num_remaining_statues + 1
end
SH04_original_num_statues = SH04_num_remaining_statues;
objective_text( 0, HELPTEXT_DESTROY_STATUES, 0, SH04_original_num_statues, SYNC_ALL, OI_ASSET_KILL )
end
function sh04_setup_slots()
on_random_mover_killed( "sh04_slot_died", "sh04")
--create initial groups
group_create( SH04_group.initial_luchadors.name, true )
if coop_is_active() == true then
group_create(SH04_group.coop_initial_luchadors.name, true )
end
group_create( SH04_group.first_specialist.name, true )
group_create( SH04_group.right_door.name, true )
group_create( SH04_group.left_door.name, true )
--create the manager and set him up
group_create( SH04_group.casino_manager.name, true )
SH04_group.casino_manager.id = audio_persona_load_2d("Interrogation") --persona for the manager's lines are in the interrogation persona
turn_invulnerable( SH04_group.casino_manager.members )
character_set_counter_on_grabbed( SH04_group.casino_manager.members, true )
if( coop_is_active() ) then
SH04_TOTAL_DAMAGE = 200
end
--objective_text( 0, HELPTEXT_DESTROY_STATUES, 0, SH04_original_num_statues, SYNC_ALL, OI_ASSET_KILL )
hud_bar_on( 0, "Default", SH04_DAMAGE, SH04_TOTAL_DAMAGE, SYNC_ALL )
notoriety_set_max( "luchadores", SH04_MIN_NOTORIETY )
notoriety_set("luchadores", SH04_MIN_NOTORIETY)
notoriety_set_can_decay(false)
notoriety_set_max( "police", 0 )
end
-- Activates the continuous spawns during the Killbane statue sequence.
--
function sh04_activate_continuous_spawns( activate )
--shut down spawns if the statues are gone
if activate == false then
continuous_spawn_stop(SH04_group.cont_spawn_c.name, true)
continuous_spawn_stop(SH04_group.cont_spawn_d.name, true)
continuous_spawn_regions_enable( CONTINUOUS_SPAWN_POINTS, activate )
if SH04_THREAD_SPAWN_SECOND_SQUAD ~= INVALID_THREAD_HANDLE then
thread_kill(SH04_THREAD_SPAWN_SECOND_SQUAD)
end
elseif activate == true then
continuous_spawn_regions_enable( CONTINUOUS_SPAWN_POINTS, activate )
continuous_spawn_start( SH04_group.cont_spawn_c.name, 5, SH04_NORMAL_SQUAD_RESPAWN_DELAY_SECONDS )
--delay( SH04_SPECIALIST_SPAWN_DELAY_SECONDS )
continuous_spawn_start( SH04_group.cont_spawn_d.name, 5, SH04_NORMAL_SQUAD_RESPAWN_DELAY_SECONDS+SH04_SPECIALIST_SPAWN_DELAY_SECONDS )
end
end
-- This function waits until the statues of Killbane are destroyed before continuing.
--
function sh04_wait_on_statues_destroyed()
trigger_enable( SH04_TRIGGER_UPSTAIRS, true )
on_trigger( "sh04_setup_upstairs", SH04_TRIGGER_UPSTAIRS )
trigger_enable( SH04_TRIGGER_ALPHA, true )
on_trigger( "sh04_setup_alpha", SH04_TRIGGER_ALPHA )
trigger_enable( SH04_TRIGGER_BETA, true )
on_trigger( "sh04_setup_beta", SH04_TRIGGER_BETA )
while ( SH04_num_remaining_statues > 0 ) do
thread_yield()
end
--on_mover_destroyed( "", statue )
-- We've destroyed all statues, so stop the objective text
objective_text_clear( 0 )
end
function sh04_wait_on_leftovers_killed()
while ( SH04_num_remaining_luchadors > 0 ) do
if( SH04_num_remaining_luchadors <= 2 ) and sh04_spawn_brutes then
--set up brutes
sh04_brute_finale()
end
thread_yield()
end
--need to make sure the brutes were spawned since it's possible to kill all the enemies before this function is called
if sh04_spawn_brutes == true then
--set up brutes
sh04_brute_finale()
end
-- We've destroyed all dudes, so stop the objective text
objective_text_clear( 0 )
end
-- start the continuous spawns that are active during the destruction objective
--
function sh04_initial_cont_spawn()
continuous_spawn_regions_enable( SH04_INIT_SPAWN_POINTS, true )
continuous_spawn_start( SH04_group.cont_spawn_a.name, 4, SH04_INT_CONT_SPAWN_TIME )
continuous_spawn_start( SH04_group.cont_spawn_b.name, 4, SH04_INT_CONT_SPAWN_TIME )
end
function sh04_obj_manager()
local display = false
on_random_mover_killed( "", "sh04")
--stop continuous spawns
continuous_spawn_regions_enable( SH04_INIT_SPAWN_POINTS, false )
continuous_spawn_stop(SH04_group.cont_spawn_a.name, true)
continuous_spawn_stop(SH04_group.cont_spawn_b.name, true)
--create manager
--group_show( SH04_group.casino_manager.name )
--character_set_counter_on_grabbed( SH04_group.casino_manager.members, true )
marker_add( SH04_group.casino_manager.members, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAG_STICKY + OI_FLAG_DISPLAY_DISTANCE, SYNC_ALL)
--on_character_grabbed("sh04_manager_interrogation_cb", SH04_group.casino_manager.members)
--thread for the manager to seek out the player
SH04_group.casino_manager.thread = thread_new( "sh04_move_manager" )
--objective text, talk to the manager
objective_text_clear( 0 )
objective_text( 0, SH04_MANAGER, nil, nil, SYNC_ALL, OI_ASSET_USE )
--wait until the player gets close to the manager
while (get_dist_closest_player_to_object( SH04_group.casino_manager.members ) > 20 ) or ( character_is_ragdolled(SH04_group.casino_manager.members) ) do
thread_yield()
end
--you're seen the manager, say something
sh04_convo( SH04_convo.see_manager )
npc_go_idle(ANGEL_NO_MASK)
ai_suggest_action(ANGEL_NO_MASK, "follow player" )
set_player_can_take_human_shields(LOCAL_PLAYER, false )
if coop_is_active() == true then
set_player_can_take_human_shields(REMOTE_PLAYER, false )
end
display = false
local dist
while SH04_INTERROGATION == false do --need to repeat until the interrogation is started
--thread_yield()
dist, SH04_INTERROGATE_PLAYER = get_dist_closest_player_to_object( SH04_group.casino_manager.members )
--check if the player is inside the display range && the display is not on
if get_dist_closest_player_to_object( SH04_group.casino_manager.members ) <= 2 and display == false and character_is_ragdolled(SH04_group.casino_manager.members) == false then
dist, SH04_INTERROGATE_PLAYER = get_dist_closest_player_to_object( SH04_group.casino_manager.members )
hud_prompt(SH04_INTERROGATE_PLAYER, "SH04_MSG_GRAB", "sh04_grab_manager_local") --sh04_grab_manager_local
display = true
--allow grabbing now
character_set_counter_on_grabbed( SH04_group.casino_manager.members , false )
end
--check if the player is outside the display range or the manager is ragdolled
if( (get_dist_closest_player_to_object( SH04_group.casino_manager.members ) > 2 or character_is_ragdolled(SH04_group.casino_manager.members) == true) and display == true ) then
dist, SH04_INTERROGATE_PLAYER = get_dist_closest_player_to_object( SH04_group.casino_manager.members )
hud_prompt_clear(SH04_INTERROGATE_PLAYER)
display = false
--disallow grabbing now
character_set_counter_on_grabbed( SH04_group.casino_manager.members , true )
end
delay(.1)
end
repeat thread_yield() until SH04_INTERROGATION_COMPLETE == true
marker_remove(SH04_group.casino_manager.members, SYNC_ALL)
ai_suggest_action(ANGEL_NO_MASK , "follow player" )
on_character_grabbed("", SH04_group.casino_manager.members)
end
function sh04_grab_manager_local()
--tell angel to move to the player so he's around to threaten the manager
SH04_group.homies.thread = thread_new( "sh04_move_angel" )
clear_animation_state( SH04_group.casino_manager.members )
--clear the prompt
SH04_INTERROGATION = true
hud_prompt_clear(LOCAL_PLAYER)
hud_prompt_clear(REMOTE_PLAYER)
--so the player and the manager can't be separated
character_set_no_explosive_panic( SH04_group.casino_manager.members, true )
character_set_no_explosive_panic( SH04_INTERROGATE_PLAYER, true )
--the interrogation animations work best with certain inventory sets, so set one of them
local weapon
weapon = inv_item_in_slot(SH04_INTERROGATE_PLAYER, "rifle")
inv_item_equip(weapon, SH04_INTERROGATE_PLAYER)
--player_take_human_shield(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, false)
--delay until the human shield is registered. this seems stupid but for some reason is necessary for timings...
while character_has_specific_human_shield(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members) == false do
player_take_human_shield(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, false)
thread_yield()
end
--disable ragdolling so things don't mess up
character_allow_ragdoll(SH04_INTERROGATE_PLAYER, false)
character_allow_ragdoll(SH04_group.casino_manager.members, false)
-- Block controls until the interrogation is complete
player_human_shield_lock(SH04_INTERROGATE_PLAYER, true)
delay(1)
--animations
action_play_synced_state(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "Gat Interrogation State")
action_play_synced(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "Gat Interrogation Entry")
set_ignore_ai_flag(ANGEL_NO_MASK, true) --so angel doesn't act like a dumbass and shoot enemies
--sh04_convo( SH04_convo.threaten_manager )
if (sh04_status.convo_is_playing) then
repeat
thread_yield()
until (sh04_status.convo_is_playing == false)
end
delay(.25)
SH04_convo.threaten_manager.handle = audio_conversation_load_direct(SH04_convo.threaten_manager.name)
-- Play the conversation. This isn't played in the queue because I need the exact timing for the animation states
audio_conversation_play(SH04_convo.threaten_manager.handle)
--enable the vault trigger, safety net in case the player interrogates back there
trigger_enable( TRIGGER_MASK_CUTSCENE, true )
on_trigger( "sh04_hit_mask_cutscene", TRIGGER_MASK_CUTSCENE )
-- Wait for the conversation to end
audio_conversation_wait_for_end(SH04_convo.threaten_manager.handle)
SH04_convo.threaten_manager.handle = INVALID_CONVERSATION_HANDLE
sh04_status.convo_is_playing = false
--re-enable stuff
turn_vulnerable( SH04_group.casino_manager.members )
--action_play_synced_state(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "Gat Interrogation Return" )
action_play_synced_state(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "HS_Stand")
action_play_synced(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "Gat Interrogation Return")
character_set_no_explosive_panic( SH04_group.casino_manager.members, false )
character_set_no_explosive_panic( SH04_INTERROGATE_PLAYER, false )
character_allow_ragdoll(SH04_INTERROGATE_PLAYER, true)
character_allow_ragdoll(SH04_group.casino_manager.members, true)
set_ignore_ai_flag(ANGEL_NO_MASK, false) --end dumbass lock
player_human_shield_lock(SH04_INTERROGATE_PLAYER, false)
while not action_play_is_finished(SH04_INTERROGATE_PLAYER) do
thread_yield()
end
--action_stop_synced_state(SH04_INTERROGATE_PLAYER)
player_release_human_shield(SH04_INTERROGATE_PLAYER, true, false)
SH04_INTERROGATION_COMPLETE = true
end
function sh04_manager_interrogation_cb( victim, attacker )
if attacker ~= LOCAL_PLAYER and attacker ~= REMOTE_PLAYER then
return
end
clear_animation_state( SH04_group.casino_manager.members )
--the interrogation animations work best with certain inventory sets, so set one of them
local weapon
weapon = inv_item_in_slot(attacker, "rifle")
inv_item_equip(weapon, attacker)
SH04_INTERROGATION = true --in case weird stuff happened and the prompt didn't get triggered
hud_prompt_clear(SH04_INTERROGATE_PLAYER)
--disable ragdolling so things don't mess up
character_allow_ragdoll(SH04_INTERROGATE_PLAYER, false)
character_allow_ragdoll(SH04_group.casino_manager.members, false)
-- Block controls until the interrogation is complete
player_human_shield_lock(SH04_INTERROGATE_PLAYER, true)
action_play_synced(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "Gat Interrogation Entry")
action_play_synced_state(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "Gat Interrogation State")
set_ignore_ai_flag(ANGEL_NO_MASK, true) --so angel doesn't act like a dumbass and shoot enemies
hud_prompt_clear(SH04_INTERROGATE_PLAYER)
-- hud_prompt_clear(REMOTE_PLAYER)
--sh04_convo( SH04_convo.threaten_manager )
if (sh04_status.convo_is_playing) then
repeat
thread_yield()
until (sh04_status.convo_is_playing == false)
end
delay(.5)
SH04_convo.threaten_manager.handle = audio_conversation_load_direct(SH04_convo.threaten_manager.name)
-- Play the conversation. This isn't played in the queue because I need the exact timing for the animation states
audio_conversation_play(SH04_convo.threaten_manager.handle)
--enable the vault trigger, safety net in case the player interrogates back there
trigger_enable( TRIGGER_MASK_CUTSCENE, true )
on_trigger( "sh04_hit_mask_cutscene", TRIGGER_MASK_CUTSCENE )
-- Wait for the conversation to end
audio_conversation_wait_for_end(SH04_convo.threaten_manager.handle)
SH04_convo.threaten_manager.handle = INVALID_CONVERSATION_HANDLE
sh04_status.convo_is_playing = false
--re-enable stuff
turn_vulnerable( SH04_group.casino_manager.members )
action_play_synced_state(SH04_INTERROGATE_PLAYER, SH04_group.casino_manager.members, "Gat Interrogation Return" )
character_allow_ragdoll(SH04_INTERROGATE_PLAYER, true)
character_allow_ragdoll(SH04_group.casino_manager.members, true)
set_ignore_ai_flag(ANGEL_NO_MASK, false) --end dumbass lock
player_human_shield_lock(SH04_INTERROGATE_PLAYER, false)
while not action_play_is_finished(SH04_INTERROGATE_PLAYER) do
thread_yield()
end
action_stop_synced_state(SH04_INTERROGATE_PLAYER)
player_release_human_shield(SH04_INTERROGATE_PLAYER, true, false)
SH04_INTERROGATION_COMPLETE = true
end
function sh04_brute_finale()
sh04_spawn_brutes = false
if group_is_loaded(SH04_group.brute_g02.name) == false then
group_create( SH04_group.brute_g02.name )
marker_add_script_group( SH04_group.brute_g02.name, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_ALL )
for i, enemy in pairs(SH04_group.brute_g02.members) do
--if ( character_is_dead(enemy) == false ) then
on_death("sh04_brute_killed", enemy)
--end
end
end
delay(.5)
--move_to( SH04_group.brute_g02.members[1], SH04_BRUTE_DEST)
--move_to( SH04_group.brute_g02.members[2], SH04_BRUTE_DEST)
--ai_add_enemy_target(ANGEL_WITH_MASK, SH04_group.brute_g02.members[1], ATTACK_NOW_NEVER_LOSE, true)
--while( (fov_check_xz_plane(LOCAL_PLAYER, SH04_group.brute_g02.members[0]) == false ) or (fov_check_xz_plane(LOCAL_PLAYER, SH04_group.brute_g02.members[1]) == false) ) do --
--thread_yield()
--end
--audio_play_persona_line( LOCAL_PLAYER, SH04_dialog_lines.brute02 )
end
-- ***************************************************
-- sh04_initialize Helper Functions
-- ***************************************************
-- Handle any common initialization
--
function sh04_initialize_common()
-- Initialization common to all checkpoints
end
-- Checkpoint specific initialization
--
-- checkpoint: The checkpoint to be initialized
function sh04_initialize_checkpoint(checkpoint)
local current_checkpoint = checkpoint
if SH04_THREAD_CONVO == INVALID_THREAD_HANDLE then
SH04_THREAD_CONVO = thread_new("sh04_play_convo")
end
--need to diable the sonic gun since it does not kill movers
--local_weap = inv_item_in_slot(LOCAL_PLAYER, WEAPON_SLOT_SPECIAL)
group_create( SH04_group.homies.name, true )
trigger_enable( TRIGGER_MISSION_AREA_001, true )
on_trigger( "sh04_player_entered_mission_area_trigger", TRIGGER_MISSION_AREA_001 )
--group_create( SH04_group.peds.name )
--for i, member in pairs( SH04_group.peds.members ) do
-- npc_go_idle( member )
-- end
if current_checkpoint == CHECKPOINT_START then
if( inv_has_item("Special-SonicGun", LOCAL_PLAYER) == true ) then
inv_weapon_disable_slot( WEAPON_SLOT_SPECIAL, true, SYNC_LOCAL)
end
if coop_is_active() then
--remote_weap = inv_item_in_slot(REMOTE_PLAYER, WEAPON_SLOT_SPECIAL)
if ( inv_has_item("Special-SonicGun", REMOTE_PLAYER) == true ) then
inv_weapon_disable_slot( WEAPON_SLOT_SPECIAL, true, SYNC_REMOTE)
end
end
if IS_RESTART == true then
teleport_coop( START_WARP_LOCATIONS[LOCAL_PLAYER], START_WARP_LOCATIONS[REMOTE_PLAYER], true )
end
-- Add Angel as homie
--group_create( SH04_group.homies.name, true )
party_add( ANGEL_NO_MASK, LOCAL_PLAYER )
-- Hide other Angel
character_hide( ANGEL_WITH_MASK )
on_attack_performed("sh04_angel_attack_line_cb", ANGEL_NO_MASK)
on_death( "sh04_failure_angel_died", ANGEL_NO_MASK )
on_dismiss( "sh04_failure_angel_abandoned", ANGEL_NO_MASK )
follower_set_can_abandon( ANGEL_NO_MASK, true )
--set_player_can_take_human_shields(ANGEL_NO_MASK, false)
character_set_can_take_human_shield( ANGEL_NO_MASK, false )
--SH04_THREAD_ANGEL_WATCHER = thread_new( "sh04_angel_watcher", ANGEL_NO_MASK )
--npc_leash_to_object( ANGEL_NO_MASK, LOCAL_PLAYER, 5 )
sh04_initialize_load_groups( checkpoint )
end
if ( checkpoint == SH04_CHECKPOINT_MASK ) then
-- This also has the side effect of placing Angel near the player
character_hide( ANGEL_NO_MASK )
on_attack_performed("", ANGEL_NO_MASK)
--SH04_THREAD_ANGEL_WATCHER = thread_new( "sh04_angel_watcher", ANGEL_WITH_MASK )
teleport_coop( POST_MASK_CHECKPOINT_WARP_LOCATIONS[LOCAL_PLAYER], POST_MASK_CHECKPOINT_WARP_LOCATIONS[REMOTE_PLAYER], true )
teleport( ANGEL_WITH_MASK, NAVPOINT_ANGEL_POST_MASK )
party_add( ANGEL_WITH_MASK, LOCAL_PLAYER )
on_death( "sh04_failure_angel_died", ANGEL_WITH_MASK )
on_dismiss( "sh04_failure_angel_abandoned", ANGEL_WITH_MASK )
on_attack_performed("sh04_angel_attack_line_cb", ANGEL_WITH_MASK)
inv_item_equip( "Rifle-Gang", ANGEL_WITH_MASK )
end
end
-- Load groups during initialization based on the current checkpoint.
-- These are loaded while the screen is faded out.
--
function sh04_initialize_load_groups( checkpoint )
-- Currently, all checkpoints have the "no mask" Angel, so create and add him:
if ( checkpoint == CHECKPOINT_START ) then
end
end
-- Loads conversations played during the mission.
--
function sh04_initialize_conversations( checkpoint )
if ( checkpoint ~= CHECKPOINT_FAKE_MASK ) then
--SH04_convo.angel_sees_mask.handle = audio_conversation_load(SH04_convo.angel_sees_mask.name)
--SH04_convo.angel_mask_is_fake.handle = audio_conversation_load(SH04_convo.angel_mask_is_fake.name)
end
end
-- ***************************************************
-- Miscellaneous SH04 Helper Funcrtions
-- ***************************************************
-- This function can set up Angel to play the mask sequence and reset him to normal afterward.
--
-- start: Set to true if the sequence is started, false if it's ending.
--
function sh04_setup_angel_for_sequence( start )
set_ignore_ai_flag( ANGEL_NO_MASK, start )
turn_invulnerable( ANGEL_NO_MASK, start )
character_prevent_bumping( ANGEL_NO_MASK, start )
character_prevent_explosion_fling( ANGEL_NO_MASK, start )
character_prevent_flinching( ANGEL_NO_MASK, start )
character_prevent_kneecapping( ANGEL_NO_MASK, start )
end
function sh04_angel_move( statue )
ai_do_scripted_advance(ANGEL_WITH_MASK, statue)
--make sure the triggers are cleaned up
for i, trigger in pairs(sh04_objectives.statues.members) do
if sh04_objectives.statues.active[i] == true then
sh04_objectives.statues.active[i] = false
end
end
end
-- Removes callbacks from all triggers.
--
function sh04_clear_triggers()
on_trigger( "", SH04_TRIGGER_UPSTAIRS )
on_trigger( "", SH04_TRIGGER_CONT_SPAWN )
on_trigger( "", TRIGGER_TO_VAULT_001 )
on_trigger( "", TRIGGER_TO_VAULT_002 )
--on_trigger( "", SH04_TRIGGER_ALARM )
on_trigger( "", TRIGGER_MASK_CUTSCENE )
on_trigger( "", TRIGGER_MISSION_AREA_001 )
--on_trigger( "", TRIGGER_MISSION_AREA_002 )
on_trigger_exit( "", TRIGGER_MISSION_AREA_001 )
on_trigger( "", SH04_TRIGGER_BETA )
on_trigger( "", SH04_TRIGGER_ALPHA )
end
-- Disables continuous spawn regions and stops all continuously spawning groups.
--
function sh04_stop_spawns()
continuous_spawn_regions_enable( CONTINUOUS_SPAWN_POINTS, false )
continuous_spawn_regions_enable( SH04_INIT_SPAWN_POINTS, false )
-- continuous_spawn_stop( SH04_group.cont_spawn_spec.name )
continuous_spawn_stop( SH04_group.cont_spawn_a.name )
continuous_spawn_stop( SH04_group.cont_spawn_b.name )
-- continuous_spawn_stop( SH04_group.attack_squad_omega.name )
--continuous_spawn_stop( SH04_group.backroom_specialist.name )
end
-- Ends any conversations that happen to be playing.
--
function sh04_end_conversations()
if SH04_convo.angel_sees_mask.handle ~= INVALID_CONVERSATION_HANDLE then
audio_conversation_end( SH04_convo.angel_sees_mask.handle )
SH04_convo.angel_sees_mask.handle = INVALID_CONVERSATION_HANDLE
end
if SH04_convo.angel_mask_is_fake.handle ~= INVALID_CONVERSATION_HANDLE then
audio_conversation_end(SH04_convo.angel_mask_is_fake.handle)
SH04_convo.angel_mask_is_fake.handle = INVALID_CONVERSATION_HANDLE
end
end
-- Releases/destroys all groups used by this mission to the world, as appropriate.
--
function sh04_cleanup_groups( mission_successful )
-- On mission success, release everyone to the world except for homies
if ( mission_successful ) then
for index, group in pairs( SH04_group ) do
if ( group_is_loaded( group.name ) and group.name ~= SH04_group.homies.name ) then
release_to_world( group.name )
end
end
group_destroy( SH04_group.homies.name )
-- On failure/cancel, destroy everyone, because it should be like the mission never happened
else
for index, group in pairs( SH04_group ) do
if ( group_is_loaded( group.name ) and group.name ~= SH04_group.homies.name ) then
group_destroy( group.name )
end
end
end
end
function cleanup_statues()
for index, statue in pairs( SH04_killbane_statues ) do
marker_remove( statue, SYNC_ALL )
mesh_mover_set_invulnerable( statue, true )
on_mover_destroyed( "", statue )
end
end
-- Kills any threads that may still be running.
--
function sh04_kill_threads()
if ( SH04_THREAD_SPAWN_SECOND_SQUAD ~= INVALID_THREAD_HANDLE ) then
thread_kill( SH04_THREAD_SPAWN_SECOND_SQUAD )
SH04_THREAD_SPAWN_SECOND_SQUAD = INVALID_THREAD_HANDLE
end
if ( SH04_THREAD_SPAWN_SECOND_SQUAD ~= INVALID_THREAD_HANDLE ) then
thread_kill( SH04_THREAD_SPAWN_SECOND_SQUAD )
SH04_THREAD_SPAWN_SECOND_SQUAD = INVALID_THREAD_HANDLE
end
if( SH04_THREAD_ANGEL_WATCHER ~= INVALID_THREAD_HANDLE ) then
thread_kill( SH04_THREAD_ANGEL_WATCHER )
SH04_THREAD_ANGEL_WATCHER = INVALID_THREAD_HANDLE
end
if( SH04_THREAD_CONVO ~= INVALID_THREAD_HANDLE ) then
thread_kill( SH04_THREAD_CONVO )
SH04_THREAD_CONVO = INVALID_THREAD_HANDLE
end
if SH04_group.casino_manager.thread ~= INVALID_THREAD_HANDLE then
thread_kill(SH04_group.casino_manager.thread)
SH04_group.casino_manager.thread = INVALID_THREAD_HANDLE
end
if SH04_group.homies.thread ~= INVALID_THREAD_HANDLE then
thread_kill(SH04_group.homies.thread)
SH04_group.homies.thread = INVALID_THREAD_HANDLE
end
cleanup_threads( SH04_group.right_door.thread )
cleanup_threads( SH04_group.left_door.thread )
end
-- Stops any failure timers that may be running.
--
function sh04_stop_failure_timers()
hud_critical_timer_stop( 1 )
--hud_critical_timer_set( 1, 0, "" )
--hud_timer_hide( 1, true )
end
-- *************************
--
-- Callback functions
--
-- *************************
function sh04_hit_trigger(player, current_trigger)
local cur_statue
sh04_disable_trigger(current_trigger)
for i, trigger in pairs(sh04_objectives.statues.members) do
if sh04_objectives.statues.status[i] == false and sh04_objectives.statues.members[i] == current_trigger then
cur_statue = sh04_objectives.statues.nav[i]
sh04_objectives.statues.active[i] = true
end
end
sh04_angel_move( cur_statue )
end
function sh04_brute_killed( brute )
SH04_DEAD_BRUTES = SH04_DEAD_BRUTES + 1
marker_remove( brute, SYNC_ALL )
on_death("", brute)
sh04_dead_enemy( brute )
if( SH04_DEAD_BRUTES == 2 ) then
Mission_successful = true
end
end
function sh04_player_entered_mission_area_trigger( player_name, trigger_name )
--Players_in_mission_area_triggers[trigger_name][player_name] = false
if SH04_TIMER_ACTIVE == true then
hud_critical_timer_stop( 1 )
end
SH04_TIMER_ACTIVE = false
on_trigger_exit( "sh04_player_left_mission_area_trigger", TRIGGER_MISSION_AREA_001 )
Players_in_mission_area_triggers[trigger_name][player_name] = true
Players_in_mission_area[player_name] = true
end
function sh04_player_left_mission_area_trigger( player_name, trigger_name )
-- Player is no longer in this trigger, so register a new on_trigger callback
on_trigger( "sh04_player_entered_mission_area_trigger", TRIGGER_MISSION_AREA_001 )
SH04_TIMER_ACTIVE = true
Players_in_mission_area_triggers[trigger_name][player_name] = false
Players_in_mission_area[player_name] = false
local sync = SYNC_LOCAL
if ( player_name == REMOTE_PLAYER ) then
sync = SYNC_REMOTE
end
hud_critical_timer_set( SH04_OUT_OF_AREA_FAILURE_TIME_MS, SH04_HELPTEXT_GET_BACK_TO_THE_CASINO, "sh04_out_of_area_failure", sync ) --FAIL_TIMER_INDICES[player_name]
mission_help_table_nag( SH04_HELPTEXT_GET_BACK_TO_THE_CASINO, "", "", sync )
end
function sh04_out_of_area_failure( player_name, delay_seconds )
sh04_stop_failure_timers()
mission_end_failure( "sh04", HELPTEXT_FAILURE_LEFT_MISSION )
end
-- This function is intended to act as a failsafe timeout if the Angel mask sequence takes too
-- long, but it wasn't working so I temporarily disabled it.
--
function sh04_angel_max_action_delay()
Wait_on_Angel_timer_expired = true
end
-- End the mission if Angel dies
--
function sh04_failure_angel_died()
mission_end_failure( "sh04", HELPTEXT_FAILURE_ANGEL_DIED )
end
-- End the mission if Angel is abandoned
--
function sh04_failure_angel_abandoned()
mission_end_failure( "sh04", HELPTEXT_FAILURE_ANGEL_ABANDONED )
end
-- Trigger for reaching the fake mask
--
function sh04_reached_fake_mask( character_name, trigger_name )
local distance = get_dist( ANGEL_NO_MASK, LOCAL_PLAYER )
if ( ( character_name == LOCAL_PLAYER and distance < ANGEL_NEAR_PLAYER_DISTANCE_METERS ) or
character_name == ANGEL_NO_MASK ) then
Reached_fake_mask = true
end
end
-- Sets up the enemies around the statues upstairs
--
function sh04_setup_upstairs()
--right room
group_create( SH04_group.right_room.name )
for index, member in pairs( SH04_group.right_room.members ) do
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
on_attack_performed("sh04_attack_line_cb", member)
end
trigger_enable( SH04_TRIGGER_UPSTAIRS, false )
end
function sh04_setup_alpha()
group_create( SH04_group.alpha_squad.name )
group_create( SH04_group.beta_squad.name )
for index, member in pairs( SH04_group.alpha_squad.members ) do
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
on_attack_performed("sh04_attack_line_cb", member)
end
for index, member in pairs( SH04_group.beta_squad.members ) do
--ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
on_attack_performed("sh04_attack_line_cb", member)
end
trigger_enable( SH04_TRIGGER_ALPHA, false )
trigger_enable( SH04_TRIGGER_BETA, false )
on_trigger( "", SH04_TRIGGER_BETA )
on_trigger( "", SH04_TRIGGER_ALPHA )
end
function sh04_setup_beta()
group_create( SH04_group.beta_squad.name )
group_create( SH04_group.alpha_squad.name )
for index, member in pairs( SH04_group.alpha_squad.members ) do
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
on_attack_performed("sh04_attack_line_cb", member)
end
for index, member in pairs( SH04_group.beta_squad.members ) do
--ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
on_attack_performed("sh04_attack_line_cb", member)
end
trigger_enable( SH04_TRIGGER_ALPHA, false )
trigger_enable( SH04_TRIGGER_BETA, false )
on_trigger( "", SH04_TRIGGER_BETA )
on_trigger( "", SH04_TRIGGER_ALPHA )
end
-- Trigged when the player reaches the bottom floor after Angel discovers that the mask is not
-- his mask.
-- Causes Luchadors in the back room to attack and a specialist to be triggered for spawn after
-- a short delay.
--
function sh04_reached_bottom_floor()
--trigger_enable( SH04_TRIGGER_ALARM, false )
-- door_open( SIDE_DOOR_001 )
-- door_open( SIDE_DOOR_002 )
for index, member in pairs( SH04_group.back_left.members ) do
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
end
for index, member in pairs( SH04_group.back_right.members ) do
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
end
for index, member in pairs( SH04_group.backroom_guards.members ) do
ai_add_enemy_target( member, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
end
--sh04_trigger_specialist_spawn()
end
-- Breadcrumb trigger function.
--
function sh04_to_vault_001( character_name, trigger_name )
Hit_vault_one_trigger = true
trigger_enable( trigger_name, false )
marker_remove( NAVPOINT_TO_VAULT_001 )
marker_add( NAVPOINT_TO_VAULT_002, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
move_to_safe( ANGEL_NO_MASK, NAVPOINT_TO_VAULT_002, 2, true, false )
-- Mark the final location (it's already been enabled, so no need to set up callbacks)
end
-- Breadcrumb trigger function two. This one sets up the final trigger and works even if the
-- first crumb has been skipped.
--
function sh04_to_vault_002( character_name, trigger_name )
trigger_enable( trigger_name, false )
marker_remove( NAVPOINT_TO_VAULT_002 )
--marker_add( NAVPOINT_MASK_CUTSCENE, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
--move_to_safe( ANGEL_NO_MASK, NAVPOINT_TO_VAULT_002, 2, false, false ) --make angel run to the CTE trigger
end
-- Triggers the cutscene.
--
function sh04_hit_mask_cutscene( char, trigger )
trigger_enable( trigger, false )
Hit_vault_one_trigger = true --catch for the player running with the manager while interrogating him
Hit_mask_cutscene = true
end
function sh04_attack_trigger()
--open back doors to let the enemies out
door_open("left_door")
door_open("right_door")
--have the guys file in and attack the player
for i, enemy in pairs( SH04_group.initial_luchadors.members ) do
set_attack_player_flag( enemy, true )
on_attack_performed("sh04_attack_line_cb", enemy)
end
for i, enemy in pairs( SH04_group.right_door.members ) do
set_attack_player_flag( enemy, true )
on_attack_performed("sh04_attack_line_cb", enemy )
SH04_group.right_door.thread[i] = thread_new( "sh04_attack", enemy, SH04_group.right_door.navs[i] )
end
for i, enemy in pairs( SH04_group.left_door.members ) do
set_attack_player_flag( enemy, true )
on_attack_performed("sh04_attack_line_cb", enemy )
SH04_group.left_door.thread[i] = thread_new( "sh04_attack", enemy, SH04_group.left_door.navs[i] )
end
--ai_do_scripted_move( SH04_group.first_specialist.name, SH04_group.first_specialist.dest, true, false )
move_to_safe( SH04_group.first_specialist.members, SH04_group.first_specialist.dest, 2, true, false )
end
-- Tracking callback for "kill all the Luchadors" behavior.
--
function sh04_remaining_luchador_died( dead_luchador )
marker_remove( dead_luchador, SYNC_ALL )
on_death( "", dead_luchador )
on_attack_performed("", dead_luchador)
sh04_dead_enemy( dead_luchador )
SH04_num_remaining_luchadors = SH04_num_remaining_luchadors - 1
objective_text( 0, HELPTEXT_DESTROY_LUCHADORES, nil, nil, SYNC_ALL, OI_ASSET_KILL )
end
function sh04_remove_markers()
SH04_num_remaining_luchadors = 0
--brutes
--[[----------------------------------------------------------------------]]
if( group_is_loaded( SH04_group.brute_g01.name ) ) then
if ( character_is_dead( SH04_group.brute_g01.members ) == false ) then
marker_remove( SH04_group.brute_g01.members, SYNC_ALL )
on_death( "", SH04_group.brute_g01.members )
end
end
if( group_is_loaded( SH04_group.brute_g02.name ) ) then
for index, member in pairs( SH04_group.brute_g02.members ) do
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.brute_g03.name ) ) then
for index, member in pairs( SH04_group.brute_g03.members ) do
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
--[[----------------------------------------------------------------------]]
--specialists
--[[----------------------------------------------------------------------]]
if( group_is_loaded( SH04_group.backroom_specialist.name ) ) then
if ( character_is_dead( SH04_group.backroom_specialist.members ) == false ) then
marker_remove( SH04_group.backroom_specialist.members, SYNC_ALL )
on_death( "", SH04_group.backroom_specialist.members )
end
end
if( group_is_loaded( SH04_group.backroom_specialist_coop.name ) ) then
if ( character_is_dead( SH04_group.backroom_specialist_coop.members ) == false ) then
marker_remove( SH04_group.backroom_specialist.members, SYNC_ALL )
on_death( "", SH04_group.backroom_specialist.members )
end
end
--[[----------------------------------------------------------------------]]
--initial guys
--[[----------------------------------------------------------------------]]
if( group_is_loaded( SH04_group.initial_luchadors.name ) ) then
for index, member in pairs( SH04_group.initial_luchadors.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.coop_initial_luchadors.name ) ) then
for index, member in pairs( SH04_group.coop_initial_luchadors.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
--doors
if( group_is_loaded( SH04_group.left_door.name ) ) then
for index, member in pairs( SH04_group.left_door.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.right_door.name ) ) then
for index, member in pairs( SH04_group.right_door.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
--[[----------------------------------------------------------------------]]
--upstairs
--[[----------------------------------------------------------------------]]
if( group_is_loaded( SH04_group.alpha_squad.name ) ) then
for index, member in pairs( SH04_group.alpha_squad.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.beta_squad.name ) ) then
for index, member in pairs( SH04_group.beta_squad.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
--[[----------------------------------------------------------------------]]
--misc
--[[----------------------------------------------------------------------]]
if group_is_loaded( SH04_group.right_room.name ) == true then
for index, member in pairs( SH04_group.right_room.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.post_mask_attackers.name ) ) then
for index, member in pairs( SH04_group.post_mask_attackers.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.back_left.name ) ) then
for index, member in pairs( SH04_group.back_left.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.back_right.name ) ) then
for index, member in pairs( SH04_group.back_right.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
if( group_is_loaded( SH04_group.ambush.name ) ) then
for index, member in pairs( SH04_group.ambush.members ) do
on_attack_performed("", member)
if ( character_is_dead( member ) == false ) then
marker_remove( member, SYNC_ALL )
on_death( "", member )
end
end
end
end
-- Track callback for "kill all the statues" behavior.
--
function sh04_statue_died( destroyed_statue_name )
on_mover_destroyed( "", destroyed_statue_name )
marker_remove( destroyed_statue_name )
SH04_num_remaining_statues = SH04_num_remaining_statues - 1
objective_text( 0, HELPTEXT_DESTROY_STATUES, SH04_original_num_statues - SH04_num_remaining_statues, SH04_original_num_statues, SYNC_ALL, OI_ASSET_KILL )
--sh04_play_statue_line()
audio_play_persona_line( LOCAL_PLAYER, SH04_dialog_lines.statue_destroyed[SH04_num_remaining_statues + 1] )
if ( SH04_num_remaining_statues == 3 ) then --spawn melee brute
group_create( SH04_group.brute_g01.name )
move_to( SH04_group.brute_g01.members, SH04_BRUTE_DEST)
ai_add_enemy_target( SH04_group.brute_g01.members, get_random_target_player(), ATTACK_NOW_NEVER_LOSE )
end
if ( SH04_num_remaining_statues == 2 ) then --spawn specialists
sh04_trigger_specialist_spawn()
end
--if ( SH04_num_remaining_statues == 1 ) then --spawn a couple guys as a cool down
--group_create( SH04_group.ambush.name )
--end
end
function sh04_play_statue_line()
local i = rand_int(1, 4)
audio_play_persona_line( LOCAL_PLAYER, SH04_dialog_lines.statue_destroyed[i] )
end
function sh04_spawn_brute()
SH04_num_remaining_statues = SH04_num_remaining_statues - 1
end
function sh04_slot_died()
if SH04_GO_HOSTILE == false then
SH04_GO_HOSTILE = true
sh04_attack_trigger()
end
SH04_destroyed_slots = SH04_destroyed_slots +1
hud_bar_set_value( 0, SH04_destroyed_slots, SYNC_ALL )
if( SH04_destroyed_slots >= SH04_TOTAL_DAMAGE ) then
SH04_slot_obj = true
end
end
function sh04_dead_enemy( char )
release_to_world( char )
--SH04_TOTAL_DAMAGE = SH04_TOTAL_DAMAGE + 1
end
-- *************************
--
-- Thread functions
--
-- *************************
-- Activates delayed spawning for the second group. This is done to allow a group to spawn every
-- X seconds. If we start them both at once, it doesn't work, because they spawn at the same time.
-- If we start one with twice the time, then both will spawn at once when they go back in phase.
-- Instead, we delay and then activate the spawn.
--
function sh04_activate_second_group( delay_seconds )
--group_create( SH04_group.cont_spawn_b.name )
delay( delay_seconds )
continuous_spawn_start( SH04_group.cont_spawn_b.name, 0, SH04_NORMAL_SQUAD_RESPAWN_DELAY_SECONDS )
end
function sh04_angel_watcher(angel)
while( true ) do
while ( get_dist_closest_player_to_object( angel ) < 8.5 ) do
thread_yield()
end
ai_do_scripted_move( angel, LOCAL_PLAYER, false )
end
end
-- play convo thread. this plays conversations from the convo queue
--
function sh04_play_convo()
while(true) do
if( sh04_queue_size > 0 ) then
-- If another conversation is already playing, wait for it to finish
if (sh04_status.convo_is_playing) then
repeat
thread_yield()
until (sh04_status.convo_is_playing == false)
end
sh04_status.convo_is_playing = true
-- Load the conversation
if (sh04_queue[0].load_direct) then
sh04_queue[0].handle = audio_conversation_load_direct(sh04_queue[0].name)
else
sh04_queue[0].handle = audio_conversation_load(sh04_queue[0].name)
end
-- Play the conversation
audio_conversation_play(sh04_queue[0].handle)
delay(1)
-- Wait for the conversation to end
audio_conversation_wait_for_end(sh04_queue[0].handle)
sh04_queue[0].handle = INVALID_CONVERSATION_HANDLE
sh04_status.convo_is_playing = false
for i = 1, sh04_queue_size do
sh04_queue[i - 1] = sh04_queue[i]
end
sh04_queue_size = sh04_queue_size - 1
end
delay(.1)
end
end
function sh04_attack_line_cb( name, weapon, attack )
-- SAY IT! - "it"
local situation = "SH04_Attack"
-- don't play this if we have done this recently
if (not thread_check_done(sh04_threads.attack_line_timer)) then
return
end
-- start timer
sh04_threads.attack_line_timer = thread_new("delay", 10)
-- play situation
audio_play_persona_line(name, situation)
end
function sh04_angel_attack_line_cb( name, weapon, attack )
local persona
-- don't play this if we have done this recently
if (not thread_check_done(sh04_threads.attack_line_timer)) then
return
end
if( name == "ANGEL_NO_MASK" ) then
persona = SH04_dialog_lines.pre_mask
else--( name == "ANGEL_WITH_MASK" )
persona = SH04_dialog_lines.post_mask
end
-- start timer
sh04_threads.attack_line_timer = thread_new("delay", 10)
audio_play_persona_line( name, persona )
end
function sh04_attack( attacker, dest )
--tell the AI to go to the navpoint and attack the player on sight
--move_to_safe( attacker, dest, 3, true, false )
--ai_do_scripted_move( attacker, dest, true )
ai_do_scripted_advance( attacker, dest )
ai_attack_region(attacker, dest, 8.0)
set_attack_player_flag( attacker, true )
--on_attack_performed("sh04_attack_line_cb", attacker)
end
function sh04_move_manager()
ai_do_scripted_move( SH04_group.casino_manager.members, LOCAL_PLAYER, true )
--npc_leash_to_object( SH04_group.casino_manager.members, LOCAL_PLAYER, 5 )
end
function sh04_move_angel()
ai_do_scripted_move( ANGEL_NO_MASK, SH04_INTERROGATE_PLAYER, true )
-- npc_leash_to_object( ANGEL_NO_MASK, SH04_INTERROGATE_PLAYER, 5 )
end