4535 lines
125 KiB
Text
4535 lines
125 KiB
Text
|
/****************************************************************************
|
|||
|
Level: Launch Facility #1
|
|||
|
Campaign: Marine Force Recon
|
|||
|
****************************************************************************/
|
|||
|
#include common_scripts\utility;
|
|||
|
#include maps\_utility;
|
|||
|
#include maps\_anim;
|
|||
|
#include maps\_vehicle;
|
|||
|
#include maps\jake_tools;
|
|||
|
#using_animtree("generic_human");
|
|||
|
|
|||
|
main()
|
|||
|
{
|
|||
|
if ( getdvar( "r_reflectionProbeGenerate" ) == "1" )
|
|||
|
return;
|
|||
|
|
|||
|
setsaveddvar( "r_specularcolorscale", "1.2" );
|
|||
|
if (getdvar("debug_bmp") == "")
|
|||
|
setdvar("debug_bmp", "0");
|
|||
|
if (getdvar("debug_launch") == "")
|
|||
|
setdvar("debug_launch", "0");
|
|||
|
|
|||
|
initPrecache();
|
|||
|
createThreatBiasGroup( "player" );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
LEVEL VARIABLES
|
|||
|
-------------------------*/
|
|||
|
level.team01 = [];
|
|||
|
level.team02 = [];
|
|||
|
level.team03 = [];
|
|||
|
level.cosine[ "45" ] = cos( 45 );
|
|||
|
level.balconyflag = getent( "balcony_flag", "script_noteworthy" );
|
|||
|
level.bmpExcluders = [];
|
|||
|
level.hindAttacker = undefined;
|
|||
|
level.peoplespeaking = false;
|
|||
|
level.team01breacher = undefined;
|
|||
|
level.team02breacher = undefined;
|
|||
|
level.team03breacher = undefined;
|
|||
|
level.sniperkills = 0;
|
|||
|
level.sniperConfirmDialogue = true;
|
|||
|
level.sniperTarget = undefined;
|
|||
|
level.sniperInterval = 5;
|
|||
|
level.snipersActive = false;
|
|||
|
level.playerMaxDistanceToBMPC4 = 256;
|
|||
|
level.playerMaxDistanceToBMPC4squared = level.playerMaxDistanceToBMPC4 * level.playerMaxDistanceToBMPC4;
|
|||
|
level.playerMaxDistanceFromBMP = 1024;
|
|||
|
level.playerMaxDistanceFromBMPsquared = level.playerMaxDistanceFromBMP * level.playerMaxDistanceFromBMP;
|
|||
|
level.playerDistanceToAI = 256;
|
|||
|
level.playerDistanceToAIsquared = level.playerDistanceToAI * level.playerDistanceToAI;
|
|||
|
level.axisKilledByPlayer = 0;
|
|||
|
level.playerParticipationContainer = 10;
|
|||
|
level.playerParticipationGate = 15;
|
|||
|
level.minBMPexplosionDmg = 50;
|
|||
|
level.maxBMPexplosionDmg = 100;
|
|||
|
level.bmpCannonRange = 2048;
|
|||
|
level.bmpMGrange = 850;
|
|||
|
level.bmpMGrangeSquared = level.bmpMGrange * level.bmpMGrange;
|
|||
|
level.playerVehicleDamageRange = 256;
|
|||
|
level.playerVehicleDamageRangeSquared = level.playerVehicleDamageRange * level.playerVehicleDamageRange;
|
|||
|
level.ent = undefined;
|
|||
|
level.AIdeleteDistance = 512;
|
|||
|
level.enemyArmor = [];
|
|||
|
level.enemyArmorIndex = 0;
|
|||
|
level.maxFriendliesKilled = 2;
|
|||
|
level.cosine = [];
|
|||
|
level.cosine["35"] = cos(35);
|
|||
|
level.cosine["45"] = cos(45);
|
|||
|
level.cosine["180"] = cos(180);
|
|||
|
level.color["white"] = (1, 1, 1);
|
|||
|
level.color["red"] = (1, 0, 0);
|
|||
|
level.color["blue"] = (.1, .3, 1);
|
|||
|
level.c4_callback_thread = ::c4_callback_thread_launchfacility;
|
|||
|
level.spawnerCallbackThread = ::AI_think;
|
|||
|
level.excludedAi = [];
|
|||
|
level.aColornodeTriggers = [];
|
|||
|
trigs = getentarray("trigger_multiple", "classname");
|
|||
|
for(i=0;i<trigs.size;i++)
|
|||
|
{
|
|||
|
if ( ( isdefined(trigs[i].script_noteworthy) ) && ( getsubstr(trigs[i].script_noteworthy, 0, 10) == "colornodes" ) )
|
|||
|
level.aColornodeTriggers = array_add(level.aColornodeTriggers, trigs[i]);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
STARTS
|
|||
|
-------------------------*/
|
|||
|
add_start("container", ::start_container, &"STARTS_CONTAINER" );
|
|||
|
add_start("tarmac", ::start_tarmac, &"STARTS_TARMAC" );
|
|||
|
add_start("gate", ::start_gate, &"STARTS_GATE" );
|
|||
|
add_start("vents", ::start_vents, &"STARTS_VENTS" );
|
|||
|
default_start(::start_default );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GLOBAL SCRIPTS
|
|||
|
-------------------------*/
|
|||
|
level.weaponClipModels = [];
|
|||
|
level.weaponClipModels[0] = "weapon_m16_clip";
|
|||
|
level.weaponClipModels[1] = "weapon_saw_clip";
|
|||
|
level.weaponClipModels[2] = "weapon_ak47_clip";
|
|||
|
level.weaponClipModels[3] = "weapon_dragunov_clip";
|
|||
|
level.weaponClipModels[4] = "weapon_g3_clip";
|
|||
|
level.weaponClipModels[5] = "weapon_g36_clip";
|
|||
|
|
|||
|
maps\createart\launchfacility_a_art::main();
|
|||
|
maps\_hind::main("vehicle_mi24p_hind_woodland");
|
|||
|
maps\_bm21::main("vehicle_bm21_mobile");
|
|||
|
maps\_bmp::main("vehicle_bmp_woodland");
|
|||
|
maps\_mig29::main( "vehicle_mig29_desert" );
|
|||
|
maps\_blackhawk::main("vehicle_blackhawk");
|
|||
|
level thread maps\launchfacility_a_fx::main();
|
|||
|
maps\_c4::main();
|
|||
|
thread maps\_leak::main();
|
|||
|
thread maps\_pipes::main();
|
|||
|
maps\_load::main();
|
|||
|
maps\launchfacility_a_anim::main();
|
|||
|
maps\_nightvision::main();
|
|||
|
maps\_javelin::init();
|
|||
|
maps\_compass::setupMiniMap("compass_map_launchfacility_a");
|
|||
|
|
|||
|
level thread maps\launchfacility_a_amb::main();
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
FLAGS
|
|||
|
-------------------------*/
|
|||
|
flag_init( "aa_first_bmp_section" );
|
|||
|
flag_init( "aa_container_to_gate_section" );
|
|||
|
flag_init( "aa_tarmac_bmp01_section" );
|
|||
|
flag_init( "aa_tarmac_bmp02_section" );
|
|||
|
|
|||
|
flag_init("bmp_02_spawned");
|
|||
|
flag_init("bmp_03_spawned");
|
|||
|
flag_init("bmp_04_spawned");
|
|||
|
|
|||
|
//objectives
|
|||
|
flag_init("obj_gain_access_given");
|
|||
|
flag_init("obj_gain_access_complete");
|
|||
|
flag_init("obj_enemy_armor_given");
|
|||
|
flag_init("obj_enemy_armor_complete");
|
|||
|
flag_init("obj_north_tarmac_given");
|
|||
|
flag_init("obj_north_tarmac_complete");
|
|||
|
flag_init("obj_rappel_given");
|
|||
|
flag_init("obj_rappel_complete");
|
|||
|
|
|||
|
//approach & container
|
|||
|
flag_init( "container_loudspeaker" );
|
|||
|
flag_init("friendly_shoots_down_heli");
|
|||
|
flag_init("friendly_shoots_down_heli_new");
|
|||
|
flag_init("enemy_can_blow_up_truck");
|
|||
|
flag_init("hind_intro_dialogue");
|
|||
|
flag_init("friendlies_past_killzone");
|
|||
|
flag_init("inside_perimeter");
|
|||
|
flag_init("stop_alarm");
|
|||
|
flag_init("hind_crash");
|
|||
|
flag_init("heli_attractor_deleted");
|
|||
|
flag_init("flanking_wall_breached");
|
|||
|
flag_init("blow_the_gate");
|
|||
|
flag_init("bmp_02_destroyed");
|
|||
|
flag_init("gate_sequence_starting");
|
|||
|
flag_init("migs_flyby1");
|
|||
|
flag_init("migs_flyby2");
|
|||
|
flag_init( "music_gimme_sitrep" );
|
|||
|
|
|||
|
//tarmac
|
|||
|
flag_init("bmp_03_destroyed");
|
|||
|
flag_init("bmp_04_destroyed");
|
|||
|
flag_init("one_bmp_left");
|
|||
|
|
|||
|
//vents
|
|||
|
flag_init("blackhawk_dudes_unloaded");
|
|||
|
flag_init("hinds_appear");
|
|||
|
flag_init("hind_rocket_sequence");
|
|||
|
flag_init("hind_missiles_fired");
|
|||
|
flag_init("vent01_open");
|
|||
|
flag_init("vent02_open");
|
|||
|
flag_init("vent03_open");
|
|||
|
flag_init("rappel_started");
|
|||
|
flag_init("team01_hooked_up");
|
|||
|
flag_init("team02_hooked_up");
|
|||
|
flag_init("team03_hooked_up");
|
|||
|
|
|||
|
//misc
|
|||
|
flag_init("player_reached_kill_max");
|
|||
|
flag_init("level_fade_out");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GLOBAL THREADS
|
|||
|
-------------------------*/
|
|||
|
initDifficulty();
|
|||
|
initPlayer();
|
|||
|
vehicle_patrol_init();
|
|||
|
disable_color_trigs();
|
|||
|
hideAll();
|
|||
|
launch_lid_setup();
|
|||
|
thread migs_flyby1();
|
|||
|
thread migs_flyby2();
|
|||
|
thread sniper_activity();
|
|||
|
array_thread( getvehiclenodearray( "plane_sound", "script_noteworthy" ), maps\_mig29::plane_sound_node );
|
|||
|
array_thread( getentarray( "hostiles_container_runners", "script_noteworthy" ), ::add_spawn_function, ::AI_chain_and_seek );
|
|||
|
array_thread( getentarray( "hostiles_player_seek", "script_noteworthy" ), ::add_spawn_function, ::AI_player_seek );
|
|||
|
array_thread( getentarray( "hostiles_vehicle_support", "script_noteworthy" ), ::add_spawn_function, ::AI_vehicle_support );
|
|||
|
array_thread( getentarray( "enemy_rpd", "script_noteworthy" ), ::add_spawn_function, ::AI_enemy_RPD );
|
|||
|
//array_thread( getentarray( "vehicle_path_disconnector", "targetname" ), ::vehicle_path_disconnector );
|
|||
|
|
|||
|
aVehicles_BMP_targetnames = [];
|
|||
|
aVehicles_BMP_targetnames[0] = "bmp_02";
|
|||
|
aVehicles_BMP_targetnames[1] = "bmp_03";
|
|||
|
aVehicles_BMP_targetnames[2] = "bmp_04";
|
|||
|
thread vehicle_bmp_setup( aVehicles_BMP_targetnames );
|
|||
|
thread vehicle_truck_setup();
|
|||
|
aC4_plants = getentarray( "c4_plant", "targetname" );
|
|||
|
if ( aC4_plants.size > 0 )
|
|||
|
array_thread( aC4_plants, ::c4_plant_think);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DEBUG
|
|||
|
-------------------------*/
|
|||
|
//thread debug();
|
|||
|
}
|
|||
|
|
|||
|
debug()
|
|||
|
{
|
|||
|
thread print3Dthread("X", (-6271, -16779,-964), 10);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
START FUNCTIONS
|
|||
|
****************************************************************************/
|
|||
|
start_default()
|
|||
|
{
|
|||
|
AA_approach_init();
|
|||
|
//start_container();
|
|||
|
//start_gate();
|
|||
|
//start_tarmac();
|
|||
|
//start_vents();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
start_container()
|
|||
|
{
|
|||
|
initFriendlies("container");
|
|||
|
}
|
|||
|
|
|||
|
start_gate()
|
|||
|
{
|
|||
|
initFriendlies("gate");
|
|||
|
AA_gate_init();
|
|||
|
wait(0.5);
|
|||
|
flag_set("bmp_02_destroyed");
|
|||
|
}
|
|||
|
|
|||
|
start_tarmac()
|
|||
|
{
|
|||
|
initFriendlies("tarmac");
|
|||
|
}
|
|||
|
|
|||
|
start_vents()
|
|||
|
{
|
|||
|
initFriendlies("vents");
|
|||
|
AA_vents_init();
|
|||
|
}
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
LEVEL START: APPROACH
|
|||
|
****************************************************************************/
|
|||
|
AA_approach_init()
|
|||
|
{
|
|||
|
flag_set( "aa_first_bmp_section" );
|
|||
|
|
|||
|
thread loudspeaker();
|
|||
|
thread music_intro();
|
|||
|
thread launchfacility_a_intro_dvars();
|
|||
|
thread AA_gate_init();
|
|||
|
initFriendlies("default");
|
|||
|
thread dialogue_intro();
|
|||
|
thread dialogue_c4_hints();
|
|||
|
battlechatter_off( "allies" );
|
|||
|
triggersEnable("colornodes_approach", "script_noteworthy", true);
|
|||
|
triggersEnable("colornodes_container", "script_noteworthy", true);
|
|||
|
thread friendlies_blow_bmp02();
|
|||
|
thread alarm_sound_thread();
|
|||
|
thread obj_gain_access();
|
|||
|
thread reach_container_area();
|
|||
|
thread container_rpg_moment();
|
|||
|
thread exit_container_area();
|
|||
|
thread hind_intro_think();
|
|||
|
thread heli_guy_death();
|
|||
|
thread container_heli_sequence();
|
|||
|
thread flanking_wall_breached();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
music_intro()
|
|||
|
{
|
|||
|
//flag_wait( "inside_perimeter" );
|
|||
|
flag_wait( "music_gimme_sitrep" );
|
|||
|
|
|||
|
wait 2;
|
|||
|
|
|||
|
while( 1 )
|
|||
|
{
|
|||
|
MusicPlayWrapper( "launch_a_action_music" );
|
|||
|
wait 115;
|
|||
|
musicStop( 1 );
|
|||
|
wait 1.2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
launchfacility_a_intro_dvars()
|
|||
|
{
|
|||
|
level waittill("introscreen_complete");
|
|||
|
setsaveddvar( "compass", 1 );
|
|||
|
SetSavedDvar( "ammoCounterHide", "0" );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
container_rpg_moment()
|
|||
|
{
|
|||
|
level endon ("exit_container_area");
|
|||
|
|
|||
|
flag_wait ("reach_container_area");
|
|||
|
flag_wait("heli_attractor_deleted");
|
|||
|
volume_containers = getent("volume_containers", "targetname");
|
|||
|
aRpgSources = getentarray("rpg_source", "targetname");
|
|||
|
assert(isdefined(aRpgSources));
|
|||
|
aRpgTargets = getentarray("rpg_target", "targetname");
|
|||
|
assert(isdefined(aRpgTargets));
|
|||
|
wait (2);
|
|||
|
|
|||
|
thread rpg_ambient(aRpgSources, aRpgTargets, 2);
|
|||
|
wait (randomfloatrange(10, 20));
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait (0.5);
|
|||
|
while (!level.player istouching(volume_containers))
|
|||
|
{
|
|||
|
iRand = randomintrange(1, 3);
|
|||
|
thread rpg_ambient(aRpgSources, aRpgTargets, iRand);
|
|||
|
wait (randomfloatrange(10, 20));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
loudspeaker()
|
|||
|
{
|
|||
|
flag_wait ("container_loudspeaker");
|
|||
|
|
|||
|
//Facility perimeter has been compromised. All units proceed to defensive positions. Unknown enemy force moving in from the South or West. Facility is now on high alert.
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_highalert");
|
|||
|
|
|||
|
|
|||
|
flag_wait( "inside_perimeter" );
|
|||
|
wait(1);
|
|||
|
//Russian Loudspeaker
|
|||
|
//We are under attack! Lock down all points of entry immediately. megaphone/loudspeaker
|
|||
|
level thread dialogue_loudspeaker("launchfacility_a_rul_underattack");
|
|||
|
|
|||
|
flag_wait( "migs_flyby1" );
|
|||
|
|
|||
|
wait(7.5);
|
|||
|
//Russian Loudspeaker
|
|||
|
//Enemy units confirmed to be American special forces. Exercise extreme caution. Red Spetznaz units are en route to intercept. megaphone/loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_redspentznaz");
|
|||
|
|
|||
|
while ( !flag( "obj_enemy_armor_complete" ) )
|
|||
|
{
|
|||
|
//Russian Loudspeaker
|
|||
|
//Fight for the glory of the Motherland! Fight the corruption of our once great nation! loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_motherland");
|
|||
|
|
|||
|
if ( flag( "obj_enemy_armor_complete" ) )
|
|||
|
break;
|
|||
|
wait (3);
|
|||
|
|
|||
|
if ( flag( "obj_enemy_armor_complete" ) )
|
|||
|
break;
|
|||
|
//Russian Loudspeaker
|
|||
|
//Comrades! Remember the fallen and avenge them! Let us ensure that their sacrifices were not made in vain! loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_avengefallen");
|
|||
|
|
|||
|
if ( flag( "obj_enemy_armor_complete" ) )
|
|||
|
break;
|
|||
|
wait (3);
|
|||
|
|
|||
|
if ( flag( "obj_enemy_armor_complete" ) )
|
|||
|
break;
|
|||
|
//Russian Loudspeaker
|
|||
|
//We shall restore the honor of the days when this nation was feared by all others! We will not be stopped! We will not be turned aside so easily! loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_restorehonor");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//Russian Loudspeaker
|
|||
|
//Preparing launch tubes 2 through 6 for firing. Standby. megaphone/loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_preptubes");
|
|||
|
|
|||
|
|
|||
|
while ( true )
|
|||
|
{
|
|||
|
//Russian Loudspeaker
|
|||
|
//Fight for the glory of the Motherland! Fight the corruption of our once great nation! loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_motherland");
|
|||
|
|
|||
|
wait(2);
|
|||
|
|
|||
|
//Russian Loudspeaker
|
|||
|
//Comrades! Remember the fallen and avenge them! Let us ensure that their sacrifices were not made in vain! loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_avengefallen");
|
|||
|
|
|||
|
wait (3);
|
|||
|
|
|||
|
//Russian Loudspeaker
|
|||
|
//We shall restore the honor of the days when this nation was feared by all others! We will not be stopped! We will not be turned aside so easily! loudspeaker
|
|||
|
dialogue_loudspeaker("launchfacility_a_rul_restorehonor");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
dialogue_intro()
|
|||
|
{
|
|||
|
waittillframeend;
|
|||
|
|
|||
|
level.grigsby delayThread( 1.5, ::anim_single_solo, level.grigsby, "spin" );
|
|||
|
//friendly2 delayThread( 1.5, ::anim_single_solo, friendly2, "spin" );
|
|||
|
|
|||
|
//Loudspeaker
|
|||
|
//"Facility perimeter has been compromised. All units proceed to defensive positions. Unknown enemy force moving in from the South or West. Facility is now on high alert."
|
|||
|
//thread dialogue_loudspeaker("launchfacility_a_rul_highalert");
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
|
|||
|
//HQ Radio
|
|||
|
//"Bravo Six, we're picking up heavy activity inside the facility. Enemy air is running search patterns. What's your status over?"
|
|||
|
//level radio_dialogue_queue("launchfacility_a_hqradio_activity");
|
|||
|
|
|||
|
//Price
|
|||
|
//"Status is TARFU and we're workin' on it, out!"
|
|||
|
//level.price dialogue_execute("launchfacility_a_price_tarfu");
|
|||
|
|
|||
|
//HQ Radio Voice
|
|||
|
//Uh, Bravo Six, we're still working with the Russians to get the launch codes. We should have them shortly. Keep moving. Out.
|
|||
|
level radio_dialogue_queue("launchfacility_a_hqr_stillworking");
|
|||
|
|
|||
|
flag_set("obj_gain_access_given");
|
|||
|
|
|||
|
//Price
|
|||
|
//"All right our cover<65>s blown! Grenier! Prep the AT4!"
|
|||
|
//level.price dialogue_execute("launchfacility_a_price_at4_prep");
|
|||
|
|
|||
|
|
|||
|
//Marine 01
|
|||
|
//"Roger that. Last round sir."
|
|||
|
//radio_dialogue("launchfacility_a_marine_01_at4_prep");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
flag_wait("hind_intro_dialogue");
|
|||
|
guy = get_closest_ally();
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
|
|||
|
//Marine 01
|
|||
|
//"Hind!!! 12 o'clock high!!!"
|
|||
|
//guy dialogue_execute("launchfacility_a_marine1_chopper");
|
|||
|
|
|||
|
battlechatter_on( "allies" );
|
|||
|
|
|||
|
wait (3);
|
|||
|
//Price
|
|||
|
//"Go go go!!!"
|
|||
|
level.price dialogue_execute("launchfacility_a_price_gogogo1");
|
|||
|
|
|||
|
//Sniper team
|
|||
|
//"Bravo Six, Sniper Team Two is now in position. We'll give ya sniper cover and recon from where we are, over."
|
|||
|
level radio_dialogue_queue("launchfacility_a_recon_sniperteamtwo");
|
|||
|
|
|||
|
//Price
|
|||
|
//"Copy!!! Keep us posted!!! Out!!!!"
|
|||
|
level.price dialogue_execute("launchfacility_a_price_keepposted");
|
|||
|
|
|||
|
flag_set( "container_loudspeaker" );
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
wait(5);
|
|||
|
|
|||
|
thread dialogue_smoke_hints();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
dialogue_smoke_hints()
|
|||
|
{
|
|||
|
flag_wait("bmp_02_spawned");
|
|||
|
level endon ("bmp_02_destroyed");
|
|||
|
level endon ("bmp_bypassed");
|
|||
|
level endon ("player_reached_kill_max");
|
|||
|
|
|||
|
if (flag("bmp_02_destroyed"))
|
|||
|
return;
|
|||
|
|
|||
|
flag_wait_either( "reach_container_halfwaypoint", "enter_container_area" );
|
|||
|
|
|||
|
iNags = 0;
|
|||
|
volume_smoke = getent("volume_smoke", "targetname");
|
|||
|
volume_smoke.smokethrown = false;
|
|||
|
volume_smoke thread smoke_detect();
|
|||
|
thread dialogue_smoke_hints_cleanup(volume_smoke);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
FRIENDLIES GIVE SMOKE HINTS
|
|||
|
-------------------------*/
|
|||
|
while (volume_smoke.smokethrown == false)
|
|||
|
{
|
|||
|
iNags++;
|
|||
|
if (iNags == 1)
|
|||
|
{
|
|||
|
|
|||
|
//Sniper team
|
|||
|
//"This is Sniper Team Two. You've got hostiles and light armor coming to you from the north. Suggest you get some C4 out there or find some heavy weapons, over."
|
|||
|
level radio_dialogue_queue("launchfacility_a_recon_enemiestonorth");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else if (iNags == 2)
|
|||
|
{
|
|||
|
|
|||
|
//Price
|
|||
|
//"Throw some smoooke!!!!"
|
|||
|
level.price dialogue_execute("launchfacility_a_price_smoke_nag_01");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else if (iNags == 3)
|
|||
|
{
|
|||
|
|
|||
|
//Grigsby
|
|||
|
//"We gotta cover our advaaaance! Everyone pop smooooke!"
|
|||
|
level.grigsby dialogue_execute("launchfacility_a_grigsby_smoke_nag_01");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else
|
|||
|
break;
|
|||
|
|
|||
|
thread hint(&"SCRIPT_PLATFORM_LAUNCHFACILITY_A_HINT_SMOKE", 5);
|
|||
|
wait(randomfloatrange(6,11));
|
|||
|
}
|
|||
|
/*-----------------------
|
|||
|
A FRIENDLY POPS SMOKE NEAR TANK IF PLAYER STILL HAS NOT THROWN
|
|||
|
-------------------------*/
|
|||
|
if (volume_smoke.smokethrown == false)
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
FURTHEST FRIENDLY THROWS SMOKE
|
|||
|
-------------------------*/
|
|||
|
aExcluders = [];
|
|||
|
aExcluders[0] = level.price;
|
|||
|
aExcluders[1] = level.grigsby;
|
|||
|
ai = get_array_of_closest(level.player.origin, level.squad, aExcluders);
|
|||
|
dude = ai[ai.size - 1];
|
|||
|
if ( (isdefined(dude)) && (isalive(dude)) )
|
|||
|
{
|
|||
|
dude thread dialogue_execute("launchfacility_a_marine_01_throwing_smoke");
|
|||
|
bmp = getent("bmp_02", "targetname");
|
|||
|
oldGrenadeWeapon = dude.grenadeWeapon;
|
|||
|
dude.grenadeWeapon = "smoke_grenade_american";
|
|||
|
dude.grenadeAmmo++;
|
|||
|
dude MagicGrenadeManual( bmp.origin, (0,0,0), 0 );
|
|||
|
//dude magicgrenade(bmp.origin, bmp.origin + (0,200,64), .1);
|
|||
|
volume_smoke notify ("smoke_has_been_thrown");
|
|||
|
dude.grenadeWeapon = oldGrenadeWeapon;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
dialogue_C4_hints()
|
|||
|
{
|
|||
|
flag_wait("bmp_02_spawned");
|
|||
|
level endon ("bmp_02_destroyed");
|
|||
|
level endon ("bmp_bypassed");
|
|||
|
level endon ("player_reached_kill_max");
|
|||
|
|
|||
|
if (flag("bmp_02_destroyed"))
|
|||
|
return;
|
|||
|
if (flag("bmp_bypassed"))
|
|||
|
return;
|
|||
|
if (flag("player_reached_kill_max"))
|
|||
|
return;
|
|||
|
|
|||
|
volume_smoke = getent("volume_smoke", "targetname");
|
|||
|
volume_smoke waittill ("smoke_has_been_thrown");
|
|||
|
|
|||
|
wait (2);
|
|||
|
|
|||
|
thread bmp_nags( "bmp_02_destroyed", true );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
dialogue_smoke_hints_cleanup(eVolume)
|
|||
|
{
|
|||
|
eVolume waittill ("smoke_has_been_thrown");
|
|||
|
thread hint_fade();
|
|||
|
}
|
|||
|
|
|||
|
flanking_wall_breached()
|
|||
|
{
|
|||
|
flag_wait("flanking_wall_breached");
|
|||
|
|
|||
|
if(flag("exit_container_area"))
|
|||
|
return;
|
|||
|
/*-----------------------
|
|||
|
STOP SPAWNING GUYS AND SET FLAG THAT OUT OF CONTAINER
|
|||
|
-------------------------*/
|
|||
|
flag_set("exit_container_area");
|
|||
|
trig_killspawner = getent("killspawner_exit_container", "targetname");
|
|||
|
trig_killspawner notify ("trigger", level.player);
|
|||
|
}
|
|||
|
|
|||
|
alarm_sound_thread()
|
|||
|
{
|
|||
|
sound_ent = getent("origin_sound_alarm", "targetname");
|
|||
|
|
|||
|
//sound_ent thread play_loop_sound_on_entity( "emt_alarm_base_alert" );
|
|||
|
sound_ent playloopsound( "emt_alarm_base_alert" );
|
|||
|
flag_wait( "stop_alarm" );
|
|||
|
sound_ent stopLoopSound( "emt_alarm_base_alert" );
|
|||
|
|
|||
|
//sound_ent notify ( "stop soundemt_alarm_base_alert" );
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
friendlies_blow_bmp02()
|
|||
|
{
|
|||
|
level endon ("bmp_02_destroyed");
|
|||
|
//level thread player_kill_counter(level.playerParticipationContainer);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAIT FOR PLAYER TO KILL ENOUGH DUDES OR BYPASS BMP
|
|||
|
-------------------------*/
|
|||
|
//flag_wait_either ("bmp_bypassed", "player_reached_kill_max");
|
|||
|
flag_wait("bmp_bypassed");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
PLAYER STILL HASN'T KILLED BMP
|
|||
|
-------------------------*/
|
|||
|
thread squad_bmp_destroy("bmp_02");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
fireMG(iBurstNumber, fZoffset, eTargetEnt)
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
if (!isdefined(eTargetEnt))
|
|||
|
eTargetEnt = level.player;
|
|||
|
|
|||
|
if (!isdefined(fZoffset))
|
|||
|
fZoffset = 0;
|
|||
|
|
|||
|
self setturrettargetent(eTargetEnt, (0, 0, fZoffset));
|
|||
|
iFireTime = 0.1;
|
|||
|
//iFireTime = weaponfiretime("hind_turret");
|
|||
|
assert(isdefined(iFireTime));
|
|||
|
|
|||
|
if (!isdefined(iBurstNumber))
|
|||
|
iBurstNumber = randomintrange(8, 20);
|
|||
|
|
|||
|
self.turretFiring = true;
|
|||
|
i = 0;
|
|||
|
while (i < iBurstNumber)
|
|||
|
{
|
|||
|
i++;
|
|||
|
wait(iFireTime);
|
|||
|
self fireWeapon();
|
|||
|
}
|
|||
|
self.turretFiring = false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
reach_container_area()
|
|||
|
{
|
|||
|
flag_wait ("reach_container_area");
|
|||
|
thread autosave_by_name( "container" );
|
|||
|
|
|||
|
wait (2);
|
|||
|
//Loudspeaker
|
|||
|
//"We are under attack! Lock down all points of entry immediately."
|
|||
|
//thread dialogue_loudspeaker("launchfacility_a_rul_underattack");
|
|||
|
}
|
|||
|
|
|||
|
container_heli_sequence()
|
|||
|
{
|
|||
|
while (!isdefined(level.friendly_at4))
|
|||
|
wait (0.05);
|
|||
|
node = getnode( "node_at4_guy", "targetname");
|
|||
|
|
|||
|
createthreatbiasgroup( "ignored" );
|
|||
|
level.friendly_at4 set_threatbiasgroup( "ignored" );
|
|||
|
setignoremegroup( "ignored", "axis" );
|
|||
|
setignoremegroup( "axis", "ignored" );
|
|||
|
|
|||
|
assert(isdefined(node));
|
|||
|
level.friendly_at4 set_animname( "frnd" );
|
|||
|
level.friendly_at4.ignoreme = true;
|
|||
|
|
|||
|
//anim_reach_solo( guy, anime, tag, node, tag_entity )
|
|||
|
//anim_loop_solo( guy, anime, tag, ender, entity )
|
|||
|
|
|||
|
|
|||
|
node anim_reach_solo (level.friendly_at4, "AT4_fire_start");
|
|||
|
level.friendly_at4 allowedStances ("crouch");
|
|||
|
|
|||
|
flag_wait( "friendly_shoots_down_heli_new" );
|
|||
|
|
|||
|
level.friendly_at4 allowedStances ("crouch", "stand", "prone");
|
|||
|
level.friendly_at4 attach("weapon_stinger", "TAG_INHAND");
|
|||
|
node thread anim_single_solo( level.friendly_at4, "AT4_fire" );
|
|||
|
level.friendly_at4 waittillmatch ( "single anim", "fire" );
|
|||
|
org = level.friendly_at4 gettagorigin( "TAG_INHAND" );
|
|||
|
magicbullet( "rpg_player", org, level.eHindIntro.origin );
|
|||
|
|
|||
|
level.friendly_at4 waittillmatch ( "single anim", "end" );
|
|||
|
org_hand = level.friendly_at4 gettagorigin("TAG_INHAND");
|
|||
|
angles_hand = level.friendly_at4 gettagangles("TAG_INHAND");
|
|||
|
level.friendly_at4 detach("weapon_stinger", "TAG_INHAND");
|
|||
|
model_at4 = spawn("script_model", org_hand);
|
|||
|
model_at4 setmodel( "weapon_stinger" );
|
|||
|
model_at4.angles = angles_hand;
|
|||
|
node thread anim_loop_solo (level.friendly_at4, "AT4_idle", undefined, "stop_idle");
|
|||
|
|
|||
|
flag_wait("exit_container_area");
|
|||
|
|
|||
|
if (isdefined(level.friendly_at4))
|
|||
|
{
|
|||
|
node notify ( "stop_idle" );
|
|||
|
if ( isdefined( level.friendly_at4.magic_bullet_shield ) )
|
|||
|
level.friendly_at4 stop_magic_bullet_shield();
|
|||
|
level.friendly_at4 delete();
|
|||
|
model_at4 delete();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
container_heli_sequence2()
|
|||
|
{
|
|||
|
while (!isdefined(level.friendly_at4))
|
|||
|
wait (0.05);
|
|||
|
node = getnode( "node_at4_guy", "targetname");
|
|||
|
|
|||
|
createthreatbiasgroup( "ignored" );
|
|||
|
level.friendly_at4 set_threatbiasgroup( "ignored" );
|
|||
|
setignoremegroup( "ignored", "axis" );
|
|||
|
setignoremegroup( "axis", "ignored" );
|
|||
|
|
|||
|
assert(isdefined(node));
|
|||
|
level.friendly_at4 set_animname( "frnd" );
|
|||
|
level.friendly_at4.ignoreme = true;
|
|||
|
|
|||
|
//anim_reach_solo( guy, anime, tag, node, tag_entity )
|
|||
|
//anim_loop_solo( guy, anime, tag, ender, entity )
|
|||
|
|
|||
|
node anim_reach_solo (level.friendly_at4, "RPG_conceal_idle_start");
|
|||
|
node thread anim_loop_solo (level.friendly_at4, "RPG_conceal_idle", undefined, "stop_idle");
|
|||
|
|
|||
|
flag_wait( "friendly_shoots_down_heli" );
|
|||
|
|
|||
|
node notify ( "stop_idle" );
|
|||
|
node anim_single_solo( level.friendly_at4, "RPG_conceal_2_standR" );
|
|||
|
|
|||
|
org = level.friendly_at4 gettagorigin( "TAG_WEAPON_RIGHT" );
|
|||
|
magicbullet( "rpg_player", org, level.eHindIntro.origin );
|
|||
|
|
|||
|
level.friendly_at4 anim_single_solo( level.friendly_at4, "RPG_standR_2_conceal" );
|
|||
|
|
|||
|
node thread anim_loop_solo (level.friendly_at4, "RPG_conceal_idle", undefined, "stop_idle");
|
|||
|
|
|||
|
flag_wait("exit_container_area");
|
|||
|
|
|||
|
if (isdefined(level.friendly_at4))
|
|||
|
{
|
|||
|
if ( isdefined( level.friendly_at4.magic_bullet_shield ) )
|
|||
|
level.friendly_at4 stop_magic_bullet_shield();
|
|||
|
level.friendly_at4 delete();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
hind_crash_failsafe()
|
|||
|
{
|
|||
|
level.eHindIntro endon ("death");
|
|||
|
wait(4.75);
|
|||
|
level.eHindIntro notify ("death");
|
|||
|
}
|
|||
|
|
|||
|
hind_intro_think()
|
|||
|
{
|
|||
|
level.eHindIntro = spawn_vehicle_from_targetname("hind_intro_flyby_01");
|
|||
|
level thread maps\_vehicle::gopath(level.eHindIntro);
|
|||
|
//sTag = "tag_missile_right";
|
|||
|
sTag = "tag_origin";
|
|||
|
targetOrg = spawn("script_origin", level.eHindIntro gettagorigin(sTag));
|
|||
|
targetOrg linkto(level.eHindIntro, sTag);
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
targetOrg thread print3Dthread("TARGET");
|
|||
|
|
|||
|
wait(3.5);
|
|||
|
level.eHindIntro thread fireMG(randomintrange(14, 17), 80);
|
|||
|
|
|||
|
wait (2);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
wait (2);
|
|||
|
hind_intro_target2 = getent("hind_intro_target2", "targetname");
|
|||
|
level.eHindIntro thread fireMG(randomintrange(20, 24), 80, hind_intro_target2);
|
|||
|
wait(1);
|
|||
|
flag_set("hind_intro_dialogue");
|
|||
|
|
|||
|
wait (2);
|
|||
|
|
|||
|
flag_set( "friendly_shoots_down_heli_new" );
|
|||
|
|
|||
|
wait (3);
|
|||
|
/*-----------------------
|
|||
|
HIND STARTS CRASH SEQUENCE
|
|||
|
-------------------------*/
|
|||
|
//flag_wait("player_near_intro_heli_sequnce");
|
|||
|
|
|||
|
flag_set( "friendly_shoots_down_heli" );
|
|||
|
level.eHindIntro thread hind_crash_failsafe();
|
|||
|
level.eHindIntro thread hind_earthquake();
|
|||
|
wait(1);
|
|||
|
attractor = missile_createAttractorEnt( targetOrg, 100000, 60000 );
|
|||
|
|
|||
|
wait(1);
|
|||
|
level.eHindIntro thread fireMG(15, 80);
|
|||
|
level.eHindIntro waittill("death");
|
|||
|
missile_deleteAttractor(attractor);
|
|||
|
flag_set("heli_attractor_deleted");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
END OLD CRASH SEQUENCE
|
|||
|
-------------------------*/
|
|||
|
level.eHindIntro waittill("crash_done");
|
|||
|
flag_set("hind_crash");
|
|||
|
flag_set("stop_alarm");
|
|||
|
|
|||
|
wait(.5);
|
|||
|
hind_crash = getent("hind_crash", "targetname");
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
hind_earthquake()
|
|||
|
{
|
|||
|
self waittill( "death" );
|
|||
|
earthquake (0.4, 2, self.origin, 4000);
|
|||
|
}
|
|||
|
|
|||
|
hind_intro_think2()
|
|||
|
{
|
|||
|
hind_crash = getent("hind_crash", "script_noteworthy");
|
|||
|
level.eHindIntro = maps\_vehicle::waittill_vehiclespawn( "hind_intro" );
|
|||
|
level.eHindIntro setmaxpitchroll(50,30);
|
|||
|
level.eHindIntro setspeed(120, 15, 15);
|
|||
|
//crash_path = getent("crash_path", "script_noteworthy");
|
|||
|
|
|||
|
wait(1);
|
|||
|
flag_set("hind_intro_dialogue");
|
|||
|
wait(.5);
|
|||
|
|
|||
|
level.eHindIntro thread fireMG(15, 80);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
HIND STARTS CRASH SEQUENCE
|
|||
|
-------------------------*/
|
|||
|
flag_set( "friendly_shoots_down_heli" );
|
|||
|
attractor = missile_createAttractorEnt( level.eHindIntro, 10000, 6000 );
|
|||
|
|
|||
|
level.eHindIntro thread hind_crash_failsafe();
|
|||
|
|
|||
|
wait(2.5);
|
|||
|
missile_deleteAttractor(attractor);
|
|||
|
flag_set("heli_attractor_deleted");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
BEGIN OLD CRASH SEQUENCE
|
|||
|
-------------------------*/
|
|||
|
/*
|
|||
|
level.eHindIntro waittill ("hit_by_rpg");
|
|||
|
wait(.2);
|
|||
|
level.eHindIntro vehicle_detachfrompath();
|
|||
|
level.eHindIntro thread vehicle_dynamicpath( crash_path, false );
|
|||
|
level.eHindIntro thread hind_crash_fx();
|
|||
|
|
|||
|
wait(1);
|
|||
|
level.eHindIntro thread play_loop_sound_on_entity(level.scr_sound["launch_heli_dying_loop"]);
|
|||
|
missile_deleteAttractor(attractor);
|
|||
|
flag_set("heli_attractor_deleted");
|
|||
|
|
|||
|
wait(3);
|
|||
|
|
|||
|
level.eHindIntro thread play_loop_sound_on_entity(level.scr_sound["launch_heli_alarm_loop"]);
|
|||
|
|
|||
|
wait( 4.5 );
|
|||
|
|
|||
|
thread play_sound_in_space( "explo_metal_rand", hind_crash.origin );
|
|||
|
level.eHindIntro notify ( "stop sound" + level.scr_sound["launch_heli_alarm_loop"] );
|
|||
|
level.eHindIntro notify ( "stop sound" + level.scr_sound["launch_heli_dying_loop"] );
|
|||
|
|
|||
|
wait(.2);
|
|||
|
playfx ( level._effect["hind_explosion"], hind_crash.origin );
|
|||
|
earthquake (0.6, 2, hind_crash.origin, 2000);
|
|||
|
if ( isdefined(level.eHindIntro) )
|
|||
|
level.eHindIntro delete();
|
|||
|
wait (.75);
|
|||
|
playfx ( level._effect["hind_explosion"], hind_crash.origin + (200, 0, 800) );
|
|||
|
thread play_sound_in_space( "building_explosion1", hind_crash.origin );
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
END OLD CRASH SEQUENCE
|
|||
|
-------------------------*/
|
|||
|
level.eHindIntro waittill("crash_done");
|
|||
|
flag_set("hind_crash");
|
|||
|
flag_set("stop_alarm");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
heli_guy_death()
|
|||
|
{
|
|||
|
flag_wait( "friendly_shoots_down_heli" );
|
|||
|
wait(19);
|
|||
|
spawner = getent("heli_dude", "targetname");
|
|||
|
assert(isdefined(spawner));
|
|||
|
eGuy = spawner stalingradspawn();
|
|||
|
spawn_failed(eGuy);
|
|||
|
org = eGuy.origin + (100, -50, -100);
|
|||
|
eGuy.skipdeathanim = true;
|
|||
|
eGuy doDamage (eGuy.health + 1, eGuy.origin);
|
|||
|
wait(0.1);
|
|||
|
physicsExplosionSphere( org, 356, 128, 10 );
|
|||
|
}
|
|||
|
|
|||
|
hind_crash_fx()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
wait(1.2);
|
|||
|
playfxontag( level._effect["heli_aerial_explosion"], self, "tag_body" );
|
|||
|
thread play_sound_in_space( "explo_metal_rand", self.origin );
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
//playfxontag( level._effect["fire_trail_heli"], level.eHindIntro, "tag_origin" );
|
|||
|
playfxontag( level._effect["smoke_trail_heli"], self, "tag_engine_right" );
|
|||
|
wait(0.01);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
LEVEL START: CONTAINER
|
|||
|
****************************************************************************/
|
|||
|
|
|||
|
exit_container_area()
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
AI LEFT BEHIND CHASE PLAYER
|
|||
|
-------------------------*/
|
|||
|
flag_wait( "exit_container_area" );
|
|||
|
thread ignore_friendlies_till_past_killzone();
|
|||
|
//thread autosave_by_name( "exit_container" );
|
|||
|
volume = getent("volume_containers", "targetname");
|
|||
|
volume thread AI_in_volume_chase_player();
|
|||
|
thread truck_blows_up();
|
|||
|
thread left_gate_nag();
|
|||
|
}
|
|||
|
|
|||
|
left_gate_nag()
|
|||
|
{
|
|||
|
level endon ("obj_gain_access_complete");
|
|||
|
flag_wait("bmp_02_destroyed");
|
|||
|
volume_leftgate = getent("volume_leftgate", "script_noteworthy");
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait(randomfloatrange(15, 30));
|
|||
|
if (level.player istouching(volume_leftgate))
|
|||
|
{
|
|||
|
level.dialogueGateHint_number++;
|
|||
|
if (level.dialogueGateHint_number > level.dialogueGateHint_MAX)
|
|||
|
level.dialogueGateHint_number = 1;
|
|||
|
|
|||
|
sDialogue = "launchfacility_a_gate_hint_0" + level.dialogueGateHint_number;
|
|||
|
level radio_dialogue_queue(sDialogue);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
truck_blows_up()
|
|||
|
{
|
|||
|
level endon ("right_gate_approach");
|
|||
|
flag_wait("bmp_02_destroyed");
|
|||
|
flag_wait("truck_approach");
|
|||
|
flag_set("enemy_can_blow_up_truck");
|
|||
|
|
|||
|
playerEye = level.player getEye();
|
|||
|
truck = getent("truck_troops_perimeter", "script_noteworthy");
|
|||
|
while (flag("enemy_can_blow_up_truck"))
|
|||
|
{
|
|||
|
if (!isdefined(truck))
|
|||
|
return;
|
|||
|
qInFOV = within_fov(playerEye, level.player getPlayerAngles(), truck.origin, level.cosine["45"]);
|
|||
|
if (qInFOV)
|
|||
|
break;
|
|||
|
wait (0.05);
|
|||
|
}
|
|||
|
if (!isdefined(truck))
|
|||
|
return;
|
|||
|
|
|||
|
guy = get_closest_ally();
|
|||
|
if (isdefined(guy))
|
|||
|
guy thread play_sound_on_entity("US_grg_threat_rpg");
|
|||
|
|
|||
|
rpgorg = getent("rpg_source_right_1", "script_noteworthy");
|
|||
|
truck_rpg_target = getent("truck_rpg_target", "targetname");
|
|||
|
attractorRPG = missile_createAttractorEnt(truck_rpg_target, 10000, 6000 );
|
|||
|
magicbullet("rpg", rpgorg.origin, truck_rpg_target.origin);
|
|||
|
wait(3);
|
|||
|
missile_deleteAttractor(attractorRPG);
|
|||
|
}
|
|||
|
|
|||
|
ignore_friendlies_till_past_killzone()
|
|||
|
{
|
|||
|
trig_ignoreme = getent("trig_ignoreme", "targetname");
|
|||
|
assert(isdefined(trig_ignoreme));
|
|||
|
for(i=0;i<level.squad.size;i++)
|
|||
|
level.squad[i] thread ignoreme_when_in_trigger(trig_ignoreme);
|
|||
|
}
|
|||
|
|
|||
|
ignoreme_when_in_trigger(trig_ignoreme)
|
|||
|
{
|
|||
|
level endon ("friendlies_past_killzone");
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait (0.05);
|
|||
|
trig_ignoreme waittill ("trigger", other);
|
|||
|
if (other != self)
|
|||
|
continue;
|
|||
|
|
|||
|
self.ignoreme = true;
|
|||
|
self.a.disablePain = true;
|
|||
|
self set_maxsightdistsqrd(128);
|
|||
|
//self thread print3Dthread("IGNORED");
|
|||
|
while (self istouching(trig_ignoreme))
|
|||
|
wait (0.05);
|
|||
|
|
|||
|
|
|||
|
self.ignoreme = false;
|
|||
|
self.a.disablePain = false;
|
|||
|
self reset_maxsightdistsqrd();
|
|||
|
//self notify ("stop_3dprint");
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
LEVEL START: GATE
|
|||
|
****************************************************************************/
|
|||
|
AA_gate_init()
|
|||
|
{
|
|||
|
thread balcony_think();
|
|||
|
thread gate_squad_advance_no_bmp();
|
|||
|
thread gate_left_approach();
|
|||
|
thread gate_right_approach();
|
|||
|
thread gate_right_reach();
|
|||
|
thread gate_player_participation();
|
|||
|
thread gate_sequence();
|
|||
|
}
|
|||
|
|
|||
|
balcony_think()
|
|||
|
{
|
|||
|
|
|||
|
level endon( "gate_sequence_starting" );
|
|||
|
flag_wait( "reached_balcony" );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
BLOW THE GATE WITH NO AI IF NOT DONE ALREADY
|
|||
|
-------------------------*/
|
|||
|
level thread gate_blowup();
|
|||
|
|
|||
|
//Marine 01
|
|||
|
//"Cover me! I'm gonna blow the gate!"
|
|||
|
org = getent( "obj_gain_access", "targetname" );
|
|||
|
guy = get_closest_ally( org );
|
|||
|
guy dialogue_execute("launchfacility_a_marine1_gate_blow");
|
|||
|
wait(1);
|
|||
|
flag_set("blow_the_gate");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
gate_squad_advance_no_bmp()
|
|||
|
{
|
|||
|
flag_wait ("bmp_02_destroyed");
|
|||
|
flag_clear( "aa_first_bmp_section" );
|
|||
|
flag_set( "aa_container_to_gate_section" );
|
|||
|
|
|||
|
|
|||
|
disable_color_trigs();
|
|||
|
triggersEnable("colornodes_gate_no_bmp", "script_noteworthy", true);
|
|||
|
|
|||
|
trig_killspawner = getent("killspawner_exit_container", "targetname");
|
|||
|
trig_killspawner notify ("trigger", level.player);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
TRY TO KILL ANY REMAINING ENEMIES IN CONTAINER AREA
|
|||
|
-------------------------*/
|
|||
|
eVolume = getent("volume_containers", "targetname");
|
|||
|
aAI_to_delete = getAIarrayTouchingVolume("axis", undefined,eVolume);
|
|||
|
if (aAI_to_delete.size > 0)
|
|||
|
{
|
|||
|
for(i=0;i<aAI_to_delete.size;i++)
|
|||
|
aAI_to_delete[i].health = 1;
|
|||
|
thread AI_delete_when_out_of_sight(aAI_to_delete, level.AIdeleteDistance);
|
|||
|
}
|
|||
|
|
|||
|
wait (2);
|
|||
|
|
|||
|
|
|||
|
while(level.peoplespeaking)
|
|||
|
wait(0.5);
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
//HQ radio
|
|||
|
//"Bravo Six, this is command, gimme a sit-rep over."
|
|||
|
level radio_dialogue_queue("launchfacility_a_cmd_sitrep");
|
|||
|
|
|||
|
flag_set( "music_gimme_sitrep" );
|
|||
|
|
|||
|
//Price
|
|||
|
//"We're inside the perimeter, approaching the gates to the silos!!! Out!!!"
|
|||
|
level.price dialogue_execute("launchfacility_a_price_were_inside");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
flag_set( "inside_perimeter" );
|
|||
|
wait(1.5);
|
|||
|
//Loudspeaker
|
|||
|
//"Enemy units confirmed to be American special forces. Exercise extreme caution. Red Spetznaz units are en route to intercept."
|
|||
|
//thread dialogue_loudspeaker("launchfacility_a_rul_redspentznaz");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
gate_left_approach()
|
|||
|
{
|
|||
|
flag_wait("reached_left_gate");
|
|||
|
if (getdvar("debug_bmp") == "1")
|
|||
|
println("REACHED LEFT GATE");
|
|||
|
//thread autosave_by_name("left_gate");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
gate_right_approach()
|
|||
|
{
|
|||
|
flag_wait("right_gate_approach");
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
//Grigsby
|
|||
|
//"We're gonna need some more ground support sir!!!!"
|
|||
|
level.grigsby dialogue_execute("launchfacility_a_griggs_moreground");
|
|||
|
|
|||
|
//Price
|
|||
|
//"Already got it covered Griggs!!!"
|
|||
|
level.price dialogue_execute("launchfacility_a_price_alreadygot");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
flag_set("migs_flyby1");
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
gate_right_push_forward()
|
|||
|
{
|
|||
|
level endon ("blow_the_gate");
|
|||
|
flag_wait("migs_flyby1");
|
|||
|
|
|||
|
wait (8);
|
|||
|
|
|||
|
retreat_gate = getent( "retreat_gate", "targetname" );
|
|||
|
while ( !level.player istouching( retreat_gate ) )
|
|||
|
wait (3);
|
|||
|
//*****Captain Price
|
|||
|
//We've got to breach the gate to the tarmac! Keep pushing forward!
|
|||
|
level.price dialogue_execute("launchfacility_a_pri_breachgate");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
gate_player_participation()
|
|||
|
{
|
|||
|
level endon ( "reached_balcony" );
|
|||
|
level endon ("gate_sequence_starting");
|
|||
|
|
|||
|
flag_wait ("bmp_02_destroyed");
|
|||
|
//flag_wait("right_gate_approach");
|
|||
|
|
|||
|
level thread player_kill_counter(level.playerParticipationGate);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAIT FOR PLAYER TO KILL ENOUGH DUDES
|
|||
|
-------------------------*/
|
|||
|
flag_clear("player_reached_kill_max");
|
|||
|
wait(.5);
|
|||
|
flag_wait("player_reached_kill_max");
|
|||
|
if (getdvar("debug_bmp") == "1")
|
|||
|
printLn("player has killed " + level.axisKilledByPlayer + " dudes...additional gate trigger activated");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ACTIVATE ADDITIONAL GATE TRIGGERS
|
|||
|
-------------------------*/
|
|||
|
aTrigs1 = getentarray("reached_right_gate_additional", "targetname");
|
|||
|
aTrigs2 = getentarray("reached_right_gate", "targetname");
|
|||
|
|
|||
|
for(i=0;i<aTrigs1.size;i++)
|
|||
|
aTrigs1[i] trigger_on();
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAIT FOR PLAYER TO APPROACH GATE VIA LARGER TRIGGER
|
|||
|
-------------------------*/
|
|||
|
array_thread (aTrigs1, ::gate_right_reach_trig_wait);
|
|||
|
level waittill ("level_ent_updated");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
CANCEL ALL OTHER TRIGGERS
|
|||
|
-------------------------*/
|
|||
|
for(i=0;i<aTrigs1.size;i++)
|
|||
|
aTrigs1[i] notify ("cancel");
|
|||
|
|
|||
|
for(i=0;i<aTrigs2.size;i++)
|
|||
|
aTrigs2[i] notify ("cancel");
|
|||
|
|
|||
|
flag_set("gate_sequence_starting");
|
|||
|
}
|
|||
|
|
|||
|
gate_right_reach()
|
|||
|
{
|
|||
|
level endon( "reached_balcony" );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAIT FOR PLAYER TO APPROACH GATE
|
|||
|
-------------------------*/
|
|||
|
aTrigs = getentarray("reached_right_gate", "targetname");
|
|||
|
array_thread (aTrigs, ::gate_right_reach_trig_wait);
|
|||
|
level waittill ("level_ent_updated");
|
|||
|
for(i=0;i<aTrigs.size;i++)
|
|||
|
aTrigs[i] notify ("cancel");
|
|||
|
|
|||
|
flag_set("gate_sequence_starting");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
gate_sequence()
|
|||
|
{
|
|||
|
flag_wait("gate_sequence_starting");
|
|||
|
|
|||
|
thread autosave_by_name("right_gate");
|
|||
|
/*-----------------------
|
|||
|
SPAWN GATE DUDE AND HAVE PLANT C4
|
|||
|
-------------------------*/
|
|||
|
assertEx((isdefined(level.ent)), "level.ent should have been updated when trigger was hit");
|
|||
|
eGateDude = level.ent stalingradspawn();
|
|||
|
spawn_failed(eGateDude);
|
|||
|
eGateDude thread friendly_blows_gate();
|
|||
|
|
|||
|
level thread gate_blowup();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
gate_blowup()
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
KILL ALL SPAWNERS IN GATE AREA
|
|||
|
-------------------------*/
|
|||
|
thread autosave_by_name("gate_being_blown");
|
|||
|
|
|||
|
aKillspawners_gate = getentarray("killspawners_gate", "script_noteworthy");
|
|||
|
for(i=0;i<aKillspawners_gate.size;i++)
|
|||
|
aKillspawners_gate[i] notify ("trigger", level.player);
|
|||
|
|
|||
|
flag_wait("blow_the_gate");
|
|||
|
/*-----------------------
|
|||
|
BLOW THE GATE
|
|||
|
-------------------------*/
|
|||
|
flag_clear( "aa_container_to_gate_section" );
|
|||
|
flag_set( "aa_tarmac_bmp01_section" );
|
|||
|
|
|||
|
|
|||
|
exploder(500);
|
|||
|
org = getent("gate_explosives", "targetname");
|
|||
|
thread play_sound_in_space("detpack_explo_metal", org.origin );
|
|||
|
radiusdamage( org.origin, 256, 200, 50);
|
|||
|
earthquake (0.6, 1, org.origin, 2000);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
MOVE INTO NEXT AREA
|
|||
|
-------------------------*/
|
|||
|
disable_color_trigs();
|
|||
|
triggersEnable("colornodes_tarmac_front", "script_noteworthy", true);
|
|||
|
triggersEnable("colornodes_tarmac_rear", "script_noteworthy", true);
|
|||
|
triggersEnable("colornodes_tarmac_always_on", "script_noteworthy", true);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
FRIENDLIES MOVE INTO NEXT AREA, BMPS SPAWNED
|
|||
|
-------------------------*/
|
|||
|
trig_colornode = getent("colornodes_tarmac_front_start", "targetname");
|
|||
|
trig_colornode notify("trigger", level.player);
|
|||
|
triggers_bmp_tarmac = getentarray("triggers_bmp_tarmac", "script_noteworthy");
|
|||
|
for(i=0;i<triggers_bmp_tarmac.size;i++)
|
|||
|
triggers_bmp_tarmac[i] notify("trigger", level.player);
|
|||
|
|
|||
|
flag_set ("obj_gain_access_complete");
|
|||
|
|
|||
|
thread autosave_by_name( "gate_blown" );
|
|||
|
|
|||
|
thread AA_tarmac_init();
|
|||
|
|
|||
|
/*------------------------
|
|||
|
TRY TO KILL ANY REMAINING ENEMIES IN PERIMETER
|
|||
|
-------------------------*/
|
|||
|
aVolumes = getentarray("volumes_perimeter", "script_noteworthy");
|
|||
|
aAI_to_delete = [];
|
|||
|
aStragglers = undefined;
|
|||
|
for(i=0;i<aVolumes.size;i++)
|
|||
|
{
|
|||
|
aStragglers = undefined;
|
|||
|
aStragglers = getAIarrayTouchingVolume("axis", undefined,aVolumes[i]);
|
|||
|
if (aStragglers.size > 0)
|
|||
|
aAI_to_delete = array_merge(aAI_to_delete, aStragglers);
|
|||
|
}
|
|||
|
|
|||
|
if (aAI_to_delete.size > 0)
|
|||
|
{
|
|||
|
for(i=0;i<aAI_to_delete.size;i++)
|
|||
|
aAI_to_delete[i].health = 1;
|
|||
|
thread AI_delete_when_out_of_sight(aAI_to_delete, level.AIdeleteDistance);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
friendly_blows_gate()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
self disable_ai_color();
|
|||
|
self.animname = "frnd";
|
|||
|
self invulnerable(true);
|
|||
|
self.ignoreme = true;
|
|||
|
self setFlashbangImmunity( true );
|
|||
|
//self teleport (org.origin);
|
|||
|
//self setgoalpos (org.origin);
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
|
|||
|
//Marine 01
|
|||
|
//"Cover me! I'm gonna blow the gate!"
|
|||
|
self thread dialogue_execute("launchfacility_a_marine1_gate_blow");
|
|||
|
|
|||
|
eNode = getent("node_gate_destroy", "targetname");
|
|||
|
eNodeRetreat = getnode(eNode.target, "targetname");
|
|||
|
eNode anim_reach_solo (self, "C4_gate_plant_start");
|
|||
|
|
|||
|
org = getent("gate_explosives", "targetname");
|
|||
|
assert(isdefined(org));
|
|||
|
|
|||
|
eNode thread anim_single_solo(self, "C4_gate_plant");
|
|||
|
self waittillmatch ( "single anim", "c4plant" );
|
|||
|
self attach("weapon_c4", "TAG_INHAND");
|
|||
|
self waittillmatch ( "single anim", "c4swap" );
|
|||
|
|
|||
|
self detach("weapon_c4", "TAG_INHAND");
|
|||
|
C4org = self gettagorigin( "TAG_INHAND" );
|
|||
|
C4angles = self gettagangles( "TAG_INHAND" );
|
|||
|
c4_model = spawn( "script_model", C4org);
|
|||
|
c4_model setmodel( "weapon_c4" );
|
|||
|
c4_model.angles = C4angles;
|
|||
|
|
|||
|
//Marine 02
|
|||
|
//"Charges set!!!!! Get back get back!!!"
|
|||
|
self thread dialogue_execute("launchfacility_a_marine2_gate_getback");
|
|||
|
|
|||
|
|
|||
|
self setGoalRadius(eNodeRetreat.radius);
|
|||
|
self setgoalnode(eNodeRetreat);
|
|||
|
self waittill ("goal");
|
|||
|
wait (.5);
|
|||
|
self resetGoalRadius();
|
|||
|
|
|||
|
//Marine 02
|
|||
|
//"Fire in the hole!!!"
|
|||
|
self dialogue_execute("launchfacility_a_marine2_fireinhole");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GATE BLOWN
|
|||
|
-------------------------*/
|
|||
|
flag_set("blow_the_gate");
|
|||
|
c4_model delete();
|
|||
|
wait (1);
|
|||
|
|
|||
|
self enable_ai_color();
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
MAKE GATE DUDE VULNERABLE SO HE GETS KILLED
|
|||
|
-------------------------*/
|
|||
|
wait (6);
|
|||
|
self invulnerable(false);
|
|||
|
self.ignoreme = false;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
gate_right_reach_trig_wait()
|
|||
|
{
|
|||
|
self endon ("cancel");
|
|||
|
level endon( "player_in_balcony" );
|
|||
|
spawner = getent(self.script_linkto, "script_linkname");
|
|||
|
assertEx((isdefined(spawner)), "trigger must linkto a spawner");
|
|||
|
self waittill ("trigger");
|
|||
|
level.ent = spawner;
|
|||
|
level notify ("level_ent_updated");
|
|||
|
}
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
LEVEL START: TARMAC
|
|||
|
****************************************************************************/
|
|||
|
AA_tarmac_init()
|
|||
|
{
|
|||
|
flag_set("friendlies_past_killzone");
|
|||
|
thread tarmac_colornodes_think();
|
|||
|
array_thread(level.squad, ::tarmac_friendly_engagement_think);
|
|||
|
thread reach_tarmac_halfwaypoint();
|
|||
|
thread tarmac_objectives();
|
|||
|
thread obj_enemy_armor();
|
|||
|
thread dialogue_tarmac_hints();
|
|||
|
thread proceed_to_vents();
|
|||
|
}
|
|||
|
|
|||
|
tarmac_objectives()
|
|||
|
{
|
|||
|
maps\_vehicle::waittill_vehiclespawn("bmp_04");
|
|||
|
|
|||
|
//Russian Loudspeaker
|
|||
|
//Fight for the glory of the Motherland! Fight the corruption of our once great nation! loudspeaker
|
|||
|
//thread dialogue_loudspeaker("launchfacility_a_rul_motherland");
|
|||
|
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
|
|||
|
//Price
|
|||
|
//"Through the gate! Let's go!!!"
|
|||
|
level.price thread dialogue_execute("launchfacility_a_price_tothetarmac");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
wait (5);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ARMOR DIALOGUE & OBJECTIVE
|
|||
|
-------------------------*/
|
|||
|
level.peoplespeaking = true;
|
|||
|
|
|||
|
//Grigsby
|
|||
|
//"Shit we got more BMPs!!! Take cover!!!!"
|
|||
|
level.grigsby dialogue_execute("launchfacility_a_griggs_morebmps");
|
|||
|
|
|||
|
//Price
|
|||
|
//"Jackson!!! Griggs!!! Knock 'em out, GO!!!!"
|
|||
|
level.price dialogue_execute("launchfacility_a_price_knockemout");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
|
|||
|
flag_set("obj_enemy_armor_given");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAIT FOR EITHER BMP TO BE KILLED
|
|||
|
-------------------------*/
|
|||
|
flag_wait_either("bmp_03_destroyed", "bmp_04_destroyed");
|
|||
|
flag_set("one_bmp_left");
|
|||
|
|
|||
|
flag_clear( "aa_tarmac_bmp01_section" );
|
|||
|
flag_set( "aa_tarmac_bmp02_section" );
|
|||
|
|
|||
|
wait (4);
|
|||
|
flag_set("migs_flyby2");
|
|||
|
}
|
|||
|
|
|||
|
dialogue_tarmac_hints()
|
|||
|
{
|
|||
|
flag_wait("obj_enemy_armor_given");
|
|||
|
|
|||
|
wait (10);
|
|||
|
|
|||
|
if (flag("one_bmp_left"))
|
|||
|
return;
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
//Grigsby
|
|||
|
//"Yo Jackson!! Keep your eyes open for RPGs!! We can use 'em to take out the armor from long range!!!"
|
|||
|
level.grigsby dialogue_execute("launchfacility_a_griggs_userpghint");
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
wait (10);
|
|||
|
|
|||
|
if (flag("one_bmp_left"))
|
|||
|
return;
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
//Grigsby
|
|||
|
//"We need to take out the BMPs! "
|
|||
|
level.grigsby dialogue_execute("launchfacility_a_griggs_vehicles_hint_01");
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
wait (13);
|
|||
|
thread bmp_nags( "obj_enemy_armor_complete", false, true );
|
|||
|
}
|
|||
|
|
|||
|
tarmac_friendly_engagement_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
//self set_maxsightdistsqrd(512);
|
|||
|
}
|
|||
|
|
|||
|
reach_tarmac_halfwaypoint()
|
|||
|
{
|
|||
|
flag_wait("reach_tarmac_halfwaypoint");
|
|||
|
|
|||
|
//Loudspeaker
|
|||
|
//"Preparing launch tubes 2 through 6 for firing. Standby."
|
|||
|
//thread dialogue_loudspeaker("launchfacility_a_rul_preptubes");
|
|||
|
|
|||
|
flag_set("player_near_launchtube_03");
|
|||
|
wait(2);
|
|||
|
flag_set("player_near_launchtube_04");
|
|||
|
wait (1);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ignoreme_thread(bool)
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
if (!isalive(self))
|
|||
|
return;
|
|||
|
if (!isdefined(self))
|
|||
|
return;
|
|||
|
|
|||
|
self.ignoreme = bool;
|
|||
|
}
|
|||
|
|
|||
|
tarmac_colornodes_think()
|
|||
|
{
|
|||
|
thread bmp_03_colornodes();
|
|||
|
thread bmp_04_colornodes();
|
|||
|
}
|
|||
|
|
|||
|
bmp_03_colornodes()
|
|||
|
{
|
|||
|
level endon ("obj_enemy_armor_complete");
|
|||
|
flag_wait("bmp_03_destroyed");
|
|||
|
|
|||
|
triggersEnable("colornodes_tarmac_front", "script_noteworthy", false);
|
|||
|
triggersEnable("colornodes_tarmac_bmp_04_dead", "script_noteworthy", false);
|
|||
|
triggersEnable("colornodes_tarmac_bmp_03_dead", "script_noteworthy", true);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ACTIVATE THE MIDDLE COLORNODES NEAREST TO PLAYER
|
|||
|
-------------------------*/
|
|||
|
colornode_triggers = getentarray("colornodes_tarmac_bmp_03_dead", "script_noteworthy");
|
|||
|
eTrigger = getclosest(level.player.origin, colornode_triggers);
|
|||
|
eTrigger notify ("trigger", level.player);
|
|||
|
}
|
|||
|
|
|||
|
bmp_04_colornodes()
|
|||
|
{
|
|||
|
level endon ("obj_enemy_armor_complete");
|
|||
|
flag_wait("bmp_04_destroyed");
|
|||
|
|
|||
|
triggersEnable("colornodes_tarmac_rear", "script_noteworthy", false);
|
|||
|
triggersEnable("colornodes_tarmac_bmp_03_dead", "script_noteworthy", false);
|
|||
|
triggersEnable("colornodes_tarmac_bmp_04_dead", "script_noteworthy", true);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ACTIVATE THE MIDDLE COLORNODES NEAREST TO PLAYER
|
|||
|
-------------------------*/
|
|||
|
colornode_triggers = getentarray("colornodes_tarmac_bmp_04_dead", "script_noteworthy");
|
|||
|
eTrigger = getclosest(level.player.origin, colornode_triggers);
|
|||
|
eTrigger notify ("trigger", level.player);
|
|||
|
}
|
|||
|
|
|||
|
proceed_to_vents()
|
|||
|
{
|
|||
|
flag_wait ("obj_enemy_armor_complete");
|
|||
|
thread AA_vents_init();
|
|||
|
aAI_to_delete = getaiarray("axis");
|
|||
|
thread AI_delete_when_out_of_sight(aAI_to_delete, level.AIdeleteDistance);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
flag_set("player_near_launchtube_06");
|
|||
|
wait(2);
|
|||
|
flag_set("player_near_launchtube_05");
|
|||
|
}
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
LEVEL START: VENTS
|
|||
|
****************************************************************************/
|
|||
|
|
|||
|
AA_vents_init()
|
|||
|
{
|
|||
|
thread blackhawk_arrive();
|
|||
|
thread vents_objectives();
|
|||
|
thread vents_friendly_movement();
|
|||
|
thread hind_rocket_sequence();
|
|||
|
thread obj_north_tarmac();
|
|||
|
thread obj_rappel();
|
|||
|
thread player_rappel();
|
|||
|
thread vent_sequence();
|
|||
|
thread hind_attack();
|
|||
|
thread level_end();
|
|||
|
}
|
|||
|
|
|||
|
vents_objectives()
|
|||
|
{
|
|||
|
wait(1);
|
|||
|
flag_set("obj_north_tarmac_given");
|
|||
|
|
|||
|
flag_wait( "obj_rappel_given" );
|
|||
|
|
|||
|
flag_set("obj_north_tarmac_complete");
|
|||
|
}
|
|||
|
|
|||
|
blackhawk_arrive()
|
|||
|
{
|
|||
|
thread blackhawk_think();
|
|||
|
wait(1);
|
|||
|
trigger_blackhawk = getent("trigger_blackhawk", "script_noteworthy");
|
|||
|
trigger_blackhawk notify ("trigger", level.player);
|
|||
|
|
|||
|
wait (7);
|
|||
|
|
|||
|
level.peoplespeaking = true;
|
|||
|
//HQ radio
|
|||
|
//"Bravo Six, this is Strike Team Three inserting from the east. Repeat, we're movin' in from the east. Check your targets and confirm, over."
|
|||
|
level radio_dialogue("launchfacility_a_friendlies_east");
|
|||
|
|
|||
|
//Price
|
|||
|
//"Copy Team Three! We'll meet you at the north end of the tarmac, out!!"
|
|||
|
level.price dialogue_execute("launchfacility_a_price_copyteamthree");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
|
|||
|
thread vent_dialogue();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
vent_dialogue()
|
|||
|
{
|
|||
|
level waittill ("cutting_vents");
|
|||
|
|
|||
|
//Marine 3
|
|||
|
//Team, give us few seconds to cut through the vents.
|
|||
|
level thread radio_dialogue_queue("launchfacility_a_gm3_cutvents");
|
|||
|
|
|||
|
//Marine 01
|
|||
|
//Cutting. Standby.
|
|||
|
level thread radio_dialogue_queue("launchfacility_a_gm1_cutting");
|
|||
|
}
|
|||
|
|
|||
|
blackhawk_think()
|
|||
|
{
|
|||
|
eBlackhawk = maps\_vehicle::waittill_vehiclespawn("blackhawk");
|
|||
|
assert(isdefined(eBlackhawk.riders));
|
|||
|
println("there are " + eBlackhawk.riders.size + " dudes in the chopper");
|
|||
|
|
|||
|
|
|||
|
aStrikeTeamThree = eBlackhawk.riders;
|
|||
|
array_thread(aStrikeTeamThree, ::AI_friendly_reinforcements_think, eBlackhawk);
|
|||
|
eBlackhawk waittill("unload");
|
|||
|
|
|||
|
flag_set("blackhawk_dudes_unloaded");
|
|||
|
|
|||
|
wait (11);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
BLACKHAWK LEAVES
|
|||
|
-------------------------*/
|
|||
|
eBlackhawk_depart_path = getstruct("blackhawk_depart_path", "script_noteworthy");
|
|||
|
eBlackhawk vehicle_detachfrompath();
|
|||
|
eBlackhawk thread vehicle_dynamicpath(eBlackhawk_depart_path, false );
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
AI_friendly_reinforcements_think(eVehicle)
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
self.ignoreme = true;
|
|||
|
|
|||
|
wait(.5);
|
|||
|
if ( (isdefined(self.script_noteworthy)) && (self.script_noteworthy == "pilot") )
|
|||
|
{
|
|||
|
if ( isdefined( self.magic_bullet_shield ) )
|
|||
|
self stop_magic_bullet_shield();
|
|||
|
}
|
|||
|
|
|||
|
eVehicle waittill("unload");
|
|||
|
}
|
|||
|
|
|||
|
vents_friendly_movement()
|
|||
|
{
|
|||
|
disable_color_trigs();
|
|||
|
triggersEnable("colornodes_vents", "script_noteworthy", true);
|
|||
|
trig = getent("colornodes_vents", "script_noteworthy");
|
|||
|
trig notify ("trigger", level.player);
|
|||
|
|
|||
|
thread team02_rappel();
|
|||
|
thread team03_rappel();
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
TEAM ONE READY
|
|||
|
-------------------------*/
|
|||
|
flag_wait("team01_hooked_up");
|
|||
|
|
|||
|
//Price
|
|||
|
//"Squad, hook up! "
|
|||
|
level.price thread dialogue_execute("launchfacility_a_price_ropesout_01");
|
|||
|
flag_set("obj_rappel_given");
|
|||
|
|
|||
|
thread vent_nag();
|
|||
|
wait(2);
|
|||
|
flag_set("hinds_appear");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
vent_explode(iExploder)
|
|||
|
{
|
|||
|
ent = getent("exploder_sound_" + iExploder, "targetname");
|
|||
|
thread play_sound_in_space("detpack_explo_metal", ent.origin );
|
|||
|
exploder(iExploder);
|
|||
|
}
|
|||
|
|
|||
|
vent_sequence()
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
GET TEAM 01 VENT NODES
|
|||
|
-------------------------*/
|
|||
|
level.team01_sawGuysFinished = 0;
|
|||
|
level.team01_sawGuysInPosition = 0;
|
|||
|
level.team01_ventOpen = false;
|
|||
|
vent_org = getent( "vent_team_01", "targetname" );
|
|||
|
aVentNodes01 = getentarray("node_rappel_team_1", "targetname");
|
|||
|
assertex( aVentNodes01.size == 1, "there should be 1 script_origins with targetname 'node_rappel_team_1'" );
|
|||
|
aSawNodes01 = getentarray( "node_saw_team_1", "targetname" );
|
|||
|
assertex( aSawNodes01.size == 2, "there should be 2 script_origins with targetname 'node_saw_team_1'" );
|
|||
|
/*-----------------------
|
|||
|
ASSIGN TEAM 01 NODES
|
|||
|
-------------------------*/
|
|||
|
level.team01 = [];
|
|||
|
level.team01[0] = level.price;
|
|||
|
level.team01[1] = level.grigsby;
|
|||
|
aFriendlies = getaiarray("allies");
|
|||
|
aPossibleNumberThree = [];
|
|||
|
for(i=0;i<aFriendlies.size;i++)
|
|||
|
{
|
|||
|
if ( is_in_array( level.team01, aFriendlies[i] ) )
|
|||
|
continue;
|
|||
|
if ( is_in_array( level.team02, aFriendlies[i] ) )
|
|||
|
continue;
|
|||
|
if ( is_in_array( level.team03, aFriendlies[i] ) )
|
|||
|
continue;
|
|||
|
|
|||
|
aPossibleNumberThree[aPossibleNumberThree.size] = aFriendlies[i];
|
|||
|
}
|
|||
|
level.team01[2] = getclosest( vent_org.origin, aPossibleNumberThree );
|
|||
|
assertex( level.team01.size == 3, "Team 01 needs to be exactly 3 dudes. There are only " + level.team01.size );
|
|||
|
level.team01 = get_array_of_closest( vent_org.origin , level.team01 , undefined , level.team01.size );
|
|||
|
level.team01[0].rappelNode = aSawNodes01[0];
|
|||
|
level.team01[1].rappelNode = aSawNodes01[1];
|
|||
|
level.team01[2].rappelNode = aVentNodes01[0];
|
|||
|
eVent = getent( "vent_02", "targetname" );
|
|||
|
assert(isdefined(eVent));
|
|||
|
eVent thread vent_drop();
|
|||
|
array_thread ( level.team01, ::friendly_vent_think, level.team01, "01", eVent );
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GET TEAM 02 VENT NODES
|
|||
|
-------------------------*/
|
|||
|
level.team02_sawGuysFinished = 0;
|
|||
|
level.team02_sawGuysInPosition = 0;
|
|||
|
level.team02_ventOpen = false;
|
|||
|
vent_org = getent( "vent_team_02", "targetname" );
|
|||
|
aVentNodes02 = getentarray("node_rappel_team_2", "targetname");
|
|||
|
assertex( aVentNodes02.size == 2, "there should be 2 script_origins with targetname 'node_rappel_team_2'" );
|
|||
|
aSawNodes02 = getentarray( "node_saw_team_2", "targetname" );
|
|||
|
assertex( aSawNodes02.size == 2, "there should be 2 script_origins with targetname 'node_saw_team_2'" );
|
|||
|
/*-----------------------
|
|||
|
ASSIGN TEAM 02 NODES
|
|||
|
-------------------------*/
|
|||
|
level.team02 = array_removeDead(level.team02);
|
|||
|
assertex( level.team02.size > 2, "Team 01 needs to be at least 3 dudes. There are only " + level.team02.size );
|
|||
|
level.team02 = get_array_of_closest( vent_org.origin , level.team02 , undefined , level.team02.size );
|
|||
|
level.team02[0].rappelNode = aSawNodes02[0];
|
|||
|
level.team02[1].rappelNode = aSawNodes02[1];
|
|||
|
level.team02[2].rappelNode = aVentNodes02[0];
|
|||
|
eVent = getent( "vent_03", "targetname" );
|
|||
|
assert(isdefined(eVent));
|
|||
|
eVent thread vent_drop();
|
|||
|
array_thread ( level.team02, ::friendly_vent_think, level.team02, "02", eVent );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GET TEAM 03 VENT NODES
|
|||
|
-------------------------*/
|
|||
|
level.team03_sawGuysFinished = 0;
|
|||
|
level.team03_sawGuysInPosition = 0;
|
|||
|
level.team03_ventOpen = false;
|
|||
|
vent_org = getent( "vent_team_03", "targetname" );
|
|||
|
aVentNodes03 = getentarray("node_rappel_team_3", "targetname");
|
|||
|
assertex( aVentNodes03.size == 2, "there should be 2 script_origins with targetname 'node_rappel_team_3'. There are currently " + aVentNodes03.size );
|
|||
|
aSawNodes03 = getentarray( "node_saw_team_3", "targetname" );
|
|||
|
assertex( aSawNodes03.size == 2, "there should be 2 script_origins with targetname 'node_saw_team_3'" );
|
|||
|
|
|||
|
|
|||
|
flag_wait("blackhawk_dudes_unloaded");
|
|||
|
/*-----------------------
|
|||
|
ASSIGN TEAM 03 NODES
|
|||
|
-------------------------*/
|
|||
|
level.team03 = array_removeDead(level.team03);
|
|||
|
assertex( level.team03.size > 3, "Team 03 needs to be at least 4 dudes. There are only " + level.team03.size );
|
|||
|
level.team03 = get_array_of_closest( vent_org.origin , level.team03 , undefined , level.team03.size );
|
|||
|
level.team03[0].rappelNode = aSawNodes03[0];
|
|||
|
level.team03[1].rappelNode = aSawNodes03[1];
|
|||
|
level.team03[2].rappelNode = aVentNodes03[0];
|
|||
|
level.team03[3].rappelNode = aVentNodes03[1];
|
|||
|
eVent = getent( "vent_01", "targetname" );
|
|||
|
assert(isdefined(eVent));
|
|||
|
eVent thread vent_drop();
|
|||
|
array_thread ( level.team03, ::friendly_vent_think, level.team03, "03", eVent );
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
saw_notify_start( guy )
|
|||
|
{
|
|||
|
guy notify( "start" );
|
|||
|
}
|
|||
|
|
|||
|
saw_notify_stop( guy )
|
|||
|
{
|
|||
|
guy notify( "stop" );
|
|||
|
}
|
|||
|
|
|||
|
saw_notify_switch( guy )
|
|||
|
{
|
|||
|
guy notify( "switch" );
|
|||
|
}
|
|||
|
|
|||
|
saw_sound_and_fx(iSound, eVent, bVentDrop)
|
|||
|
{
|
|||
|
self attach("weapon_saw_rescue", "TAG_INHAND");
|
|||
|
if (iSound == "1")
|
|||
|
self thread play_sound_on_entity(level.scr_sound["launch_chopsaw1"]);
|
|||
|
else
|
|||
|
self thread play_sound_on_entity(level.scr_sound["launch_chopsaw2"]);
|
|||
|
|
|||
|
self waittill( "start" );
|
|||
|
self thread saw_sparks();
|
|||
|
self waittill( "stop" );
|
|||
|
self notify( "stop_sparks" );
|
|||
|
self waittill( "start" );
|
|||
|
self thread saw_sparks();
|
|||
|
self waittill( "stop" );
|
|||
|
self notify( "stop_sparks" );
|
|||
|
|
|||
|
if ( ( isdefined( bVentDrop ) ) && ( bVentDrop == true ) )
|
|||
|
eVent notify ("vent_drop");
|
|||
|
self waittill( "switch" );
|
|||
|
|
|||
|
org_hand = self gettagorigin("TAG_INHAND");
|
|||
|
angles_hand = self gettagangles("TAG_INHAND");
|
|||
|
self detach("weapon_saw_rescue", "TAG_INHAND");
|
|||
|
model_saw = spawn("script_model", org_hand);
|
|||
|
model_saw setmodel( "weapon_saw_rescue" );
|
|||
|
model_saw.angles = angles_hand;
|
|||
|
}
|
|||
|
|
|||
|
vent_drop()
|
|||
|
{
|
|||
|
org_sound = spawn( "script_origin", self.origin + ( 0, 0, -350 ) );
|
|||
|
assert(isdefined(org_sound));
|
|||
|
self waittill("vent_drop");
|
|||
|
thread play_sound_in_space( "launch_grate_falling", org_sound.origin);
|
|||
|
fTime = 2.5;
|
|||
|
newAngles = self.angles + ( 0, 0, 25 );
|
|||
|
self movez( -3500, fTime, fTime/3 );
|
|||
|
self rotateto( newAngles, 1, .2 );
|
|||
|
}
|
|||
|
|
|||
|
saw_sparks()
|
|||
|
{
|
|||
|
self endon( "stop_sparks" );
|
|||
|
|
|||
|
while( true )
|
|||
|
{
|
|||
|
playfxontag( getfx("saw_sparks"), self, "TAG_SPARKS");
|
|||
|
wait (.1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
friendly_vent_think( aTeam, sNumber, eVent )
|
|||
|
{
|
|||
|
if ( !isdefined( self ) )
|
|||
|
return;
|
|||
|
if ( !isalive( self ) )
|
|||
|
return;
|
|||
|
if ( !isdefined( self.rappelNode ) )
|
|||
|
return;
|
|||
|
|
|||
|
self.isSawDude = false;
|
|||
|
bVentDrop = undefined;
|
|||
|
self pushplayer( true );
|
|||
|
self.hookedUp = false;
|
|||
|
sFlagTeamInPosition = undefined;
|
|||
|
sFlagVentOpen = undefined;
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
SETUP ROPE AND HIDE FOR NOW
|
|||
|
-------------------------*/
|
|||
|
eRope = spawn_anim_model( "rope" );
|
|||
|
self.rappelNode thread anim_first_frame_solo( eRope, "rappel_setup_start" );
|
|||
|
eRope hide();
|
|||
|
|
|||
|
switch ( sNumber )
|
|||
|
{
|
|||
|
case "01":
|
|||
|
if ( (self != level.price) && (self != level.grigsby) )
|
|||
|
level.otherSquadFriendly = self;
|
|||
|
sFlagTeamInPosition = "team01_hooked_up";
|
|||
|
sFlagVentOpen = "vent02_open";
|
|||
|
break;
|
|||
|
case "02":
|
|||
|
sFlagTeamInPosition = "team02_hooked_up";
|
|||
|
sFlagVentOpen = "vent03_open";
|
|||
|
break;
|
|||
|
case "03":
|
|||
|
sFlagTeamInPosition = "team03_hooked_up";
|
|||
|
sFlagVentOpen = "vent01_open";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DO SAW SEQUENCE?
|
|||
|
-------------------------*/
|
|||
|
if ( issubstr( self.rappelNode.targetname, "node_saw_team" ) )
|
|||
|
{
|
|||
|
self.isSawDude = true;
|
|||
|
assert(isdefined(self.RappelNode.script_parameters));
|
|||
|
iNumber = self.RappelNode.script_parameters;
|
|||
|
|
|||
|
self disable_ai_color();
|
|||
|
eStartNode = getnode( "team_" + sNumber + "_saw_start_node_" + iNumber, "targetname" );
|
|||
|
assertex( isdefined( eStartNode ), "No node exists with targetname team_" + sNumber + "_saw_start_node_" + iNumber );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GET SAW DUDES TO NODES NEAR VENTS
|
|||
|
-------------------------*/
|
|||
|
if ( sNumber == "01" )
|
|||
|
self get_to_node_no_matter_what( eStartNode, 30 ); //If Price, etc...they absolutely positively must get there
|
|||
|
else
|
|||
|
{
|
|||
|
self setgoalnode( eStartNode );
|
|||
|
self waittill ( "goal" );
|
|||
|
}
|
|||
|
|
|||
|
switch ( sNumber )
|
|||
|
{
|
|||
|
case "01":
|
|||
|
if ( level.team01_sawGuysInPosition == 0 )
|
|||
|
bVentDrop = false;
|
|||
|
else
|
|||
|
bVentDrop = true;
|
|||
|
level.team01_sawGuysInPosition++;
|
|||
|
while ( level.team01_sawGuysInPosition != 2 )
|
|||
|
wait (0.05);
|
|||
|
break;
|
|||
|
case "02":
|
|||
|
if ( level.team02_sawGuysInPosition == 0 )
|
|||
|
bVentDrop = false;
|
|||
|
else
|
|||
|
bVentDrop = true;
|
|||
|
level.team02_sawGuysInPosition++;
|
|||
|
while ( level.team02_sawGuysInPosition != 2 )
|
|||
|
wait (0.05);
|
|||
|
break;
|
|||
|
case "03":
|
|||
|
if ( level.team03_sawGuysInPosition == 0 )
|
|||
|
bVentDrop = false;
|
|||
|
else
|
|||
|
bVentDrop = true;
|
|||
|
level.team03_sawGuysInPosition++;
|
|||
|
while ( level.team03_sawGuysInPosition != 2 )
|
|||
|
wait (0.05);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
wait(randomfloatrange(.5,.75));
|
|||
|
self.disableArrivals = true;
|
|||
|
self.rappelNode anim_reach_solo(self, "saw_" + iNumber + "_start");
|
|||
|
level notify ("cutting_vents");
|
|||
|
self thread saw_sound_and_fx(iNumber, eVent, bVentDrop);
|
|||
|
//self.rappelNode anim_custom_animmode_solo( self, "gravity", "saw_" + iNumber );
|
|||
|
self.rappelNode anim_single_solo( self, "saw_" + iNumber );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DO RAPPEL SETUP IDLE UNTIL VENT OPEN
|
|||
|
-------------------------*/
|
|||
|
if ( self.isSawDude == true )
|
|||
|
self setgoalpos( self.origin );
|
|||
|
|
|||
|
thread vent_flag( sNumber, sFlagVentOpen );
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DO RAPPEL ROPE THROW WHEN VENT OPEN
|
|||
|
-------------------------*/
|
|||
|
if ( self.isSawDude == false )
|
|||
|
flag_wait( sFlagVentOpen );
|
|||
|
|
|||
|
sAnim_rappel_setup_to_stand = undefined;
|
|||
|
sAnim_rappel_stand_idle = undefined;
|
|||
|
|
|||
|
if ( (isdefined(self.rappelNode)) && (isdefined(self.rappelNode.script_noteworthy)) && (self.rappelNode.script_noteworthy == "rappel_variation_1") )
|
|||
|
{
|
|||
|
sAnim_rappel_setup_to_stand = "rappel_setup_to_stand_1";
|
|||
|
sAnim_rappel_stand_idle = "rappel_stand_idle_1";
|
|||
|
}
|
|||
|
|
|||
|
else if ( (isdefined(self.rappelNode)) && (isdefined(self.rappelNode.script_noteworthy)) && (self.rappelNode.script_noteworthy == "rappel_variation_2") )
|
|||
|
{
|
|||
|
sAnim_rappel_setup_to_stand = "rappel_setup_to_stand_2";
|
|||
|
sAnim_rappel_stand_idle = "rappel_stand_idle_2";
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
sAnim_rappel_setup_to_stand = "rappel_setup_to_stand_2";
|
|||
|
sAnim_rappel_stand_idle = "rappel_stand_idle_3";
|
|||
|
}
|
|||
|
|
|||
|
//wait(randomfloatrange(1,2.75));
|
|||
|
self disable_ai_color();
|
|||
|
|
|||
|
if ( self.isSawDude == false )
|
|||
|
self.rappelNode anim_reach_solo (self, sAnim_rappel_setup_to_stand );
|
|||
|
|
|||
|
eRope show();
|
|||
|
/*-----------------------
|
|||
|
ROPE THROWN OUT
|
|||
|
-------------------------*/
|
|||
|
//thread rope_anim( self.rappelNode, eRope, sAnim_rappel_setup_to_stand, sAnim_rappel_stand_idle );
|
|||
|
self.rappelNode thread anim_single_solo(eRope, sAnim_rappel_setup_to_stand);
|
|||
|
self.rappelNode anim_single_solo(self, sAnim_rappel_setup_to_stand);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
IDLE ON ROPE
|
|||
|
-------------------------*/
|
|||
|
self.rappelNode thread anim_loop_solo (self, sAnim_rappel_stand_idle, undefined, "stop_idle");
|
|||
|
self.rappelNode thread anim_loop_solo (eRope, sAnim_rappel_stand_idle, undefined, "stop_idle");
|
|||
|
/*-----------------------
|
|||
|
IF ALL FRIENDLIES HOOKED UP, SET FLAG
|
|||
|
-------------------------*/
|
|||
|
self.hookedUp = true;
|
|||
|
|
|||
|
bTeamReady = true;
|
|||
|
for(i=0;i<aTeam.size;i++)
|
|||
|
{
|
|||
|
if (!isdefined(aTeam[i].hookedUp))
|
|||
|
continue;
|
|||
|
if (aTeam[i].hookedUp == false)
|
|||
|
bTeamReady = false;
|
|||
|
}
|
|||
|
if (bTeamReady)
|
|||
|
flag_set(sFlagTeamInPosition);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAITS TO RAPPEL IF PRICE/GRIGGS
|
|||
|
-------------------------*/
|
|||
|
if ( ( self == level.price) || ( self == level.grigsby ) )
|
|||
|
self waittill ("rappel_down_vent");
|
|||
|
else
|
|||
|
wait( randomfloatrange( 1, 3 ) );
|
|||
|
|
|||
|
self.rappelNode notify( "stop_idle" );
|
|||
|
self.rappelNode thread anim_single_solo(eRope, "rappel_drop");
|
|||
|
self.rappelNode anim_single_solo(self, "rappel_drop");
|
|||
|
|
|||
|
if ( isdefined( self.magic_bullet_shield ) )
|
|||
|
self stop_magic_bullet_shield();
|
|||
|
self delete();
|
|||
|
}
|
|||
|
|
|||
|
get_to_node_no_matter_what( eStartNode, iTimeout )
|
|||
|
{
|
|||
|
self thread teleport_or_timeout( eStartNode, iTimeout );
|
|||
|
self setgoalnode( eStartNode );
|
|||
|
self waittill ( "goal" );
|
|||
|
self.MadeItToGoal = true;
|
|||
|
}
|
|||
|
|
|||
|
teleport_or_timeout( eStartNode, iTimeout )
|
|||
|
{
|
|||
|
wait(5);
|
|||
|
/*-----------------------
|
|||
|
KILL THIS THREAD IF REACHES GOAL
|
|||
|
-------------------------*/
|
|||
|
self endon( "goal" );
|
|||
|
self waittill_notify_or_timeout( "bad_path", iTimeout );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
CAN'T GET THERE OR TIMED OUT
|
|||
|
-------------------------*/
|
|||
|
self thread teleport_behind_player_back( eStartNode );
|
|||
|
}
|
|||
|
|
|||
|
teleport_behind_player_back( eStartNode )
|
|||
|
{
|
|||
|
while ( !isdefined( self.MadeItToGoal ) )
|
|||
|
{
|
|||
|
wait( 0.05 );
|
|||
|
playerEye = level.player getEye();
|
|||
|
bDestInFOV = within_fov( playerEye, level.player getPlayerAngles(), eStartNode.origin, level.cosine[ "45" ]);
|
|||
|
if ( (!bDestInFOV) && ( !isdefined( self.MadeItToGoal ) ) )
|
|||
|
{
|
|||
|
self force_teleport( eStartNode.origin, eStartNode.angles );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
rope_anim( eNode, eRope, sAnim1, aAnim2 )
|
|||
|
{
|
|||
|
eNode anim_single_solo(eRope, sAnim1);
|
|||
|
eNode thread anim_loop_solo (eRope, aAnim2, undefined, "stop_idle");
|
|||
|
}
|
|||
|
|
|||
|
vent_flag( sNumber, sFlagVentOpen )
|
|||
|
{
|
|||
|
switch ( sNumber )
|
|||
|
{
|
|||
|
case "01":
|
|||
|
level.team01_sawGuysFinished++;
|
|||
|
while (level.team01_sawGuysFinished != 2)
|
|||
|
wait (0.05);
|
|||
|
break;
|
|||
|
case "02":
|
|||
|
level.team02_sawGuysFinished++;
|
|||
|
while (level.team02_sawGuysFinished != 2)
|
|||
|
wait (0.05);
|
|||
|
break;
|
|||
|
case "03":
|
|||
|
level.team03_sawGuysFinished++;
|
|||
|
while (level.team03_sawGuysFinished != 2)
|
|||
|
wait (0.05);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ( !flag( sFlagVentOpen ) )
|
|||
|
flag_set( sFlagVentOpen );
|
|||
|
}
|
|||
|
|
|||
|
team03_rappel()
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
TEAM THREE GOES DOWN
|
|||
|
-------------------------*/
|
|||
|
flag_wait("team03_hooked_up");
|
|||
|
|
|||
|
//Team Three rapelling now.
|
|||
|
level thread radio_dialogue_queue("launchfacility_a_gm3_rapellingnow");
|
|||
|
|
|||
|
|
|||
|
wait (3);
|
|||
|
//Marine 03
|
|||
|
//"Team Three is inside."
|
|||
|
level thread radio_dialogue_queue("launchfacility_a_marine3_teamin");
|
|||
|
}
|
|||
|
|
|||
|
team02_rappel()
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
TEAM TWO GOES DOWN
|
|||
|
-------------------------*/
|
|||
|
flag_wait("team02_hooked_up");
|
|||
|
|
|||
|
//Marine 02
|
|||
|
//"Team Two rappelling now."
|
|||
|
level thread radio_dialogue_queue("launchfacility_a_marine2_rappelling");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
player_rappel()
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
PLAYER ROPE
|
|||
|
-------------------------*/
|
|||
|
player_node = getnode( "player_rappel_node", "targetname" );
|
|||
|
eRope = spawn_anim_model( "player_rope" );
|
|||
|
eRope hide();
|
|||
|
player_node thread anim_loop_solo (eRope, "rappel_idle_for_player", undefined, "stop_idle");
|
|||
|
|
|||
|
flag_wait("obj_rappel_given");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GLOWING OBJ AND USE TRIGGERS
|
|||
|
-------------------------*/
|
|||
|
eRope show();
|
|||
|
obj_position = getent ("obj_rappel", "targetname");
|
|||
|
rappelObjModel = spawn ("script_model", obj_position.origin);
|
|||
|
rappelObjModel setmodel("rope_coil_obj");
|
|||
|
rappelObjModel.angles = obj_position.angles;
|
|||
|
trigRappel = getent("trig_rappel", "targetname");
|
|||
|
trigRappel sethintstring( &"SCRIPT_PLATFORM_HINTSTR_RAPPEL" );
|
|||
|
trigRappel waittill("trigger");
|
|||
|
trigRappel trigger_off();
|
|||
|
rappelObjModel setmodel("rope_coil");
|
|||
|
//effect delete();
|
|||
|
|
|||
|
flag_set("obj_rappel_complete");
|
|||
|
level.player EnableInvulnerability();
|
|||
|
level.player disableWeapons();
|
|||
|
|
|||
|
thread player_squad_rappel();
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
PLAYER PLAYS RAPPEL ANIMATION
|
|||
|
-------------------------*/
|
|||
|
|
|||
|
// this is the model the player will attach to for the rappel sequence
|
|||
|
model = spawn_anim_model( "player_rappel" );
|
|||
|
model hide();
|
|||
|
|
|||
|
// put the model in the first frame so the tags are in the right place
|
|||
|
player_node anim_first_frame_solo( model, "rappel" );
|
|||
|
|
|||
|
// this smoothly hooks the player up to the animating tag
|
|||
|
model lerp_player_view_to_tag( "tag_player", 0.5, 0.9, 35, 35, 45, 0 );
|
|||
|
|
|||
|
// now animate the tag and then unlink the player when the animation ends
|
|||
|
player_node thread anim_single_solo( model, "rappel" );
|
|||
|
eRope notify( "stop_idle" );
|
|||
|
player_node notify( "stop_idle" );
|
|||
|
player_node thread anim_single_solo( eRope, "rappel_for_player" );
|
|||
|
|
|||
|
//player_node waittill( "rappel" );
|
|||
|
//level.player unlink();
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
player_squad_rappel()
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
wait (1.2);
|
|||
|
|
|||
|
level.price notify ("rappel_down_vent");
|
|||
|
|
|||
|
wait (1);
|
|||
|
|
|||
|
level.grigsby notify ("rappel_down_vent");
|
|||
|
|
|||
|
set_vision_set( "launchfacility_a_rappel", 4 );
|
|||
|
|
|||
|
//SAS
|
|||
|
//Bloody hell, that was close
|
|||
|
//level thread radio_dialogue_queue("launchfacility_a_sas2_bloodyhell");
|
|||
|
|
|||
|
wait (2);
|
|||
|
|
|||
|
//Price
|
|||
|
//"Ok, we're in."
|
|||
|
level thread radio_dialogue("launchfacility_a_price_inside_facility");
|
|||
|
|
|||
|
wait(.75);
|
|||
|
level.player enableWeapons();
|
|||
|
wait (.25);
|
|||
|
flag_set("level_fade_out");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
hind_attack()
|
|||
|
{
|
|||
|
flag_wait("hinds_appear");
|
|||
|
|
|||
|
aAttackPointsHigher = getentarray("hind_attack_point_higher", "script_noteworthy");
|
|||
|
aAttackPointsLower = getentarray("hind_attack_point_lower", "script_noteworthy");
|
|||
|
assert(isdefined(aAttackPointsHigher));
|
|||
|
assert(isdefined(aAttackPointsLower));
|
|||
|
|
|||
|
wait (1.5);
|
|||
|
thread hind_attack_think(aAttackPointsHigher, "hind_end_higher");
|
|||
|
thread hind_attack_think(aAttackPointsLower, "hind_end_lower");
|
|||
|
|
|||
|
thread hind_sequence();
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
hind_sequence()
|
|||
|
{
|
|||
|
thread autosave_by_name("hinds_closing");
|
|||
|
|
|||
|
if( !flag( "obj_rappel_complete") )
|
|||
|
{
|
|||
|
level.peoplespeaking = true;
|
|||
|
//Sniper team
|
|||
|
//"Bravo Six, Two Hinds closing fast on your position. You gotta get outta sight, now!"
|
|||
|
level radio_dialogue_queue("launchfacility_a_recon_two_helis");
|
|||
|
|
|||
|
level.peoplespeaking = false;
|
|||
|
|
|||
|
wait(4.6);
|
|||
|
|
|||
|
flag_set("hind_rocket_sequence");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
hind_rocket_sequence()
|
|||
|
{
|
|||
|
level endon( "obj_rappel_complete" );
|
|||
|
flag_wait("hind_rocket_sequence");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
VARIABLE SETUP
|
|||
|
-------------------------*/
|
|||
|
eTarget = getent("rocket_target", "targetname");
|
|||
|
eDamageTrig = getent("rocket_damage", "targetname");
|
|||
|
eDamageTrig thread hind_tree_explosion();
|
|||
|
eDamageTrig thread hind_tree_fx(eTarget);
|
|||
|
|
|||
|
//level.hindAttacker settargetyaw(<yaw>)
|
|||
|
level.hindAttacker setLookAtEnt(eTarget);
|
|||
|
|
|||
|
//INCOMING!!!!!
|
|||
|
guy = get_closest_ally();
|
|||
|
if (isdefined(guy))
|
|||
|
guy dialogue_execute("launchfacility_a_gm1_incoming");
|
|||
|
|
|||
|
wait (.5);
|
|||
|
|
|||
|
level.hindAttacker maps\_helicopter_globals::fire_missile( "ffar_hind_nodamage", 2, eTarget, .75);
|
|||
|
|
|||
|
wait(.5);
|
|||
|
//cleartargetyaw();
|
|||
|
level.hindAttacker clearLookAtEnt();
|
|||
|
|
|||
|
|
|||
|
|
|||
|
wait(3);
|
|||
|
flag_set("hind_missiles_fired");
|
|||
|
}
|
|||
|
|
|||
|
hind_tree_explosion()
|
|||
|
{
|
|||
|
level endon ("hind_missiles_fired");
|
|||
|
eTarget = getent("rocket_target", "targetname");
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
self waittill ("damage", amount, attacker);
|
|||
|
if (attacker == level.player)
|
|||
|
continue;
|
|||
|
iRand = randomIntRange(1, 4);
|
|||
|
thread play_sound_in_space( "launch_rocket_hit_treeline", eTarget.origin);
|
|||
|
earthquake (0.8, 2, eTarget.origin, 2000);
|
|||
|
fRand = randomfloatrange(0, 150);
|
|||
|
playfx ( getfx("hind_explosion"), eTarget.origin + (fRand, 0, 0));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
hind_tree_fx(eTarget)
|
|||
|
{
|
|||
|
self waittill ("damage", amount, attacker);
|
|||
|
if (attacker == level.player)
|
|||
|
return;
|
|||
|
thread hind_trees_fall();
|
|||
|
aFireOrgs = getentarray("tree_fire", "targetname");
|
|||
|
assertEx(aFireOrgs.size <= level._effect["tree_fire_fx"].size, "There are more 'tree_fire' script_origins than there are 'tree_fire_fx' to play on them");
|
|||
|
for(i=0;i<aFireOrgs.size;i++)
|
|||
|
{
|
|||
|
playfx ( level._effect["tree_fire_fx"][i], aFireOrgs[i].origin);
|
|||
|
}
|
|||
|
|
|||
|
eTarget thread play_sound_in_space("medfire");
|
|||
|
}
|
|||
|
|
|||
|
hind_trees_fall()
|
|||
|
{
|
|||
|
aTrees = getentarray("trees_end", "script_noteworthy");
|
|||
|
minAngles = 18;
|
|||
|
maxAngles = 35;
|
|||
|
for(i=0;i<aTrees.size;i++)
|
|||
|
{
|
|||
|
fRotateTime = randomfloatrange(.5, 1.5);
|
|||
|
ang = aTrees[i].angles;
|
|||
|
ang += (randomfloatrange(minAngles, maxAngles),randomfloatrange(minAngles, maxAngles),randomfloatrange(minAngles, maxAngles));
|
|||
|
aTrees[i] thread hind_tree_rotate(ang, fRotateTime);
|
|||
|
//wait (randomfloatrange(.25, .8));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
hind_tree_rotate(ang, fRotateTime)
|
|||
|
{
|
|||
|
self rotateto(ang, fRotateTime, fRotateTime/2, fRotateTime/2);
|
|||
|
}
|
|||
|
|
|||
|
hind_go_to_vent()
|
|||
|
{
|
|||
|
if (!isdefined(self))
|
|||
|
return;
|
|||
|
|
|||
|
flag_wait("obj_rappel_complete");
|
|||
|
org = getent("hind_above_vent", "targetname");
|
|||
|
assert(isdefined(org));
|
|||
|
self clearLookAtEnt();
|
|||
|
self setspeed(200, 15, 15);
|
|||
|
self setvehgoalpos(org.origin, true);
|
|||
|
}
|
|||
|
|
|||
|
hind_attack_think(aAttackPoints, sTargetname)
|
|||
|
{
|
|||
|
level endon ("obj_rappel_complete");
|
|||
|
eHind = spawn_vehicle_from_targetname(sTargetname);
|
|||
|
|
|||
|
if ( (isdefined(eHind.script_noteworthy)) && (eHind.script_noteworthy == "hind_rocket_attacker") )
|
|||
|
level.hindAttacker = eHind;
|
|||
|
|
|||
|
eHind endon ("death");
|
|||
|
|
|||
|
if (sTargetname == "hind_end_lower")
|
|||
|
eHind thread hind_go_to_vent();
|
|||
|
|
|||
|
eStartPoint = getent(eHind.target, "targetname");
|
|||
|
eHind setspeed(120, 15, 15);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GO TO THE END OF PATH, THEN ATTACK
|
|||
|
-------------------------*/
|
|||
|
eHind setneargoalnotifydist(500);
|
|||
|
dest = getent(eStartPoint.target, "targetname");
|
|||
|
eHind setvehgoalpos(dest.origin, false);
|
|||
|
eHind waittill ("near_goal");
|
|||
|
eHind vehicle_detachfrompath();
|
|||
|
eHind thread hind_guns_think();
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GET ON LOOP PATH
|
|||
|
-------------------------*/
|
|||
|
eAttackPoint = getent(dest.script_linkTo, "script_linkname");
|
|||
|
assert(isdefined(eAttackPoint));
|
|||
|
eHind setvehgoalpos(eAttackPoint.origin, true);
|
|||
|
eHind waittill ("near_goal");
|
|||
|
eHind setLookAtEnt(level.player);
|
|||
|
eHind setspeed(30, 15, 15);
|
|||
|
|
|||
|
dest = eAttackPoint;
|
|||
|
bStrafe = false;
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
bStrafe = false;
|
|||
|
/*-----------------------
|
|||
|
STRAFE IF DEFINED AND PLAYER A TARGET
|
|||
|
-------------------------*/
|
|||
|
if (isdefined(dest.script_linkTo))
|
|||
|
{
|
|||
|
sStrafeNumber = getsubstr(dest.targetname, 7);
|
|||
|
eStrafeVolume = getent("strafe_volume_" + sStrafeNumber, "targetname");
|
|||
|
assert(isdefined(eStrafeVolume));
|
|||
|
if (level.player istouching(eStrafeVolume))
|
|||
|
{
|
|||
|
dest = getent(dest.script_linkTo, "script_linkname");
|
|||
|
eHind clearLookAtEnt();
|
|||
|
eHind setspeed(200, 15, 15);
|
|||
|
bStrafe = true;
|
|||
|
}
|
|||
|
}
|
|||
|
/*-----------------------
|
|||
|
JUST GET NEXT NODE IN CHAIN
|
|||
|
-------------------------*/
|
|||
|
if (bStrafe == false)
|
|||
|
{
|
|||
|
dest = getent(dest.target, "targetname");
|
|||
|
eHind setLookAtEnt(level.player);
|
|||
|
eHind setspeed(30, 15, 15);
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GO TO NEXT NODE (STRAFE OR RING)
|
|||
|
-------------------------*/
|
|||
|
eHind setvehgoalpos(dest.origin, false);
|
|||
|
eHind waittill ("near_goal");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
hind_guns_think()
|
|||
|
{
|
|||
|
level endon ("obj_rappel_complete");
|
|||
|
self endon ("death");
|
|||
|
flag_wait("hind_missiles_fired");
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait (randomfloatrange(2, 5));
|
|||
|
self thread fireMG(randomintrange(8, 17));
|
|||
|
wait (randomfloatrange(2, 5));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
level_end()
|
|||
|
{
|
|||
|
flag_wait("level_fade_out");
|
|||
|
|
|||
|
maps\_loadout::SavePlayerWeaponStatePersistent( "launchfacility_a" );
|
|||
|
nextmission();
|
|||
|
}
|
|||
|
|
|||
|
vent_nag()
|
|||
|
{
|
|||
|
level endon ("obj_rappel_complete");
|
|||
|
wait (6.5);
|
|||
|
thread vent_nag_cleanup();
|
|||
|
if (!flag("obj_rappel_complete"))
|
|||
|
thread hint(&"LAUNCHFACILITY_A_HINTSTR_RAPPEL_DOWN_SHAFT", 9999);
|
|||
|
|
|||
|
while (!flag("obj_rappel_complete"))
|
|||
|
{
|
|||
|
wait(randomfloatrange(6, 10));
|
|||
|
{
|
|||
|
level.launchfacility_a_price_ropenag_number++;
|
|||
|
if (level.launchfacility_a_price_ropenag_number > level.launchfacility_a_price_ropenag_MAX)
|
|||
|
level.launchfacility_a_price_ropenag_number = 1;
|
|||
|
|
|||
|
sDialogue = "launchfacility_a_price_ropenag_0" + level.launchfacility_a_price_ropenag_number;
|
|||
|
level.price dialogue_execute(sDialogue);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
vent_nag_cleanup()
|
|||
|
{
|
|||
|
flag_wait("obj_rappel_complete");
|
|||
|
thread hint_fade();
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
//friendly_vent_think2(sTeam)
|
|||
|
//{
|
|||
|
// self endon ("death");
|
|||
|
//
|
|||
|
// if (!isdefined(self))
|
|||
|
// return;
|
|||
|
// if (!isalive(self))
|
|||
|
// return;
|
|||
|
//
|
|||
|
// /*-----------------------
|
|||
|
// EACH AI GETS ASSIGNED CLOSEST NODE
|
|||
|
// -------------------------*/
|
|||
|
//
|
|||
|
// self.rappelNode = undefined;
|
|||
|
// self.hookedUp = false;
|
|||
|
// sFlagVentOpen = undefined;
|
|||
|
// sFlagTeamInPosition = undefined;
|
|||
|
// sDialogue = undefined;
|
|||
|
// aTeam = undefined;
|
|||
|
//
|
|||
|
// switch (sTeam)
|
|||
|
// {
|
|||
|
// case "01":
|
|||
|
// aTeam = level.team01;
|
|||
|
// if (!level.ventNodes01.size > 0)
|
|||
|
// {
|
|||
|
// self.hookedUp = true;
|
|||
|
// return;
|
|||
|
// }
|
|||
|
// self.rappelNode = getclosest(self.origin, level.ventNodes01);
|
|||
|
// level.ventNodes01 = array_remove(level.ventNodes01, self.rappelNode);
|
|||
|
// sFlagTeamInPosition = "team01_hooked_up";
|
|||
|
// sFlagVentOpen = "vent02_open";
|
|||
|
// if (!isdefined(level.team01breacher))
|
|||
|
// {
|
|||
|
// level.team01breacher = self;
|
|||
|
// self thread friendly_breach_vent("02", sFlagVentOpen);
|
|||
|
// }
|
|||
|
// if ( (self != level.price) && (self != level.grigsby) )
|
|||
|
// level.otherSquadFriendly = self;
|
|||
|
// break;
|
|||
|
// case "02":
|
|||
|
// aTeam = level.team02;
|
|||
|
// if (!level.ventNodes02.size > 0)
|
|||
|
// {
|
|||
|
// self.hookedUp = true;
|
|||
|
// return;
|
|||
|
// }
|
|||
|
// self.rappelNode = getclosest(self.origin, level.ventNodes02);
|
|||
|
// level.ventNodes02 = array_remove(level.ventNodes02, self.rappelNode);
|
|||
|
// sFlagTeamInPosition = "team02_hooked_up";
|
|||
|
// sFlagVentOpen = "vent03_open";
|
|||
|
// sDialogue = "launchfacility_a_marine2_rappelling";
|
|||
|
// if (!isdefined(level.team02breacher))
|
|||
|
// {
|
|||
|
// level.team02breacher = self;
|
|||
|
// self thread friendly_breach_vent("03", sFlagVentOpen);
|
|||
|
// }
|
|||
|
// break;
|
|||
|
// case "03":
|
|||
|
// aTeam = level.team03;
|
|||
|
// if (!level.ventNodes03.size > 0)
|
|||
|
// {
|
|||
|
// self.hookedUp = true;
|
|||
|
// return;
|
|||
|
// }
|
|||
|
// self.rappelNode = getclosest(self.origin, level.ventNodes03);
|
|||
|
// level.ventNodes03 = array_remove(level.ventNodes03, self.rappelNode);
|
|||
|
// sFlagTeamInPosition = "team03_hooked_up";
|
|||
|
// sFlagVentOpen = "vent01_open";
|
|||
|
// sDialogue = "launchfacility_a_marine3_teamin";
|
|||
|
// if (!isdefined(level.team03breacher))
|
|||
|
// {
|
|||
|
// level.team03breacher = self;
|
|||
|
// self thread friendly_breach_vent("01", sFlagVentOpen);
|
|||
|
// }
|
|||
|
// break;
|
|||
|
// }
|
|||
|
//
|
|||
|
// flag_wait(sFlagVentOpen);
|
|||
|
// while (!isdefined(self.rappelNode))
|
|||
|
// wait (0.05);
|
|||
|
//
|
|||
|
// /*-----------------------
|
|||
|
// PICK RAPPEL IDLES AND SETUP
|
|||
|
// -------------------------*/
|
|||
|
// sAnim_rappel_setup_to_stand = undefined;
|
|||
|
// sAnim_rappel_stand_idle = undefined;
|
|||
|
// if ( (isdefined(self.rappelNode)) && (isdefined(self.rappelNode.targetname)) && (self.rappelNode.targetname == "rappel_variation_1") )
|
|||
|
// {
|
|||
|
// sAnim_rappel_setup_to_stand = "rappel_setup_to_stand_1";
|
|||
|
// sAnim_rappel_stand_idle = "rappel_stand_idle_1";
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// sAnim_rappel_setup_to_stand = "rappel_setup_to_stand_2";
|
|||
|
// sAnim_rappel_stand_idle = "rappel_stand_idle_2";
|
|||
|
// }
|
|||
|
//
|
|||
|
// /*-----------------------
|
|||
|
// FRIENDLY HOOKS UP TO ROPE
|
|||
|
// -------------------------*/
|
|||
|
// self disable_ai_color();
|
|||
|
// self.rappelNode anim_reach_solo (self, "rappel_setup_start");
|
|||
|
// self.rappelNode anim_single_solo(self, "rappel_setup_start");
|
|||
|
// self.rappelNode anim_single_solo(self, sAnim_rappel_setup_to_stand);
|
|||
|
// self.rappelNode thread anim_loop_solo (self, sAnim_rappel_stand_idle, undefined, "stop_idle");
|
|||
|
//
|
|||
|
// self.hookedUp = true;
|
|||
|
//
|
|||
|
// /*-----------------------
|
|||
|
// IF ALL FRIENDLIES HOOKED UP, SET FLAG
|
|||
|
// -------------------------*/
|
|||
|
// bTeamReady = true;
|
|||
|
// for(i=0;i<aTeam.size;i++)
|
|||
|
// {
|
|||
|
// if (aTeam[i].hookedUp == false)
|
|||
|
// bTeamReady = false;
|
|||
|
// }
|
|||
|
// if (bTeamReady)
|
|||
|
// flag_set(sFlagTeamInPosition);
|
|||
|
//
|
|||
|
// /*-----------------------
|
|||
|
// WAITS AND THEN RAPPELS DOWN
|
|||
|
// -------------------------*/
|
|||
|
// self waittill ("rappel_down_vent");
|
|||
|
//
|
|||
|
// self.rappelNode anim_single_solo(self, "rappel_drop");
|
|||
|
//
|
|||
|
// self stop_magic_bullet_shield();
|
|||
|
// self delete();
|
|||
|
//}
|
|||
|
|
|||
|
friendly_breach_vent(sVentNumber, sFlagVentOpen)
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
self disable_ai_color();
|
|||
|
|
|||
|
eAnimEnt = getent("node_scripted_vent_" + sVentNumber, "script_noteworthy");
|
|||
|
assert(isdefined(eAnimEnt));
|
|||
|
eAnimEnt anim_reach_solo (self, "C4_plant_start");
|
|||
|
eAnimEnt anim_single_solo(self, "C4_plant");
|
|||
|
self enable_ai_color();
|
|||
|
wait (3);
|
|||
|
|
|||
|
switch (sVentNumber)
|
|||
|
{
|
|||
|
case "01":
|
|||
|
thread vent_explode(600);
|
|||
|
break;
|
|||
|
case "02":
|
|||
|
thread vent_explode(700);
|
|||
|
break;
|
|||
|
case "03":
|
|||
|
thread vent_explode(800);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
VENT HAS BEEN BREACHED
|
|||
|
-------------------------*/
|
|||
|
flag_set(sFlagVentOpen);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
UTILITY FUNCTIONS
|
|||
|
****************************************************************************/
|
|||
|
AA_utility()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
initDifficulty()
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
SETUP VARIABLES
|
|||
|
-------------------------*/
|
|||
|
skill = getdifficulty();
|
|||
|
level.skill = undefined;
|
|||
|
switch( skill )
|
|||
|
{
|
|||
|
case "gimp":
|
|||
|
case "easy":
|
|||
|
level.skill = "easy";
|
|||
|
break;
|
|||
|
case "medium":
|
|||
|
level.skill = "medium";
|
|||
|
break;
|
|||
|
case "hard":
|
|||
|
case "difficult":
|
|||
|
level.skill = "hard";
|
|||
|
break;
|
|||
|
case "fu":
|
|||
|
level.skill = "veteran";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DELETE EASY WEAPON CACHES
|
|||
|
-------------------------*/
|
|||
|
easyWeapons = getentarray("gameskill_easy", "script_noteworthy");
|
|||
|
assertEx((isdefined(easyWeapons)), "No weapons found with script_noteworthy 'gameskill_easy'");
|
|||
|
mediumWeapons = getentarray("gameskill_medium", "script_noteworthy");
|
|||
|
assertEx((isdefined(easyWeapons)), "No weapons found with script_noteworthy 'gameskill_medium'");
|
|||
|
switch( level.skill )
|
|||
|
{
|
|||
|
case "medium":
|
|||
|
array_thread (easyWeapons, ::deleteWeapons);
|
|||
|
break;
|
|||
|
case "hard":
|
|||
|
case "veteran":
|
|||
|
array_thread (easyWeapons, ::deleteWeapons);
|
|||
|
array_thread (mediumWeapons, ::deleteWeapons);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bmp_nags( sFlagEndon, bHintPrint, bLongWait )
|
|||
|
{
|
|||
|
level endon( sFlagEndon );
|
|||
|
while ( !flag( sFlagEndon ) )
|
|||
|
{
|
|||
|
level.launchfacility_a_price_bmp_nag_number++;
|
|||
|
if (level.launchfacility_a_price_bmp_nag_number > level.launchfacility_a_price_bmp_nag_MAX)
|
|||
|
level.launchfacility_a_price_bmp_nag_number = 1;
|
|||
|
|
|||
|
sDialogue = "launchfacility_a_price_bmp_nag_0" + level.launchfacility_a_price_bmp_nag_number;
|
|||
|
if ( ( level.launchfacility_a_price_bmp_nag_number == 7 ) || ( level.launchfacility_a_price_bmp_nag_number == 8 ) )
|
|||
|
level.grigsby dialogue_execute(sDialogue);
|
|||
|
else
|
|||
|
level.price dialogue_execute(sDialogue);
|
|||
|
|
|||
|
if ( ( isdefined( bHintPrint ) ) && ( bHintPrint == true ) )
|
|||
|
thread hint(&"SCRIPT_PLATFORM_LAUNCHFACILITY_A_HINT_PLANT_C4_GLOW", 7);
|
|||
|
|
|||
|
if ( ( isdefined( bLongWait ) ) && ( bLongWait == true ) )
|
|||
|
wait(randomfloatrange(20,30));
|
|||
|
else
|
|||
|
wait(randomfloatrange(10,15));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
deleteWeapons()
|
|||
|
{
|
|||
|
if (isdefined(self))
|
|||
|
self delete();
|
|||
|
}
|
|||
|
|
|||
|
migs_flyby1()
|
|||
|
{
|
|||
|
flag_wait("migs_flyby1");
|
|||
|
trigger_migs_intro = getent("trigger_migs_intro", "script_noteworthy");
|
|||
|
trigger_migs_intro notify ("trigger", level.player);
|
|||
|
}
|
|||
|
|
|||
|
migs_flyby2()
|
|||
|
{
|
|||
|
flag_wait("migs_flyby2");
|
|||
|
trigger_migs_end = getent("trigger_migs_end", "script_noteworthy");
|
|||
|
trigger_migs_end notify ("trigger", level.player);
|
|||
|
}
|
|||
|
|
|||
|
sniper_activity()
|
|||
|
{
|
|||
|
level.aSniper_orgs = getentarray("sniper_position_container", "targetname");
|
|||
|
flag_wait ("obj_gain_access_complete");
|
|||
|
level.aSniper_orgs = getentarray("sniper_position_tarmac", "targetname");
|
|||
|
}
|
|||
|
|
|||
|
rpg_ambient(aRpgSources, aRpgTargets, iQuantity)
|
|||
|
{
|
|||
|
iRpgs = 0;
|
|||
|
while (iRpgs < iQuantity)
|
|||
|
{
|
|||
|
iRpgs++;
|
|||
|
assertEx(aRpgSources.size > 0, "No more RPG sources left");
|
|||
|
assertEx(aRpgTargets.size > 0, "No more RPG targets left");
|
|||
|
eSource = getFarthest(level.player.origin, aRpgSources);
|
|||
|
aRpgSources = array_remove(aRpgSources, eSource);
|
|||
|
eTarget = getClosest(level.player.origin, aRpgTargets);
|
|||
|
//attractorRPG = missile_createAttractorEnt( eTarget, 10000, 6000 );
|
|||
|
aRpgTargets = array_remove(aRpgTargets, eTarget);
|
|||
|
magicbullet("rpg", eSource.origin, eTarget.origin);
|
|||
|
wait(randomfloatrange(1.5,2.5));
|
|||
|
//missile_deleteAttractor(attractorRPG);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
c4_plant_think()
|
|||
|
{
|
|||
|
iExploderNum = self.script_noteworthy;
|
|||
|
assertEx((isdefined(iExploderNum)), "Need to specify an integer for the exploder number to be used with this entity");
|
|||
|
eApproachTrigger = getent( self.target, "targetname" );
|
|||
|
assertEx((isdefined(eApproachTrigger)), "script_origin needs to target a trigger_multiple");
|
|||
|
eApproachTrigger waittill ( "trigger" );
|
|||
|
|
|||
|
self maps\_c4::c4_location( undefined, (0, 0, 0), (0, 0, 0), self.origin );
|
|||
|
self waittill( "c4_detonation" );
|
|||
|
exploder(iExploderNum);
|
|||
|
|
|||
|
self thread play_sound_in_space("detpack_explo_concrete");
|
|||
|
|
|||
|
if ( isdefined( level.c4_callback_thread ) )
|
|||
|
self thread [[ level.c4_callback_thread ]]();
|
|||
|
}
|
|||
|
|
|||
|
launch_lid_setup()
|
|||
|
{
|
|||
|
thread launch_lid_think("03");
|
|||
|
thread launch_lid_think("04");
|
|||
|
thread launch_lid_think("05");
|
|||
|
thread launch_lid_think("06");
|
|||
|
}
|
|||
|
|
|||
|
launch_flag_management(iTubeNumber)
|
|||
|
{
|
|||
|
sFlag = "player_near_launchtube_" + iTubeNumber;
|
|||
|
flag_wait(sFlag);
|
|||
|
sOtherFlag = undefined;
|
|||
|
|
|||
|
wait(2);
|
|||
|
if (iTubeNumber == "03")
|
|||
|
sOtherFlag = "player_near_launchtube_04";
|
|||
|
if (iTubeNumber == "04")
|
|||
|
sOtherFlag = "player_near_launchtube_03";
|
|||
|
if (iTubeNumber == "05")
|
|||
|
sOtherFlag = "player_near_launchtube_06";
|
|||
|
if (iTubeNumber == "06")
|
|||
|
sOtherFlag = "player_near_launchtube_05";
|
|||
|
|
|||
|
if (!flag(sOtherFlag))
|
|||
|
flag_set(sOtherFlag);
|
|||
|
}
|
|||
|
|
|||
|
launch_lid_think(iTubeNumber)
|
|||
|
{
|
|||
|
|
|||
|
thread launch_flag_management(iTubeNumber);
|
|||
|
/*-----------------------
|
|||
|
VARIABLE SETUP
|
|||
|
-------------------------*/
|
|||
|
sFlag = "player_near_launchtube_" + iTubeNumber;
|
|||
|
eLidArm = getent("lid_arm_" + iTubeNumber, "targetname");
|
|||
|
eLid = getent("lid_" + iTubeNumber, "targetname");
|
|||
|
eLid.trigger = getent( "trigger_hurt_player_lid_" + iTubeNumber, "targetname" );
|
|||
|
eLid.trigger enablelinkto();
|
|||
|
eLidFxEnt = getent("lid_fx_" + iTubeNumber, "targetname");
|
|||
|
eLidFxEnt.opening = false;
|
|||
|
eAnimEnt = getent("lid_origin_" + iTubeNumber, "targetname");
|
|||
|
assert(isdefined(eLid.trigger));
|
|||
|
assert(isdefined(eLidArm));
|
|||
|
assert(isdefined(eLid));
|
|||
|
assert(isdefined(eAnimEnt));
|
|||
|
eLid.rotationDummy = spawn( "script_origin", ( 0, 0, 0 ) );
|
|||
|
eLid.rotationDummy.angles = eAnimEnt.angles;
|
|||
|
eLid.rotationDummy.origin = eAnimEnt.origin;
|
|||
|
eLidArm.rotationDummy = spawn( "script_origin", ( 0, 0, 0 ) );
|
|||
|
eLidArm.rotationDummy.angles = eAnimEnt.angles;
|
|||
|
eLidArm.rotationDummy.origin = eAnimEnt.origin;
|
|||
|
eLid linkTo(eLid.rotationDummy);
|
|||
|
eLidArm linkTo(eLidArm.rotationDummy);
|
|||
|
eLid.trigger linkTo(eLid.rotationDummy);
|
|||
|
eMissile = getent("missile" + iTubeNumber, "targetname");
|
|||
|
assert(isdefined(eMissile));
|
|||
|
assert(isdefined(eMissile.target));
|
|||
|
eMissileKilltrig = getent( eMissile.target, "targetname" );
|
|||
|
assert(isdefined(eMissileKilltrig));
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ROTATE ARMAS DOWN IMMEDIATELY IN PREP
|
|||
|
-------------------------*/
|
|||
|
eLidArm.rotationDummy rotatepitch(125, .5);
|
|||
|
//moveto( <point>, <time>, <acceleration time>, <deceleration time> )
|
|||
|
eLidArm.rotationDummy moveto(eLidArm.rotationDummy.origin + (0, 0, -50), .5);
|
|||
|
/*-----------------------
|
|||
|
WAIT UNTIL PLAYER CLOSE TO LID
|
|||
|
-------------------------*/
|
|||
|
flag_wait(sFlag);
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
INITIAL PARTICLES AND SOUND
|
|||
|
-------------------------*/
|
|||
|
eLidFxEnt thread launch_lid_alarm();
|
|||
|
eLidFxEnt playsound (level.scr_sound["launch_tube_prepare"], "sounddone");
|
|||
|
playfx (level._effect["launchtube_steam"], eLidFxEnt.origin);
|
|||
|
|
|||
|
eLidFxEnt waittill ("sounddone");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
BADPLACE
|
|||
|
-------------------------*/
|
|||
|
eBadplace = getent("badplace_lid_" + iTubeNumber, "targetname");
|
|||
|
assertEx((isdefined(eBadplace)), "There is no volume with targetname badplace_lid_" + iTubeNumber);
|
|||
|
badplace_brush("badplace_lid_volume" + iTubeNumber, 0, eBadplace, "allies", "axis");
|
|||
|
//badplace_cylinder("badplace_lid_volume" + iTubeNumber, 0, eAnimEnt.origin, 225, 512, "axis", "allies");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ROTATE LID OUTWARDS AND PLAY LOOP SOUND
|
|||
|
-------------------------*/
|
|||
|
iOpenTime = 20;
|
|||
|
|
|||
|
eLidFxEnt.opening = true;
|
|||
|
eLid thread lid_kill( iTubeNumber, eLidFxEnt );
|
|||
|
eLidFxEnt thread launch_lid_sound();
|
|||
|
|
|||
|
eMissile thread missile_move();
|
|||
|
|
|||
|
eLid.rotationDummy rotatepitch(-125, iOpenTime, 2, 2);
|
|||
|
eLidArm.rotationDummy rotatepitch(-125, iOpenTime/1.5, 1, 1);
|
|||
|
eLidArm.rotationDummy moveto(eLidArm.rotationDummy.origin + (0, 0, 50), (iOpenTime/2.5), 0, 2);
|
|||
|
wait (iOpenTime - 1);
|
|||
|
eLidFxEnt.opening = false;
|
|||
|
eLidFxEnt notify("stopped_opening");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
CLEANUP
|
|||
|
-------------------------*/
|
|||
|
wait (2);
|
|||
|
eLid.rotationDummy delete();
|
|||
|
eLidArm.rotationDummy delete();
|
|||
|
eAnimEnt delete();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
lid_kill(iTubeNumber, eLidFxEnt)
|
|||
|
{
|
|||
|
|
|||
|
while ( eLidFxEnt.opening == true )
|
|||
|
{
|
|||
|
wait( 0.05 );
|
|||
|
if ( level.player istouching( self.trigger ) )
|
|||
|
{
|
|||
|
level notify( "new_quote_string" );
|
|||
|
setdvar( "ui_deadquote", &"LAUNCHFACILITY_A_DEADQUOTE_KILLED_BY_LID" );
|
|||
|
level.player dodamage(level.player.health + 1000, level.player.origin );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
missile_move()
|
|||
|
{
|
|||
|
//self ==> the missile
|
|||
|
self moveto( self.origin + (0, 0, 175), 18, 4, 4);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
launch_lid_sound()
|
|||
|
{
|
|||
|
//self ==> eLidFxEnt script_origin
|
|||
|
self playsound (level.scr_sound["launch_tube_open_start"]);
|
|||
|
wait(1);
|
|||
|
self thread play_loop_sound_on_entity (level.scr_sound["launch_tube_open_loop"]);
|
|||
|
self waittill ("stopped_opening");
|
|||
|
self notify ( "stop sound" + level.scr_sound["launch_tube_open_loop"]);
|
|||
|
self playsound (level.scr_sound["launch_tube_open_end"]);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
launch_lid_alarm()
|
|||
|
{
|
|||
|
if ( ( isdefined( level.lidLoopPlaying ) ) && ( level.lidLoopPlaying == true ) )
|
|||
|
return;
|
|||
|
level.lidLoopPlaying = true;
|
|||
|
self play_sound_on_entity( "emt_alarm_launch_doors" );
|
|||
|
level.lidLoopPlaying = false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
disable_color_trigs()
|
|||
|
{
|
|||
|
array_thread(level.aColornodeTriggers, ::trigger_off);
|
|||
|
}
|
|||
|
|
|||
|
dialogue_loudspeaker(sDialogue)
|
|||
|
{
|
|||
|
|
|||
|
level.player play_sound_on_entity(level.scr_sound[sDialogue]);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
squad_bmp_destroy(sTargetname)
|
|||
|
{
|
|||
|
sFlagName = sTargetname + "_destroyed";
|
|||
|
level endon (sFlagName);
|
|||
|
bmp = getent(sTargetname, "targetname");
|
|||
|
assertEx((isdefined(bmp)), "BMP with targetname " + sTargetname + " is not defined");
|
|||
|
sFlagPlayerNearBMP = "player_near_" + sTargetname;
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAIT FOR PLAYER TO BE OUT OF VIEW
|
|||
|
-------------------------*/
|
|||
|
while (flag(sFlagPlayerNearBMP))
|
|||
|
wait (.5);
|
|||
|
|
|||
|
//Marine 01
|
|||
|
//"Charges placed! We<57>re blowing the BMP! Take cover! Move Move!!!"
|
|||
|
radio_dialogue("launchfacility_a_marine_01_blowing_bmp");
|
|||
|
|
|||
|
if(isdefined(bmp))
|
|||
|
{
|
|||
|
if (!flag(sFlagName))
|
|||
|
{
|
|||
|
bmp endon ("death");
|
|||
|
iEntityNumber = bmp getentitynumber();
|
|||
|
bmp thread vehicle_death(iEntityNumber);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
player_kill_counter(iKillMax)
|
|||
|
{
|
|||
|
level notify("reset_kill_counter");
|
|||
|
level endon("reset_kill_counter");
|
|||
|
flag_clear("player_reached_kill_max");
|
|||
|
|
|||
|
level.axisKilledByPlayer = 0;
|
|||
|
while (level.axisKilledByPlayer < iKillMax)
|
|||
|
wait (2);
|
|||
|
|
|||
|
flag_set("player_reached_kill_max");
|
|||
|
}
|
|||
|
|
|||
|
c4_callback_thread_launchfacility()
|
|||
|
{
|
|||
|
//self ==> the script_origin that acted as the location for the C4 plant and the exploder number
|
|||
|
switch (self.script_noteworthy)
|
|||
|
{
|
|||
|
case "100": //the side breach wall beyond container area
|
|||
|
flag_set("flanking_wall_breached");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
obj_gain_access()
|
|||
|
{
|
|||
|
flag_wait("obj_gain_access_given");
|
|||
|
objective_number = 1;
|
|||
|
|
|||
|
obj_position = getent ("obj_gain_access", "targetname");
|
|||
|
objective_add(objective_number, "active", &"LAUNCHFACILITY_A_OBJ_GAIN_ACCESS", obj_position.origin);
|
|||
|
objective_current (objective_number);
|
|||
|
|
|||
|
flag_wait ("obj_gain_access_complete");
|
|||
|
|
|||
|
objective_state (objective_number, "done");
|
|||
|
}
|
|||
|
|
|||
|
obj_enemy_armor()
|
|||
|
{
|
|||
|
flag_wait("obj_enemy_armor_given");
|
|||
|
|
|||
|
objective_add(10, "invisible", &"LAUNCHFACILITY_A_OBJ_ENEMY_ARMOR");
|
|||
|
objective_state(10, "active");
|
|||
|
objective_string(10, &"LAUNCHFACILITY_A_OBJ_ENEMY_ARMOR", level.enemyArmor.size);
|
|||
|
objective_current(10);
|
|||
|
|
|||
|
flag_wait ("obj_enemy_armor_complete");
|
|||
|
|
|||
|
objective_state (10, "done");
|
|||
|
}
|
|||
|
|
|||
|
obj_enemy_armor_vehicle_think()
|
|||
|
{
|
|||
|
level.enemyArmorIndex++;
|
|||
|
index = level.enemyArmorIndex;
|
|||
|
level.enemyArmor = array_add(level.enemyArmor, self);
|
|||
|
objective_string(10, &"LAUNCHFACILITY_A_OBJ_ENEMY_ARMOR", level.enemyArmor.size);
|
|||
|
|
|||
|
objective_additionalposition(10, index, self.origin);
|
|||
|
|
|||
|
if (level.enemyArmorIndex == 2 )
|
|||
|
{
|
|||
|
wait(1);
|
|||
|
objective_string(10, &"LAUNCHFACILITY_A_OBJ_ENEMY_ARMOR", level.enemyArmor.size);
|
|||
|
}
|
|||
|
|
|||
|
self thread obj_enemy_armor_vehicle_death(index);
|
|||
|
self thread obj_enemy_armor_vehicle_position(index);
|
|||
|
}
|
|||
|
|
|||
|
obj_enemy_armor_vehicle_death(index)
|
|||
|
{
|
|||
|
self waittill ("death");
|
|||
|
level.enemyArmor = array_remove(level.enemyArmor, self);
|
|||
|
waittillframeend;
|
|||
|
objective_additionalposition(10, index, (0,0,0));
|
|||
|
|
|||
|
if (level.enemyArmor.size == 0)
|
|||
|
{
|
|||
|
flag_set ("obj_enemy_armor_complete");
|
|||
|
objective_state(10, "invisible");
|
|||
|
flag_clear( "aa_tarmac_bmp02_section" );
|
|||
|
}
|
|||
|
|
|||
|
objective_string(10, &"LAUNCHFACILITY_A_OBJ_ENEMY_ARMOR", level.enemyArmor.size);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
obj_enemy_armor_vehicle_position(index)
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait(0.05);
|
|||
|
objective_additionalposition(10, index, self.origin);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
obj_north_tarmac()
|
|||
|
{
|
|||
|
flag_wait("obj_north_tarmac_given");
|
|||
|
objective_number = 11;
|
|||
|
|
|||
|
obj_position = getent ("obj_north_tarmac", "targetname");
|
|||
|
objective_add(objective_number, "active", &"LAUNCHFACILITY_A_OBJ_NORTH_TARMAC", obj_position.origin);
|
|||
|
objective_current (objective_number);
|
|||
|
|
|||
|
flag_wait ("obj_north_tarmac_complete");
|
|||
|
|
|||
|
objective_state (objective_number, "done");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
obj_rappel()
|
|||
|
{
|
|||
|
flag_wait("obj_rappel_given");
|
|||
|
objective_number = 12;
|
|||
|
|
|||
|
obj_position = getent ("obj_rappel", "targetname");
|
|||
|
objective_add(objective_number, "active", &"LAUNCHFACILITY_A_OBJ_RAPPEL", obj_position.origin);
|
|||
|
objective_current (objective_number);
|
|||
|
|
|||
|
flag_wait ("obj_rappel_complete");
|
|||
|
|
|||
|
objective_state (objective_number, "done");
|
|||
|
}
|
|||
|
|
|||
|
vehicle_bmp_setup( aTargetname )
|
|||
|
{
|
|||
|
for(i=0;i<aTargetname.size;i++)
|
|||
|
thread vehicle_bmp_think ( aTargetname[i] );
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
vehicle_truck_setup()
|
|||
|
{
|
|||
|
aTrucks = getentarray("truck_troops", "targetname");
|
|||
|
for(i=0;i<aTrucks.size;i++)
|
|||
|
aTrucks[i] thread vehicle_truck_think();
|
|||
|
}
|
|||
|
|
|||
|
vehicle_truck_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
self truck_death_think();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
truck_death_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
iProjectileHits = 0;
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName );
|
|||
|
|
|||
|
// if ( (isdefined(attacker)) && (isdefined(attacker.team)) && (attacker.team == "axis") )
|
|||
|
// {
|
|||
|
// if (!flag("enemy_can_blow_up_truck"))
|
|||
|
// continue;
|
|||
|
// }
|
|||
|
if ( (isdefined(attacker)) && (attacker != level.player) )
|
|||
|
{
|
|||
|
if (!flag("enemy_can_blow_up_truck"))
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if ( !isdefined( damage ) )
|
|||
|
continue;
|
|||
|
if ( damage <= 0 )
|
|||
|
continue;
|
|||
|
type = getDamageType( type );
|
|||
|
assert( isdefined( type ) );
|
|||
|
|
|||
|
if ( type == "rocket" )
|
|||
|
{
|
|||
|
if (damage >= 300)
|
|||
|
break;
|
|||
|
}
|
|||
|
else if ( type == "c4" )
|
|||
|
{
|
|||
|
if (damage >= 250)
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//thread play_sound_in_space( "building_explosion3", self.origin);
|
|||
|
thread play_sound_in_space("exp_armor_vehicle", self.origin);
|
|||
|
earthquake (0.6, 2, self.origin, 2000);
|
|||
|
self notify ("death");
|
|||
|
}
|
|||
|
|
|||
|
vehicle_bmp_death_wait()
|
|||
|
{
|
|||
|
self waittill( "death" );
|
|||
|
Target_Remove( self );
|
|||
|
}
|
|||
|
|
|||
|
vehicle_bmp_think( sTargetname )
|
|||
|
{
|
|||
|
add_hint_string( "armor_damage", &"SCRIPT_ARMOR_DAMAGE", undefined );
|
|||
|
eVehicle = maps\_vehicle::waittill_vehiclespawn( sTargetname );
|
|||
|
|
|||
|
target_set( eVehicle, ( 0, 0, 0 ) );
|
|||
|
Target_SetJavelinOnly( eVehicle, true );
|
|||
|
eVehicle thread vehicle_bmp_death_wait();
|
|||
|
flag_set(sTargetname + "_spawned");
|
|||
|
|
|||
|
if ( (isdefined(eVehicle.script_noteworthy)) && (eVehicle.script_noteworthy == "objective_tarmac_armor") )
|
|||
|
eVehicle thread obj_enemy_armor_vehicle_think();
|
|||
|
|
|||
|
eVehicle thread vehicle_turret_think();
|
|||
|
eVehicle thread vehicle_death_think();
|
|||
|
//eVehicle thread vehicle_damage_hints();
|
|||
|
eVehicle thread maps\_vehicle::damage_hints();
|
|||
|
eVehicle thread vehicle_patrol_think();
|
|||
|
eVehicle thread vehicle_c4_think();
|
|||
|
eVehicle thread vehicle_enemies_setup();
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
BADPLACE TO KEEP ALLIES ON PERIMETER OF BMP
|
|||
|
-------------------------*/
|
|||
|
eBadplace = getent("badplace_" + sTargetname, "targetname");
|
|||
|
if (isdefined(eBadplace))
|
|||
|
badplace_brush(sTargetname, 0, eBadplace, "allies");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DELETE BADPLACE AND SET FLAG WHEN DEAD
|
|||
|
-------------------------*/
|
|||
|
eVehicle waittill ("death");
|
|||
|
eVehicleDeathOrigin = spawn( "script_origin", ( 0, 0, 0 ) );
|
|||
|
eVehicleDeathOrigin.angles = eVehicle.angles;
|
|||
|
eVehicleDeathOrigin.origin = eVehicle.origin;
|
|||
|
|
|||
|
sFlag = sTargetname + "_destroyed";
|
|||
|
flag_set(sFlag);
|
|||
|
|
|||
|
if (isdefined(eBadplace))
|
|||
|
badplace_delete(sTargetname);
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
vehicle_damage_hints()
|
|||
|
{
|
|||
|
self endon ( "death" );
|
|||
|
while ( true )
|
|||
|
{
|
|||
|
self waittill ( "damage", amount, attacker, direction_vec, point, type );
|
|||
|
if (attacker != level.player)
|
|||
|
continue;
|
|||
|
switch( tolower(type) )
|
|||
|
{
|
|||
|
case "mod_grenade":
|
|||
|
case "mod_grenade_splash":
|
|||
|
thread hint_fade();
|
|||
|
thread hint(&"SCRIPT_ARMOR_DAMAGE", 5);
|
|||
|
wait (10);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
vehicle_death_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
iEntityNumber = self getentitynumber();
|
|||
|
iProjectileHits = 0;
|
|||
|
qDestroyedByRpg = false;
|
|||
|
qDestroyedByJavelin = false;
|
|||
|
while (true)
|
|||
|
{
|
|||
|
self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName );
|
|||
|
|
|||
|
if (attacker != level.player)
|
|||
|
continue;
|
|||
|
if ( !isdefined( damage ) )
|
|||
|
continue;
|
|||
|
if ( damage <= 0 )
|
|||
|
continue;
|
|||
|
type = getDamageType( type );
|
|||
|
assert( isdefined( type ) );
|
|||
|
|
|||
|
if ( type == "rocket" )
|
|||
|
{
|
|||
|
//javelin
|
|||
|
if (damage >= 900)
|
|||
|
{
|
|||
|
qDestroyedByJavelin = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
//rpg
|
|||
|
if (damage >= 300)
|
|||
|
{
|
|||
|
iProjectileHits++;
|
|||
|
if (iProjectileHits == 1)
|
|||
|
self thread vehicle_smoke();
|
|||
|
if (iProjectileHits == 2)
|
|||
|
{
|
|||
|
qDestroyedByRpg = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
if ( type == "c4" )
|
|||
|
{
|
|||
|
if (damage >= 250)
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
if ( (qDestroyedByRpg) || (qDestroyedByJavelin) )
|
|||
|
thread bmp_death_dialogue();
|
|||
|
self thread vehicle_death(iEntityNumber);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
bmp_death_dialogue()
|
|||
|
{
|
|||
|
wait (1);
|
|||
|
/*-----------------------
|
|||
|
RANDOM RPG KILL DIALOGUE
|
|||
|
-------------------------*/
|
|||
|
level.dialogueRpgGoodShot_number++;
|
|||
|
if (level.dialogueRpgGoodShot_number > level.dialogueRpgGoodShot_MAX)
|
|||
|
level.dialogueRpgGoodShot_number = 1;
|
|||
|
|
|||
|
sDialogue = "launchfacility_a_rpg_kill_0" + level.dialogueRpgGoodShot_number;
|
|||
|
|
|||
|
if (!level.peoplespeaking)
|
|||
|
{
|
|||
|
level.peoplespeaking = true;
|
|||
|
level radio_dialogue(sDialogue);
|
|||
|
level.peoplespeaking = false;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
vehicle_smoke()
|
|||
|
{
|
|||
|
wait(1);
|
|||
|
/*-----------------------
|
|||
|
RANDOM RPG FIRST HIT DIALOGUE
|
|||
|
-------------------------*/
|
|||
|
level.dialogueRpgHit_number++;
|
|||
|
if (level.dialogueRpgHit_number > level.dialogueRpgHit_MAX)
|
|||
|
level.dialogueRpgHit_number = 1;
|
|||
|
|
|||
|
sDialogue = "launchfacility_a_rpg_hit_0" + level.dialogueRpgHit_number;
|
|||
|
if (!level.peoplespeaking)
|
|||
|
{
|
|||
|
level.peoplespeaking = true;
|
|||
|
level radio_dialogue(sDialogue);
|
|||
|
level.peoplespeaking = false;
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
BMP STARTS SMOKING
|
|||
|
-------------------------*/
|
|||
|
eSmokeOrg = spawn( "script_origin", ( 0, 0, 0 ) );
|
|||
|
eSmokeOrg.origin = self gettagorigin("tag_origin");
|
|||
|
eSmokeOrg linkto(self);
|
|||
|
|
|||
|
while (isalive(self))
|
|||
|
{
|
|||
|
playfx (getfx( "smoke_trail_bmp"), eSmokeOrg.origin);
|
|||
|
playfx (getfx( "smoke_trail_bmp"), eSmokeOrg.origin + (50,50,-50));
|
|||
|
wait(.1);
|
|||
|
}
|
|||
|
|
|||
|
self waittill("death");
|
|||
|
eSmokeOrg delete();
|
|||
|
}
|
|||
|
|
|||
|
getDamageType( type )
|
|||
|
{
|
|||
|
//returns a simple damage type: melee, bullet, splash, or unknown
|
|||
|
|
|||
|
if ( !isdefined( type ) )
|
|||
|
return "unknown";
|
|||
|
|
|||
|
type = tolower( type );
|
|||
|
switch( type )
|
|||
|
{
|
|||
|
case "mod_explosive":
|
|||
|
case "mod_explosive_splash":
|
|||
|
return "c4";
|
|||
|
case "mod_projectile":
|
|||
|
case "mod_projectile_splash":
|
|||
|
return "rocket";
|
|||
|
case "mod_grenade":
|
|||
|
case "mod_grenade_splash":
|
|||
|
return "grenade";
|
|||
|
case "unknown":
|
|||
|
return "unknown";
|
|||
|
default:
|
|||
|
return "unknown";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
vehicle_get_target(aExcluders)
|
|||
|
{
|
|||
|
// getEnemyTarget( fRadius, iFOVcos, getAITargets, doSightTrace, getVehicleTargets, randomizeTargetArray, aExcluders )
|
|||
|
eTarget = maps\_helicopter_globals::getEnemyTarget( level.bmpCannonRange, level.cosine[ "180" ], true, true, false, true, aExcluders);
|
|||
|
return eTarget;
|
|||
|
}
|
|||
|
|
|||
|
vehicle_get_target_player_only()
|
|||
|
{
|
|||
|
aExcluders = level.squad;
|
|||
|
// getEnemyTarget( fRadius, iFOVcos, getAITargets, doSightTrace, getVehicleTargets, randomizeTargetArray, aExcluders )
|
|||
|
eTarget = maps\_helicopter_globals::getEnemyTarget( level.bmpCannonRange, level.cosine[ "180" ], false, true, false, false, aExcluders);
|
|||
|
return eTarget;
|
|||
|
}
|
|||
|
|
|||
|
vehicle_debug()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait(.5);
|
|||
|
thread debug_circle( self.origin, level.bmpMGrange, 0.5, level.color[ "red" ], undefined, true);
|
|||
|
thread debug_circle( self.origin, level.bmpCannonRange, 0.5, level.color[ "blue" ], undefined, true);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
vehicle_turret_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
self endon ( "c4_detonation" );
|
|||
|
self thread maps\_vehicle::mgoff();
|
|||
|
self.turretFiring = false;
|
|||
|
eTarget = undefined;
|
|||
|
|
|||
|
currentTargetLoc = undefined;
|
|||
|
|
|||
|
if (getdvar("debug_bmp") == "1")
|
|||
|
self thread vehicle_debug();
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait (0.05);
|
|||
|
/*-----------------------
|
|||
|
TRY TO GET THE PLAYER AS A TARGET FIRST
|
|||
|
-------------------------*/
|
|||
|
if ( !isdefined(eTarget) )
|
|||
|
eTarget = self vehicle_get_target_player_only();
|
|||
|
else if ( ( isdefined(eTarget) ) && ( eTarget != level.player ) )
|
|||
|
eTarget = self vehicle_get_target_player_only();
|
|||
|
/*-----------------------
|
|||
|
IF CURRENT IS PLAYER, DO SIGHT TRACE
|
|||
|
-------------------------*/
|
|||
|
if ( (isdefined(eTarget)) && (eTarget == level.player) )
|
|||
|
{
|
|||
|
sightTracePassed = false;
|
|||
|
sightTracePassed = sighttracepassed( self.origin, level.player.origin + ( 0, 0, 150 ), false, self );
|
|||
|
/*-----------------------
|
|||
|
IF CURRENT IS PLAYER BUT CAN'T SEE HIM, GET ANOTHER TARGET
|
|||
|
-------------------------*/
|
|||
|
if ( !sightTracePassed )
|
|||
|
{
|
|||
|
//self clearTurretTarget();
|
|||
|
eTarget = self vehicle_get_target(level.bmpExcluders);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
/*-----------------------
|
|||
|
IF PLAYER ISN'T CURRENT TARGET, GET ANOTHER
|
|||
|
-------------------------*/
|
|||
|
else
|
|||
|
eTarget = self vehicle_get_target(level.bmpExcluders);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ROTATE TURRET TO CURRENT TARGET
|
|||
|
-------------------------*/
|
|||
|
if ( (isdefined(eTarget)) && (isalive(eTarget)) )
|
|||
|
{
|
|||
|
targetLoc = eTarget.origin + (0, 0, 32);
|
|||
|
self setTurretTargetVec(targetLoc);
|
|||
|
|
|||
|
|
|||
|
if (getdvar("debug_bmp") == "1")
|
|||
|
thread draw_line_until_notify(self.origin + (0, 0, 32), targetLoc, 1, 0, 0, self, "stop_drawing_line");
|
|||
|
|
|||
|
fRand = ( randomfloatrange(2, 3));
|
|||
|
self waittill_notify_or_timeout( "turret_rotate_stopped", fRand );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
FIRE MAIN CANNON OR MG
|
|||
|
-------------------------*/
|
|||
|
if ( (isdefined(eTarget)) && (isalive(eTarget)) )
|
|||
|
{
|
|||
|
if ( distancesquared(eTarget.origin,self.origin) <= level.bmpMGrangeSquared)
|
|||
|
{
|
|||
|
if (!self.mgturret[0] isfiringturret())
|
|||
|
self thread maps\_vehicle::mgon();
|
|||
|
|
|||
|
wait(.5);
|
|||
|
if (!self.mgturret[0] isfiringturret())
|
|||
|
{
|
|||
|
self thread maps\_vehicle::mgoff();
|
|||
|
if (!self.turretFiring)
|
|||
|
self thread vehicle_fire_main_cannon();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
self thread maps\_vehicle::mgoff();
|
|||
|
if (!self.turretFiring)
|
|||
|
self thread vehicle_fire_main_cannon();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//wait( randomfloatrange(2, 5));
|
|||
|
|
|||
|
if (getdvar( "debug_bmp") == "1")
|
|||
|
self notify( "stop_drawing_line" );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
vehicle_fire_main_cannon()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
self endon ( "c4_detonation" );
|
|||
|
//self notify ("firing_cannon");
|
|||
|
//self endon ("firing_cannon");
|
|||
|
|
|||
|
iFireTime = weaponfiretime("bmp_turret");
|
|||
|
assert(isdefined(iFireTime));
|
|||
|
|
|||
|
iBurstNumber = randomintrange(3, 8);
|
|||
|
|
|||
|
self.turretFiring = true;
|
|||
|
i = 0;
|
|||
|
while (i < iBurstNumber)
|
|||
|
{
|
|||
|
i++;
|
|||
|
wait(iFireTime);
|
|||
|
self fireWeapon();
|
|||
|
}
|
|||
|
self.turretFiring = false;
|
|||
|
}
|
|||
|
|
|||
|
vehicle_c4_think()
|
|||
|
{
|
|||
|
|
|||
|
iEntityNumber = self getentitynumber();
|
|||
|
rearOrgOffset = (0, -33, 10);
|
|||
|
rearAngOffset = (0, 90, -90);
|
|||
|
frontOrgOffset = (129, 0, 35);
|
|||
|
frontAngOffset = (0, 90, 144);
|
|||
|
|
|||
|
self maps\_c4::c4_location( "rear_hatch_open_jnt_left", rearOrgOffset, rearAngOffset);
|
|||
|
self maps\_c4::c4_location( "tag_origin", frontOrgOffset, frontAngOffset );
|
|||
|
self.rearC4location = spawn("script_origin", self.origin);
|
|||
|
self.frontC4location = spawn("script_origin", self.origin);
|
|||
|
self.rearC4location linkto(self, "rear_hatch_open_jnt_left", rearOrgOffset, rearAngOffset);
|
|||
|
self.frontC4location linkto(self, "tag_origin", frontOrgOffset, frontAngOffset);
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
{
|
|||
|
self.frontC4location thread print3Dthread("Front");
|
|||
|
self.rearC4location thread print3Dthread("Back");
|
|||
|
}
|
|||
|
self waittill( "c4_detonation" );
|
|||
|
|
|||
|
self.frontC4location delete();
|
|||
|
self.rearC4location delete();
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
C4 STUNS AI CLOSEBY
|
|||
|
-------------------------*/
|
|||
|
AI = get_ai_within_radius(512, self.origin, "axis");
|
|||
|
if ( (isdefined(AI)) && (AI.size > 0) )
|
|||
|
array_thread(AI, ::AI_stun, .75);
|
|||
|
|
|||
|
self thread vehicle_death(iEntityNumber);
|
|||
|
}
|
|||
|
|
|||
|
vehicle_death(iEntityNumber)
|
|||
|
{
|
|||
|
self notify("clear_c4");
|
|||
|
arcadeMode_kill( self.origin, "explosive", 150 );
|
|||
|
setplayerignoreradiusdamage(true);
|
|||
|
|
|||
|
if ( distancesquared(self.origin,level.player.origin) <= level.bmpMGrangeSquared )
|
|||
|
level.player PlayRumbleOnEntity( "damage_heavy" );
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
FINAL EXPLOSION
|
|||
|
-------------------------*/
|
|||
|
earthquake (0.6, 2, self.origin, 2000);
|
|||
|
self notify( "death" );
|
|||
|
//thread play_sound_in_space( "building_explosion3", self gettagorigin( "tag_turret" ) );
|
|||
|
thread play_sound_in_space( "exp_armor_vehicle", self gettagorigin( "tag_turret" ) );
|
|||
|
AI = get_ai_within_radius(1024, self.origin, "axis");
|
|||
|
if ( (isdefined(AI)) && (AI.size > 0) )
|
|||
|
array_thread(AI, ::AI_stun, .85);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ONLY TOKEN DAMAGE INFLICTED ON PLAYER
|
|||
|
-------------------------*/
|
|||
|
radiusdamage(self.origin, 256, level.maxBMPexplosionDmg, level.minBMPexplosionDmg);
|
|||
|
thread player_token_vehicle_damage(self.origin);
|
|||
|
thread autosave_by_name("bmp_" + iEntityNumber + "_destroyed");
|
|||
|
|
|||
|
wait (2);
|
|||
|
setplayerignoreradiusdamage(false);
|
|||
|
}
|
|||
|
|
|||
|
player_token_vehicle_damage(org)
|
|||
|
{
|
|||
|
if ( distancesquared(org,level.player.origin) <= level.playerVehicleDamageRangeSquared )
|
|||
|
level.player dodamage(level.player.health / 3, (0,0,0));
|
|||
|
}
|
|||
|
|
|||
|
vehicle_enemies_setup()
|
|||
|
{
|
|||
|
//self ==> the vehicle
|
|||
|
if (!isdefined(self.script_linkto))
|
|||
|
return;
|
|||
|
eSpawnTrigger = getent(self.script_linkto, "script_linkname");
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
SPAWN HOSTILE SUPPORT
|
|||
|
-------------------------*/
|
|||
|
eSpawnTrigger notify ("trigger", level.player);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
KILLSPAWNERS GET TRIGGERED WHEN VEHICLE DIES
|
|||
|
-------------------------*/
|
|||
|
aKillSpawnerTrigs = getentarray(eSpawnTrigger.script_linkto, "script_linkname");
|
|||
|
// aKillSpawnerTrigs = [];
|
|||
|
// tokens = strtok( eSpawnTrigger.script_linkto, " " );
|
|||
|
// for ( i=0; i < tokens.size; i++ )
|
|||
|
// aKillSpawnerTrigs[aKillSpawnerTrigs.size] = getent( tokens[ i ], "script_linkname" );
|
|||
|
|
|||
|
assertEx((aKillSpawnerTrigs.size > 0), "Vehicle trigger that spawns support AI needs to scriptLinkto one or more killspawners. Targetname: " + self.targetname);
|
|||
|
array_thread(aKillSpawnerTrigs, ::vehicle_AI_killspawner_triggers_think, self);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
ENEMY MOVES WHEN VEHICLE MOVES
|
|||
|
-------------------------*/
|
|||
|
aHostileMovementTriggers = getentarray("triggers_" + self.targetname, "script_noteworthy");
|
|||
|
assertEx((isdefined(aHostileMovementTriggers)), "There are no triggers with script_noteworthy of triggers_" + self.targetname);
|
|||
|
array_thread(aHostileMovementTriggers, ::vehicle_AI_movement_triggers_think, self);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
vehicle_AI_killspawner_triggers_think(eVehicle)
|
|||
|
{
|
|||
|
eVehicle waittill ("death");
|
|||
|
self notify ("trigger", level.player);
|
|||
|
}
|
|||
|
|
|||
|
vehicle_AI_movement_triggers_think(eVehicle)
|
|||
|
{
|
|||
|
//self ==> the vehicle trigger that targets the goal volumes for enemy AI
|
|||
|
eVehicle endon ("death");
|
|||
|
|
|||
|
eGoalVolume = getent(self.target, "targetname");
|
|||
|
assert(isdefined(eGoalVolume));
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
self waittill("trigger", ent);
|
|||
|
if (ent != eVehicle)
|
|||
|
continue;
|
|||
|
|
|||
|
eVehicle notify ("changing_volume", eGoalVolume);
|
|||
|
eVehicle.enemyvolume = eGoalVolume;
|
|||
|
eVehicle waittill ("changing_volume");
|
|||
|
wait (5);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AI_vehicle_support()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
eVehicleOrigin = getent(self.script_linkto, "script_linkname");
|
|||
|
assertEx((isdefined(eVehicleOrigin)), "Spawner with export number " + self.export + " needs to scriptLinkTo a single script_origin named origin_<vehiclename>");
|
|||
|
sVehicleName = getsubstr(eVehicleOrigin.script_noteworthy, 7);
|
|||
|
eVehicle = getent(sVehicleName, "targetname");
|
|||
|
assertEx((isdefined(eVehicle)), "There is no vehicle spawned with a targetname of " + sVehicleName);
|
|||
|
|
|||
|
|
|||
|
self thread AI_vehicle_support_vehicle_dead(eVehicle);
|
|||
|
|
|||
|
wait(0.05);
|
|||
|
//go to whatever volume the tank is in
|
|||
|
if (isdefined(eVehicle.enemyvolume))
|
|||
|
self set_goalvolume(undefined, eVehicle.enemyvolume);
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
eVehicle waittill ("changing_volume", eGoalVolume);
|
|||
|
self set_goalvolume(undefined, eGoalVolume);
|
|||
|
wait (0.05);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AI_vehicle_support_vehicle_dead(eVehicle)
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
eVehicle waittill ("death");
|
|||
|
|
|||
|
self.health = 1;
|
|||
|
self thread AI_player_seek();
|
|||
|
}
|
|||
|
|
|||
|
AI_enemy_RPD()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
//self.providecoveringfire = true;
|
|||
|
|
|||
|
}
|
|||
|
vehicle_patrol_init()
|
|||
|
{
|
|||
|
level.aVehicleNodes = [];
|
|||
|
array1 = getvehiclenodearray( "go_right", "script_noteworthy" );
|
|||
|
array2 = getvehiclenodearray( "go_left", "script_noteworthy" );
|
|||
|
level.aVehicleNodes = array_merge( array1, array2 );
|
|||
|
}
|
|||
|
|
|||
|
vehicle_patrol_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
ePathstart = self.attachedpath;
|
|||
|
self waittill ("reached_end_node");
|
|||
|
|
|||
|
switch ( self.targetname )
|
|||
|
{
|
|||
|
case "bmp_02":
|
|||
|
self.balconyPositionOrg = getent( "bmp_02_balcony_org", "targetname" );
|
|||
|
break;
|
|||
|
case "bmp_03":
|
|||
|
self.balconyPositionOrg = getent( "bmp_03_balcony_org", "targetname" );
|
|||
|
break;
|
|||
|
case "bmp_04":
|
|||
|
self.balconyPositionOrg = getent( "bmp_04_balcony_org", "targetname" );
|
|||
|
break;
|
|||
|
default:
|
|||
|
assertmsg( "need a script_origin for this vehicle named " + self.targetname + "_balcony_org" );
|
|||
|
}
|
|||
|
assert(isdefined(self.balconyPositionOrg));
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
wait (0.05);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
REINITIALIZE ALL VARIABLES
|
|||
|
-------------------------*/
|
|||
|
aLinked_nodes = [];
|
|||
|
eCurrentNode = undefined;
|
|||
|
go_left_node = undefined;
|
|||
|
go_right_node = undefined;
|
|||
|
eStartNode = undefined;
|
|||
|
aPossibleEndNodes = [];
|
|||
|
closestEndNode = undefined;
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GET LAST NODE IN CHAIN (CURRENT POSITION
|
|||
|
-------------------------*/
|
|||
|
assert(isdefined(ePathstart));
|
|||
|
eCurrentNode = ePathstart get_last_ent_in_chain("vehiclenode");
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GET ALL NODES THAT ARE GROUPED WITH THIS PATH END
|
|||
|
-------------------------*/
|
|||
|
aLinked_nodes = level.aVehicleNodes;
|
|||
|
aLinked_nodes = array_remove( aLinked_nodes, eCurrentNode);
|
|||
|
aVehicleNodes = level.aVehicleNodes;
|
|||
|
sScript_vehiclenodegroup = eCurrentNode.script_vehiclenodegroup;
|
|||
|
assert(isdefined(sScript_vehiclenodegroup));
|
|||
|
for(i=0;i<aVehicleNodes.size;i++)
|
|||
|
{
|
|||
|
assertEx((isdefined(aVehicleNodes[i].script_vehiclenodegroup)), "Vehiclenode at " + aVehicleNodes[i].origin + " needs to be assigned a script_vehiclenodegroup");
|
|||
|
if ( aVehicleNodes[i].script_vehiclenodegroup != sScript_vehiclenodegroup )
|
|||
|
aLinked_nodes = array_remove( aLinked_nodes, aVehicleNodes[i] );
|
|||
|
}
|
|||
|
/*-----------------------
|
|||
|
GET START NODES TO GO LEFT/RIGHT FROM HERE
|
|||
|
-------------------------*/
|
|||
|
assertEx(aLinked_nodes.size > 0, "Ends of vehicle paths need to be grouped with at least one other chain of nodes for moving left, right or both");
|
|||
|
for(i=0;i<aLinked_nodes.size;i++)
|
|||
|
{
|
|||
|
if ( isdefined(aLinked_nodes[i].script_noteworthy) && (aLinked_nodes[i].script_noteworthy == "go_left") )
|
|||
|
{
|
|||
|
go_left_node = aLinked_nodes[i];
|
|||
|
go_left_node.end = undefined;
|
|||
|
}
|
|||
|
|
|||
|
else if ( isdefined(aLinked_nodes[i].script_noteworthy) && (aLinked_nodes[i].script_noteworthy == "go_right") )
|
|||
|
{
|
|||
|
go_right_node = aLinked_nodes[i];
|
|||
|
go_right_node.end = undefined;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DEFINE THE END NODE FOR EACH START NODE
|
|||
|
-------------------------*/
|
|||
|
aPossibleEndNodes[0] = eCurrentNode;
|
|||
|
if ( isdefined(go_left_node) )
|
|||
|
{
|
|||
|
go_left_node.end = go_left_node get_last_ent_in_chain("vehiclenode");
|
|||
|
aPossibleEndNodes = array_add( aPossibleEndNodes, go_left_node.end );
|
|||
|
}
|
|||
|
|
|||
|
if ( isdefined(go_right_node) )
|
|||
|
{
|
|||
|
go_right_node.end = go_right_node get_last_ent_in_chain("vehiclenode");
|
|||
|
aPossibleEndNodes = array_add( aPossibleEndNodes, go_right_node.end );
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
STAY PUT, OR START A NEW PATH?
|
|||
|
-------------------------*/
|
|||
|
org = undefined;
|
|||
|
if ( level.player isTouching( level.balconyflag ) )
|
|||
|
org = self.balconyPositionOrg.origin;
|
|||
|
else
|
|||
|
org = level.player.origin;
|
|||
|
closestEndNode = getclosest( org, aPossibleEndNodes );
|
|||
|
if ( closestEndNode == eCurrentNode )
|
|||
|
eStartNode = undefined;
|
|||
|
else if ( (isdefined(go_left_node)) && ( closestEndNode == go_left_node.end ) )
|
|||
|
eStartNode = go_left_node;
|
|||
|
else if ( (isdefined(go_right_node)) && ( closestEndNode == go_right_node.end ) )
|
|||
|
eStartNode = go_right_node;
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
IF PLAYER IS RIGHT BEHIND/IN FRONT, TRY TO RETREAT
|
|||
|
-------------------------*/
|
|||
|
if ( !isdefined( eStartNode ) )
|
|||
|
{
|
|||
|
if (distancesquared(self.rearC4location.origin,level.player.origin) <= level.playerMaxDistanceToBMPC4squared)
|
|||
|
{
|
|||
|
//sighttracepassed(<start>, <end>, <hit characters>, <ignore entity>)
|
|||
|
bmpCanSee = bullettracepassed(level.player.origin, self gettagorigin("tag_turret"), false, self);
|
|||
|
if (bmpCanSee)
|
|||
|
{
|
|||
|
if (isdefined(go_left_node))
|
|||
|
eStartNode = go_left_node;
|
|||
|
//else if (isdefined(go_right_node))
|
|||
|
//eStartNode = go_right_node;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
else if (distancesquared(self.frontC4location.origin,level.player.origin) <= level.playerMaxDistanceToBMPC4squared)
|
|||
|
{
|
|||
|
//sighttracepassed(<start>, <end>, <hit characters>, <ignore entity>)
|
|||
|
bmpCanSee = bullettracepassed(level.player.origin, self gettagorigin("tag_turret"), false, self);
|
|||
|
if (bmpCanSee)
|
|||
|
{
|
|||
|
if (isdefined(go_right_node))
|
|||
|
eStartNode = go_right_node;
|
|||
|
//else if (isdefined(go_left_node))
|
|||
|
//eStartNode = go_left_node;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
GO ON THE NEW PATH TO GET CLOSER TO PLAYER
|
|||
|
-------------------------*/
|
|||
|
if ( isdefined(eStartNode) )
|
|||
|
{
|
|||
|
self attachpath( eStartNode );
|
|||
|
|
|||
|
if ( isdefined( eStartNode.script_wheeldirection ) )
|
|||
|
self maps\_vehicle::wheeldirectionchange( eStartNode.script_wheeldirection );
|
|||
|
|
|||
|
ePathstart = eStartNode;
|
|||
|
//thread maps\_vehicle::gopath( self );
|
|||
|
self setspeed(5, 2, 2);
|
|||
|
self waittill ("reached_end_node");
|
|||
|
}
|
|||
|
/*-----------------------
|
|||
|
STAY PUT AND WAIT A FEW SECONDS
|
|||
|
-------------------------*/
|
|||
|
else
|
|||
|
{
|
|||
|
wait (3);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// /*-----------------------
|
|||
|
// IF PLAYER AND VEHICLE NOT IN SAME AREA
|
|||
|
// -------------------------*/
|
|||
|
// sPlayerLocation = get_player_general_location();
|
|||
|
//
|
|||
|
// if ( sCurrentVehiclePosition != sPlayerLocation )
|
|||
|
// {
|
|||
|
// eStartNode = undefined;
|
|||
|
// switch ( sPlayerLocation )
|
|||
|
// {
|
|||
|
// case "left":
|
|||
|
// if ( isdefined(go_left_node) )
|
|||
|
// eStartNode = go_left_node;
|
|||
|
// break;
|
|||
|
// case "right":
|
|||
|
// if ( isdefined(go_right_node) )
|
|||
|
// eStartNode = go_right_node;
|
|||
|
// break;
|
|||
|
// case "mid":
|
|||
|
// if ( sCurrentVehiclePosition == "left" )
|
|||
|
// eStartNode = go_right_node;
|
|||
|
// if ( sCurrentVehiclePosition == "right" )
|
|||
|
// eStartNode = go_left_node;
|
|||
|
// break;
|
|||
|
// }
|
|||
|
// }
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
AI_think(guy)
|
|||
|
{
|
|||
|
/*-----------------------
|
|||
|
RUN ON EVERY DUDE THAT SPAWNS
|
|||
|
-------------------------*/
|
|||
|
if (guy.team == "axis")
|
|||
|
guy thread AI_axis_think();
|
|||
|
|
|||
|
if (guy.team == "allies")
|
|||
|
guy thread AI_allies_think();
|
|||
|
}
|
|||
|
|
|||
|
AI_allies_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
self.animname = "frnd";
|
|||
|
self thread AI_friendly_waittill_death();
|
|||
|
if ( !isdefined( self.magic_bullet_shield ) )
|
|||
|
self thread magic_bullet_shield();
|
|||
|
self setFlashbangImmunity(true);
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WHICH TEAM IS FRIENDLY ON
|
|||
|
-------------------------*/
|
|||
|
if (isdefined(self.script_forcecolor))
|
|||
|
{
|
|||
|
switch (self.script_forcecolor)
|
|||
|
{
|
|||
|
case "r":
|
|||
|
level.team01 = array_add(level.team01, self);
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
self thread print3Dthread("Team 01");
|
|||
|
break;
|
|||
|
case "o":
|
|||
|
level.team01 = array_add(level.team01, self);
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
self thread print3Dthread("Wingman");
|
|||
|
break;
|
|||
|
case "y":
|
|||
|
level.team02 = array_add(level.team02, self);
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
self thread print3Dthread("Team 02");
|
|||
|
break;
|
|||
|
case "g":
|
|||
|
level.team03 = array_add(level.team03, self);
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
self thread print3Dthread("Team 03");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DAMAGE BEHAVIOR
|
|||
|
-------------------------*/
|
|||
|
while (true)
|
|||
|
{
|
|||
|
self waittill ( "damage", damage, attacker );
|
|||
|
/*-----------------------
|
|||
|
EVERY TIME HIT, IGNORE ME FOR A WHILE
|
|||
|
-------------------------*/
|
|||
|
level.bmpExcluders = array_add( level.bmpExcluders, self );
|
|||
|
self.ignoreme = true;
|
|||
|
wait(1);
|
|||
|
self.a.disablePain = true;
|
|||
|
|
|||
|
wait (randomfloatrange(3,5));
|
|||
|
|
|||
|
self.ignoreme = false;
|
|||
|
level.bmpExcluders = array_remove( level.bmpExcluders, self );
|
|||
|
self.a.disablePain = false;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AI_friendly_waittill_death()
|
|||
|
{
|
|||
|
self waittill ("death");
|
|||
|
if ( is_in_array( level.bmpExcluders, self ) )
|
|||
|
array_remove( level.bmpExcluders, self );
|
|||
|
}
|
|||
|
|
|||
|
AI_axis_think()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
self.animname = "hostile";
|
|||
|
self thread AI_axis_death();
|
|||
|
self thread AI_axis_player_distance();
|
|||
|
self thread AI_axis_sniper_fodder();
|
|||
|
}
|
|||
|
|
|||
|
AI_axis_player_distance()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
|
|||
|
wait(.25);
|
|||
|
if (level.snipersActive)
|
|||
|
continue;
|
|||
|
prof_begin("sniper_activity");
|
|||
|
if (distancesquared(self.origin,level.player.origin) <= level.playerDistanceToAIsquared)
|
|||
|
self notify ("close_to_player");
|
|||
|
prof_end("sniper_activity");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AI_axis_sniper_fodder()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
|
|||
|
|
|||
|
while (true)
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WAIT TILL IN RANGE, THEN CHECK
|
|||
|
-------------------------*/
|
|||
|
self waittill("close_to_player");
|
|||
|
|
|||
|
//Abort if people speaking
|
|||
|
if (level.peoplespeaking)
|
|||
|
continue;
|
|||
|
|
|||
|
//Abort if snipers already shooting
|
|||
|
if (level.snipersActive)
|
|||
|
continue;
|
|||
|
|
|||
|
//if (!level.player islookingat(self))
|
|||
|
//continue;
|
|||
|
|
|||
|
//Abort if AI not in designated volume
|
|||
|
//if (!self istouching(level.snipervolume))
|
|||
|
//continue;
|
|||
|
|
|||
|
//Abort if player can't see
|
|||
|
playerEye = level.player getEye();
|
|||
|
targetTagOrigin = self gettagorigin ("TAG_EYE");
|
|||
|
|
|||
|
prof_begin("sniper_activity");
|
|||
|
qInFOV = within_fov(playerEye, level.player getPlayerAngles(), targetTagOrigin, level.cosine["35"]);
|
|||
|
prof_end("sniper_activity");
|
|||
|
|
|||
|
if (!qInFOV)
|
|||
|
continue;
|
|||
|
|
|||
|
prof_begin("sniper_activity");
|
|||
|
playerCanSee = sighttracepassed(playerEye, targetTagOrigin, false, undefined);
|
|||
|
prof_end("sniper_activity");
|
|||
|
|
|||
|
if (!playerCanSee)
|
|||
|
continue;
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
SHOOT
|
|||
|
-------------------------*/
|
|||
|
//Abort if can't get a clear shot
|
|||
|
targetTagOrigin = self gettagorigin ("TAG_EYE");
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
self thread print3Dthread("target");
|
|||
|
for(i=0;i<level.aSniper_orgs.size;i++)
|
|||
|
{
|
|||
|
prof_begin("sniper_activity");
|
|||
|
sniperCanShoot = sighttracepassed(level.aSniper_orgs[i].origin, targetTagOrigin, true, self);
|
|||
|
prof_end("sniper_activity");
|
|||
|
|
|||
|
if (sniperCanShoot)
|
|||
|
{
|
|||
|
self thread sniper_execute(targetTagOrigin, level.aSniper_orgs[i]);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
sniper_execute(targetTagOrigin, eSniper_org)
|
|||
|
{
|
|||
|
//self ==> the AI targeted for execution
|
|||
|
if (!isdefined(self))
|
|||
|
return;
|
|||
|
if (!isalive(self))
|
|||
|
return;
|
|||
|
if (level.snipersActive)
|
|||
|
return;
|
|||
|
|
|||
|
level.snipersActive = true;
|
|||
|
|
|||
|
level.sniperTarget = self;
|
|||
|
level notify ("sniper_target_updated");
|
|||
|
/*-----------------------
|
|||
|
SNIPER SHOOTS AI
|
|||
|
-------------------------*/
|
|||
|
level.sniperkills++;
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
{
|
|||
|
level notify ("stop_drawing_line");
|
|||
|
thread draw_line_until_notify(eSniper_org.origin, targetTagOrigin, 1, 0, 0, level, "stop_drawing_line");
|
|||
|
println("***Snipers have killed " + level.sniperkills + " enemies");
|
|||
|
}
|
|||
|
iBurst = randomintrange(1, 3);
|
|||
|
iBulletsFired = 0;
|
|||
|
while ( iBulletsFired < iBurst)
|
|||
|
{
|
|||
|
iBulletsFired++;
|
|||
|
if (iBulletsFired == 1)
|
|||
|
playfxontag(getfx("headshot"), self, "tag_eye");
|
|||
|
magicbullet("m14_scoped", eSniper_org.origin, targetTagOrigin);
|
|||
|
bullettracer (eSniper_org.origin, targetTagOrigin, true);
|
|||
|
thread play_sound_in_space( "weap_m82sniper_fire_launcha", level.player.origin );
|
|||
|
|
|||
|
if (iBulletsFired != iBurst)
|
|||
|
wait(randomfloatrange(.25, .75));
|
|||
|
}
|
|||
|
|
|||
|
wait(randomfloatrange(.75, 1.5));
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
RANDOM CONFIRM DIALOGUE
|
|||
|
-------------------------*/
|
|||
|
if (level.sniperConfirmDialogue)
|
|||
|
{
|
|||
|
level.dialogueSniperConfirm_number++;
|
|||
|
if (level.dialogueSniperConfirm_number > level.dialogueSniperConfirm_MAX)
|
|||
|
level.dialogueSniperConfirm_number = 1;
|
|||
|
|
|||
|
sDialogue = "launchfacility_a_sniper_confirm_0" + level.dialogueSniperConfirm_number;
|
|||
|
|
|||
|
if (!level.peoplespeaking)
|
|||
|
level radio_dialogue_queue(sDialogue);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
DON'T ALLOW ANY MORE SNIPER TILL INTERVAL EXPIRED
|
|||
|
-------------------------*/
|
|||
|
wait (level.sniperInterval);
|
|||
|
|
|||
|
level.snipersActive = false;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
AI_axis_death()
|
|||
|
{
|
|||
|
self waittill ("death", attacker);
|
|||
|
if (!isdefined (attacker))
|
|||
|
return;
|
|||
|
if (attacker == level.player)
|
|||
|
{
|
|||
|
level.axisKilledByPlayer++;
|
|||
|
if (getdvar("debug_launch") == "1")
|
|||
|
println("Player has killed " + level.axisKilledByPlayer + " enemies");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AI_in_volume_chase_player()
|
|||
|
{
|
|||
|
//self ==> the volume passed
|
|||
|
aHostiles = getaiarray( "axis" );
|
|||
|
for( i = 0 ; i < aHostiles.size ; i++ )
|
|||
|
{
|
|||
|
if ( aHostiles[i] istouching( self ) )
|
|||
|
{
|
|||
|
aHostiles[i].goalradius = 600;
|
|||
|
aHostiles[i] setgoalentity( level.player );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AI_chain_and_seek()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
self waittill( "reached_path_end" );
|
|||
|
self thread AI_player_seek();
|
|||
|
}
|
|||
|
|
|||
|
AI_player_seek()
|
|||
|
{
|
|||
|
self endon ("death");
|
|||
|
newGoalRadius = distance( self.origin, level.player.origin );
|
|||
|
for(;;)
|
|||
|
{
|
|||
|
wait 2;
|
|||
|
self.goalradius = newGoalRadius;
|
|||
|
|
|||
|
self setgoalentity ( level.player );
|
|||
|
newGoalRadius -= 175;
|
|||
|
if ( newGoalRadius < 512 )
|
|||
|
{
|
|||
|
newGoalRadius = 512;
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
initPlayer()
|
|||
|
{
|
|||
|
level.player set_threatbiasgroup ("player");
|
|||
|
//level.player_location = undefined;
|
|||
|
aTrigger_player_location = getentarray( "trigger_player_location", "targetname" );
|
|||
|
//array_thread ( aTrigger_player_location, :: trigger_player_location_think);
|
|||
|
}
|
|||
|
|
|||
|
initFriendlies(sStartPoint)
|
|||
|
{
|
|||
|
waittillframeend;
|
|||
|
|
|||
|
assert(isdefined(sStartPoint));
|
|||
|
level.squad = [];
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
PRICE AND GRIGSBY
|
|||
|
-------------------------*/
|
|||
|
level.price = spawn_script_noteworthy( "price" );
|
|||
|
level.grigsby = spawn_script_noteworthy( "grigsby" );
|
|||
|
level.squad[0] = level.price;
|
|||
|
level.squad[1] = level.grigsby;
|
|||
|
level.otherSquadFriendly = undefined;
|
|||
|
level.excludedAi = [];
|
|||
|
level.excludedAi[0] = level.price;
|
|||
|
level.excludedAi[1] = level.grigsby;
|
|||
|
/*-----------------------
|
|||
|
SPAWN FRIENDLIES
|
|||
|
-------------------------*/
|
|||
|
switch ( sStartPoint )
|
|||
|
{
|
|||
|
case "default":
|
|||
|
level.friendly_at4 = spawn_script_noteworthy( "friendly_at4" );
|
|||
|
aFriendly_support = spawnGroup( getentarray("friendly_support", "script_noteworthy") );
|
|||
|
level.squad = array_merge( level.squad, aFriendly_support );
|
|||
|
break;
|
|||
|
case "container":
|
|||
|
level.friendly_at4 = spawn_script_noteworthy( "friendly_at4" );
|
|||
|
aFriendly_support = spawnGroup( getentarray("friendly_support", "script_noteworthy") );
|
|||
|
level.squad = array_merge( level.squad, aFriendly_support );
|
|||
|
break;
|
|||
|
case "gate":
|
|||
|
aFriendly_support = spawnGroup( getentarray("friendly_support", "script_noteworthy") );
|
|||
|
level.squad = array_merge( level.squad, aFriendly_support );
|
|||
|
break;
|
|||
|
case "tarmac":
|
|||
|
break;
|
|||
|
case "vents":
|
|||
|
aFriendly_support = spawnGroup( getentarray("friendly_support", "script_noteworthy") );
|
|||
|
level.squad = array_merge( level.squad, aFriendly_support );
|
|||
|
break;
|
|||
|
default:
|
|||
|
assertmsg("The startPoint ' " + sStartPoint + " ' is not valid");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WARP HEROES TO CORRECT POSITIONS
|
|||
|
-------------------------*/
|
|||
|
aFriendlies = level.squad;
|
|||
|
warpNodes = getnodearray("nodeStart_" + sStartPoint, "targetname");
|
|||
|
assertEx((isdefined(warpNodes)), "No nodes with targetname: nodeStart_" + sStartPoint);
|
|||
|
iKeyFriendlies = 0;
|
|||
|
playerNode = undefined;
|
|||
|
while (iKeyFriendlies < 3)
|
|||
|
{
|
|||
|
wait (0.05);
|
|||
|
for(i=0;i<warpNodes.size;i++)
|
|||
|
{
|
|||
|
if (isdefined(warpNodes[i].script_noteworthy))
|
|||
|
{
|
|||
|
switch (warpNodes[i].script_noteworthy)
|
|||
|
{
|
|||
|
case "nodePrice":
|
|||
|
level.price start_teleport ( warpNodes[i] );
|
|||
|
aFriendlies = array_remove(aFriendlies, level.price);
|
|||
|
warpNodes = array_remove(warpNodes, warpNodes[i]);
|
|||
|
iKeyFriendlies ++;
|
|||
|
break;
|
|||
|
case "nodeGrigsby":
|
|||
|
level.grigsby start_teleport ( warpNodes[i] );
|
|||
|
aFriendlies = array_remove(aFriendlies, level.grigsby);
|
|||
|
warpNodes = array_remove(warpNodes, warpNodes[i]);
|
|||
|
iKeyFriendlies ++;
|
|||
|
break;
|
|||
|
case "nodePlayer":
|
|||
|
playerNode = warpNodes[i];
|
|||
|
warpNodes = array_remove(warpNodes, warpNodes[i]);
|
|||
|
iKeyFriendlies ++;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WARP SUPPORT FRIENDLIES TO CORRECT POSITIONS
|
|||
|
-------------------------*/
|
|||
|
if (aFriendlies.size > 0)
|
|||
|
{
|
|||
|
for(i=0;i<aFriendlies.size;i++)
|
|||
|
{
|
|||
|
assertEx((isdefined(warpNodes[i])), "May not be enough warp nodes for support friendlies for start name");
|
|||
|
aFriendlies[i] start_teleport ( warpNodes[i] );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*-----------------------
|
|||
|
WARP PLAYER LAST SO HE DOESN'T SEE
|
|||
|
-------------------------*/
|
|||
|
assert(isdefined(playerNode));
|
|||
|
level.player setorigin ( playerNode.origin );
|
|||
|
level.player setplayerangles ( playerNode.angles );
|
|||
|
|
|||
|
level.excludedAi[0] = level.price;
|
|||
|
level.excludedAi[1] = level.grigsby;
|
|||
|
}
|
|||
|
|
|||
|
initPrecache()
|
|||
|
{
|
|||
|
//Objective strings
|
|||
|
precacheString(&"LAUNCHFACILITY_A_OBJ_GAIN_ACCESS");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_OBJ_RIGHT_GATE");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_OBJ_ENEMY_ARMOR");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_OBJ_NORTH_TARMAC");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_OBJ_RAPPEL");
|
|||
|
|
|||
|
precacheItem("m14_scoped");
|
|||
|
precacheItem("rpg_player");
|
|||
|
precacheItem("hind_turret");
|
|||
|
precacheItem("hind_FFAR");
|
|||
|
precacheItem("hind_FFAR_nodamage");
|
|||
|
precacheModel("weapon_c4");
|
|||
|
precacheModel("weapon_c4_obj");
|
|||
|
precacheModel("rope_coil_obj");
|
|||
|
precacheModel("rope_coil");
|
|||
|
precacheModel("viewmodel_base_fastrope_character");
|
|||
|
precacheModel("weapon_rpd_MG_Setup");
|
|||
|
precacheModel("weapon_stinger");
|
|||
|
precacheModel( "weapon_saw_rescue" );
|
|||
|
//precacheModel( "weapon_javelin" );
|
|||
|
|
|||
|
precacheString(&"SCRIPT_ARMOR_DAMAGE");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_DEBUG_LEVEL_END");
|
|||
|
precacheString(&"SCRIPT_PLATFORM_LAUNCHFACILITY_A_HINT_SMOKE");
|
|||
|
precacheString(&"SCRIPT_PLATFORM_LAUNCHFACILITY_A_HINT_PLANT_C4_GLOW");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_HINTSTR_C4_PLANT");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_HINTSTR_C4_DETONATE");
|
|||
|
precacheString(&"SCRIPT_PLATFORM_HINTSTR_RAPPEL");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_HINTSTR_RAPPEL_DOWN_SHAFT");
|
|||
|
precacheString(&"LAUNCHFACILITY_A_HINTSTR_EXPLOSIVES_PLANTED");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
vehicle_path_disconnector()
|
|||
|
{
|
|||
|
zone = getent( self.target, "targetname" );
|
|||
|
assert( isdefined( zone ) );
|
|||
|
zone notsolid();
|
|||
|
zone.origin -= ( 0, 0, 1024 );
|
|||
|
|
|||
|
for(;;)
|
|||
|
{
|
|||
|
self waittill( "trigger", tank );
|
|||
|
assert( isdefined( tank ) );
|
|||
|
assert( tank == level.abrams );
|
|||
|
|
|||
|
if ( !isdefined( zone.pathsDisconnected ) )
|
|||
|
{
|
|||
|
zone solid();
|
|||
|
zone disconnectpaths();
|
|||
|
zone notsolid();
|
|||
|
zone.pathsDisconnected = true;
|
|||
|
}
|
|||
|
|
|||
|
thread vehicle_reconnects_paths( zone );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
vehicle_reconnects_paths( zone )
|
|||
|
{
|
|||
|
zone notify( "waiting_for_path_reconnection" );
|
|||
|
zone endon( "waiting_for_path_reconnection" );
|
|||
|
wait 0.5;
|
|||
|
|
|||
|
// paths get reconnected
|
|||
|
zone solid();
|
|||
|
zone connectpaths();
|
|||
|
zone notsolid();
|
|||
|
zone.pathsDisconnected = undefined;
|
|||
|
}
|