nx1-gsc-dump/maps/nx_hithard_secure.gsc

3696 lines
113 KiB
Plaintext
Raw Blame History

//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: nx_hithard_secure.gsc **
// NOTE: called from nx_hithard.gsc **
// **
// Created: 1/13/2011 - Brian Marvin **
// **
//****************************************************************************
#include maps\_utility;
#include maps\_nx_utility;
#include common_scripts\utility;
#include maps\_anim;
#include maps\_vehicle;
#include maps\_nx_objective_util;
#include maps\_hud_util;
#include maps\nx_hithard_util;
//*******************************************************************
// *
// *
//*******************************************************************
// Objective-specific PreCache calls
// NOTE: for any assets other than strings that require precaching, please place them in "nx_hithard::mission_precache()"
precache_strings()
{
}
// Objective specific flag_init() calls
flag_inits()
{
// "Secure The Motorcade"
flag_init( "flag_vtol_flyover" ); // When VTOL flies over player, triggers effects
flag_init( "flag_prep_secure" ); // Player runs through flag and triggers prep_secure_intersection
flag_init( "flag_secure_rooftop_prep_complete" ); // Once the prep_secure_intersection finishes
flag_init( "flag_script_vip_guard_almost_dead" ); // Almost all of the vip guard is dead
flag_init( "flag_script_vip_guard_dead" ); // All vip guard forces are dead
flag_init( "flag_secure_objective_failed" ); // Secure objective failed
flag_init( "flag_secure_objective_complete" ); // Main secure objective complete
flag_init( "flag_secure_vip_vulnerable" ); // In nx_hithard_script_secure. Defines enemy range where vip guard becomes vulnerable to attack.
flag_init( "flag_secure_objective_active" ); // Secure objective active - main objective
flag_init( "flag_script_uav_dropped_smoke" ); // Detect that UAV has dropped smoke
flag_init( "flag_cortel_window_destroy_01" ); // Guy in cortel building blows out windows
flag_init( "flag_cortel_window_destroy_02" ); // Guy in cortel building blows out windows
flag_init( "flag_secure_rooftop_aware" );
flag_init( "flag_secure_intro_dialogue_complete" ); // Intro dialogue completes
flag_init( "flag_script_uav_attack_roof" ); // UAVs attacking player
flag_init( "flag_script_spawnpool_allow" ); // Allow continuous ground spawners
flag_init( "flag_script_objective_wave_1_active" ); // Wave 1 objective active
flag_init( "flag_script_objective_wave_2_active" ); // Wave 2 objective active
flag_init( "flag_script_ground_threat_id_allow" ); // Allow threat ID on ground troops
flag_init( "flag_script_vip_guard_vulnerable_override" ); // Turns on when EnableHurt is on
flag_init( "flag_script_low_priority_dialogue_allow" ); // Will allow / disallow lower priority dialogue
flag_init( "flag_script_high_priority_dialogue_allow" ); // Will allow / disallow lower priority dialogue
flag_init( "flag_script_ground_rush" ); // Have guys on ground rush the motorcade
flag_init( "_flag_script_attention_pointer_active" ); // Flag for attention pointer
flag_init( "flag_secure_dpad_pressed" ); // Waits for player to press dpad left for zoom
flag_init( "flag_secure_vtol_uav_drop_in_position" );
// Don't slomo sounds
SoundSetTimeScaleFactor( "Mission", 0 );
SoundSetTimeScaleFactor( "Shellshock", 0 );
SoundSetTimeScaleFactor( "Voice", 0 );
SoundSetTimeScaleFactor( "Menu", 0 );
SoundSetTimeScaleFactor( "Effects1", 0 );
SoundSetTimeScaleFactor( "Effects2", 0 );
SoundSetTimeScaleFactor( "Announcer", 0 );
SoundSetTimeScaleFactor( "Music", 0 );
SoundSetTimeScaleFactor( "ambient", 0 );
SoundSetTimeScaleFactor( "weapon", 0 );
SoundSetTimeScaleFactor( "weapon2d", 0 );
SoundSetTimeScaleFactor( "auto2d", 0 );
SoundSetTimeScaleFactor( "auto", 0 );
SoundSetTimeScaleFactor( "element", 0 );
}
// Objective specific add_hint_string() calls
hint_string_inits()
{
// Secure Motorcade hints
add_hint_string( "hint_motorcade_vip_guard_almost_dead", &"NX_HITHARD_SECURE_HINT_VIP_GUARD_ALMOST_DEAD", ::hint_motorcade_vip_guard_almost_dead );
add_hint_string( "hint_secure_vulnerable", &"NX_HITHARD_SECURE_HINT_VIP_GUARD_VULNERABLE", ::hint_secure_vulnerable );
add_hint_string( "hint_secure_zoom", &"NX_HITHARD_SECURE_HINT_ZOOM", ::hint_secure_zoom );
}
//*******************************************************************
// *
// *
//*******************************************************************
// MOTORCADE: VP's guard is dead
hint_motorcade_vip_guard_almost_dead()
{
return flag( "flag_secure_objective_failed");
}
// MOTORCADE: VP's guard is vulnerable
hint_secure_vulnerable()
{
return !flag( "flag_secure_vip_vulnerable" ) || flag( "flag_script_vip_guard_almost_dead" ) || flag( "flag_secure_objective_failed" );
}
// Press D-Pad Left to switch zooms
hint_secure_zoom()
{
return flag( "flag_secure_dpad_pressed" ) || ( level._main_gun_accessory == level._player GetCurrentWeapon() );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Setup global variables for sniper section
A_secure_globals()
{
thread audio_nodes_secure();
thread sound_play_explosion();
helivolume = GetEnt( "helicopter_trigger", "targetname" );
helivolume thread triggerhelicopter();
// First encounter to start with (0 is default)
// ONLY CHANGE THIS FOR DEBUG PURPOSES!!!!
level.encounter_start = 0;
// enables front text to appear over enemies
level.show_debug_fronts = false;
// Print a warning message
if( level.encounter_start != 0 )
{
iprintlnbold( "NX_HITHARD_SECURE.GSC WARNING:" );
iprintlnbold( "Skip to encounter is enabled!" );
iprintlnbold( "level.encounter_start is set to '" + level.encounter_start + "'" );
}
// Print a warning message
if( level.show_debug_fronts )
{
iprintlnbold( "NX_HITHARD_SECURE.GSC WARNING:" );
iprintlnbold( "Battle front debug text is enabled!" );
iprintlnbold( "level.show_debug_fronts is set to '" + level.show_debug_fronts + "'" );
}
// List of encounter functions
level.encounter_list =
[
::encounter_wave_1,
::encounter_uav
];
// General Variables
level.secure_ground_num_guys_allowed = 16; // # of enemies allowed on ground from spawners
level.secure_civilian_ai_max = 10; // Max number of civilian AI allowed
level.secure_civilian_ai_buffer = 2; // # of ai allowed near max (32 is max ai, setting this to "4" would make the max civilians in-game 28 ai)
level.secure_standard_goalradius = 512; // Standard goal radius for enemies
level.secure_civilian_goalradius = 8; // Goal radius for VP and other civilians
level.secure_vip_guard_goalradius = 512; // Goal radius for vip guard
level.secure_special_goalradius = 128; // Goal radius for speciality encounters (buildings)
level.secure_vip_vulnerable_grace_time = 5; // Time (in seconds) before vip guard becomes vulnerable
level.secure_dialogue_encouragement_time = 5; // Minimum time requred between kills before baker encourages player
level.secure_ss_accuracy_badass = 100.0;
level.secure_ss_accuracy_weak = 0.7;
level.secure_squad_accuracy_wave_1 = 5.0;
level.secure_squad_accuracy_wave_2 = 5.0;
level.secure_global_accuracy_cortel_start = 10.0;
level.secure_global_accuracy_cortel_end = 100.0;
level.secure_squad_accuracy_uav = 0.01;
level.secure_enemy_accuracy_bon = 30000.0;
// Encounter-specific variables
level.secure_wave_2_num_enemies = 16; // # of enemies to proceed past wave_2
// Non-Tweakable vars
level.secure_vip_vulnerable_first_time = true; // Keeps track of the first time vip guard becomes vulnerable
level.secure_uav_duke_dialog_done = false;
level.num_uav_smoke_dropped = 0; // number of smokes dropped by uavs
level.num_enemies_spawned = 0; // Counts spawners
level.secure_human_enemies_num_killed = 0; // Counter for # of enemies killed during wave_1
level.secure_vip_hunt_count = 0;
level.secure_kill_tracker = [];
level.secure_kill_tracker[ "player" ] = 0;
level.secure_kill_tracker[ "baker" ] = 0;
level.secure_kill_tracker[ "duke" ] = 0;
level.secure_kill_tracker[ "ss" ] = 0;
level.secure_kill_tracker[ "other" ] = 0;
level.secure_ss_cant_die = 0;
// Player attention focus marker
level.vip_focus_pointer = GetEnt( "secure_vip_focus", "targetname" );
// Main dialogue array
level.secure_dialogue = [];
// Dialogue: Baker: "Patriot is being compromised!"
// Dialogue: Baker: "Patriot needs support!"
// Dialogue: Baker: "Specter, clear the threats!"
// Dialogue: Baker: "Eyes on Patriot!<21>
level.secure_dialogue[ "baker_vip_vulnerable" ] =
[
"hithard_bak_secure_48",
"hithard_bak_secure_49",
"hithard_bak_snipe_threats",
"hithard_bak_secure_43"
];
// Dialogue: Baker: "Keep dropping 'em"
// Dialogue: Baker: "Confirmed kill"
// Dialogue: Baker: "Drop an' pop em boys"
level.secure_dialogue[ "baker_encouragement" ] =
[
"hithard_bak_snipe_keepdrop",
"hithard_bak_snipe_kill",
"hithard_bak_snipe_dropem"
];
// Dialogue: Duke: "...fucking mess..."
// Dialogue: Duke: "Fuck, Fuck, Fuck!"
// Dialogue: Duke: "Take that. Tin piece of shit!"
level.secure_dialogue[ "duke_uav_random" ] =
[
"hithard_gyp_secure_03",
"hithard_gyp_snipe_01",
"hithard_gyp_snipe_tin"
];
// Dialogue: SS: "Patriot needs support!"
// Dialogue: SS: "Getting overrun!<21> We need more support!"
// Dialogue: SS: "We're being overrun!"
// Dialogue: SS: "They're getting too close!"
// Dialogue: SS: "We need more support!"
level.secure_dialogue[ "ss_need_help" ] =
[
"hithard_sslead_snipe_support",
"hithard_sslead_snipe_overrun",
"hithard_sslead_snipe_05",
"hithard_sslead_snipe_06",
"hithard_sslead_snipe_07"
];
// Names for good guys
level.secure_vip_guard_names =
[
"Flores",
"Guillote",
"Hall",
"Hughes",
"Inkel",
"Johnson",
"K",
"Kadel",
"Knutson",
"Marvin",
"Stowater",
"Vance",
"Winte"
];
// Set the # of enemies needed to be killed based on diff level
Assert( IsDefined( level._gameskill ) );
switch( level._gameSkill )
{
case 0: // Easy
{
break;
}
case 1: // Regular
{
break;
}
case 2: // Hardened
{
break;
}
case 3: // Veteran
{
break;
}
}
//
// Setup character arrays
//
// motorcade enemies array
level.secure_enemies = [];
level.secure_enemies[ "ground" ] = [];
level.secure_enemies[ "ground_front_0" ] = [];
level.secure_enemies[ "spawnpool" ] = [];
level.secure_enemies[ "cortel_balcony" ] = [];
level.secure_enemies[ "cortel_terrace" ] = [];
level.secure_enemies[ "cortel_all" ] = [];
level.secure_enemies[ "bon_01" ] = [];
level.secure_enemies[ "bon_02" ] = [];
level.secure_enemies[ "bon_all" ] = [];
level.secure_enemies[ "uavs" ] = [];
level.secure_enemies[ "uavs_attack" ] = [];
// vip
level.secure_vip= undefined;
// vip vehicle
level.secure_vip_vehicle = undefined;
// vip guard
level.secure_vip_guard = [];
level.secure_vip_guard[ "ss" ] = []; // Secret Service
level.secure_vip_guard[ "swat" ] = []; // Swat
level.secure_vip_guard[ "all" ] = []; // All good guys on the ground (minus vip)
// VTOLs
level.secure_vtols = [];
level.secure_vtols[ "vtol_01" ] = [];
level.secure_vtols[ "vtol_02" ] = [];
level.secure_vtols[ "vtol_03" ] = [];
// Vehicles
level.vehicles = [];
level.vehicles[ "lapd_backup" ] = [];
// UAV nodes
level.secure_uav_path = [];
level.secure_uav_path[ "smoke" ] = [];
level.secure_uav_path[ "circle1" ] = [];
level.secure_uav_path[ "circle2" ] = [];
// Global container for AI civvies
level.secure_civilians = [];
// Setup "front" volumes
level.secure_front = prep_secure_fronts();
}
//*******************************************************************
// *
// *
//*******************************************************************
audio_nodes_secure()
{
mynode = spawn( "sound_emitter", ( 6919, -1633, -23 ) );
mynode PlayloopSound( "emt_hh_crowd_screams" );
mynode2 = spawn( "sound_emitter", ( 7682, -1908, 403 ) );
mynode2 PlayloopSound( "emt_hh_fire" );
mynode stopsounds();
//mynode2 stopsounds();
wait 0.1;
mynode delete();
//mynode2 delete();
//mynode stopsounds();
//mynode2 stopsound();
//wait 0.1;
//mynode delete();
//mynode2 delete();
level waittill( "car_explosion_done" );
thread set_ambient( "nx_hithard_vicepres" );
}
triggerhelicopter()
{
self waittill( "trigger" );
println( "i'm in my trigger volume" );
level._player playsound( "elm_hh_helicopter_pass" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// First sniping objective (wave_1)
encounter_wave_1()
{
flag_set( "flag_script_objective_wave_1_active" );
flag_set( "flag_script_vip_guard_vulnerable_override" );
// Turn on vulnerability for allies
level.secure_vip_guard[ "ss" ] enable_hurt();
// Weaken SS guys
level.secure_vip_guard[ "ss" ] set_ai_accuracy_array( level.secure_ss_accuracy_weak );
// Set squad accuracy
level.squad set_ai_accuracy_array( level.secure_squad_accuracy_wave_1 );
// Turn on attention pointer
thread enableAttentionPointer( level.vip_focus_pointer, level.secure_vip, level.objective[ "obj_secure_snipe" ] );
// Reset kill counter
level.secure_human_enemies_num_killed = 0;
// Setup hatred
//SetThreatBias( "squad", "secure_wave_1", 1000 );
guys_unfixed = false;
guys_rushing = false;
send_in_uav_vtol = false;
position_uav_vtol = false;
// Wait for enough wave_1 enemies to be killed around the motorcade before proceeding
while( ( level.secure_enemies[ "ground" ].size > 0 ) || ( level.secure_enemies[ "ground_front_0" ].size > 0 ) || flag( "flag_secure_vip_vulnerable" ))
{
// Clean arrays
level.secure_enemies[ "ground" ] = remove_dead_from_array( level.secure_enemies[ "ground" ] );
level.secure_enemies[ "ground_front_0" ] = remove_dead_from_array( level.secure_enemies[ "ground_front_0" ] );
if( ( level.secure_enemies[ "ground" ].size <= 9 ) && !guys_unfixed )
{
// Unstick the enemies so they run around
foreach( guy in level.secure_enemies[ "ground" ] )
{
if( isalive( guy ))
{
guy set_fixednode_false();
}
}
guys_unfixed = true;
}
else if( ( level.secure_enemies[ "ground" ].size <= 5 ) && !guys_rushing && flag( "flag_script_high_priority_dialogue_allow" ))
{
// Tell enemies to ignore squad
set_squad_ignore( true );
// Send enemies in for the kill
level.secure_enemies[ "ground" ] = go_forth_and_die( level.secure_enemies[ "ground" ] );
guys_rushing = true;
}
wait 0.05;
}
//
// END
//
// Wait a frame to allow threat detect counter to catch up
wait 0.05;
// Turn off ally vulnerability
level.secure_vip_guard[ "ss" ] disable_hurt();
// Turn off attention pointer
DisableAttentionPointer();
// Turn off threat id for ground guys
flag_clear( "flag_script_ground_threat_id_allow" );
//level.secure_enemies[ "ground_front_0" ] thread SetThreatIDOverlay_array( "off" );
// Kill threat id counter script
level notify( "notify_secure_objective_wave_1_complete" );
flag_clear( "flag_script_objective_wave_1_active" );
// Make SS guys badass again
level.secure_vip_guard[ "ss" ] set_ai_accuracy_array( level.secure_ss_accuracy_badass );
set_squad_ignore( false );
objective_end( "obj_secure_snipe" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Sets squad and player's ignoreme
set_ignore_array( ignore_bool )
{
if( !isdefined( ignore_bool ))
{
AssertMsg( "'ignore_bool' is not defined for set_ignore_squad()" );
}
foreach( guy in self )
{
guy.ignoreme = ignore_bool;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Sets squad and player's ignoreme
set_squad_ignore( ignore_bool )
{
if( !isdefined( ignore_bool ))
{
AssertMsg( "'ignore_bool' is not defined for set_ignore_squad()" );
}
foreach( guy in level.squad )
{
guy.ignoreme = ignore_bool;
}
level._player.ignoreme = ignore_bool;
}
//*******************************************************************
// *
// *
//*******************************************************************
// Baker encourages the player when they make a kill
dialogue_baker_encouragement( end_notify )
{
level endon( end_notify );
baker_encouragement = [];
baker_encouragement = level.secure_dialogue[ "baker_encouragement" ];
// Counts the time
thread counter();
while( 1 )
{
level waittill( "secure_enemy_killed" );
if( baker_encouragement.size == 0 )
{
// Quit when out of dialogue
return;
}
else if( flag( "flag_script_low_priority_dialogue_allow" ))
{
// Baker encourages the player
if( level.time_between_enemy_deaths > level.secure_dialogue_encouragement_time )
{
baker_encouragement = play_random_dialogue_safe_and_remove( baker_encouragement );
level.time_between_enemy_deaths = 0;
}
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Keeps track of time
counter()
{
level endon( "secure_kill_counter" );
level.time_between_enemy_deaths = 0;
while( 1 )
{
wait 0.05;
level.time_between_enemy_deaths = level.time_between_enemy_deaths + 0.05;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Cortel building encounter
encounter_cortel()
{
// Setup hatred
//SetThreatBias( "secure_wave_cortel", "player", 1000 );
// Squad accuracy
level.squad set_ai_accuracy_array( level.secure_global_accuracy_cortel_start );
// Setup ignores
SetIgnoreMeGroup( "secure_wave_cortel", "secure_vip_guard" );
SetIgnoreMeGroup( "secure_vip_guard", "secure_wave_cortel" );
SetIgnoreMeGroup( "squad", "secure_wave_cortel" );
// Threat ID counter
thread watcher_threat_counter( "cortel_all", "notify_secure_objective_cortel_complete" );
// Send out UAV VTOL to circle
thread event_vtol_uav_drop();
flag_clear( "flag_script_low_priority_dialogue_allow" );
// Dialogue: Baker: "Eleven o'clock! Balcony! RPG!"
dialogue_array =
[
"hithard_bak_secure_19"
];
// Player will fail if they don't kill the RPG guy before he blows up VP vehicle
level.secure_enemies[ "cortel_balcony" ] = spawn_enemy_wave( "motorcade_enemies_rooftop_rpg_01", ::spawnfunc_enemy_cortel_balcony, "secure_wave_cortel", dialogue_array );
level.secure_enemies[ "cortel_all" ] = array_combine
( remove_dead_from_array( level.secure_enemies[ "cortel_balcony" ] ), remove_dead_from_array( level.secure_enemies[ "cortel_all" ] ));
waittill_dead( level.secure_enemies["cortel_balcony"], undefined, 3 );
//
// Terrace enemies
//
// Dialogue: Baker: "One o'clock! Terrace! RPG!"
dialogue_array =
[
"hithard_bak_secure_22"
];
level.secure_enemies["cortel_terrace"] = spawn_enemy_wave( "motorcade_enemies_terrace_01", ::spawnfunc_enemy_cortel_terrace, "secure_wave_cortel", dialogue_array );
level.secure_enemies[ "cortel_all" ] = array_combine
( remove_dead_from_array( level.secure_enemies[ "cortel_terrace" ] ), remove_dead_from_array( level.secure_enemies[ "cortel_all" ] ));
//
// Inside Cortel building
//
// Dialogue: Baker: "Twelve o'clock! Inside the building!"
dialogue_array =
[
"hithard_bak_secure_25"
];
level.secure_enemies[ "inside_cortel" ] = spawn_enemy_wave( "motorcade_enemies_cortel_inside_01", ::spawnfunc_enemy_cortel_inside, "secure_wave_cortel", dialogue_array );
level.secure_enemies[ "cortel_all" ] = array_combine
( remove_dead_from_array( level.secure_enemies[ "inside_cortel" ] ), remove_dead_from_array( level.secure_enemies[ "cortel_all" ] ));
thread watcher_enemy_cortel_dead( level.secure_enemies[ "cortel_all" ] );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Keeps count of threats on the screen
watcher_threat_counter( array_name, end_notify, array_name2 )
{
level endon( end_notify );
second_array = false;
if( isdefined( array_name2 ))
{
second_array = true;
}
while( 1 )
{
level.secure_enemies[ array_name ] = remove_dead_from_array( level.secure_enemies[ array_name ] );
if( second_array )
{
level.secure_enemies[ array_name2 ] = remove_dead_from_array( level.secure_enemies[ array_name2 ] );
level._player SetActiveThreatCount( level.secure_enemies[ array_name ].size + level.secure_enemies[ array_name2 ].size );
}
else
{
level._player SetActiveThreatCount( level.secure_enemies[ array_name ].size );
}
wait 0.05;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Bonaventure encoutners
encounter_bon()
{
radio_dialogue_stop();
level.secure_vip_guard[ "ss" ] enable_hurt( "bon_01" );
// Setup hatred
//setthreatbias( "secure_wave_bon", "secure_vip_guard", 1000 );
// Dialogue: Baker: "Ten o'clock! Bridge! Snipers!"
dialogue_array =
[
"hithard_bak_secure_27"
];
level.secure_enemies["bon_01"] = spawn_enemy_wave( "bon_01", ::spawnfunc_enemy_bon, "secure_wave_bon", dialogue_array );
//
// END
//
thread watcher_enemy_bon_dead( level.secure_enemies["bon_01"] );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Wait for bon guys to die before setting UAVs to attack sniper perch
watcher_enemy_bon_dead( guy_array )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
living_guys = remove_dead_from_array( guy_array );
waittill_dead( living_guys );
// Turn off ally vulnerability
level.secure_vip_guard[ "ss" ] disable_hurt();
// Autosave
thread autosave_by_name( "nx_hithard_secure_uav");
level notify( "notify_secure_objective_bon_complete" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Wait for bon guys to die before setting UAVs to attack sniper perch
watcher_enemy_cortel_dead( guy_array )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
thread watcher_ally_cortel_focus();
living_guys = remove_dead_from_array( guy_array );
waittill_dead( living_guys );
// Get the numbers on the ground up
level.secure_ground_num_guys_allowed = level.secure_wave_2_num_enemies;
// Autosave
thread autosave_by_name( "nx_hithard_secure_uav");
// Wait a frame (to let threat counter catch up)
waittillframeend;
// Kill threat counter
level notify( "notify_secure_objective_cortel_complete" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Wait a little bit of time, then sic squad on cortel guys
watcher_ally_cortel_focus()
{
wait 15.0;
// Squad accuracy
level.squad set_ai_accuracy_array( level.secure_global_accuracy_cortel_end );
// Setup ignores
//SetIgnoreMeGroup( "secure_wave_1", "squad" );
//SetIgnoreMeGroup( "secure_wave_1_front_0", "squad" );
// Set hatred
SetThreatBias( "squad", "secure_wave_cortel", 999999 );
SetThreatBias( "secure_wave_cortel", "squad", 1000 );
foreach( guy in level.secure_enemies[ "cortel_all" ] )
{
if( isalive( guy ))
{
guy.ignoreme = false;
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// UAV drop and smoke
encounter_uav()
{
// Autosave
thread autosave_by_name( "nx_hithard_secure_uav");
// Setup ignores
SetIgnoreMeGroup( "secure_wave_uavs", "secure_vip_guard" );
SetIgnoreMeGroup( "secure_vip", "secure_wave_uavs" );
SetIgnoreMeGroup( "squad", "secure_wave_uavs" );
SetIgnoreMeGroup( "secure_vip_guard", "secure_wave_uavs" );
// Setup hatred
SetThreatBias( "secure_wave_uavs", "player", 10000 );
objective_setpointertextoverride( level.objective[ "obj_secure_snipe" ], "" ); //Clear the pointer text
foreach( guy in level.squad )
{
guy set_goal_radius( 1024 );
guy set_ai_accuracy( level.secure_squad_accuracy_uav );
}
// Wait a frame (to let threat counter catch up)
waittillframeend;
// Drop UAVs
thread event_vtol_uav_drop();
// Dialogue: Baker: "VTOL Incoming"
radio_dialogue( "hithard_bak_snipe_09" );
// Wait until UAVs spawned
while( level.secure_enemies[ "uavs" ].size == 0 )
{
wait 0.05;
}
// Dialogue for UAVs
thread dialogue_baker_uavs();
// Objective
objective_start( "obj_secure_uavs", &"NX_HITHARD_SECURE_OBJ_UAVS" );
// Threat ID counter
thread watcher_threat_counter( "uavs", "notify_secure_objective_uavs_complete" );
// Break front_0 focus
level notify( "notify_secure_squad_front_0_focus_off" );
// Unstick allies
level.squad set_fixednode_false_array();
while( level.secure_enemies[ "uavs" ].size > 0 )
{
wait 0.05;
}
level notify( "notify_secure_objective_uavs_complete" );
objective_end( "obj_secure_uavs" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Wait a little bit, then send spawners out
send_in_spawnpool( wait_time )
{
if( isdefined( wait_time ))
{
wait wait_time;
}
// Send out spawners
flag_set( "flag_script_spawnpool_allow" );
}
//*******************************************************************
// *
// *
//*******************************************************************
event_end_sequence()
{
// Grab spawners
spawner_vip_move = GetEnt( "vp_transition", "script_noteworthy" );
spawner_ss_move = GetEnt( "ss_fodder1", "script_noteworthy" );
// Make vip vehicle start smoking
level.secure_vip_vehicle godoff();
level.secure_vip_vehicle2 godoff();
exploder( "fx_vip_vehicle_fire" );
wait 1.0;
radio_dialogue_stop();
thread radio_dialogue( "hithard_sslead_snipe_gonnablow" );
// Grab random SS guys for scene, rest will die
level.secure_vip_guard[ "ss" ] = remove_dead_from_array( level.secure_vip_guard[ "ss" ] );
level.ss_fodder1 = undefined;
level.ss_fodder2 = undefined;
level.ss_fodder3 = undefined;
if( level.secure_vip_guard[ "ss" ].size >= 3 )
{
level.ss_fodder1 = level.secure_vip closest_guy_to();
level.secure_vip_guard[ "ss" ] = array_remove( level.secure_vip_guard[ "ss" ], level.ss_fodder1 );
level.ss_fodder2 = random( level.secure_vip_guard[ "ss" ] );
level.secure_vip_guard[ "ss" ] = array_remove( level.secure_vip_guard[ "ss" ], level.ss_fodder2 );
level.ss_fodder3 = random( level.secure_vip_guard[ "ss" ] );
level.secure_vip_guard[ "ss" ] = array_remove( level.secure_vip_guard[ "ss" ], level.ss_fodder3 );
}
else
{
switch( level.secure_vip_guard[ "ss" ].size )
{
case 2:
{
level.ss_fodder1 = level.secure_vip closest_guy_to();
level.secure_vip_guard[ "ss" ] = array_remove( level.secure_vip_guard[ "ss" ], level.ss_fodder1 );
level.ss_fodder2 = random( level.secure_vip_guard[ "ss" ] );
level.secure_vip_guard[ "ss" ] = array_remove( level.secure_vip_guard[ "ss" ], level.ss_fodder2 );
level.ss_fodder3 = GetEnt( "ss_fodder3", "script_noteworthy" ) spawn_ai();
break;
}
case 1:
{
level.ss_fodder1 = level.secure_vip closest_guy_to();
level.secure_vip_guard[ "ss" ] = array_remove( level.secure_vip_guard[ "ss" ], level.ss_fodder1 );
level.ss_fodder2 = GetEnt( "ss_fodder2", "script_noteworthy" ) spawn_ai();
level.ss_fodder3 = GetEnt( "ss_fodder3", "script_noteworthy" ) spawn_ai();
break;
}
case 0:
{
level.ss_fodder1 = GetEnt( "ss_fodder1", "script_noteworthy" ) spawn_ai();
level.ss_fodder2 = GetEnt( "ss_fodder2", "script_noteworthy" ) spawn_ai();
level.ss_fodder3 = GetEnt( "ss_fodder3", "script_noteworthy" ) spawn_ai();
break;
}
}
}
//level.run_position = vector_multiply( AnglesToForward( AnglesToRight( level.secure_vip_vehicle.angles )), 256 );
// fodder guy array
fodder_guys = [ level.ss_fodder1, level.ss_fodder2, level.ss_fodder3 ];
// Prep the SS guys for next scene
fodder_guys prep_ss_motorcade_array();
// SS and VP run for cover
vp_ss_cover = GetEnt( "origin_secure_vp_ss_cover", "targetname" );
vp_ss_cover thread vp_protect_at_node( level.secure_vip, level.ss_fodder1 );
vp_ss_cover waittill( "reach_done" );
fodder_guys run_to_vp();
level.secure_vip_guard[ "ss" ] run_to_vp();
flag_set( "music_smoke_battle_ends" );
wait 1.0;
thread car_explode_slow_mo();
// Kill vehicle, civilians, and remaining SS guys
stop_exploder( "fx_vip_vehicle_fire" );
level.secure_vip_vehicle playsound( "scn_hithard_ugvcar03" );
level.secure_vip_vehicle kill();
foreach( guy in level.secure_vip_guard[ "ss" ] )
{
if( isalive( guy ))
{
guy kill();
}
}
foreach( guy in level.secure_vip_guard[ "ss" ] )
{
if( isalive( guy ))
{
guy kill();
}
}
foreach( guy in fodder_guys )
{
if( isalive( guy ))
{
guy SetGoalPos( guy.origin );
}
}
// Send VP and SS guy to positions
level waittill( "car_explosion_done" );
vp_ss_cover vp_protect_end();
level.ss_fodder1.script_forcegoal = 1;
level.secure_vip.script_forcegoal = 1;
level.ss_fodder1.goalradius = 8;
level.secure_vip.goalradius = 8;
vp_and_ss = [ level.secure_vip, level.ss_fodder1 ];
level.secure_vip.animname = "vp";
level.ss_fodder1.animname = "secret_service1";
node = getstruct("node_vp_ss_loop2", "script_noteworthy");
wait .5;
node anim_reach_and_approach( vp_and_ss, "vp_loop" );
radio_dialogue_stop();
// Dialogue: Baker: "Ok. Looks Clear - powering down Threat Detection"
thread radio_dialogue_interupt( "hithard_bak_snipe_21" );
// Disable threat ID usage
thread maps\_threatid::threatid_disable_overlay_and_effect();
}
run_to_vp()
{
foreach( guy in self )
{
if( isalive( guy ))
{
guy.goalradius = 8;
guy.script_forcegoal = 1;
guy SetGoalEntity( level.secure_vip );
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
closest_guy_to( vip )
{
protect_vol = GetEnt( "volume_secure_vp_protect", "targetname" );
vp_right = protect_vol get_ai_touching_volume( "allies" );
array_of_dudes = [];
foreach( guy in vp_right )
{
if( guy.classname == "actor_nx_ally_us_secretservice" )
{
array_of_dudes = add_to_array( array_of_dudes, guy );
}
}
closest_dude = undefined;
if( array_of_dudes.size > 0 )
{
closest_dude = self closest_to( array_of_dudes );
}
else
{
closest_dude = self closest_to( level.secure_vip_guard[ "ss" ] );
}
Assert( isdefined( closest_dude ));
return closest_dude;
}
//*******************************************************************
// *
// *
//*******************************************************************
closest_to( array_of_dudes )
{
closest_dist = 999999999;
closest_dude = undefined;
for( i = 0; i < array_of_dudes.size; i++ )
{
distance_between = distance( array_of_dudes[ i ].origin, self.origin );
if( distance_between < closest_dist )
{
closest_dist = distance_between;
closest_dude = array_of_dudes[ i ];
}
}
Assert( isdefined( closest_dude ));
return closest_dude;
}
//*******************************************************************
// *
// *
//*******************************************************************
car_explode_slow_mo()
{
// Don't slomo sounds
SoundSetTimeScaleFactor( "Mission", 0 );
SoundSetTimeScaleFactor( "Shellshock", 0 );
SoundSetTimeScaleFactor( "Voice", 0 );
SoundSetTimeScaleFactor( "Menu", 0 );
SoundSetTimeScaleFactor( "Effects1", 0 );
SoundSetTimeScaleFactor( "Effects2", 0 );
SoundSetTimeScaleFactor( "Announcer", 0 );
SoundSetTimeScaleFactor( "Music", 0 );
SoundSetTimeScaleFactor( "vignette3d", 0 );
SoundSetTimeScaleFactor( "vignette2d", 0 );
SoundSetTimeScaleFactor( "ambient", 0 );
SoundSetTimeScaleFactor( "weapon", 0 );
SoundSetTimeScaleFactor( "weapon2d", 0 );
SoundSetTimeScaleFactor( "auto2d", 0 );
SoundSetTimeScaleFactor( "auto", 0 );
SoundSetTimeScaleFactor( "element", 0 );
level._player magic_bullet_shield();
// Start slo motion
slowmo_speed = 0.20;
slowmo_setspeed_slow( slowmo_speed );
slowmo_setlerptime_in( 0.5 );
slowmo_lerp_in();
level._player SetMoveSpeedScale( 0.1 );
// Wait slo mo duration
real_time = 3.0;
wait real_time * slowmo_speed ;
// Stop slo motion
slowmo_setlerptime_out( 0.65 );
slowmo_lerp_out();
slowmo_end();
level._player SetMoveSpeedScale( 1.0 );
wait 1.0;
level._player stop_magic_bullet_shield();
level notify( "car_explosion_done" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Waits for multiple notifies before continuing
waittill_multi( array_of_ai, msg )
{
foreach( thing in array_of_ai )
{
thing thread waittill_multi_thread( msg );
}
msg_count = 0;
while( msg_count < array_of_ai.size )
{
level waittill( "notify_waittill_complete" );
msg_count++;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
waittill_multi_thread( msg )
{
self waittill( msg );
level notify( "notify_waittill_complete" );
}
//*******************************************************************
// *
// *
//*******************************************************************
main_rappel()
{
radio_dialogue_stop();
// Dialogue: SS: "Convoy 2, we<77>re getting overrun!<21>
//radio_dialogue( "hithard_sslead_snipe_08");
// Dialogue: Baker: "They're going for Patriot!"
//radio_dialogue( "hithard_bak_secure_45" );
// Dialogue: Baker: "Latch up. We're roping down."
// add_dialogue_line( "Baker", "Latch-up. We're roping down.", "green", 2 );
// Dialogue: Baker: "Duke, Specter, we're movin"
radio_dialogue( "hithard_bak_snipe_weremovin" );
level.squad[ 0 ] thread ally_rappel( "baker", GetNode( "node_secure_ground_ally_02", "script_noteworthy" ));
level.squad[ 1 ] thread ally_rappel( "duke", GetNode( "node_secure_ground_ally_01", "script_noteworthy" ));
waittill_multi( level.squad, "notify_rappel_idle" );
// Obj position for rappel
rappel_node = GetEnt( "player_rappel_animent", "targetname" );
objective_start( "obj_secure_rappel", &"NX_HITHARD_SECURE_OBJ_RAPPEL", rappel_node );
// Summon player after a bit
thread dialogue_rappel_summon_player();
// Ready to start smoke when player rappel starts
thread spawn_smoke();
// Player Rappel setup
thread maps\_rappel_util::rappel_start();
level._player waittill( "notify_rappel_start" );
level._player playsound("hithard_rappel_scene");
// Apply vision and fog
thread maps\nx_hithard_fx::apply_effects_sniper_wave4();
radio_dialogue_stop();
thread replenish_ss( level.secure_vip_guard[ "ss" ].size );
level waittill( "notify_rappel_complete" );
objective_setpointertextoverride( level.objective[ "obj_secure_snipe" ], &"NX_HITHARD_SECURE_OBJ_PROTECT" );
objective_OnEntity( level.objective[ "obj_secure_snipe" ], level.secure_vip );
objective_end( "obj_secure_rappel" );
//debug_warp_ground();
}
//*******************************************************************
// *
// *
//*******************************************************************
dialogue_rappel_summon_player()
{
level._player endon( "notify_rappel_start" );
wait 5;
// Dialogue: Baker: "Specter, let's go"
radio_dialogue( "hithard_bak_snipe_letsgo" );
}
//*******************************************************************
// *
// *
//*******************************************************************
replenish_ss( count )
{
while( count < 6 )
{
array = spawn_vip_guard( "motorcade_vip_guard_replenish", "ss", 1 );
level.secure_vip_guard[ "ss" ] = add_to_array( level.secure_vip_guard[ "ss" ], array[0] );
count++;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
main_secure_ground()
{
flag_wait( "flag_secure_rooftop_prep_complete" );
battlechatter_on( "allies" );
battlechatter_on( "axis" );
//setting ambient
thread set_ambient( "nx_hithard_ext" );
// Autosave
thread autosave_by_name( "nx_hithard_secure_ground" );
// Start objective
objective_start( "obj_secure_ground", &"NX_HITHARD_SECURE_OBJ_GROUND", level.secure_vip, &"NX_HITHARD_SECURE_OBJ_PROTECT" );
// Send allies to back of car
foreach( guy in level.secure_vip_guard[ "ss" ] )
{
guy set_force_color( "c" );
guy set_fixednode_true();
}
issue_color_orders( "c1", "allies" );
// Setup ignores
//set_squad_ignore( true );
//SetIgnoreMeGroup( "secure_wave_1", "player" );
//SetIgnoreMeGroup( "secure_wave_1_front_0", "player" );
flag_clear( "flag_script_low_priority_dialogue_allow" );
flag_set( "flag_script_ground_threat_id_allow" );
// Setup hatred
SetThreatBias( "squad", "secure_wave_1", 1000 );
SetThreatBias( "squad", "secure_wave_1_front_0", 1000 );
SetThreatBias( "secure_wave_1", "secure_vip_guard" , 2000 );
SetThreatBias( "secure_wave_1_front_0", "secure_vip_guard" , 4000 );
// Turn on threat ID for ground guys
//level.secure_enemies[ "ground" ] SetThreatIDOverlay_array( "auto" );
// Threat ID counter
thread watcher_threat_counter( "ground", "notify_secure_objective_wave_2_complete", "ground_front_0" );
// Baker encourages
//thread dialogue_baker_encouragement( "notify_secure_objective_wave_2_complete" );
// Make SS guys weak again
level.secure_vip_guard[ "ss" ] set_ai_accuracy_array( level.secure_ss_accuracy_weak );
level.squad thread allies_to_start_nodes();
// Large group moving through the smoke!
radio_dialogue( "hithard_bak_secure_51" );
flag_set( "music_smoke_battle_starts" );
flag_set( "flag_script_objective_wave_2_active" );
flag_set( "flag_script_low_priority_dialogue_allow" );
// Turn on threat ID for civvies
foreach( guy in level.secure_civilians )
{
//guy SetThreatIDOverlay( "auto" );
}
// Turn on vulnerability for allies
level.secure_vip_guard[ "ss" ] enable_hurt();
// Turn on attention pointer
//thread enableAttentionPointer( level.vip_focus_pointer, level.secure_vip, level.objective[ "obj_secure_snipe" ] );
level.secure_human_enemies_num_killed = 0;
// Give allies back their mojo
level.squad set_ai_accuracy_array( level.secure_squad_accuracy_wave_2 );
while( level.secure_enemies[ "ground" ].size == 0 )
{
wait 0.05;
}
// Wait for enough wave_1 enemies to be killed before proceeding
while(( level.secure_enemies[ "ground" ].size > 0 ) || ( level.secure_enemies[ "ground_front_0" ].size > 0 ))
{
//issue_color_orders( "p1", "axis" );
// Clean arrays
level.secure_enemies[ "ground" ] = remove_dead_from_array( level.secure_enemies[ "ground" ] );
level.secure_enemies[ "ground_front_0" ] = remove_dead_from_array( level.secure_enemies[ "ground_front_0" ] );
if(( level.secure_enemies[ "ground_front_0" ].size < 3 ) && ( level.secure_enemies[ "ground" ].size > 0 ))
{
// Send enemies in for the kill
guy = random( level.secure_enemies[ "ground" ] );
guy go_forth_and_die_solo();
level.secure_enemies[ "ground" ] = array_remove( level.secure_enemies[ "ground" ], guy );
}
wait 0.05;
}
//
// END
//
// Turn off ally vulnerability script
level.secure_vip_guard[ "ss" ] disable_hurt();
waittillframeend;
// Remove bullet shielding
level.secure_vip_guard[ "ss" ] thread stop_magic_bullet_shield_array();
// Turn off attention pointer
thread DisableAttentionPointer();
// Break front_0 focus
level notify( "notify_secure_squad_front_0_focus_off" );
level notify( "notify_secure_objective_wave_2_complete" );
level notify( "notify_secure_objective_complete" );
objective_end( "obj_secure_ground" );
// Play final sequence leading into cutscene
event_end_sequence();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Turns off the spawnpool during wave_2 when enough guys have spawned
watcher_enemy_spawnpool_off( num_guys_allowed )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
// Set spawner counter to current number of guys on the ground
level.num_enemies_spawned = isalive_array( level.secure_enemies[ "ground" ]);
while( level.num_enemies_spawned < num_guys_allowed )
{
wait 0.05;
}
flag_clear( "flag_script_spawnpool_allow");
}
//*******************************************************************
// *
// *
//*******************************************************************
// Force an AI to a node
allies_to_start_nodes()
{
node = [];
node[ "ally_01" ] = GetNode( "node_secure_ally_01_cover", "script_noteworthy" );
node[ "ally_02" ] = GetNode( "node_secure_ally_02_cover", "script_noteworthy" );
foreach( guy in self )
{
guy.script_forcegoal = 1;
guy SetGoalNode( node[ guy.script_noteworthy ] );
}
wait 3.0;
level notify( "notify_script_secure_allies_in_position" );
}
//*******************************************************************
// *
// *
//*******************************************************************
debug_warp_ground()
{
// Warp player
//level._player maps\_nx_utility::move_player_to_start_point( "playerstart_secure_ground" );
// Move squad to positions
ally_set_goal_noteworthies = [ "node_secure_ground_ally_02", "node_secure_ground_ally_01" ];
level.squad maps\nx_hithard_util::moveAlliesToStartPoint( ally_set_goal_noteworthies, ally_set_goal_noteworthies, true );
level.squad set_fixednode_true_array();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Reinforcements drive in and get RPGed
event_lapd_backup()
{
/*
lapd_spawner = GetEntArray( "motorcade_vip_guard_backup1", "script_noteworthy" );
foreach( guy in lapd_spawner )
{
guy set_script_friendname( "Officer" );
}
array_spawn_function( lapd_spawner, ::spawnfunc_ally_swat_backup, "secure_vip_guard" );
*/
level.vehicles[ "lapd_backup" ] = spawn_vehicle_from_targetname_and_drive( "vehicle_lapd_assist_1" );
level.vehicles[ "lapd_backup" ] waittill( "reached_end_node" );
//level.vehicles[ "lapd_backup" ] vehicle_unload();
wait 1.0;
rpg_guy_spawner = GetEnt( "secure_enemy_ground_rpg", "targetname" );
rpg_guy_spawner add_spawn_function( ::spawnfunc_enemy_wave_1_lapd_rpg, "secure_wave_1_front_0", level.vehicles[ "lapd_backup" ] );
rpg_guy_spawner spawn_ai();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Intro dialogue between baker and patriot
dialogue_baker_and_patriot()
{
radio_dialogue_stop();
// Dialogue: Baker: "Patriot, this is convoy 2.<2E> Engaging from Southwest roof."
radio_dialogue( "hithard_bak_snipe_05" );
// Dialgoue: Baker: "About time! We have no exit!"
radio_dialogue( "hithard_sslead_snipe_01" );
// Dialogue: Baker: "Roger, we're on it!"
radio_dialogue( "hithard_bak_snipe_06" );
// Baker encourages
thread dialogue_baker_encouragement( "notify_secure_objective_wave_1_complete" );
flag_set( "flag_secure_intro_dialogue_complete" );
level.squad ignore_all_off();
thread fire_up_threat_detection();
}
//*******************************************************************
// *
// *
//*******************************************************************
active_weapon()
{
while( 1 )
{
iprintlnbold( level._player GetCurrentWeapon() );
wait 1.0;
}
}
// Main objective script
main_secure()
{
flag_wait( "flag_secure_rooftop_prep_complete" );
// Kill off all ai spawners from parachute section
maps\_spawner::kill_spawnerNum( 2 );
// Wait until guys have spawned
//flag_wait( "flag_secure_rooftop_prep_complete" );
// Send in a VTOL with some ropers
thread event_enemy_vtol_enemy_roper();
battlechatter_off( "allies" );
battlechatter_off( "axis" );
flag_wait( "flag_secure_rooftop_aware" );
thread event_lapd_backup();
// Baker talks with patriot
thread dialogue_baker_and_patriot();
//setting ambient
thread set_ambient( "nx_hithard_ext2" );
// Lower the objective distance (so marker doesn't fade)
setSavedDvar( "ObjectiveFadeTooFar", 15 );
// Autosave
thread autosave_by_name( "nx_hithard_secure_start" );
flag_wait( "flag_secure_intro_dialogue_complete" );
// Start snipe objective
objective_start( "obj_secure_snipe", &"NX_HITHARD_SECURE_OBJ_SNIPE", level.secure_vip, &"NX_HITHARD_SECURE_OBJ_PROTECT" );
flag_set( "flag_secure_objective_active" );
// Watch the vip's security forces
thread watcher_vip_guard();
// Watch for vehicle damage by specific enemies
//level.secure_vip_vehicle thread watcher_vip_vehicle();
// Run through each encounter
for( i = level.encounter_start; i < level.encounter_list.size; i++ )
{
[[level.encounter_list[ i ]]]();
}
// Lower the objective distance back to default
setSavedDvar( "ObjectiveFadeTooFar", 25 );
// Objective Complete
//objective_end( "obj_secure_snipe" );
flag_clear( "flag_secure_objective_active" );
flag_clear( "flag_script_ground_threat_id_allow" );
flag_set( "flag_secure_objective_complete" );
flag_set( "music_snipe_ends" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Sets up ally for rappel
ally_rappel_latch_on_sfx( animname )
{
wait 2.0;
if( animname == "baker")
level.squad[ 0 ] playsound("hithard_rappel_baker_latch_on");
else
level.squad[ 1 ] playsound("hithard_rappel_duke_latch_on");
}
ally_rappel( animname, goal_node )
{
rappel_node = GetEnt( "player_rappel_animent", "targetname" );
self.animname = animname;
rappel_node anim_reach_solo( self, "rappel_intro" );
thread ally_rappel_latch_on_sfx( animname );
rappel_node anim_single_solo( self, "rappel_intro" );
rappel_node thread anim_loop_solo( self, "rappel_idle" );
waittillframeend;
self notify( "notify_rappel_idle" );
level._player waittill( "notify_rappel_start" );
rappel_node notify( "stop_loop" );
self anim_stopanimscripted();
rappel_node anim_single_solo( self, "rappel_outro", undefined, 0.2 );
wait 1;
self set_fixednode_false();
self.goalradius = 8;
self.script_forcegoal = 1;
self SetGoalNode( goal_node );
//self waittill( "goal" );
//self set_fixednode_true();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Start threat detection
fire_up_threat_detection()
{
// Dialogue: Baker: "firing up threat detection."
radio_dialogue( "hithard_bak_secure_02" );
// enable threat ID usage
flag_set( "flag_script_ground_threat_id_allow" );
thread maps\_threatid::threatid_bootup_and_enable();
// Threat ID counter
thread watcher_threat_counter( "ground", "notify_secure_objective_wave_1_complete", "ground_front_0" );
// Dialogue: Baker "Go to High Power Scopes"
radio_dialogue( "hithard_bak_snipe_18" );
flag_set( "flag_script_high_priority_dialogue_allow" );
flag_set( "flag_script_low_priority_dialogue_allow" );
// Display zoom hint
thread watcher_zoom_hint();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Display zoom hint
watcher_zoom_hint()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
cycles = 0;
thread watcher_zoom_hint_switch();
flag_clear( "flag_secure_dpad_pressed" );
while( !flag( "flag_secure_dpad_pressed" ) && ( cycles < 3 ))
{
display_hint_timeout( "hint_secure_zoom", 3.0 );
wait 10;
cycles++;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Watches for player to press dpad left, then sends notify
watcher_zoom_hint_switch()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
while( !level._player ButtonPressed( "DPAD_LEFT" ))
{
wait 0.05;
}
flag_set( "flag_secure_dpad_pressed" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Logic for cortel inside RPG guys
spawnfunc_enemy_cortel_inside_watcher( destroy_node_targetname, node2_targetname )
{
self endon( "death" );
topfloor = false;
if( self.target == "topfloor" )
{
topfloor = true;
}
go_node = GetNode( node2_targetname, "targetname" );
window_target = GetEnt( destroy_node_targetname, "targetname" );
billboard_nodes = GetEntArray( "origin_billboard_killer", "targetname" );
self waittill( "reached_path_end" );
// Give him a moment so he doesn't blow himself up
wait 1.0;
// Blow out the windows
weapon_origin = self GetTagOrigin( "TAG_WEAPON_LEFT" ) + vector_multiply( AnglesToForward( self.angles ), 10 );
// Top guy shoots through window, bottom guy blows up window
if( topfloor )
{
randomTarget = random( billboard_nodes );
MagicBullet( "rpgx_straight", weapon_origin, randomTarget.origin );
}
else
{
MagicBullet( "rpgx_straight", weapon_origin, window_target.origin );
}
self SetGoalNode( go_node );
self waittill( "goal" );
self.ignoreall = false;
level notify( "notify_" + self.script_noteworthy + "_at_goal" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Order to squad allies to kill wave_1 baddies
watcher_squad_front_0_focus()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
level endon( "notify_secure_squad_front_0_focus_off" );
while( 1 )
{
flag_wait( "flag_secure_vip_vulnerable" );
//SetThreatBias( "squad", "secure_wave_1_front_0", 10000 );
flag_waitopen( "flag_secure_vip_vulnerable" );
//SetThreatBias( "squad", "secure_wave_1_front_0", 0 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// VTOL drops off wave_1 dudes
event_enemy_vtol_secure_intro()
{
// flyby vtol
level.secure_vtols[ "vtol_03" ] = spawn_vtol_from_noteworthy( "secure_vtol_3", undefined, "secure_vtol_enter_03" );
level.secure_vtols[ "vtol_03" ] thread vtol_exit();
}
//*******************************************************************
// *
// *
//*******************************************************************
// VTOL flies in and drops reinforcements
event_enemy_vtol_enemy_roper()
{
vtol_guys = getentarray( "motorcade_enemies_1_vtol", "script_noteworthy" );
array_thread( vtol_guys, ::add_spawn_function, ::spawnfunc_enemy_wave_1_vtol, "secure_wave_1_front_0" );
thread watcher_enemy_vtol_shake_and_bake();
// enemy roper vtol
level.secure_vtols[ "vtol_01" ] = spawn_vtol_from_noteworthy( "secure_vtol_1", "secure_vtol4_1", "secure_vtol_exit2" );
vtol1_sfx = Get_Vehicle( "secure_vtol_1", "targetname" );
vtol1_sfx playsound( "scn_hhh_vtol_flyin02" );
level.secure_vtols[ "vtol_01" ] vtol_enter( true );
//level.secure_vtols playsound("nx_npc_fastrope");
wait 15.0;
level.secure_vtols[ "vtol_01" ] vtol_exit();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Flyover shakes player
watcher_enemy_vtol_shake_and_bake()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
while( !flag( "flag_secure_objective_active" ))
{
flag_wait( "flag_vtol_flyover" );
Earthquake( .3, 1.0 , level._player.origin, 5000 );
level._player PlayRumbleOnEntity( "artillery_rumble" );
flag_clear( "flag_vtol_flyover" );
}
}
sound_play_explosion()
{
flag_wait ("flag_intersection_first_fireball");
thread maps\_utility::set_ambient( "nx_hithard_ext2" );
mynodebomb = spawn( "sound_emitter", ( 8336, -2458, 7 ) );
wait 0.2;
mynodebomb PlaySound( "expl_hh_bomb", "expl_hh_bomb", true );
mynodebomb waittill( "expl_hh_bomb" );
mynodebomb delete();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Announce the wave once enemies in place
dialogue_baker_wave_callout( enemy_noteworthy_name, dialogue_array )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
first_time = true;
allowed = true;
if( isalive_array( self ))
{
//self SetThreatIDOverlay_array( "auto" );
}
// Wait until one of the enemies reaches his goal
level waittill( "notify_" + enemy_noteworthy_name + "_at_goal" );
play_count = 0;
// Play the dialogue
if( isalive_array( self ))
{
if( first_time )
{
// First time callouts get priority
radio_dialogue_stop();
radio_dialogue_interupt( dialogue_array[ 0 ] );
first_time = false;
}
else
{
radio_dialogue( dialogue_array[ 0 ] );
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// guy targetting VIP vehicle
waittill_goal_notify( enemy_noteworthy_name )
{
self endon( "death" );
self waittill( "reached_path_end" );
level notify( "notify_" + enemy_noteworthy_name + "_at_goal" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Prepares all entities in "sniping" intersection
prep_secure_intersection( spawn_first_wave )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
// Wait to spawn dudes until player trips the below flag
flag_wait( "flag_prep_secure" );
// Setup global variables
A_secure_globals();
// Kill lingering guys in rooftop section when they are out of sight
delete_ai_volume_out_of_sight( "secure_rooftop_cleanup" );
// Grab VIP car
level.secure_vip_vehicle = getent( "vip_busted", "targetname" );
level.secure_vip_vehicle godon();
level.secure_vip_vehicle2 = getent( "ugv_targetcar1", "targetname" );
level.secure_vip_vehicle2 godon();
//level.secure_vip_vehicle kill(); // Kill
// Spawn vip
level.secure_vip = spawn_vip( "ultra_vp", ::spawnfunc_ally_vip, "secure_vip" );
// Spawn vip guard
level.secure_vip_guard[ "ss" ] = spawn_vip_guard( "motorcade_vip_guard_1", "secret_service" );
roaming_secret_service = spawn_vip_guard( "motorcade_vip_guard_3", "secret_service" );
foreach( guy in roaming_secret_service )
{
level.secure_vip_guard[ "ss" ] = add_to_array( level.secure_vip_guard[ "ss" ], guy );
}
level.secure_vip_guard[ "swat" ] = spawn_vip_guard( "motorcade_vip_guard_2", "swat" );
level.secure_vip_guard[ "all" ] = array_combine( level.secure_vip_guard[ "ss" ], level.secure_vip_guard[ "swat" ] );
// Spawn and kill bodies for ground
deadguys_spawner = getEntArray( "motorcade_vip_guard_4", "script_noteworthy" );
foreach( guy in deadguys_spawner )
{
deadguy = guy spawn_ai();
deadguy kill();
}
// Setup allies to color yellow
issue_color_orders( "g1", "allies" );
// Setup allies to color yellow
issue_color_orders( "c1", "allies" );
// Civilian drones running around intersection and streets
thread civilians_drones();
// AI civilians running around intersection and streets from cortel building
thread civilians_ai();
// start the vfx sequencing
thread maps\nx_hithard_fx::fx_secure_init();
//thread event_enemy_vtol_secure_intro();
// Change Friendly Fire participation points (can accidentally kill more civvies / allies) Default: -650
level._friendlyfire[ "friend_kill_points" ] = 0;
if( isdefined( spawn_first_wave ))
{
if( spawn_first_wave )
{
// Spawn enemies already attacking motorcade
level.secure_enemies[ "ground" ] = spawn_enemy_wave( "motorcade_enemies_1", ::spawnfunc_enemy_ground_first, "secure_wave_1_front_0" );
level.secure_enemies[ "ground" ] thread watcher_enemy_wave_1_remove_bullet_shield();
}
else
{
// Watch the vip's security forces
thread maps\nx_hithard_secure::watcher_vip_guard();
}
}
flag_set( "flag_secure_rooftop_prep_complete" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Waits for player to get to rooftop, then removes bullet shielding on baddies
watcher_enemy_wave_1_remove_bullet_shield()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
// Wait for player to be on rooftop
flag_wait( "flag_secure_rooftop_aware" );
self stop_magic_bullet_shield_array();
}
//*******************************************************************
// *
// *
//*******************************************************************
civilians_drones()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
level endon( "notify_kill_drone_spawn" );
spawners_1 = GetEntArray( "secure_civilian_spawner", "script_noteworthy" );
starts_1 = GetEntArray( "secure_civilians_ground_start_fig_1", "script_noteworthy" );
ends_1 = GetEntArray( "secure_civilians_fig_1_end", "script_noteworthy" );
spawners_2 = GetEntArray( "secure_civilian_spawner_2", "script_noteworthy" );
starts_2 = GetEntArray( "secure_civilians_ground_start_fig_2", "script_noteworthy" );
ends_2 = GetEntArray( "secure_civilians_fig_2_end", "script_noteworthy" );
thread civilians_drone( "figueroa1", 1,spawners_1, starts_1, ends_1, 0.05, 2 );
thread civilians_drone( "figueroa2", 1,spawners_2, starts_2, ends_2, 0.05, 2 );
wait 60;
level notify( "notify_kill_drone_spawn" );
thread civilians_drone( "figueroa1", 1,spawners_1, starts_1, ends_1, 2, 4 );
thread civilians_drone( "figueroa2", 1,spawners_2, starts_2, ends_2, 2, 4 );
wait 60;
level notify( "notify_kill_drone_spawn" );
thread civilians_drone( "figueroa1", 1,spawners_1, starts_1, ends_1, 4, 6 );
thread civilians_drone( "figueroa2", 1,spawners_2, starts_2, ends_2, 4, 6 );
wait 60;
level notify( "notify_kill_drone_spawn" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Watches the main vip vehicle (where all SS and vp are hiding)
watcher_vip_vehicle()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
vip_vehicle_attacker_list = [];
while( 1 )
{
self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, idFlags );
if( attacker == level._player )
{
self damage_vip_vehicle( damage );
}
else if( isdefined( attacker.script_parameters ))
{
// Attacker is allowed to hurt vip vehicle
if( attacker.script_parameters == "secure_vip_hurt" )
{
if( isdefined( attacker.targetname ))
{
// If first attack, add targetname of attacker to list. If not first time, allow damage.
if( vip_vehicle_attacker_list[ attacker.targetname ] )
{
self damage_vip_vehicle( damage );
}
else
{
vip_vehicle_attacker_list[ attacker.targetname ] = 1;;
}
}
}
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Send the entity to a goalvolume
go_to_goal_volume( goalVolume )
{
self SetGoalVolumeAuto( level.secure_front[ goalVolume ] );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Damage the VIP vehicle (or destroy it if enough damage is taken)
damage_vip_vehicle( damage )
{
if( self.health <= damage )
{
self godoff();
// Take bulletshield off of vip crowd for effect
level.secure_vip stop_magic_bullet_shield();
foreach( guy in level.secure_vip_guard )
{
if( isalive( guy ))
{
guy stop_magic_bullet_shield();
}
}
self kill();
flag_set( "flag_secure_objective_failed" );
SetDvar( "ui_deadquote", "You failed to protect the VP! (PLACEHOLDER)" );
missionFailedWrapper();
}
else
{
self.health = self.health - damage;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// AI cvilian controller for secure motorcade
civilians_ai()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
// Grab civilian spawners and "goal" nodes
spawners = getentarray( "secure_civilians_ground_male_ai_1", "script_noteworthy" );
end_nodes = getnodearray( "secure_civ_ai_end", "script_noteworthy" );
while( 1 )
{
// Clean the undefined civvies for accurate numbers
level.secure_civilians = remove_dead_from_array( level.secure_civilians );
// Make sure we don't have too many civvies, if we don't, spawn some more
if
(
(level.secure_civilians.size < level.secure_civilian_ai_max ) &&
( GetAICount() <= ( 32 - level.secure_civilian_ai_buffer ))
)
{
while
(
( level.secure_civilians.size < level.secure_civilian_ai_max ) &&
( GetAICount() <= ( 32 - level.secure_civilian_ai_buffer ))
)
{
// Clean the undefined civvies for accurate numbers
level.secure_civilians = remove_dead_from_array( level.secure_civilians );
// Grab a spawner and a node
node = random( end_nodes );
spawner = random( spawners );
// spawn
civilian = spawner spawn_ai();
if( isdefined( civilian ))
{
civilian.goalradius = level.secure_civilian_goalradius;
civilian setGoalNode( node );
civilian thread watcher_civilians_ai();
level.secure_civilians = add_to_array( level.secure_civilians, civilian );
if( !flag( "flag_script_objective_wave_2_active" ))
{
//civilian SetThreatIDOverlay( "auto" );
}
}
wait_random_time( 1, 3 );
}
}
wait 1;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Remove civilians when they reach the end of their paths
watcher_civilians_ai()
{
self endon( "death" );
self waittill( "goal" );
self delete();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Grabs goal volumes and pathnode positions for "fronts"
prep_secure_fronts()
{
// Grab goal volumes to use as "fronts"
fronts = [];
// Enemy fronts
fronts[ "front_3" ] = getEnt( "front_3", "script_noteworthy" );
fronts[ "front_2" ] = getEnt( "front_2", "script_noteworthy" );
fronts[ "front_1" ] = getEnt( "front_1", "script_noteworthy" );
fronts[ "front_0" ] = getEnt( "front_0", "script_noteworthy" );
//Ally (vip guard) fronts
fronts[ "allies_normal" ] = getEnt( "volume_front_motorcade", "script_noteworthy" );
fronts[ "allies_last_stand" ] = getEnt( "volume_front_last_stand", "script_noteworthy" );
return fronts;
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn secure motorcade section civilians
civilians_drone( name, count, spawners, starts, ends, time_low, time_high )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
level endon( "notify_kill_drone_spawn" );
crowd = maps\nx_crowd_controller::new_crowd( name, count, spawners, starts, ends, time_low, time_high );
while( 1 )
{
thread maps\nx_crowd_controller::spawn_crowd( name );
level waittill( name );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawns new ground enemies indefinitely
watcher_enemy_spawnpool()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
number_of_spawnpools = 3;
// Check and prep spawn pools
spawnpools = getEntArray( "motorcade_enemies_spawnpool_1", "script_noteworthy" );
array_thread( spawnpools, ::add_spawn_function, ::spawnfunc_enemy_wave_1_spawnpool, "secure_wave_1" );
if( !isdefined( spawnpools ))
{
AssertMsg( "No spawnpools available at secure intersection!" );
}
if( spawnpools.size < number_of_spawnpools )
{
AssertMsg( spawnpools.size + " out of the expected " + number_of_spawnpools + " spawnpools available" );
}
while( 1 )
{
if( flag( "flag_script_spawnpool_allow" ))
{
level.secure_enemies[ "ground" ] = array_removeDead( level.secure_enemies[ "ground" ] );
if( ( level.secure_enemies[ "ground" ].size + level.secure_enemies[ "ground_front_0" ].size ) < level.secure_ground_num_guys_allowed )
{
// Choose a random spawnpool and spawn
spawner = random( spawnpools );
ent = spawner spawn_ai();
if( isdefined( ent ))
{
level.secure_enemies[ "spawnpool" ] = add_to_array( level.secure_enemies[ "spawnpool" ], ent );
level.secure_enemies[ "ground" ] = add_to_array( level.secure_enemies[ "ground" ], ent );
}
}
}
wait 0.05;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Watches the whole vip_guard group
watcher_vip_guard()
{
level endon( "notify_secure_objective_complete" );
// SS almost dead flag has been set once
flag_ss_almost_dead = false;
// First SS agent to die
flag_ss_first_dead = true;
// Time between SS deaths
time_between_ss_deaths = 0;
// While SS guys are alive
while ( 1 )
{
level.secure_vip_guard[ "ss" ] = remove_dead_from_array( level.secure_vip_guard[ "ss" ] );
// Keep track of how many SS guys we used to have
last_num_ss_guys = level.secure_vip_guard[ "ss" ].size;
if( level.secure_vip_guard[ "ss" ].size == 0 )
{
// All SS dead
break;
}
if( flag( "flag_script_vip_guard_vulnerable_override" ))
{
// All SS almost dead!
if (( level.secure_vip_guard[ "ss" ].size < 3 ) && !flag_ss_almost_dead )
{
flag_set( "flag_script_vip_guard_almost_dead" );
// vip guard pulls back to area close to VP
foreach( guy in level.secure_vip_guard[ "ss" ] )
{
if( isalive( guy ))
{
guy set_force_color( "c" );
}
}
//display_hint_timeout( "hint_motorcade_vip_guard_almost_dead", 5.0 );
thread dialogue_vip_guard_almost_dead();
// Reset flag, message will only display once
flag_ss_almost_dead = true;
flag_clear( "flag_script_vip_guard_almost_dead" );
}
else if( level.secure_vip_guard[ "ss" ].size < last_num_ss_guys )
{
result = false;
if( flag( "flag_script_high_priority_dialogue_allow" ))
{
if( flag_ss_first_dead )
{
// First time an agent dies
// Dialogue: SS: "Agent down! Cover Patriot!"
result = radio_dialogue( "hithard_sslead_snipe_04" );
flag_ss_first_dead = false;
}
else if( ( level.secure_vip_guard[ "ss" ].size < (last_num_ss_guys - 2 )) && ( time_between_ss_deaths > 7 ))
{
// Reoccurring messages while SS guys die
line = random( level.secure_dialogue[ "ss_need_help" ] );
result = radio_dialogue_safe( line );
}
if( isdefined( result ))
{
if( result )
{
time_between_ss_deaths = 0;
}
}
}
}
}
wait_time = 0.05;
time_between_ss_deaths = time_between_ss_deaths + wait_time;
wait wait_time;
}
flag_set( "flag_script_vip_guard_dead" );
// Sic the enemies on the vip
level.secure_vip thread vip_hunt();
level.secure_vip waittill( "death" );
flag_set( "flag_secure_objective_failed" );
level notify( "notify_secure_objective_failed" );
objective_failed( "obj_secure_snipe", &"NX_HITHARD_SECURE_FAIL_VIP_GUARD_DEAD" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Enemies hunt down vip
vip_hunt()
{
self endon( "death" );
// Unprotect the vip
self stop_magic_bullet_shield();
self.ignoreme = false;
self.health = 1;
self set_fixednode_false();
self set_force_color( "g" );
self setthreatbiasgroup( "secure_vip_guard" );
// Make sure enemies focus on vip
set_squad_ignore( true );
// Set ground enemies to attack vip
foreach( guy in level.secure_enemies[ "ground" ] )
{
if( isalive( guy ))
{
self vip_hunt_setup();
}
}
// Wait, if enemies don't kill, then magic bullet will
wait 3.0;
origin_kill = GetEnt( "secure_vp_kill", "targetname" );
MagicBullet( "m9", origin_kill.origin, self.origin );
self kill();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Setup an enemy to hunt the vip
vip_hunt_setup()
{
self ClearGoalVolume();
self.favoriteenemy = level.secure_vip;
self SetGoalEntity( level.secure_vip);
}
//*******************************************************************
// *
// *
//*******************************************************************
// Turn on vulnerability for a group of allies
enable_hurt( special_hurt )
{
// Sets up a watcher func that waits for enemies to enter "danger zone"
thread watcher_enable_hurt_player_attention();
// Setup damage watcher
foreach( guy in self )
{
guy thread watcher_enable_hurt_solo( special_hurt );
}
// Have allies focus on closest enemies when necessary
foreach( guy in level.squad)
{
//guy thread watcher_squad_front_0_focus();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Turn off vulnerability for a group of allies
disable_hurt()
{
flag_clear( "flag_script_vip_guard_vulnerable_override" );
// Kill vulnerability scripts
level notify( "notify_secure_vip_not_vulnerable" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Dialogue for when all agents almost dead
dialogue_vip_guard_almost_dead()
{
flag_clear( "flag_script_low_priority_dialogue_allow" );
radio_dialogue_stop();
// Dialogue: SS: "We are down to two agents.<2E> We need support, NOW!<21>
radio_dialogue( "hithard_sslead_snipe_02" );
// Dialogue: Baker: "Cover Patriot!"
radio_dialogue( "hithard_bak_snipe_patriot" );
flag_set( "flag_script_low_priority_dialogue_allow" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Baker lets the player know that enemies are close to the VIP
watcher_enable_hurt_player_attention()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
level endon( "notify_secure_vip_not_vulnerable" );
while( 1 )
{
flag_wait( "flag_secure_vip_vulnerable" );
thread dialogue_baker_vip_vulnerable_player_attention();
flag_waitopen( "flag_secure_vip_vulnerable" );
// Kill dialogue
level notify( "notify_secure_vip_vulnerable_dialogue_stop" );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
dialogue_baker_vip_vulnerable_player_attention()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
level endon( "notify_secure_vip_vulnerable_dialogue_stop" );
level endon( "notify_secure_vip_not_vulnerable" );
flag_wait( "flag_script_high_priority_dialogue_allow" );
if( level.secure_vip_vulnerable_first_time )
{
level.secure_vip_vulnerable_first_time = false;
radio_dialogue_stop();
// Dialogue: Baker: "Tangos are close to Patriot!"
radio_dialogue( "hithard_bak_secure_44" );
}
while( 1 )
{
wait_random_time( 5, 10 );
//level._player thread display_hint( "hint_secure_vulnerable" );
play_random_dialogue( level.secure_dialogue[ "baker_vip_vulnerable" ] );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// enables attention pointer
enableAttentionPointer( pointer_object, target, objective_number )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
flag_set( "_flag_script_attention_pointer_active" );
while( flag( "_flag_script_attention_pointer_active" ))
{
move_time = 0;
if( !player_looking_at( target.origin, 0.95 ))
{
// Move pointer to in front of player
pointer_object.origin = GetPlayerSightPosition( Distance( level._player.origin, target.origin ));
// Pointer to player
Objective_OnEntity( objective_number, pointer_object );
if( Distance( target.origin, pointer_object.origin ) < Distance( level._player.origin, target.origin ))
{
move_time = 1.0;
}
else
{
move_time = 2.0;
}
pointer_object Moveto( target.origin, move_time );
wait move_time;
Objective_OnEntity( objective_number, target );
}
wait 0.05;
}
Objective_OnEntity( objective_number, target );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Turns off player attention pointer
DisableAttentionPointer()
{
flag_clear( "_flag_script_attention_pointer_active" );
}
//*******************************************************************
// *
// *
//*******************************************************************
GetPlayerSightPosition( distance )
{
return level._player GetEye() + vector_multiply( AnglesToForward( level._player GetPlayerAngles() ), distance );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Set accuracy of an array of guys
set_ai_accuracy_array( accuracy_num )
{
foreach( guy in self )
{
if( isalive( guy ))
{
guy.baseaccuracy = accuracy_num;
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Set accuracy of an guy
set_ai_accuracy( accuracy_num )
{
if( isalive( self ))
{
self.baseaccuracy = accuracy_num;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn a wave of enemies
spawn_enemy_wave( enemy_noteworthy_name, spawnfunc, threatbias_group, dialogue_array )
{
// Setup spawner with script_noteworthy of "enemy_noteworthy_name"
secure_enemies_spawner = GetEntArray( enemy_noteworthy_name, "script_noteworthy" );
array_thread( secure_enemies_spawner, ::add_spawn_function, spawnfunc, threatbias_group );
secure_enemies = [];
secure_enemies = array_spawn( secure_enemies_spawner );
// Check spawns against spawners
if ( IsDefined( secure_enemies ))
{
if ( secure_enemies.size < secure_enemies_spawner.size )
{
AssertMsg( secure_enemies_spawner.script_noteworthy + ": Could not spawn ALL enemies: " + secure_enemies.size + "/" + secure_enemies_spawner.size );
}
}
else
{
AssertMsg( "Could not spawn enemies..." );
}
// If there is callout dialogue
if( IsDefined( dialogue_array ))
{
// Set the hatred
secure_enemies thread dialogue_baker_wave_callout( enemy_noteworthy_name, dialogue_array );
}
return secure_enemies;
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for secure enemies
spawnfunc_enemy_cortel_terrace( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
self.grenadeammo = 0;
self.goalradius = level.secure_special_goalradius;
self.a.disableLongDeath = true;
self.ignoreme = true;
self set_ai_accuracy( 0.01 );
self thread watcher_enemy_death_counter();
self thread waittill_goal_notify( self.script_noteworthy );
}
//*******************************************************************
// *
// *
//*******************************************************************
spawnfunc_enemy_cortel_balcony( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
self.grenadeammo = 0;
self.goalradius = level.secure_special_goalradius;
self.a.disableLongDeath = true;
self.ignoreall = true;
self.ignoreme = true;
self set_ai_accuracy( 0.01 );
self thread watcher_enemy_death_counter();
self thread spawnfunc_enemy_cortel_watcher();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Logic for cortel inside RPG guys
spawnfunc_enemy_cortel_watcher()
{
self endon( "death" );
billboard_nodes = GetEntArray( "origin_billboard_killer", "targetname" );
self waittill( "reached_path_end" );
// Give him a moment so he doesn't blow himself up
wait 1.0;
// Blow out the windows
weapon_origin = self GetTagOrigin( "TAG_WEAPON_LEFT" ) + vector_multiply( AnglesToForward( self.angles ), 10 );
// Shoot billboard first
randomTarget = random( billboard_nodes );
MagicBullet( "rpgx_straight", weapon_origin, randomTarget.origin );
self.ignoreall = false;
level notify( "notify_" + self.script_noteworthy + "_at_goal" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for secure enemies
spawnfunc_enemy_cortel_inside( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
self.grenadeammo = 0;
self.ignoreall = true;
self.goalradius = level.secure_special_goalradius;
self.a.disableLongDeath = true;
self.ignoreme = true;
self set_ai_accuracy( 0.01 );
destroyOriginTarget = "node_origin_cortel_window_" + self.target;
goToNodeTarget = self.target + "2";
self thread watcher_enemy_death_counter();
self thread spawnfunc_enemy_cortel_inside_watcher( destroyOriginTarget, goToNodeTarget);
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for secure enemies
spawnfunc_enemy_bon( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
self.grenadeammo = 0;
self.goalradius = level.secure_special_goalradius;
self.a.disableLongDeath = true;
self AllowedStances( "stand" );
self set_ai_accuracy( level.secure_enemy_accuracy_bon );
self thread watcher_enemy_bon();
self thread watcher_enemy_death_counter();
}
//*******************************************************************
// *
// *
//*******************************************************************
watcher_enemy_bon()
{
wait 2.0;
level notify( "notify_" + self.script_noteworthy + "_at_goal" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for wave_1 regular (first wave)
spawnfunc_enemy_ground_first( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
self thread magic_bullet_shield();
self.a.disableLongDeath = true;
self.script_parameters = "front_0";
self.grenadeammo = 0;
//self SetThreatIDOverlay( "auto" );
self set_ai_accuracy( 2.0 );
self set_fixednode_true();
self thread watcher_enemy_death_counter();
self thread spawnfunc_enemy_ground_first_damage_watcher();
}
//*******************************************************************
// *
// *
//*******************************************************************
// If wave_1 guy is shot, make him move to a new position
spawnfunc_enemy_ground_first_damage_watcher()
{
self endon( "death" );
self endon( "notify_secure_go_forth_and_die" );
self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, idFlags );
self set_fixednode_false();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for wave_1 spawnpool (advancing on the ground)
spawnfunc_enemy_wave_1_spawnpool( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
self.a.disableLongDeath = true;
self.grenadeammo = 0;
self.script_parameters = "front_0";
self.goalradius = level.secure_standard_goalradius;
level.num_enemies_spawned++;
self thread watcher_enemy_death_counter();
self go_to_goal_volume( "front_1" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for wave_1 secure enemies from vtol (advancing on the ground)
spawnfunc_enemy_wave_1_vtol( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
level.secure_enemies[ "ground" ] = add_to_array( level.secure_enemies[ "ground" ], self );
self.grenadeammo = 0;
self.goalradius = level.secure_standard_goalradius;
self.script_parameters = "front_0";
//self SetThreatIDOverlay( "auto" );
self thread watcher_enemy_death_counter();
self thread spawnfunc_enemy_wave_1_vtol_watcher();
}
//*******************************************************************
// *
// *
//*******************************************************************
// watcher function for rpg guy
spawnfunc_enemy_wave_1_vtol_watcher( target )
{
self endon( "death" );
self waittill( "jumpedout" );
self.a.disableLongDeath = true;
self go_to_goal_volume( "front_1" );
if( self.classname == "actor_nx_opfor_china_specops_rpg" )
{
self forceUseWeapon( "asmk27_reflex", "secondary" );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// spawn function for guy who comes in at start and fires RPG at lapd car
spawnfunc_enemy_wave_1_lapd_rpg( threatbias_group, target )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
self.a.disableLongDeath = true;
self.grenadeammo = 0;
self.goalradius = 128;
self.ignoreall = true;
level.secure_enemies[ "ground" ] = add_to_array( level.secure_enemies[ "ground" ], self );
self thread spawnfunc_enemy_wave_1_lapd_rpg_watcher( target );
self thread watcher_enemy_death_counter();
}
//*******************************************************************
// *
// *
//*******************************************************************
// watcher function for rpg guy
spawnfunc_enemy_wave_1_lapd_rpg_watcher( target )
{
self endon( "death" );
//weapon_origin = self GetTagOrigin( "TAG_WEAPON_LEFT" );
//MagicBullet( "rpgx_straight", weapon_origin, level.vehicles[ "lapd_backup" ].origin );
self set_fixednode_false();
self.ignoreall = false;
self go_to_goal_volume( "front_1" );
self waittill( "goal" );
//self SetThreatIDOverlay( "auto" );
self forceUseWeapon( "asmk27_reflex", "secondary" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for lapd car riding guys
spawnfunc_ally_swat_backup( threatbias_group )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
self setthreatbiasgroup( threatbias_group );
self.baseaccuracy = 0.01;
self.grenadeammo = 0;
self.health = 300;
self.goalradius = level.secure_vip_guard_goalradius;
level.secure_vip_guard[ "swat" ] = add_to_array( level.secure_vip_guard[ "swat" ], self );
level.secure_vip_guard[ "all" ] = add_to_array( level.secure_vip_guard[ "all" ], self );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn function for enemy UAVs
spawnfunc_enemy_uav( threatbias_group )
{
self endon( "death" );
self setthreatbiasgroup( threatbias_group );
level.secure_enemies[ "uavs" ] = add_to_array( level.secure_enemies[ "uavs" ], self );
self thread magic_bullet_shield();
self thread watcher_enemy_uav_death_solo();
self thread watcher_enemy_uav_solo();
}
//*******************************************************************
// *
// *
//*******************************************************************
watcher_enemy_uav_death_solo()
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
self waittill( "death" );
result = false;
if( !level.secure_uav_duke_dialog_done )
{
if( flag( "flag_script_low_priority_dialogue_allow" ) )
{
play_random_dialogue_positional( level.secure_dialogue[ "duke_uav_random" ], "duke" );
level.secure_uav_duke_dialog_done = true;
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// UAV logic for rooftop attack
watcher_enemy_uav_solo()
{
self endon( "death" );
wait 0.5;
self stop_magic_bullet_shield();
// Fly up to rooftop perch to wait
self vehicle_detachfrompath();
self.currentnode = random( level.secure_uav_path[ "circle2" ] );
level.secure_uav_path[ "circle2" ] = arraY_remove( level.secure_uav_path[ "circle2" ], self.currentnode );
self thread vehicle_resumepath();
self GoPath();
wait 0.5;
// Go up to player one at a time (unless two are left, then two will go)
while(( isalive_array( level.secure_enemies[ "uavs_attack" ] ) > 0 ) && ( isalive_array( level.secure_enemies[ "uavs" ] ) > 2 ))
{
wait 0.05;
}
flag_set( "flag_script_uav_attack_roof" );
// Consider the uav an "attacking" uav
level.secure_enemies[ "uavs_attack" ] = add_to_array( level.secure_enemies[ "uavs_attack" ], self );
// Choose circle node up by rooftop and go
circle = random( level.secure_uav_path[ "circle1" ] );
self thread maps\_attack_heli::SAV_switch_to_circling( circle.targetname );
wait_random_time( 5, 10 );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Dialogue for UAVs
dialogue_baker_uavs()
{
flag_clear( "flag_script_low_priority_dialogue_allow" );
radio_dialogue_stop();
// Dialogue: Baker: " UAVs!"
//radio_dialogue( "hithard_bak_secure_30" );
// Dialogue: Baker: "UAVs incoming! Take cover!"
radio_dialogue( "hithard_bak_snipe_08" );
flag_set( "flag_script_low_priority_dialogue_allow" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// UAVs drop smoke
watcher_enemy_uav_smoke_drop_solo()
{
level endon( "notify_secure_objective_wave_2_complete" );
// Drop the smoke
origin = self.origin;
MagicGrenade( "smoke_grenade_miniuav", self.origin, self.origin + ( 0, 0, -10 ), 0.01 );
level.num_uav_smoke_dropped++;
flag_set( "flag_script_uav_dropped_smoke" );
wait 10;
// Keep smoke active while wave_2 is active
while( level.secure_enemies[ "ground" ].size > 3 )
{
wait 19;
PlayFx( level._effect[ "nx_grenade_smoke_5sec" ], ( origin[ 0 ], origin[ 1 ], -128 ));
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn smoke on ground
spawn_smoke()
{
origins = GetEntArray( "secure_ground_smoke", "script_noteworthy" );
level._player waittill( "notify_rappel_start" );
thread watcher_enemy_spawnpool();
thread watcher_enemy_spawnpool_off( level.secure_wave_2_num_enemies );
thread send_in_spawnpool( 5 );
// Dialogue: Baker: "They<65>re dropping smoke!<21>
radio_dialogue( "hithard_bak_snipe_34" );
foreach( origin in origins )
{
thread spawn_smoke_solo_watcher( origin );
wait_random_time( 0, 2 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Individual smoke fx loops
spawn_smoke_solo_watcher( origin )
{
level endon( "notify_secure_objective_wave_2_complete" );
origin playsound("smokegrenade_explode_default");
// Keep smoke active while wave_2 is active
while( 1 )
{
PlayFx( level._effect[ "nx_grenade_smoke_5sec" ], ( origin.origin[ 0 ], origin.origin[ 1 ], -128 ));
wait 8;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
go_forth_and_die_ground( array, num )
{
while( ( level.secure_enemies[ "ground_front_0" ].size < num ) && ( array.size > 0 ))
{
level.secure_enemies[ "ground_front_0" ] = remove_dead_from_array( level.secure_enemies[ "ground_front_0" ] );
guy = random( array );
guy go_forth_and_die_ground_solo();
array = array_remove( array, guy );
}
return array;
}
//*******************************************************************
// *
// *
//*******************************************************************
go_forth_and_die_ground_solo()
{
self endon( "death" );
self notify( "notify_secure_go_forth_and_die" );
//self SetThreatIDOverlay( "auto" );
level.secure_enemies[ "ground_front_0" ] = add_to_array( level.secure_enemies[ "ground_front_0" ], self );
self setthreatbiasgroup( "secure_wave_1_front_0" );
self.script_parameters = "front_0";
self ClearGoalVolume();
self.goalradius = 512;
self.aggressivemode = 1;
self.baseaccuracy = 1000;
self set_fixednode_false();
self.script_forcegoal = 1;
self set_force_color( "p" );
//self set_fixednode_true();
//self enable_cqbwalk();
}
//*******************************************************************
// *
// *
//*******************************************************************
go_forth_and_die( array )
{
foreach( guy in array )
{
if( isalive( guy ))
{
guy = random( array );
guy go_forth_and_die_solo();
array = array_remove( array, guy );
}
wait 0.05;
}
return array;
}
//*******************************************************************
// *
// *
//*******************************************************************
go_forth_and_die_solo()
{
self endon( "death" );
self notify( "notify_secure_go_forth_and_die" );
level.secure_enemies[ "ground_front_0" ] = add_to_array( level.secure_enemies[ "ground_front_0" ], self );
self setthreatbiasgroup( "secure_wave_1_front_0" );
self.script_parameters = "front_0";
self.goalradius = 512;
self.aggressivemode = 1;
self.baseaccuracy = 1000;
self set_fixednode_false();
self.script_forcegoal = 1;
self go_to_goal_volume( "front_0" );
//self set_fixednode_true();
//self enable_cqbwalk();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Watches wave_1 enemies and adds to the death counter if the player kills them
watcher_enemy_death_counter()
{
level endon( "notify_secure_objective_complete" );
attacker = undefined;
partName = undefined;
while( isalive( self ))
{
self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, idFlags );
}
// Find out who killed the dude
//iprintlnbold( self.script_noteworthy + ": " + attacker.classname );
if( isdefined( attacker.classname ))
{
switch( attacker.classname )
{
case "player":
{
level.secure_kill_tracker[ "player" ]++;
break;
}
case "actor_nx_ally_us_specops_leader_pchute":
{
level.secure_kill_tracker[ "baker" ]++;
break;
}
case "actor_nx_ally_us_specops_squadmate_pchute":
{
level.secure_kill_tracker[ "duke" ]++;
break;
}
case "actor_nx_ally_us_secretservice":
{
level.secure_kill_tracker[ "ss" ]++;
break;
}
default:
{
level.secure_kill_tracker[ "other" ]++;
break;
}
}
}
// Wave_1 killing spree objective: Player delivers finishing blow, gets credit
if( IsPlayer( attacker ))
{
/*
if( partName == "j_head" )
{
dialogue_baker_encouragement( "headshot" );
}
else
{
dialogue_baker_encouragement();
}
*/
//dialogue_baker_encouragement();
level.secure_human_enemies_num_killed++;
level notify( "secure_enemy_killed" );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn vip guy
spawn_vip( guy_noteworthy, spawnfunc, threatbias )
{
vp_spawner = getent( guy_noteworthy, "script_noteworthy" );
vp_spawner add_spawn_function( spawnfunc, threatbias );
vip = vp_spawner spawn_ai();
return vip;
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn vip protection guard
// group_noteworthy = the script_noteworthy of the vip spawners
// group_type = "swat" or "secret_service"
spawn_vip_guard( group_noteworthy, group_type, number )
{
// Container for spawned guys
secure_vip_guard = [];
// Grab all of entities with the group's script_noteworthy
secure_vip_guard_spawner = GetEntArray( group_noteworthy, "script_noteworthy" );
// Check to make sure there are enough names for spawned allies
if ( secure_vip_guard_spawner.size > level.secure_vip_guard_names.size )
{
AssertMsg( "Not enough names for vip secure guard guys (spawners: " + secure_vip_guard_spawner + ", Names: " + level.secure_vip_guard_names.size );
}
foreach( guy in secure_vip_guard_spawner )
{
// Assign script_friendname to guard members
if( group_type == "swat" )
{
guy set_script_friendname( "Officer" );
array_spawn_function( secure_vip_guard_spawner, ::spawnfunc_ally_swat, "secure_vip_guard" );
}
else if( group_type == "secret_service" )
{
guy set_script_friendname( "Agent" );
array_spawn_function( secure_vip_guard_spawner, ::spawnfunc_ally_ss, "secure_vip_guard" );
}
wait 0.05;
}
secure_vip_guard = [];
//Spawn
if( isdefined( number ))
{
for( i = 0; i < number; i++ )
{
spawned = secure_vip_guard_spawner[0] spawn_ai();
secure_vip_guard = add_to_array( secure_vip_guard, spawned );
}
}
else
{
secure_vip_guard = array_spawn( secure_vip_guard_spawner );
// Make sure secure vip guard guys spawned ok
if ( IsDefined( secure_vip_guard ))
{
if ( secure_vip_guard.size != secure_vip_guard_spawner.size )
{
AssertMsg( group_noteworthy + ": Could not spawn ALL vip guard: " + secure_vip_guard.size + "/" + secure_vip_guard_spawner.size );
}
}
else
{
AssertMsg( "Could not spawn secure allies..." );
}
}
return secure_vip_guard;
}
//*******************************************************************
// *
// *
//*******************************************************************
// Create name and return
set_script_friendname( guy_title )
{
guy_name = random( level.secure_vip_guard_names );
level.secure_vip_guard_names = array_remove( level.secure_vip_guard_names, guy_name );
// Assign name
self.script_friendname = guy_title + " " + guy_name;
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn Function for vip guard guys
spawnfunc_ally_swat( threatbias_group )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
self setthreatbiasgroup( threatbias_group );
self.baseaccuracy = 0.01;
self.grenadeammo = 0;
self.health = 300;
self.goalradius = level.secure_vip_guard_goalradius;
self enable_cqbwalk();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn Function for vip
spawnfunc_ally_vip( threatbias_group )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
self maps\nx_hithard_anim::init_vp_anims();
self.dontmelee = true;
self.animname = "vp";
if( isdefined( threatbias_group ))
{
self setthreatbiasgroup( threatbias_group );
}
self.goalradius = level.secure_civilian_goalradius;
self set_fixednode_true();
self thread magic_bullet_shield();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Spawn Function for vip guard guys
spawnfunc_ally_ss( threatbias_group )
{
level endon( "notify_secure_objective_complete" );
level endon( "notify_secure_objective_failed" );
self setthreatbiasgroup( threatbias_group );
self.baseaccuracy = 0.01;
self.grenadeammo = 0;
self.health = 300;
self.goalradius = level.secure_vip_guard_goalradius;
if( level.secure_ss_cant_die < 2 )
{
self.script_parameters = "debug_cant_die";
level.secure_ss_cant_die++;
}
if( self.script_noteworthy == "motorcade_vip_guard_1" )
{
self set_fixednode_true();
}
else
{
self.aggressivemode = 1;
}
self enable_cqbwalk();
self prep_ss_motorcade();
}
//*******************************************************************
// *
// *
//*******************************************************************
// Tracks damage on individual vip guard guy
watcher_enable_hurt_solo( special_hurt )
{
level endon( "notify_secure_vip_not_vulnerable" );
level endon( "notify_secure_vip_not_vulnerable_solo" );
self endon( "death" );
if( isdefined( self.script_parameters ))
{
if( self.script_parameters == "debug_cant_die" )
{
return;
}
}
// Wait grace period time
wait level.secure_vip_vulnerable_grace_time;
// Wait until an enemy is in front of the vip guard, then make vip guard vulnerable to said enemy
while( 1 )
{
self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, idFlags );
if( attacker == level._player )
{
// The player shot
self damage_vip_guard( damage );
if( flag( "flag_script_high_priority_dialogue_allow" ))
{
// Dialogue: Baker: "Specter, check your fire!"
radio_dialogue_stop();
radio_dialogue_interupt( "hithard_bak_snipe_check" );
}
}
else if( isdefined( attacker.script_noteworthy ))
{
if( isdefined( special_hurt ))
{
if( attacker.script_noteworthy == special_hurt )
{
// Bonaventure sniper's shot
self damage_vip_guard( 99999 );
}
}
else if( flag( "flag_secure_vip_vulnerable" ) || flag( "flag_script_vip_guard_vulnerable_override" ))
{
// Someone shot, is it an allowable "damager"?
if( isdefined( attacker.script_parameters ))
{
if( attacker.script_parameters == "front_0" )
{
self damage_vip_guard( damage );
}
}
}
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Hurt a vip
damage_vip_guard( damage )
{
// Attacker is within range, damage or kill SS agent (based on amount of damage)
if( self.health <= damage )
{
self stop_magic_bullet_shield();
//iprintlnbold( "A Secret Serviceman has died! (Placeholder)" );
self kill();
}
else
{
self.health = self.health - damage;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// VTOL flies in and drops UAVs
event_vtol_uav_drop()
{
vtol_uav_spawners = GetEntArray( "vtol_miniuav", "targetname" );
//level.secure_uav_path[ "smoke" ] = GetStructArray( "uav_smoke_path", "script_noteworthy" );
level.secure_uav_path[ "circle1" ] = GetNodeArray( "uav_circle_path", "script_noteworthy" );
level.secure_uav_path[ "circle2" ] = GetStructArray( "uav_circle_path2", "script_noteworthy" );
// Spawn and go
array_thread( vtol_uav_spawners, ::add_spawn_function, ::spawnfunc_enemy_uav, "secure_wave_uavs" );
flag_set( "start_vtol_miniuav_unload" );
waittillframeend;
vtol2_sfx = Get_Vehicle( "ec_vtol_miniuav_deploy_vtol", "targetname" );
vtol2_sfx playsound( "scn_hhh_vtol_flyin03" );
}
//*******************************************************************
// *
// *
//*******************************************************************