mirror of
https://github.com/reaaLx/nx1-gsc-dump.git
synced 2025-04-22 17:15:48 +00:00
3696 lines
113 KiB
Plaintext
3696 lines
113 KiB
Plaintext
//****************************************************************************
|
||
// **
|
||
// 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" );
|
||
|
||
|
||
}
|
||
|
||
//*******************************************************************
|
||
// *
|
||
// *
|
||
//*******************************************************************
|
||
|
||
|