3070 lines
78 KiB
Plaintext
3070 lines
78 KiB
Plaintext
/****************************************************************************
|
||
|
||
Level: Loose Ends (estate.bsp)
|
||
Location: Georgian-Russian Border (45 miles into Russian territory)
|
||
Campaign: Task Force 141
|
||
Objectives:
|
||
1. Locate and neutralize Vladimir Makarov.
|
||
2. Recover the hard drive from Makarov's computer.
|
||
3. Hold out until the extraction force arrives.
|
||
4. Get to the secondary LZ for extraction.
|
||
|
||
*****************************************************************************/
|
||
|
||
#include common_scripts\utility;
|
||
#include maps\_utility;
|
||
#include maps\_vehicle;
|
||
#include maps\_anim;
|
||
#include maps\_slowmo_breach;
|
||
#include maps\estate_code;
|
||
|
||
main()
|
||
{
|
||
default_start( ::startIntro );
|
||
add_start( "intro", ::startIntro, "Intro", ::estate_ambush );
|
||
add_start( "ambush", ::startAmbush, "Ambush", ::estate_ambush );
|
||
add_start( "forest_fight", ::startForestFight, "Forest Fight", ::estate_ambush );
|
||
add_start( "house_approach", ::startHouseApproach, "House Approach", ::estate_ambush );
|
||
add_start( "house_breach", ::startHouseBreach, "House Breach" );
|
||
add_start( "house_briefing", ::startHouseBriefing, "House Briefing" );
|
||
add_start( "house_defense", ::startHouseDefense, "House Defense" );
|
||
add_start( "escape", ::startEscape, "Escape to LZ" );
|
||
add_start( "ending", ::startEnding, "Ending Sequence" );
|
||
add_start( "ending_body_throw", ::startEndingBodyTossOnly );
|
||
add_start( "alt_ending", ::startAltEnding, "Alternate Ending" );
|
||
|
||
add_start( "ending_noslowmo", ::startEndingMeh );
|
||
add_start( "diskdrive", ::startDiskdrive );
|
||
add_start( "helicopter_tweak", ::startHeliTweak );
|
||
add_start( "helicopter_tweak_2", ::startHeliTweak2 );
|
||
add_start( "ending_pavelow_heli_tweak", ::startHeliTweakPavelowEnd );
|
||
add_start( "ending_shadow_heli_tweak", ::startHeliTweakShadowBirdsEnd );
|
||
add_start( "fakeRPG_tweak", ::startFakeRPGTweak );
|
||
|
||
flags();
|
||
|
||
maps\estate_precache::main();
|
||
|
||
global_inits();
|
||
}
|
||
|
||
start_common_estate()
|
||
{
|
||
thread objectives();
|
||
|
||
thread estate_music();
|
||
|
||
thread house_autosaves();
|
||
|
||
thread bouncing_betty_gameplay_init();
|
||
thread birchfield_exfil();
|
||
thread friendly_death_cointoss();
|
||
thread bb_autosave();
|
||
|
||
thread maps\_mortar::bog_style_mortar();
|
||
|
||
thread birchfield_knockout();
|
||
thread ending_moments();
|
||
thread ending_pavelow_fakearrival();
|
||
thread end_of_level();
|
||
|
||
if( !flag( "skip_forestfight" ) )
|
||
{
|
||
thread forest_ambush_mortars();
|
||
thread forest_ambush_rpg_guys();
|
||
thread forest_enemy_deathmonitor_init();
|
||
thread forest_ghillie_reveal();
|
||
thread first_smoke_screen();
|
||
thread forest_attackers();
|
||
thread forest_smoke_fight();
|
||
thread forest_smoke_screens();
|
||
thread forest_escape_autosave();
|
||
}
|
||
|
||
if( flag( "skip_forestfight" ) )
|
||
{
|
||
flag_set( "start_ambush_music" );
|
||
}
|
||
|
||
if( !flag( "skip_houseapproach" ) )
|
||
{
|
||
//thread house_defense_heli_frontyard();
|
||
thread house_approach_jeepassault();
|
||
thread house_approach_autosave();
|
||
thread house_approach_futilejeep();
|
||
thread house_arrival_autosave();
|
||
thread house_friendly_rush();
|
||
thread house_approach_dialogue();
|
||
thread house_perimeter_jeepguards();
|
||
}
|
||
|
||
if( !flag( "skip_breachandclear" ) )
|
||
{
|
||
thread house_enemy_cleanup_tracker();
|
||
thread house_arrival_aisettings();
|
||
thread house_clearing_save_mainfloor();
|
||
thread house_clearing_save_basement();
|
||
|
||
thread house_backwards_door_handling();
|
||
|
||
//House clearing monitoring and dialogue threads
|
||
|
||
thread house_battlechatter_check();
|
||
|
||
thread house_mainfloor_cleared();
|
||
thread house_topfloor_cleared();
|
||
thread house_basement_cleared();
|
||
|
||
thread house_topfloor_breached();
|
||
thread house_basement_breached_armory();
|
||
thread house_basement_breached_guestroom();
|
||
|
||
thread house_mainfloor_cleared_dialogue();
|
||
thread house_topfloor_cleared_dialogue();
|
||
thread house_basement_cleared_dialogue();
|
||
|
||
thread house_check_upstairs_mainfloor_dialogue();
|
||
thread house_check_upstairs_basement_dialogue();
|
||
thread house_check_basement_dialogue();
|
||
thread house_clearing_banter();
|
||
|
||
thread house_ghost_sweep();
|
||
thread house_ghost_lastbreach_reset();
|
||
|
||
//basic flag setters for which exterior breach is done
|
||
|
||
thread house_extras_breach_mainfloor();
|
||
thread house_extras_breach_kitchen();
|
||
thread house_extras_breach_basement();
|
||
thread house_exterior_breach_awareness();
|
||
|
||
//**** Extra guys - Breach 0 ( Main Foyer )
|
||
|
||
thread house_extras_tally( "breach0_diningroom", "breaching_number_0" );
|
||
thread house_extras_tally( "breach0_foyerhall", "breaching_number_0" );
|
||
thread house_extras_tally( "breach0_bathroomrush", "breaching_number_0" );
|
||
|
||
thread house_extras_cancel_floorpop_monitor( "breach0_diningroom", "breach0_diningroom_cancel", "foyer_breached_first" );
|
||
thread house_extras_cancel_floorpop_monitor( "breach0_foyerhall", "breach0_foyerhall_cancel", "foyer_breached_first" );
|
||
//thread house_extras_cancel_floorpop_monitor( "breach0_bathroomrush", "breach0_bathroomrush_cancel", "foyer_breached_first" ); //no cancel triggers needed
|
||
|
||
//If player goes into kitchen first, enemies spawn from dining room and run into kitchen
|
||
thread house_extras_spawncontrol( "breach0_diningroom_spawntrig", "breach0_diningroom_cancel", "breaching_number_0", "breach0_diningroom" );
|
||
|
||
//If player goes from foyer directly straight ahead towards the dining room, enemies run out in front of player in dining room
|
||
thread house_extras_spawncontrol( "breach0_foyerhall_spawntrig", "breach0_foyerhall_cancel", "breaching_number_0", "breach0_foyerhall" );
|
||
|
||
//If player goes from foyer up the stairs, one enemy runs out of the bathroom
|
||
thread house_extras_spawncontrol( "breach0_bathroomrush_spawntrig", undefined, "breaching_number_0", "breach0_bathroomrush" );
|
||
thread house_extras_bathroom_screamingguy_setup(); //this guy screams as he emerges from the bathroom
|
||
|
||
//**** Extra guys - Breach 1 ( Kitchen )
|
||
|
||
thread house_extras_tally( "breach1_foyertodining", "breaching_number_1" );
|
||
thread house_extras_tally( "breach1_officerush", "breaching_number_1" );
|
||
|
||
thread house_extras_cancel_floorpop_monitor( "breach1_foyertodining", "breach1_foyertodining_cancel", "kitchen_breached_first" );
|
||
thread house_extras_cancel_floorpop_monitor( "breach1_officerush", "breach1_officerush_cancel", "kitchen_breached_first" ); //no cancel triggers needed
|
||
|
||
//If player goes towards the dining room, two enemies enter dining from foyerhall, one enemy enters kitchen from foyerhall
|
||
thread house_extras_spawncontrol( "breach1_foyertodining_spawntrig", "breach1_foyertodining_cancel", "breaching_number_1", "breach1_foyertodining" );
|
||
|
||
//If player enters foyerhall from kitchen, front door, or dining room, four enemies rush out of the office into the great room
|
||
thread house_extras_spawncontrol( "breach1_officerush_spawntrig", undefined, "breaching_number_1", "breach1_officerush" );
|
||
|
||
//**** Extra guys - Breach 2 ( Basement )
|
||
|
||
thread house_extras_tally( "breach2_stairdown", "breaching_number_2" );
|
||
|
||
thread house_extras_cancel_floorpop_monitor( "breach2_stairdown", "breach2_stairdown_cancel", "basement_breached_first" );
|
||
|
||
//If player continues to push into the rec room, two guys will run down and out from the stairwell that leads from the kitchen
|
||
thread house_extras_spawncontrol( "breach2_stairdown_spawntrig", "breach2_stairdown_cancel", "breaching_number_2", "breach2_stairdown" );
|
||
}
|
||
|
||
if( flag( "skip_breachandclear" ) )
|
||
{
|
||
thread delete_breach( 0 );
|
||
thread delete_breach( 1 );
|
||
thread delete_breach( 2 );
|
||
thread delete_breach( 3 );
|
||
thread delete_breach( 4 );
|
||
thread delete_breach( 5 );
|
||
thread house_guestroom_door_remove();
|
||
thread house_backwards_door_handling();
|
||
}
|
||
|
||
if( !flag( "skip_housebriefing" ) )
|
||
{
|
||
thread dsm_display_control();
|
||
thread house_briefing_dialogue();
|
||
thread download_progress();
|
||
thread download_fake_timer();
|
||
thread dsm_setup();
|
||
thread defense_intro();
|
||
thread dsm_destruction_damage_detect();
|
||
thread dsm_health_regen();
|
||
thread dsm_health_regen_calc();
|
||
}
|
||
|
||
if( flag( "skip_housebriefing" ) && !flag( "skip_defense" ) )
|
||
{
|
||
thread dsm_display_control();
|
||
thread download_progress();
|
||
thread download_fake_timer();
|
||
thread dsm_setup();
|
||
thread defense_intro();
|
||
thread dsm_destruction_damage_detect();
|
||
thread dsm_health_regen();
|
||
thread dsm_health_regen_calc();
|
||
}
|
||
}
|
||
|
||
startIntro()
|
||
{
|
||
thread start_common_estate();
|
||
|
||
ghost_init();
|
||
|
||
thread ghost_intro_nav();
|
||
thread intro();
|
||
thread intro_dialogue();
|
||
|
||
thread friendly_troop_spawn();
|
||
thread friendly_scout_spawn();
|
||
thread friendly_sniper_spawn();
|
||
}
|
||
|
||
startAmbush()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
|
||
flag_set( "print_first_objective" );
|
||
|
||
thread start_common_estate();
|
||
|
||
friendly_sniper_spawn();
|
||
|
||
player_ambush_start = getent( "player_ambush_start", "targetname" );
|
||
level.player teleport_ent( player_ambush_start );
|
||
|
||
ghost_init();
|
||
node = getnode( "ghost_ambush_start", "targetname" );
|
||
level.ghost forceTeleport( node.origin, node.angles );
|
||
|
||
redshirts = getentarray( "starterguy", "script_noteworthy" );
|
||
nodes = getnodearray( "friendly_ambush_start", "targetname" );
|
||
|
||
friendly_starts_avail = redshirts.size <= nodes.size;
|
||
|
||
assertEX( friendly_starts_avail, "Not enough start nodes exist for redshirts, add more nodes for them to start at." );
|
||
|
||
foreach ( index, redshirt in redshirts )
|
||
{
|
||
redshirt.origin = nodes[ index ].origin;
|
||
redshirt.angles = nodes[ index ].angles;
|
||
}
|
||
|
||
friendly_troop_spawn();
|
||
friendly_scout_spawn();
|
||
|
||
activate_trigger_with_targetname( "ambush_start_redshirts" );
|
||
activate_trigger_with_targetname( "ambush_start_ghost" );
|
||
}
|
||
|
||
startForestFight()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
flag_set( "skip_ambush" );
|
||
flag_set( "bouncing_betty_done" );
|
||
flag_set( "print_first_objective" );
|
||
|
||
flag_set( "deploy_rpg_ambush" );
|
||
flag_set( "deploy_mortar_attack" );
|
||
flag_set( "ambush_complete" );
|
||
|
||
thread start_common_estate();
|
||
|
||
player_forestfight_start = getent( "player_forestfight_start", "targetname" );
|
||
level.player teleport_ent( player_forestfight_start );
|
||
|
||
ghost_init();
|
||
node = getnode( "ghost_ambush_start", "targetname" );
|
||
level.ghost forceTeleport( node.origin, node.angles );
|
||
|
||
redshirts = getentarray( "starterguy", "script_noteworthy" );
|
||
nodes = getnodearray( "friendly_forestfight_start", "targetname" );
|
||
deathNodes = getnodearray ("forestfight_friendlykill", "script_noteworthy" );
|
||
|
||
friendly_starts_avail = redshirts.size <= nodes.size;
|
||
|
||
assertEX( friendly_starts_avail, "Not enough start nodes exist for redshirts, add more nodes for them to start at." );
|
||
|
||
foreach ( index, redshirt in redshirts )
|
||
{
|
||
redshirt.origin = nodes[ index ].origin;
|
||
redshirt.angles = nodes[ index ].angles;
|
||
}
|
||
|
||
friendly_troop_spawn();
|
||
friendly_scout_spawn();
|
||
|
||
activate_trigger_with_targetname( "forestfight_start_redshirts" );
|
||
activate_trigger_with_targetname( "ambush_start_ghost" );
|
||
|
||
//kill friendlies in the blast area of the bouncing betty ambush
|
||
|
||
wait 0.05;
|
||
|
||
foreach( deathNode in deathNodes )
|
||
{
|
||
radiusdamage( deathNode.origin, deathNode.radius, 1000, 180 );
|
||
}
|
||
|
||
wait 3;
|
||
|
||
flag_set( "smoke_screen_activated" );
|
||
|
||
wait 3;
|
||
|
||
flag_set( "spawn_first_ghillies" );
|
||
}
|
||
|
||
startHouseApproach()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
flag_set( "skip_ambush" );
|
||
flag_set( "skip_forestfight" );
|
||
flag_set( "bouncing_betty_done" );
|
||
flag_set( "print_first_objective" );
|
||
flag_set( "forestfight_littlebird_1" );
|
||
flag_set( "player_is_out_of_ambush_zone" );
|
||
|
||
thread start_common_estate();
|
||
|
||
player_houseapproach_start = getent( "player_houseapproach_start", "targetname" );
|
||
level.player teleport_ent( player_houseapproach_start );
|
||
|
||
ghost_init();
|
||
node = getnode( "ghost_houseapproach_start", "targetname" );
|
||
level.ghost forceTeleport( node.origin, node.angles );
|
||
|
||
redshirtStartSpawnTeleport( "houseapproach" );
|
||
}
|
||
|
||
startHouseBreach()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
flag_set( "skip_ambush" );
|
||
flag_set( "skip_forestfight" );
|
||
flag_set( "skip_houseapproach" );
|
||
flag_set( "bouncing_betty_done" );
|
||
|
||
flag_set( "print_first_objective" );
|
||
flag_set( "futilejeeps_destroyed" );
|
||
flag_set( "deploy_house_defense_jeeps" );
|
||
|
||
flag_set( "forestfight_littlebird_1" );
|
||
flag_set( "player_is_out_of_ambush_zone" );
|
||
|
||
thread start_common_estate();
|
||
|
||
player_houseapproach_start = getent( "breach_tweak_start", "targetname" );
|
||
level.player teleport_ent( player_houseapproach_start );
|
||
|
||
ghost_init();
|
||
node = getnode( "ghost_breachstart_node", "targetname" );
|
||
level.ghost forceTeleport( node.origin, node.angles );
|
||
|
||
redshirtStartSpawnTeleport( "breachhouse" );
|
||
|
||
houseAttackTrig = getent( "house_approach_friendlytrigger", "targetname" );
|
||
houseAttackTrig notify ( "trigger" );
|
||
}
|
||
|
||
startHouseBriefing()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
flag_set( "skip_ambush" );
|
||
flag_set( "skip_forestfight" );
|
||
flag_set( "skip_houseapproach" );
|
||
flag_set( "skip_breachandclear" );
|
||
|
||
flag_set( "bouncing_betty_done" );
|
||
|
||
flag_set( "print_first_objective" );
|
||
flag_set( "futilejeeps_destroyed" );
|
||
|
||
flag_set( "house_exterior_has_been_breached" );
|
||
flag_set( "house_interior_breaches_done" );
|
||
|
||
flag_set( "forestfight_littlebird_1" );
|
||
flag_set( "player_is_out_of_ambush_zone" );
|
||
|
||
level notify ( "breaching_number_3" );
|
||
|
||
thread start_common_estate();
|
||
|
||
level.playerZone = "zone_house";
|
||
|
||
player_houseapproach_start = getent( "briefing_tweak_start", "targetname" );
|
||
level.player teleport_ent( player_houseapproach_start );
|
||
|
||
ghost_init();
|
||
|
||
node = getnode( "ghost_breachstart_node", "targetname" );
|
||
level.ghost forceTeleport( node.origin, node.angles );
|
||
|
||
redshirtStartSpawnTeleport( "housebriefing" );
|
||
|
||
houseAttackTrig = getent( "house_approach_friendlytrigger", "targetname" );
|
||
houseAttackTrig notify ( "trigger" );
|
||
|
||
flag_set( "all_enemies_killed_up_to_house_capture" );
|
||
}
|
||
|
||
startHouseDefense()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
flag_set( "skip_ambush" );
|
||
flag_set( "skip_forestfight" );
|
||
flag_set( "skip_houseapproach" );
|
||
flag_set( "skip_breachandclear" );
|
||
flag_set( "skip_housebriefing" );
|
||
|
||
flag_set( "bouncing_betty_done" );
|
||
|
||
flag_set( "print_first_objective" );
|
||
flag_set( "futilejeeps_destroyed" );
|
||
|
||
flag_set( "house_exterior_has_been_breached" );
|
||
flag_set( "house_interior_breaches_done" );
|
||
|
||
flag_set( "forestfight_littlebird_1" );
|
||
flag_set( "player_is_out_of_ambush_zone" );
|
||
|
||
flag_set( "dsm_ready_to_use" );
|
||
flag_set( "house_briefing_is_over" );
|
||
flag_set( "download_started" );
|
||
|
||
flag_set( "skip_house_defense_dialogue" );
|
||
|
||
level.playerZone = "zone_house";
|
||
|
||
level notify ( "breaching_number_3" );
|
||
|
||
thread start_common_estate();
|
||
|
||
player_houseapproach_start = getent( "briefing_tweak_start", "targetname" );
|
||
level.player teleport_ent( player_houseapproach_start );
|
||
|
||
ghost_init();
|
||
|
||
node = getnode( "ghost_earlydefense_start", "targetname" );
|
||
level.ghost forceTeleport( node.origin, node.angles );
|
||
|
||
redshirtStartSpawnTeleport( "housebriefing" );
|
||
|
||
houseAttackTrig = getent( "house_approach_friendlytrigger", "targetname" );
|
||
houseAttackTrig notify ( "trigger" );
|
||
|
||
flag_set( "scarecrow_to_earlydefense_start" );
|
||
flag_set( "ozone_to_earlydefense_start" );
|
||
|
||
flag_set( "all_enemies_killed_up_to_house_capture" );
|
||
|
||
wait 1;
|
||
|
||
node = getnode( "ghost_earlydefense_start", "targetname" );
|
||
level.ghost setgoalnode( node );
|
||
|
||
thread house_briefing_scarecrow();
|
||
thread house_briefing_ozone();
|
||
}
|
||
|
||
startEscape()
|
||
{
|
||
fence = getent( "final_area_fence", "targetname" );
|
||
fence delete();
|
||
|
||
dsm_real = getent( "dsm", "targetname" );
|
||
dsm_obj = getent( "dsm_obj", "targetname" );
|
||
|
||
dsm_real hide();
|
||
dsm_obj hide();
|
||
|
||
flag_set( "skip_intro" );
|
||
flag_set( "skip_ambush" );
|
||
flag_set( "skip_forestfight" );
|
||
flag_set( "skip_houseapproach" );
|
||
flag_set( "skip_breachandclear" );
|
||
flag_set( "skip_housebriefing" );
|
||
flag_set( "skip_defense" );
|
||
|
||
flag_set( "bouncing_betty_done" );
|
||
|
||
flag_set( "print_first_objective" );
|
||
flag_set( "futilejeeps_destroyed" );
|
||
|
||
flag_set( "house_exterior_has_been_breached" );
|
||
flag_set( "house_interior_breaches_done" );
|
||
|
||
flag_set( "forestfight_littlebird_1" );
|
||
flag_set( "player_is_out_of_ambush_zone" );
|
||
|
||
flag_set( "house_briefing_is_over" );
|
||
flag_set( "download_started" );
|
||
|
||
flag_set( "skip_house_defense_dialogue" );
|
||
|
||
flag_set( "download_complete" );
|
||
|
||
flag_set( "dsm_recovered" );
|
||
|
||
level.playerZone = "zone_house";
|
||
|
||
level notify ( "breaching_number_3" );
|
||
|
||
thread start_common_estate();
|
||
|
||
player_houseapproach_start = getent( "briefing_tweak_start", "targetname" );
|
||
level.player teleport_ent( player_houseapproach_start );
|
||
|
||
ghost_init();
|
||
|
||
node = getnode( "ghost_earlydefense_start", "targetname" );
|
||
level.ghost forceTeleport( node.origin, node.angles );
|
||
|
||
redshirtStartSpawnTeleport( "housebriefing" );
|
||
|
||
houseAttackTrig = getent( "house_approach_friendlytrigger", "targetname" );
|
||
houseAttackTrig notify ( "trigger" );
|
||
|
||
flag_set( "scarecrow_to_earlydefense_start" );
|
||
flag_set( "ozone_to_earlydefense_start" );
|
||
|
||
flag_set( "all_enemies_killed_up_to_house_capture" );
|
||
|
||
wait 1;
|
||
|
||
level.scarecrow stop_magic_bullet_shield();
|
||
level.ozone stop_magic_bullet_shield();
|
||
}
|
||
|
||
startAltEnding()
|
||
{
|
||
fence = getent( "final_area_fence", "targetname" );
|
||
fence delete();
|
||
|
||
flag_set( "test_whole_ending" );
|
||
flag_set( "test_ending" );
|
||
flag_set( "play_ending_sequence" );
|
||
//flag_set( "test_with_pavelow_already_in_place" );
|
||
flag_set( "point_of_no_return" );
|
||
thread end_of_level();
|
||
thread ghost_init();
|
||
thread ending_pavelow_fakearrival();
|
||
|
||
level.player EnableDeathShield( true );
|
||
level.cover_warnings_disabled = 1;
|
||
|
||
wait 5;
|
||
flag_set( "finish_line" );
|
||
flag_set( "test_alt_ending" );
|
||
ending_moments();
|
||
}
|
||
|
||
startEnding()
|
||
{
|
||
fence = getent( "final_area_fence", "targetname" );
|
||
fence delete();
|
||
|
||
flag_set( "test_whole_ending" );
|
||
flag_set( "test_ending" );
|
||
flag_set( "play_ending_sequence" );
|
||
//flag_set( "test_with_pavelow_already_in_place" );
|
||
flag_set( "point_of_no_return" );
|
||
thread end_of_level();
|
||
thread ghost_init();
|
||
thread ending_pavelow_fakearrival();
|
||
|
||
level.player EnableDeathShield( true );
|
||
level.cover_warnings_disabled = 1;
|
||
|
||
wait 5;
|
||
flag_set( "finish_line" );
|
||
thread estate_music();
|
||
ending_moments();
|
||
}
|
||
|
||
startEndingBodyTossOnly()
|
||
{
|
||
flag_set( "play_ending_sequence" );
|
||
flag_set( "test_ending_body_toss" );
|
||
|
||
level.player EnableDeathShield( true );
|
||
level.cover_warnings_disabled = 1;
|
||
|
||
ending_moments();
|
||
}
|
||
|
||
startEndingMeh()
|
||
{
|
||
fence = getent( "final_area_fence", "targetname" );
|
||
fence delete();
|
||
|
||
flag_set( "test_whole_ending" );
|
||
flag_set( "test_ending" );
|
||
flag_set( "play_ending_sequence" );
|
||
flag_set( "test_with_pavelow_already_in_place" );
|
||
flag_set( "no_slow_mo" );
|
||
|
||
level.player EnableDeathShield( true );
|
||
level.cover_warnings_disabled = 1;
|
||
|
||
thread ghost_init();
|
||
ending_moments();
|
||
}
|
||
|
||
startDiskdrive()
|
||
{
|
||
flag_set( "download_started" );
|
||
flag_set( "download_test" );
|
||
thread download_progress();
|
||
thread download_fake_timer();
|
||
}
|
||
|
||
|
||
startHeliTweak()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
|
||
//heliName = "house_defense_heli_frontyard";
|
||
heliName = "md500_rush_3";
|
||
|
||
heli_tweak( heliName );
|
||
}
|
||
|
||
startHeliTweak2()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
|
||
/*
|
||
heliName = "md500_rush_2";
|
||
thread heli_tweak( heliName );
|
||
|
||
wait 4;
|
||
|
||
heliName = "md500_rush_1";
|
||
thread heli_tweak( heliName );
|
||
|
||
wait 2;
|
||
|
||
heliName = "md500_rush_3";
|
||
thread heli_tweak( heliName );
|
||
*/
|
||
|
||
heliName = "boathouse_mi17";
|
||
thread heli_tweak( heliName );
|
||
|
||
heliName = "boathouse_md500";
|
||
thread heli_tweak( heliName );
|
||
}
|
||
|
||
startHeliTweakPavelowEnd()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
flag_set( "point_of_no_return" );
|
||
|
||
node = getstruct( "ending_chopper_node", "targetname" );
|
||
level.player teleport_player( node );
|
||
|
||
thread ending_pavelow_fakearrival();
|
||
}
|
||
|
||
startHeliTweakShadowBirdsEnd()
|
||
{
|
||
flag_set( "skip_intro" );
|
||
flag_set( "enter_the_littlebirds" );
|
||
|
||
node = getstruct( "ending_chopper_node", "targetname" );
|
||
level.player teleport_player( node );
|
||
|
||
thread ending_shadowops_heli_sequence();
|
||
}
|
||
|
||
startFakeRPGTweak()
|
||
{
|
||
|
||
wait 5;
|
||
|
||
ambush_fake_rpg_barrage();
|
||
}
|
||
|
||
//*************** MISSION BEGINS *******************//
|
||
|
||
intro()
|
||
{
|
||
wait 2;
|
||
maps\_introscreen::estate_intro2();
|
||
|
||
flag_set( "slam_zoom_done" );
|
||
|
||
level.player setStance( "crouch" );
|
||
//level.player setPlayerAngles ( (16, 326, 0) );
|
||
|
||
wait 1.8;
|
||
|
||
flag_set( "start_ghost_intro_nav" );
|
||
|
||
wait 5;
|
||
|
||
flag_set( "print_first_objective" );
|
||
}
|
||
|
||
intro_dialogue()
|
||
{
|
||
flag_wait( "slam_zoom_done" );
|
||
|
||
//"Snipers in position."
|
||
radio_dialogue( "est_snp1_inposition" );
|
||
|
||
//"Strike team, go. Engage Makarov on sight."
|
||
level.ghost dialogue_queue( "est_gst_engageonsight" );
|
||
|
||
//"Roger that."
|
||
radio_dialogue( "est_sld1_rogerthat" );
|
||
|
||
//"Copy."
|
||
radio_dialogue( "est_sld2_solidcopy" );
|
||
|
||
//"Let's go, let's go!"
|
||
level.ghost dialogue_queue( "est_gst_letsgoletsgo" );
|
||
}
|
||
|
||
objectives()
|
||
{
|
||
flag_wait( "print_first_objective" );
|
||
|
||
objective_location_makarov = getent( "objective_location_makarov", "targetname" );
|
||
objective_add( 1, "current", &"ESTATE_OBJ_ASSASSINATE", objective_location_makarov.origin );
|
||
|
||
//flag_wait( "futilejeeps_destroyed" );
|
||
flag_wait( "deploy_house_defense_jeeps" );
|
||
|
||
objective_add( 2, "current", &"ESTATE_OBJ_BREACH" );
|
||
objective_current( 2 );
|
||
|
||
exteriorBreaches = getentarray( "breach_objective_exterior", "targetname" );
|
||
// grab the script_slow_breach index off the nearest breach and put it on the entity
|
||
assign_script_breachgroup_to_ents( exteriorBreaches );
|
||
|
||
// find out which breaches should be added to the objective positions
|
||
breach_indices = get_breach_indices_from_ents( exteriorBreaches );
|
||
|
||
// add positions for these breaches
|
||
objective_breach( 2, breach_indices[ 0 ], breach_indices[ 1 ], breach_indices[ 2 ], breach_indices[ 3 ] );
|
||
|
||
thread objective_exterior_breach_check( "0" );
|
||
thread objective_exterior_breach_check( "1" );
|
||
thread objective_exterior_breach_check( "2" );
|
||
|
||
flag_wait( "house_exterior_has_been_breached" );
|
||
|
||
// wait a moment with no breach obj's active because you see them pop at start of breach
|
||
objective_clearAdditionalPositions( 2 );
|
||
wait( 1 );
|
||
|
||
interiorBreaches = getentarray( "breach_objective_interior", "targetname" );
|
||
assign_script_breachgroup_to_ents( interiorBreaches );
|
||
|
||
level.interiorBreachesCompleted = 0;
|
||
level.interiorBreachesRequired = interiorBreaches.size;
|
||
|
||
foreach ( breach in interiorBreaches )
|
||
{
|
||
breach thread objective_interior_breach_update( breach.script_slowmo_breach );
|
||
}
|
||
|
||
// find out which breaches to add
|
||
breach_indices = get_breach_indices_from_ents( interiorBreaches );
|
||
|
||
// add positions for these breaches
|
||
maps\_slowmo_breach::objective_breach( 2, breach_indices[ 0 ], breach_indices[ 1 ], breach_indices[ 2 ], breach_indices[ 3 ] );
|
||
|
||
thread objective_interior_breach_check( "3" );
|
||
thread objective_interior_breach_check( "4" );
|
||
thread objective_interior_breach_check( "5" );
|
||
|
||
thread objective_breach_save();
|
||
|
||
flag_wait( "house_interior_breaches_done" );
|
||
|
||
flag_wait( "all_enemies_killed_up_to_house_capture" );
|
||
|
||
//wait 2;
|
||
|
||
flag_wait( "ghost_gives_regroup_order" );
|
||
|
||
objective_state( 2, "done" );
|
||
|
||
objective_delete( 1 );
|
||
|
||
node = getstruct( "ghost_talknode", "targetname" );
|
||
objective_add( 1, "current", &"ESTATE_OBJ_REGROUP", node.origin );
|
||
|
||
//flag_wait( "dsm_ready_to_use" );
|
||
flag_wait( "house_briefing_is_over" );
|
||
|
||
objective_state( 1, "done" );
|
||
|
||
dsm_real = getent( "dsm", "targetname" );
|
||
objective_add( 3, "current", &"ESTATE_OBJ_INTEL", dsm_real.origin );
|
||
|
||
flag_wait( "download_started" );
|
||
|
||
objective_state( 3, "done" );
|
||
|
||
objective_add( 4, "current", &"ESTATE_OBJ_DOWNLOAD", dsm_real.origin );
|
||
|
||
Objective_SetPointerTextOverride( 4, &"ESTATE_OBJ_POINTER_PROTECT" );
|
||
|
||
//iprintlnbold( "End of Currently Scripted Level" );
|
||
|
||
flag_wait( "download_complete" );
|
||
|
||
objective_state( 4, "done" );
|
||
|
||
objective_add( 5, "current", &"ESTATE_OBJ_RETRIEVE", dsm_real.origin );
|
||
|
||
Objective_SetPointerTextOverride( 5, &"ESTATE_OBJ_POINTER_RETRIEVE" );
|
||
|
||
flag_wait( "dsm_recovered" );
|
||
|
||
marker = getstruct( "ending_chopper_node", "targetname" );
|
||
|
||
objective_state( 5, "done" );
|
||
|
||
objective_add( 6, "current", &"ESTATE_OBJ_LZ", marker.origin );
|
||
|
||
flag_wait( "made_it_to_lz" );
|
||
|
||
objective_state( 6, "done" );
|
||
}
|
||
|
||
objective_exterior_breach_check( breachnum )
|
||
{
|
||
level waittill ( "breaching_number_" + breachnum );
|
||
|
||
flag_set( "house_exterior_has_been_breached" );
|
||
}
|
||
|
||
objective_interior_breach_check( breachnum )
|
||
{
|
||
level waittill ( "breaching_number_" + breachnum );
|
||
|
||
level.interiorBreachesCompleted++;
|
||
|
||
if( level.interiorBreachesCompleted >= level.interiorBreachesRequired )
|
||
{
|
||
flag_set( "house_interior_breaches_done" );
|
||
}
|
||
}
|
||
|
||
objective_breach_save()
|
||
{
|
||
level waittill( "slomo_breach_over" );
|
||
|
||
wait 3;
|
||
|
||
autosave_by_name( "breach_completed" );
|
||
}
|
||
|
||
objective_interior_breach_update( breachnum )
|
||
{
|
||
level waittill ( "breaching_number_" + breachnum );
|
||
|
||
// remove this breach so it doesn't get readded
|
||
self delete();
|
||
|
||
|
||
// now get all the existing breaches and recreate them
|
||
interiorBreaches = getentarray( "breach_objective_interior", "targetname" );
|
||
assign_script_breachgroup_to_ents( interiorBreaches );
|
||
|
||
// clear the old positions
|
||
objective_clearAdditionalPositions( 2 );
|
||
|
||
// find out which breaches still exist
|
||
breach_indices = get_breach_indices_from_ents( interiorBreaches );
|
||
|
||
// add positions for these breaches
|
||
maps\_slowmo_breach::objective_breach( 2, breach_indices[ 0 ], breach_indices[ 1 ], breach_indices[ 2 ], breach_indices[ 3 ] );
|
||
}
|
||
|
||
estate_ambush()
|
||
{
|
||
if( flag( "ambush_complete" ) )
|
||
{
|
||
thread bouncing_betty_throwplayer( level.player.origin );
|
||
}
|
||
|
||
if( !flag( "ambush_complete" ) )
|
||
{
|
||
flag_wait( "bouncing_betty_activated" );
|
||
|
||
battlechatter_off( "allies" );
|
||
battlechatter_off( "axis" );
|
||
|
||
thread bouncing_betty_slow_mo();
|
||
|
||
thread autosave_by_name( "bouncing_betty_sequence" );
|
||
|
||
flag_wait( "bouncing_betty_done" );
|
||
|
||
flag_set( "smoke_screen_activated" );
|
||
|
||
flag_wait( "slow_motion_ambush_done" );
|
||
|
||
wait 1;
|
||
}
|
||
|
||
battlechatter_on( "allies" );
|
||
battlechatter_on( "axis" );
|
||
}
|
||
|
||
forest_ambush_mortars()
|
||
{
|
||
flag_wait( "deploy_mortar_attack" );
|
||
|
||
wait 1;
|
||
|
||
//trig = getent( "mortar_on", "targetname" );
|
||
//trig notify ( "trigger" );
|
||
|
||
thread maps\_mortar::bog_style_mortar_on( "1" );
|
||
|
||
wait 2;
|
||
|
||
thread forest_friendly_initial_advance();
|
||
|
||
// They've got this area presighted for mortar fire!!!
|
||
level.scarecrow dialogue_queue( "est_scr_presighted" );
|
||
|
||
wait 3;
|
||
|
||
// COUNTERATTACK INTO THE SMOKE! Push push push!!! Roach
|
||
level.ghost dialogue_queue( "est_gst_counterattack" );
|
||
|
||
wait 3;
|
||
|
||
level.fixednodesaferadius_default = 256;
|
||
|
||
if( !flag( "player_is_out_of_ambush_zone" ) )
|
||
{
|
||
// Roach! You're gonna get hit by a mortar! Lose 'em in the smoke!! Go go gooo!!!!
|
||
level.ghost dialogue_queue( "est_gst_loseeminsmoke" );
|
||
}
|
||
|
||
wait 5;
|
||
|
||
thread forest_mortar_playerkill();
|
||
}
|
||
|
||
forest_friendly_initial_advance()
|
||
{
|
||
//Send the bulletproof friendlies forward into the smoke to lead the player
|
||
|
||
trig = getent( "forest_friendly_colortrig", "targetname" );
|
||
trig notify ( "trigger" );
|
||
|
||
friendlies = getaiarray( "allies" );
|
||
foreach( friendly in friendlies )
|
||
{
|
||
friendly thread disable_cqbwalk();
|
||
}
|
||
}
|
||
|
||
forest_escape_autosave()
|
||
{
|
||
flag_wait( "player_is_out_of_ambush_zone" );
|
||
|
||
autosave_by_name( "into_the_forest" );
|
||
}
|
||
|
||
forest_mortar_playerkill()
|
||
{
|
||
//Kill the player after sufficient warning is given that it is unsafe to stay in the ambush area
|
||
|
||
wait 3;
|
||
|
||
//Check if autosave happened recently
|
||
|
||
if( isdefined( level.curAutoSave ) && level.curAutoSave >= 3 )
|
||
{
|
||
//give enough time to get back to safety if autosave happened and player ran back into danger zone
|
||
|
||
wait 5;
|
||
}
|
||
|
||
if( !flag( "player_is_out_of_ambush_zone" ) )
|
||
{
|
||
flag_clear( "can_save" );
|
||
|
||
thread mortar_in_face_killplayer();
|
||
}
|
||
}
|
||
|
||
forest_ambush_rpg_guys()
|
||
{
|
||
array_spawn_function_targetname( "forest_defender_rpg_ambush", ::forest_ambush_rpg_guys_init );
|
||
|
||
flag_wait( "deploy_rpg_ambush" );
|
||
|
||
trig = getent( "forest_defender_rpg_ambush_activator", "targetname" );
|
||
trig notify ( "trigger" );
|
||
}
|
||
|
||
forest_ambush_rpg_guys_init()
|
||
{
|
||
self endon ( "death" );
|
||
|
||
flag_wait_any( "approaching_house", "stop_smokescreens" );
|
||
|
||
wait randomfloatrange( 2, 4.25 );
|
||
|
||
ent = getent( "futilejeep_javelin_sourcepoint1", "targetname" );
|
||
|
||
ent thread play_sound_on_entity( "weap_cheytac_fire_special" );
|
||
|
||
self kill();
|
||
}
|
||
|
||
forest_attackers()
|
||
{
|
||
flag_wait( "bouncing_betty_done" );
|
||
|
||
if( !flag( "ambush_complete" ) )
|
||
{
|
||
wait 10;
|
||
}
|
||
|
||
trig = getent( "forest_spawn_activator", "targetname" );
|
||
trig notify ( "trigger" );
|
||
}
|
||
|
||
forest_enemy_deathmonitor_init()
|
||
{
|
||
array_spawn_function_targetname( "forest_defender", ::forest_enemy_deathmonitor );
|
||
array_spawn_function_targetname( "forest_defender", ::forest_enemy_groundlevel_magicsnipe_cleanup );
|
||
}
|
||
|
||
forest_ghillie_reveal()
|
||
{
|
||
flag_wait( "spawn_first_ghillies" );
|
||
|
||
thread ghillie_spawn( "early_sniper" );
|
||
}
|
||
|
||
first_smoke_screen()
|
||
{
|
||
//Automatically starts after player is knocked down
|
||
|
||
level endon ( "smokepot1" );
|
||
|
||
flag_wait( "smoke_screen_activated" );
|
||
|
||
smoke_pots = getentarray( "smokepot1", "targetname" );
|
||
|
||
smoke_pots = array_randomize ( smoke_pots );
|
||
|
||
while( 1 )
|
||
{
|
||
foreach ( smoke_pot in smoke_pots )
|
||
{
|
||
wait 5;
|
||
smoke_pot thread smokepot();
|
||
level.activeSmokePots++;
|
||
thread forest_smokepot_timer();
|
||
}
|
||
|
||
wait 15;
|
||
}
|
||
}
|
||
|
||
forest_smoke_fight()
|
||
{
|
||
flag_wait( "smokepot1" );
|
||
|
||
//deploy the shotgun guys, slow crouch move
|
||
|
||
thread prowler_spawn();
|
||
}
|
||
|
||
forest_smoke_screens()
|
||
{
|
||
flag_wait( "smoke_screen_activated" );
|
||
|
||
thread forest_smokepot1();
|
||
thread forest_smokepot2();
|
||
thread forest_smokepot3();
|
||
}
|
||
|
||
/*
|
||
house_defense_heli_frontyard()
|
||
{
|
||
flag_wait( "forestfight_littlebird_1" );
|
||
//flag_wait( "start_early_helicopter" );
|
||
|
||
heli = spawn_vehicle_from_targetname_and_drive( "house_defense_heli_frontyard" );
|
||
|
||
wait 5;
|
||
}
|
||
*/
|
||
|
||
heli_tweak( heliName )
|
||
{
|
||
//for tweaking an individual heli path to make it look right, not part of the actual level
|
||
|
||
player_heli_tweak_observe = getent( "heli_tweak", "targetname" );
|
||
level.player teleport_ent( player_heli_tweak_observe );
|
||
|
||
heli = spawn_vehicle_from_targetname_and_drive( heliName );
|
||
}
|
||
|
||
house_approach_autosave()
|
||
{
|
||
flag_wait( "approaching_house" );
|
||
|
||
thread autosave_by_name( "approaching_house" );
|
||
}
|
||
|
||
house_arrival_autosave()
|
||
{
|
||
flag_wait( "autosave_housearrival" );
|
||
|
||
thread autosave_by_name( "arrival_house" );
|
||
}
|
||
|
||
house_arrival_aisettings()
|
||
{
|
||
level waittill_any ( "breaching_number_0", "breaching_number_1", "breaching_number_2" );
|
||
|
||
battlechatter_off( "allies" );
|
||
battlechatter_off( "axis" );
|
||
|
||
level.ghost.baseAccuracy = 1000000;
|
||
level.ozone.baseAccuracy = 1000000;
|
||
level.scarecrow.baseAccuracy = 1000000;
|
||
}
|
||
|
||
house_approach_jeepassault()
|
||
{
|
||
flag_wait( "deploy_house_defense_jeeps" );
|
||
|
||
jeep1 = spawn_vehicle_from_targetname_and_drive( "house_defense_jeep1_frontyard" );
|
||
jeep2 = spawn_vehicle_from_targetname_and_drive( "house_defense_jeep2_frontyard" );
|
||
}
|
||
|
||
house_approach_dialogue()
|
||
{
|
||
flag_wait( "house_approach_dialogue" );
|
||
|
||
//Clear the perimeter!
|
||
level.ghost dialogue_queue( "est_gst_clearperimieter" );
|
||
|
||
battlechatter_off( "allies" );
|
||
|
||
flag_wait( "house_perimeter_softened" );
|
||
|
||
//level.scarecrow.goalradius = 16;
|
||
//level.ozone.goalradius = 16;
|
||
|
||
//Breach and clear the safehouse! Go! Go!
|
||
level.ghost dialogue_queue( "est_gst_breachnclear" );
|
||
|
||
SoundSetTimeScaleFactor( "Announcer", 0 );
|
||
|
||
level.fixednodesaferadius_default = 64;
|
||
|
||
level.ghost.fixednodesaferadius = 64;
|
||
level.scarecrow.fixednodesaferadius = 64;
|
||
level.ozone.fixednodesaferadius = 64;
|
||
|
||
/*
|
||
level.scarecrow disable_ai_color();
|
||
node1 = getnode( "scarecrow_breachhouse_start", "targetname" );
|
||
level.scarecrow setgoalnode( node1 );
|
||
|
||
level.ozone disable_ai_color();
|
||
node2 = getnode( "ozone_breachhouse_start", "targetname" );
|
||
level.ozone setgoalnode( node2 );
|
||
*/
|
||
}
|
||
|
||
house_approach_futilejeep()
|
||
{
|
||
flag_wait( "deploy_futile_jeep" );
|
||
|
||
battlechatter_off( "allies" );
|
||
battlechatter_off( "axis" );
|
||
|
||
//Two trucks leaving the target building!
|
||
thread radio_dialogue( "est_snp1_trucksleaving" );
|
||
|
||
wait 1;
|
||
|
||
doomedJeep1 = spawn_vehicle_from_targetname_and_drive( "futile_escape_jeep1" );
|
||
doomedJeep1 godon();
|
||
|
||
doomedJeep2 = spawn_vehicle_from_targetname_and_drive( "futile_escape_jeep2" );
|
||
doomedJeep2 godon();
|
||
|
||
wait 3;
|
||
|
||
//Don't let those trucks get away!
|
||
level.ghost thread dialogue_queue( "est_gst_trucksgetaway" );
|
||
|
||
wait 1.5;
|
||
|
||
//Bloody hell, these trucks are bulletproofed!
|
||
//level.ghost thread dialogue_queue( "est_gst_bulletproofed" );
|
||
|
||
wait 2.0;
|
||
|
||
//Roger! Firing Javelin, danger close!
|
||
thread radio_dialogue( "est_snp1_firingjavelin" );
|
||
|
||
//snipers launch a magical javelin to intercept the fleeing jeeps
|
||
|
||
wait 2;
|
||
|
||
doomedJeep1 thread house_approach_futilejeep_javelin( "futilejeep_javelin_sourcepoint1" );
|
||
|
||
//Javelin, danger close!!! Get back from the road!!!
|
||
level.ghost thread dialogue_queue( "est_gst_dangerclose" );
|
||
|
||
wait 1;
|
||
|
||
//Bloody hell, these trucks are bulletproofed!
|
||
level.ghost thread dialogue_queue( "est_gst_bulletproofed" );
|
||
|
||
wait 2;
|
||
|
||
doomedJeep1 godoff();
|
||
|
||
wait 1;
|
||
|
||
//Two away!
|
||
thread radio_dialogue( "est_snp1_twoaway" );
|
||
|
||
doomedJeep2 thread house_approach_futilejeep_javelin( "futilejeep_javelin_sourcepoint2" );
|
||
|
||
wait 3;
|
||
|
||
doomedJeep2 godoff();
|
||
|
||
wait 2.75;
|
||
|
||
//Moving vehicles have been neutralized.
|
||
thread radio_dialogue( "est_snp1_neutralized" );
|
||
|
||
wait 2;
|
||
|
||
flag_set( "futilejeeps_destroyed" );
|
||
}
|
||
|
||
house_approach_futilejeep_javelin( launchEntName )
|
||
{
|
||
fakeJavLauncher = getent( launchEntName, "targetname" );
|
||
|
||
newMissile = MagicBullet( "javelin", fakeJavLauncher.origin, self.origin );
|
||
newMissile thread javelin_earthquake( self ); //quake on impact
|
||
newMissile Missile_SetTargetEnt( self );
|
||
newMissile Missile_SetFlightmodeTop(); //top down kill mode for javelin
|
||
}
|
||
|
||
javelin_earthquake( targetObj )
|
||
{
|
||
dummy = spawn( "script_origin", self.origin );
|
||
dummy linkto( self );
|
||
self waittill( "death" );
|
||
earthquake( 1.2, 1.5, dummy.origin, 1600 );
|
||
radiusdamage( targetObj.origin, 128, 25000, 25000 );
|
||
wait( 0.05 );
|
||
dummy delete();
|
||
}
|
||
|
||
house_friendly_rush()
|
||
{
|
||
flag_wait( "futilejeeps_destroyed" );
|
||
|
||
//Be advised, we have not, I repeat, we have not spotted Makarov, and no one else has left the house. Those trucks may have been decoys.
|
||
thread radio_dialogue( "est_snp1_decoys" );
|
||
|
||
wait 6;
|
||
|
||
if( !flag( "house_perimeter_softened" ) )
|
||
{
|
||
level.fixednodesaferadius_default = 1040;
|
||
}
|
||
|
||
houseAttackTrig = getent( "house_approach_friendlytrigger", "targetname" );
|
||
houseAttackTrig notify ( "trigger" );
|
||
|
||
wait 1;
|
||
|
||
flag_set( "deploy_house_defense_jeeps" );
|
||
|
||
wait 2.15;
|
||
|
||
//Roger that, we're advancing on the house now!
|
||
level.ghost dialogue_queue( "est_gst_advancingonhouse" );
|
||
|
||
battlechatter_on( "allies" );
|
||
battlechatter_on( "axis" );
|
||
|
||
/*
|
||
level.breachfriendlies = [];
|
||
level.breachfriendlies[ 0 ] = level.ghost;
|
||
level.breachfriendlies[ 1 ] = level.ozone;
|
||
level.breachfriendlies[ 2 ] = level.scarecrow;
|
||
*/
|
||
}
|
||
|
||
house_enemy_cleanup_tracker()
|
||
{
|
||
flag_wait( "house_interior_breaches_done" );
|
||
|
||
wait 2.5;
|
||
|
||
enemies = [];
|
||
enemies = getaiarray( "axis" );
|
||
|
||
level.enemyPop = enemies.size;
|
||
|
||
volume = getent( "enemy_presence_volume", "targetname" );
|
||
|
||
if( level.enemyPop )
|
||
{
|
||
foreach( enemy in enemies )
|
||
{
|
||
enemy thread house_enemy_deathmonitor();
|
||
|
||
if( enemy isTouching( volume ) )
|
||
{
|
||
enemy.goalradius = 128;
|
||
enemy thread house_enemy_cleanup_nav();
|
||
}
|
||
else
|
||
{
|
||
enemy kill();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
flag_set( "all_enemies_killed_up_to_house_capture" );
|
||
}
|
||
}
|
||
|
||
house_enemy_cleanup_nav()
|
||
{
|
||
self endon ( "death" );
|
||
wait randomfloatrange( 7, 10 );
|
||
self setgoalentity( level.player );
|
||
}
|
||
|
||
house_enemy_deathmonitor()
|
||
{
|
||
self waittill ( "death" );
|
||
|
||
level.enemyPop--;
|
||
|
||
if( !level.enemyPop )
|
||
{
|
||
flag_set( "all_enemies_killed_up_to_house_capture" );
|
||
}
|
||
}
|
||
|
||
house_clearing_save_mainfloor()
|
||
{
|
||
flag_wait( "save_the_game_indoors" );
|
||
//autosave_by_name( "inside_the_house" );
|
||
}
|
||
|
||
house_clearing_save_basement()
|
||
{
|
||
flag_wait( "save_the_game_downstairs" );
|
||
//autosave_by_name( "inside_the_house" );
|
||
}
|
||
|
||
house_backwards_door_handling()
|
||
{
|
||
fakedoor = getent( "fake_backwards_door", "targetname" );
|
||
fakedoor_clip = getent( "fake_backwards_door_clip", "targetname" );
|
||
|
||
if( !flag( "skip_breachandclear" ) )
|
||
{
|
||
level waittill_any ( "breaching_number_0", "breaching_number_1", "breaching_number_2" );
|
||
}
|
||
|
||
wait 2;
|
||
|
||
fakedoor delete();
|
||
fakedoor_clip delete();
|
||
}
|
||
|
||
house_briefing_scarecrow()
|
||
{
|
||
//*TEMP* Scarecrow needs photographer mocap for this conversation with Shepherd and Price
|
||
|
||
level.scarecrow endon ( "death" );
|
||
|
||
level.scarecrow.voice = "taskforce";
|
||
level.scarecrow.countryID = "TF";
|
||
|
||
level.scarecrow disable_ai_color();
|
||
level.scarecrow disable_cqbwalk();
|
||
level.scarecrow.goalradius = 16;
|
||
|
||
if( !flag( "skip_house_defense_dialogue" ) )
|
||
{
|
||
animStartPoint = getstruct( "scarecrow_photonode", "targetname" );
|
||
animStartPoint anim_generic_reach( level.scarecrow, "estate_house_photoshoot" );
|
||
animStartPoint thread anim_generic_run( level.scarecrow, "estate_house_photoshoot" );
|
||
|
||
//level.scarecrow waittillmatch( "single anim", "ps_scn_estate_photographer" );
|
||
//level.scarecrow thread play_sound_on_entity( "scn_estate_photographer" );
|
||
|
||
level.scarecrow waittillmatch( "single anim", "camera" );
|
||
|
||
camera = spawn( "script_model", (0, 0, 0) );
|
||
camera setmodel( "electronics_camera_pointandshoot_animated" );
|
||
camera linkto( level.scarecrow, "tag_inhand", (0, 0, 0), (0, 0, 0) );
|
||
|
||
delaythread( 10, ::flag_set, "photographs_done" );
|
||
|
||
/*
|
||
|
||
photosnap_notetracks = 15;
|
||
|
||
while( photosnap_notetracks > 0 )
|
||
{
|
||
level.scarecrow waittillmatch( "single anim", "ps_scn_estate_photo_snap" );
|
||
level.scarecrow thread play_sound_on_entity( "scn_estate_photo_snap" );
|
||
photosnap_notetracks--;
|
||
}
|
||
*/
|
||
|
||
level.scarecrow waittillmatch( "single anim", "camera" );
|
||
|
||
camera delete();
|
||
}
|
||
|
||
node = getnode( "scarecrow_earlydefense_start", "targetname" );
|
||
level.scarecrow setgoalnode( node );
|
||
|
||
level.scarecrow waittill ( "goal" );
|
||
|
||
flag_wait( "scarecrow_to_earlydefense_start" );
|
||
|
||
//I'm in position!
|
||
radio_dialogue( "est_scr_inposition" );
|
||
|
||
level.scarecrow stop_magic_bullet_shield();
|
||
|
||
switch( level.gameskill )
|
||
{
|
||
case 0:
|
||
level.scarecrow.health = 800;
|
||
break;
|
||
case 1:
|
||
level.scarecrow.health = 600;
|
||
break;
|
||
case 2:
|
||
level.scarecrow.health = 300;
|
||
break;
|
||
case 3:
|
||
level.scarecrow.health = 300;
|
||
break;
|
||
}
|
||
|
||
level.scarecrow thread tough_friendly_biometrics( "scarecrow" );
|
||
level.scarecrow thread tough_friendly_kill();
|
||
|
||
flag_wait( "dsm_compromised" );
|
||
|
||
level.scarecrow.health = 1;
|
||
}
|
||
|
||
house_briefing_ozone()
|
||
{
|
||
level.ozone endon ( "death" );
|
||
|
||
level.ozone.voice = "taskforce";
|
||
level.ozone.countryID = "TF";
|
||
|
||
level.ozone disable_ai_color();
|
||
level.ozone disable_cqbwalk();
|
||
level.ozone.goalradius = 16;
|
||
|
||
node = getnode( "ozone_housebriefing_start", "targetname" );
|
||
level.ozone setgoalnode( node );
|
||
|
||
level.ozone waittill ( "goal" );
|
||
|
||
flag_wait( "ozone_to_earlydefense_start" );
|
||
|
||
node = getnode( "ozone_earlydefense_start", "targetname" );
|
||
level.ozone setgoalnode( node );
|
||
|
||
level.ozone waittill ( "goal" );
|
||
|
||
flag_wait( "defense_battle_begins" );
|
||
|
||
//Ready to engage!
|
||
radio_dialogue( "est_ozn_readyengage" );
|
||
|
||
level.ozone stop_magic_bullet_shield();
|
||
|
||
switch( level.gameskill )
|
||
{
|
||
case 0:
|
||
level.ozone.health = 800;
|
||
break;
|
||
case 1:
|
||
level.ozone.health = 600;
|
||
break;
|
||
case 2:
|
||
level.ozone.health = 300;
|
||
break;
|
||
case 3:
|
||
level.ozone.health = 300;
|
||
break;
|
||
}
|
||
|
||
level.ozone thread tough_friendly_biometrics( "ozone" );
|
||
level.ozone thread tough_friendly_kill();
|
||
|
||
flag_wait( "dsm_compromised" );
|
||
|
||
level.ozone.health = 1;
|
||
}
|
||
|
||
house_briefing_ghosttalk()
|
||
{
|
||
animStartPoint = getstruct( "ghost_talknode", "targetname" );
|
||
animStartPoint anim_generic_reach( level.ghost, "estate_ghost_radio" );
|
||
animStartPoint thread anim_generic_run( level.ghost, "estate_ghost_radio" );
|
||
}
|
||
|
||
house_briefing_dialogue()
|
||
{
|
||
flag_wait( "all_enemies_killed_up_to_house_capture" );
|
||
|
||
battlechatter_off( "allies" );
|
||
battlechatter_off( "axis" );
|
||
|
||
wait 5;
|
||
|
||
thread autosave_by_name( "house_briefing_sequence" );
|
||
|
||
//*TEMP* Ghost needs mocap for this conversation with Shepherd and Price
|
||
|
||
level.ghost.voice = "taskforce";
|
||
level.ghost.countryID = "TF";
|
||
|
||
thread house_briefing_scarecrow();
|
||
thread house_briefing_ozone();
|
||
|
||
level.ghost disable_ai_color();
|
||
thread house_briefing_ghosttalk();
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
flag_set( "ghost_gives_regroup_order" );
|
||
|
||
//All clear. Squad, regroup on me.
|
||
thread radio_dialogue( "est_gst_regroup" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Scarecrow, photographs.
|
||
level.ghost thread dialogue_queue( "est_gst_photos" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Roger that.
|
||
thread radio_dialogue( "est_scr_rogerthat" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Shepherd, this is Ghost. No sign of Makarov, I repeat, no sign of Makarov. Captain Price, any luck in Afghanistan?
|
||
level.ghost thread dialogue_queue( "est_gst_nosign" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Price: Negative. Soap and I are in position at the boneyard. No sign of Makarov. So much for the intel.
|
||
//thread radio_dialogue( "est_pri_somuchforintel" );
|
||
|
||
//Price: Plenty...at least fifty hired guns here, but no sign of Makarov. Perhaps our intel was off.
|
||
thread radio_dialogue( "est_pri_atleast50" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Well, the quality of the intel's about to change. This safehouse's a bloody gold mine.
|
||
level.ghost thread dialogue_queue( "est_gst_goldmine" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
// Shepherd: Copy that. Ghost, have your team collect everything you can for an operations playbook. Names, contacts, places, everything.
|
||
thread radio_dialogue( "est_shp_everything" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//We're already on it sir. Makarov will have nowhere to run.
|
||
level.ghost thread dialogue_queue( "est_gst_alreadyonit" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Shepherd: That's the idea. I'm bringing up the extraction force, E.T.A. five minutes. Get that intel. Shepherd out.
|
||
thread radio_dialogue( "est_shp_eta5mins" );
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Roach, get to Makarov's computer and start the transfer.
|
||
level.ghost thread dialogue_queue( "est_gst_starttransfer" );
|
||
|
||
flag_set( "house_briefing_is_over" );
|
||
flag_set( "dsm_ready_to_use" ); //enables the use trigger
|
||
|
||
level.ghost waittillmatch( "single anim", "dialogue" );
|
||
|
||
//Ozone, you're on rear security. I've got the front. Go.
|
||
level.ghost dialogue_queue( "est_gst_rearsecurity" );
|
||
|
||
flag_set( "ozone_to_earlydefense_start" );
|
||
|
||
//node = getnode( "ghost_earlydefense_start", "targetname" );
|
||
node = getnode( "ghost_cover_front", "targetname" );
|
||
level.ghost setgoalnode( node );
|
||
level.ghost clear_run_anim();
|
||
|
||
//On my way.
|
||
radio_dialogue( "est_ozn_onmyway" );
|
||
|
||
wait 2;
|
||
|
||
//Price: Task Force, this is Price. More of Makarov's men just arrived at the boneyard. They're searching for something<6E>
|
||
radio_dialogue( "est_pri_searching" );
|
||
|
||
//Price: Wait...they're getting closer to us<75>
|
||
radio_dialogue( "est_pri_gettingcloser" );
|
||
|
||
//Price: We're going silent for a few minutes. Good luck up there in Russia. Price out.
|
||
radio_dialogue( "est_pri_goingsilent" );
|
||
|
||
flag_set( "house_briefing_dialogue_done" );
|
||
|
||
thread defense_download_nag();
|
||
|
||
wait 10;
|
||
|
||
node = getnode( "ghost_earlydefense_start", "targetname" );
|
||
level.ghost setgoalnode( node );
|
||
}
|
||
|
||
defense_intro()
|
||
{
|
||
flag_wait( "download_started" );
|
||
|
||
//*TEMP dialogue hint to the player to get weapons from the basement if desired
|
||
|
||
if( !flag( "skip_house_defense_dialogue" ) )
|
||
{
|
||
wait 3;
|
||
|
||
flag_wait( "house_briefing_dialogue_done" );
|
||
|
||
//Roach, there's an armory in the basement. Better stock up while you can.
|
||
radio_dialogue( "est_ozn_stockup" );
|
||
|
||
flag_wait( "photographs_done" );
|
||
|
||
//Makarov's men are going to do whatever it takes to keep us from leaving with this intel. We need to protect the DSM until the transfer's done.
|
||
radio_dialogue( "est_gst_withintel" );
|
||
|
||
//We got 60 seconds tops, over.
|
||
//radio_dialogue( "est_snp1_60seconds" );
|
||
|
||
//Use the weapons caches and set up your claymores if you've got any left. Defensive positions, let's go!
|
||
radio_dialogue( "est_gst_weaponscache" );
|
||
|
||
flag_set( "scarecrow_to_earlydefense_start" );
|
||
}
|
||
|
||
flag_set( "defense_battle_begins" );
|
||
|
||
autosave_by_name( "defense_started" );
|
||
|
||
wait 1; //for the house_defense startpoint to not break
|
||
|
||
level.ghost.baseAccuracy = 1;
|
||
level.ozone.baseAccuracy = 1;
|
||
level.scarecrow.baseAccuracy = 1;
|
||
|
||
level.ghost.threatbias = -1000;
|
||
|
||
level.ghost.voice = "taskforce";
|
||
level.ghost.countryID = "TF";
|
||
|
||
level.scarecrow.voice = "taskforce";
|
||
level.scarecrow.countryID = "TF";
|
||
|
||
level.ozone.voice = "taskforce";
|
||
level.ozone.countryID = "TF";
|
||
|
||
battlechatter_on( "allies" );
|
||
battlechatter_on( "axis" );
|
||
}
|
||
|
||
defense_download_nag()
|
||
{
|
||
level endon ( "download_started" );
|
||
|
||
while( !flag( "download_started" ) )
|
||
{
|
||
wait 10;
|
||
|
||
//Roach - connect the DSM to Makarov's computer.
|
||
radio_dialogue( "est_gst_filesoff" );
|
||
|
||
wait 8;
|
||
|
||
//Roach, we're not leaving without those files. Start the transfer.
|
||
radio_dialogue( "est_gst_startdownload" );
|
||
|
||
wait 30;
|
||
}
|
||
}
|
||
|
||
ending_blur_cycler()
|
||
{
|
||
level endon ( "stop_blur_cycler" );
|
||
|
||
while( 1 )
|
||
{
|
||
level.player endingBlurView( 3.6, 2 );
|
||
level.player endingBlurView( 1, 0.8 );
|
||
level.player endingBlurView( 2, 1 );
|
||
level.player endingBlurView( 1, 0.7 );
|
||
level.player endingBlurView( 3, 1.1 );
|
||
}
|
||
}
|
||
|
||
endingBlurView( blur, timer )
|
||
{
|
||
level endon ( "stop_blur_cycler" );
|
||
|
||
self notify( "blurview_stop" );
|
||
self endon( "blurview_stop" );
|
||
self SetBlurForPlayer( blur, timer );
|
||
wait( 0.05 );
|
||
self SetBlurForPlayer( 0, timer );
|
||
}
|
||
|
||
ending_passing_out( overlay )
|
||
{
|
||
level.player setBlurForPlayer( 12, 3 );
|
||
|
||
overlay grayOut( 0.4, 8 );
|
||
overlay restoreVision( 0.4, 2 );
|
||
|
||
overlay grayOut( 0.5, 9 );
|
||
overlay restoreVision( 0.5, 1.8 );
|
||
|
||
overlay grayOut( 0.4, 12 );
|
||
overlay restoreVision( 0.4, 2.2 );
|
||
|
||
overlay grayOut( 0.5, 12 );
|
||
overlay restoreVision( 0.5, 2.2 );
|
||
|
||
//Roach, hang in there!!!
|
||
thread radio_dialogue( "est_gst_hanginthere" );
|
||
}
|
||
|
||
ending_eq_reset()
|
||
{
|
||
wait 3;
|
||
|
||
// recover to the current eq
|
||
if ( level.eq_track[ level.eq_main_track ] == "" )
|
||
{
|
||
maps\_ambient::deactivate_index( level.eq_main_track );
|
||
}
|
||
else
|
||
{
|
||
thread maps\_ambient::use_eq_settings( level.eq_track[ level.eq_main_track ], level.eq_main_track );
|
||
}
|
||
|
||
if ( level.reverb_track == "" )
|
||
{
|
||
maps\_ambient::deactivate_reverb();
|
||
}
|
||
else
|
||
{
|
||
thread maps\_ambient::use_reverb_settings( level.reverb_track );
|
||
}
|
||
}
|
||
|
||
ending_attackers()
|
||
{
|
||
ending_attackers = getentarray( "ending_attacker", "targetname" );
|
||
array_thread( ending_attackers, ::ending_attackers_spawn );
|
||
|
||
//make sure all bad guys have the same settings when the player is locked into the ending sequence
|
||
|
||
wait 1;
|
||
|
||
leftovers = getaiarray( "axis" );
|
||
foreach( guy in leftovers )
|
||
{
|
||
guy.grenadeammo = 0;
|
||
guy.baseaccuracy = 0.2;
|
||
guy add_damage_function( ::ending_attackers_deathmonitor );
|
||
}
|
||
}
|
||
|
||
ending_attackers_deathmonitor( damage, attacker, direction_vec, point, type, modelName, tagName )
|
||
{
|
||
//as soon as the player kills one of the enemy during the dragging sequence, he becomes invulnerable
|
||
//self waittill ( "damage", damage, attacker );
|
||
|
||
if( !isalive( self ) )
|
||
{
|
||
if( attacker == level.player )
|
||
{
|
||
level.ending_attacker_deaths++;
|
||
|
||
if( level.gameskill == 0 )
|
||
{
|
||
level.player.attackeraccuracy = 0;
|
||
flag_set( "drag_sequence_killcount_achieved" );
|
||
}
|
||
|
||
if( level.gameskill == 1 )
|
||
{
|
||
level.player.attackeraccuracy = 0;
|
||
flag_set( "drag_sequence_killcount_achieved" );
|
||
}
|
||
|
||
if( level.gameskill == 2 )
|
||
{
|
||
//on hard and veteran, must kill two ending attackers or you die
|
||
if( level.ending_attacker_deaths > 1 )
|
||
{
|
||
level.player.attackeraccuracy = 0;
|
||
flag_set( "drag_sequence_killcount_achieved" );
|
||
}
|
||
}
|
||
|
||
if( level.gameskill == 3 )
|
||
{
|
||
//on hard and veteran, must kill two ending attackers or you die
|
||
if( level.ending_attacker_deaths > 1 )
|
||
{
|
||
level.player.attackeraccuracy = 0;
|
||
flag_set( "drag_sequence_killcount_achieved" );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
ending_attackers_spawn()
|
||
{
|
||
guy = self stalingradSpawn();
|
||
if( isdefined( guy ) )
|
||
{
|
||
guy endon ( "death" );
|
||
//guy enable_cqbwalk();
|
||
wait 1;
|
||
guy.grenadeammo = 0;
|
||
guy.baseaccuracy = 0.2;
|
||
}
|
||
|
||
/*
|
||
dist = length( guy.origin - level.player.origin );
|
||
|
||
while( dist > 700 )
|
||
{
|
||
dist = length( guy.origin - level.player.origin );
|
||
wait 0.1;
|
||
}
|
||
|
||
if( isalive( level.player ) )
|
||
{
|
||
guy.baseAccuracy = 1000000;
|
||
level.player.threatbias = 1000000;
|
||
}
|
||
*/
|
||
}
|
||
|
||
ending_drag_damagecheck()
|
||
{
|
||
//level endon ( "ending_slacker_death" );
|
||
|
||
level.player.attackeraccuracy = 0;
|
||
|
||
wait 5;
|
||
|
||
level.player.attackeraccuracy = 0.15;
|
||
|
||
wait 3;
|
||
|
||
level.player.attackeraccuracy = 0.2;
|
||
|
||
/*
|
||
while( level.player.health > 5 )
|
||
{
|
||
level.player waittill ( "damage" );
|
||
}
|
||
|
||
level notify ( "ending_normal_death" );
|
||
|
||
thread ending_drag_failure();
|
||
*/
|
||
}
|
||
|
||
ending_drag_slackerfail()
|
||
{
|
||
level endon ( "ending_normal_death" );
|
||
level endon ( "drag_sequence_killcount_achieved" );
|
||
|
||
//wait for thunder one to get to it's first waypoint
|
||
flag_wait( "drag_sequence_slacker_check" );
|
||
|
||
if( !flag( "drag_sequence_killcount_achieved" ) )
|
||
{
|
||
level notify ( "ending_slacker_death" );
|
||
|
||
level.player DoDamage( 25 / level.player.damagemultiplier, level.player.origin );
|
||
wait 1.5;
|
||
|
||
level.player DoDamage( 35 / level.player.damagemultiplier, level.player.origin );
|
||
wait 0.5;
|
||
|
||
level.player DoDamage( 25 / level.player.damagemultiplier, level.player.origin );
|
||
wait 2.5;
|
||
|
||
level.player DoDamage( 30 / level.player.damagemultiplier, level.player.origin );
|
||
wait 0.15;
|
||
level.player DoDamage( 30 / level.player.damagemultiplier, level.player.origin );
|
||
wait 0.25;
|
||
level.player DoDamage( 15 / level.player.damagemultiplier, level.player.origin );
|
||
wait 0.2;
|
||
level.player DoDamage( 15 / level.player.damagemultiplier, level.player.origin );
|
||
|
||
wait 3;
|
||
|
||
level.player DoDamage( 45 / level.player.damagemultiplier, level.player.origin );
|
||
wait 0.15;
|
||
level.player DoDamage( 75 / level.player.damagemultiplier, level.player.origin );
|
||
wait 0.15;
|
||
level.player DoDamage( 85 / level.player.damagemultiplier, level.player.origin );
|
||
|
||
thread ending_drag_failure();
|
||
}
|
||
}
|
||
|
||
ending_drag_failure()
|
||
{
|
||
level.player takeallweapons();
|
||
|
||
level.player.ignoreme = true;
|
||
level.player shellshock( "estate_bouncingbetty", 9 );
|
||
|
||
setdvar( "ui_deadquote", &"ESTATE_FAKE_DEATH_QUOTE" );
|
||
missionfailedwrapper();
|
||
}
|
||
|
||
ending_player_breathing()
|
||
{
|
||
level endon ( "stop_player_breathing" );
|
||
|
||
while( 1 )
|
||
{
|
||
level.player play_sound_on_entity( "breathing_hurt" );
|
||
wait( 0.1 + RandomFloat( 0.8 ) );
|
||
}
|
||
}
|
||
|
||
ending_moments()
|
||
{
|
||
flag_wait( "play_ending_sequence" );
|
||
|
||
thread ending_shadow_fader();
|
||
|
||
//self PlayLocalSound( "breathing_heartbeat" ); //hearbeat stuff
|
||
|
||
//thread maps\_mortar::bog_style_mortar_off( "2" );
|
||
|
||
overlay = undefined;
|
||
|
||
if( flag( "test_ending" ) )
|
||
{
|
||
thread maps\_mortar::bog_style_mortar_on( "2" );
|
||
}
|
||
|
||
if( !flag( "test_ending_body_toss" ) )
|
||
{
|
||
thread ending_thunderone_heli_sequence();
|
||
thread ending_shadowops_heli_sequence();
|
||
|
||
thread battlechatter_off( "allies" );
|
||
thread battlechatter_off( "axis" );
|
||
}
|
||
|
||
//Cut to black
|
||
|
||
overlay = newHudElem();
|
||
overlay.x = 0;
|
||
overlay.y = 0;
|
||
overlay setshader( "black", 640, 480 );
|
||
overlay.alignX = "left";
|
||
overlay.alignY = "top";
|
||
overlay.horzAlign = "fullscreen";
|
||
overlay.vertAlign = "fullscreen";
|
||
overlay.alpha = 0;
|
||
overlay.sort = 1;
|
||
|
||
overlay blackOut( 0.05, 6 );
|
||
|
||
if( !flag( "test_ending_body_toss" ) )
|
||
{
|
||
level.player FreezeControls( true );
|
||
|
||
level.player AllowProne( false );
|
||
level.player AllowCrouch( false );
|
||
level.player AllowStand( true );
|
||
|
||
//level.player painVisionOn();
|
||
thread maps\_ambient::use_eq_settings( "deathsdoor", level.eq_main_track );
|
||
thread maps\_ambient::use_reverb_settings( "deathsdoor" );
|
||
thread ending_blur_cycler();
|
||
|
||
level.player shellshock( "estate_bouncingbetty", 11 );
|
||
|
||
//thread ending_music();
|
||
flag_set( "begin_ending_music" );
|
||
|
||
SetSavedDvar( "hud_showStance", "0" );
|
||
level.player setstance( "stand" ); //otherwise the player position will be wrong when attached to the anim
|
||
|
||
//Start the dragging sequence
|
||
|
||
//node = getstruct( "ending_chopper_node", "targetname" );
|
||
node = getstruct( "ghost_dragnode", "targetname" );
|
||
|
||
playerview = spawn_anim_model( "playerview" );
|
||
playerview.angles = (0, 0, 0 );
|
||
playerview hide();
|
||
|
||
level.player disableweapons();
|
||
|
||
level.player takeallweapons();
|
||
|
||
if( !flag( "test_ending_body_toss" ) )
|
||
level.ghost.attackeraccuracy = 0;
|
||
|
||
level.player.attackeraccuracy = 0;
|
||
level.player.ignorerandombulletdamage = 1;
|
||
|
||
node anim_first_frame_solo( level.ghost, "estate_ending_drag" );
|
||
node anim_first_frame_solo( playerview, "estate_ending_drag" );
|
||
level.player PlayerLinkToDelta( playerview, "tag_player", 1, 30, 30, 30, 3 );
|
||
|
||
node anim_first_frame_solo( level.ghost, "estate_ending_drag" );
|
||
|
||
tag_origin = spawn_tag_origin();
|
||
tag_origin linkto( playerview, "tag_player", (0,0,0), (0,0,0) );
|
||
level.player playersetgroundreferenceent( tag_origin );
|
||
|
||
//Intercept with dialogue and start red smoke here
|
||
|
||
wait 1;
|
||
|
||
thread ending_attackers();
|
||
|
||
level.player giveweapon( "ak47_woodland_grenadier" );
|
||
|
||
wait 2;
|
||
|
||
thread ending_player_breathing();
|
||
level.player FreezeControls( false );
|
||
level.player LerpViewAngleClamp( 0, 0, 0, 3, 3, 5, 2 );
|
||
|
||
overlay thread restoreVision( 3, 0 );
|
||
|
||
autosave_by_name( "drag_started" );
|
||
|
||
thread ending_redsmoke_sequence();
|
||
|
||
thread ending_mortarhit_ghost_sequence();
|
||
|
||
node thread anim_single_solo( playerview, "estate_ending_drag" );
|
||
node anim_single_solo( level.ghost, "estate_ending_drag" );
|
||
|
||
//Now the player must fight or die
|
||
|
||
level.player LerpViewAngleClamp( 1, 1, 1, 30, 30, 30, 5 );
|
||
level.player enableweapons();
|
||
|
||
level.player switchToWeapon( "ak47_woodland_grenadier" );
|
||
|
||
level.player thread ending_drag_damagecheck();
|
||
|
||
if( !flag( "test_ending_body_toss" ) && !flag( "test_ending" ) )
|
||
level.ghost stop_magic_bullet_shield();
|
||
|
||
if( !flag( "test_ending_body_toss" ) )
|
||
level.ghost delete();
|
||
|
||
/*
|
||
switch( level.gameskill )
|
||
{
|
||
case 0:
|
||
level.player.attackeraccuracy = 1;
|
||
break;
|
||
case 1:
|
||
level.player.attackeraccuracy = 0.9;
|
||
break;
|
||
case 2:
|
||
level.player.attackeraccuracy = 0.3;
|
||
break;
|
||
case 3:
|
||
level.player.attackeraccuracy = 0.15;
|
||
break;
|
||
}
|
||
*/
|
||
|
||
playerview waittillmatch( "single anim", "mortarhit" );
|
||
thread ending_mortarhit( "ending_mortarhit_1" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "bottom_b" );
|
||
|
||
playerview waittillmatch( "single anim", "mortarhit" );
|
||
thread ending_mortarhit( "ending_mortarhit_2" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "right" );
|
||
|
||
level notify ( "stop_blur_cycler" );
|
||
|
||
delaythread( 2, ::ending_passing_out, overlay );
|
||
|
||
playerview waittillmatch( "single anim", "mortarhit" );
|
||
thread ending_mortarhit( "ending_mortarhit_3" );
|
||
level.player thread maps\_gameskill::grenade_dirt_on_screen( "left" );
|
||
|
||
//Start flying in the shadowops littlebirds to drop off the drones for the strugglewalk
|
||
|
||
playerview waittillmatch( "single anim", "mortarhit" );
|
||
thread ending_mortarhit( "ending_mortarhit_4" );
|
||
playerview waittillmatch( "single anim", "helicopterbuzz" );
|
||
|
||
playerview waittillmatch( "single anim", "gettingfuzzy" );
|
||
|
||
flag_set( "enter_the_littlebirds" );
|
||
|
||
thread maps\_mortar::bog_style_mortar_off( "2" );
|
||
|
||
//wait for notetrack in ending drag
|
||
|
||
overlay blackOut( 3, 12 );
|
||
|
||
level.player delaycall( 3, ::takeallweapons );
|
||
|
||
level.player FreezeControls( true );
|
||
|
||
//Wake up after dragging sequence
|
||
|
||
SetSavedDvar( "ui_hidemap", 1 );
|
||
SetSavedDvar( "compass", "0" );
|
||
SetSavedDvar( "ammoCounterHide", "1" );
|
||
|
||
enemies = getaiarray( "axis" );
|
||
foreach( enemy in enemies )
|
||
{
|
||
enemy kill();
|
||
}
|
||
|
||
wait 1;
|
||
}
|
||
|
||
array_thread( getentarray( "ending_actors", "targetname" ), ::add_spawn_function, ::ending_actors_think );
|
||
activate_trigger( "ending_actors", "target" );
|
||
wait 0.1;
|
||
|
||
gasolineGuy = undefined;
|
||
deadGhost = undefined;
|
||
|
||
node = getstruct( "ending_chopper_node", "targetname" );
|
||
guys = [];
|
||
foreach( member in level.ending_actors )
|
||
{
|
||
if( member.script_noteworthy == "gasolineGuy" )
|
||
{
|
||
gasolineGuy = member;
|
||
gasolineGuy hide();
|
||
}
|
||
else
|
||
if( !flag( "test_alt_ending" ) && member.script_noteworthy == "alt_ending_dead_guy" )
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
if( flag( "test_alt_ending" ) && member.script_noteworthy == "alt_ending_dead_guy" )
|
||
{
|
||
member.script_noteworthy = "ghost_ending_dead";
|
||
member.animname = "ghost_ending_dead";
|
||
deadGhost = member;
|
||
deadGhost hide();
|
||
}
|
||
else
|
||
if( flag( "test_alt_ending" ) && member.script_noteworthy == "ghost_ending_dead" )
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
if( !flag( "test_alt_ending" ) && member.script_noteworthy == "ghost_ending_dead" )
|
||
{
|
||
deadGhost = member;
|
||
deadGhost hide();
|
||
}
|
||
else
|
||
if( !flag( "test_alt_ending" ) && member.script_noteworthy == "alt_ending_guy" )
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
if( flag( "test_alt_ending" ) && member.script_noteworthy == "alt_ending_guy" )
|
||
{
|
||
member.script_noteworthy = "ghost_ending";
|
||
member.animname = "ghost_ending";
|
||
guys[ guys.size ] = member;
|
||
}
|
||
else
|
||
if( flag( "test_alt_ending" ) && member.script_noteworthy == "ghost_ending" )
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
guys[ guys.size ] = member;
|
||
}
|
||
}
|
||
|
||
if( flag( "test_with_pavelow_already_in_place" ) || flag( "test_ending_body_toss" ) )
|
||
{
|
||
pavelow = spawn_vehicle_from_targetname( "final_pavelow_liftoff_1" );
|
||
pavelow.animname = "pavelow";
|
||
level.pavelow = pavelow;
|
||
}
|
||
else
|
||
{
|
||
level.pavelow delete();
|
||
|
||
pavelow = spawn_vehicle_from_targetname( "animated_pavelow" );
|
||
pavelow.animname = "pavelow";
|
||
|
||
level.pavelow = pavelow; //this is for the pavelow in the gasoline function
|
||
|
||
//pavelow = getent( "final_pavelow_liftoff_1", "targetname" );
|
||
//pavelow.animname = "pavelow";
|
||
}
|
||
|
||
level.player takeallweapons();
|
||
playerview = spawn_anim_model( "playerview" );
|
||
node anim_first_frame_solo( playerview, "estate_ending_part1" );
|
||
level.player PlayerLinkToDelta( playerview, "tag_player", 1, 10, 10, 10, 2 );
|
||
|
||
playerBody = spawn_anim_model( "body_ending" );
|
||
node anim_first_frame_solo( playerBody, "estate_ending_part1" );
|
||
|
||
node anim_first_frame_solo( pavelow, "estate_ending_part1" );
|
||
|
||
tag_origin = spawn_tag_origin();
|
||
tag_origin linkto( playerview, "tag_player", (0,0,0), (0,0,0) );
|
||
level.player playersetgroundreferenceent( tag_origin );
|
||
|
||
ghost = level.ending_actors[ "ghost_ending" ];
|
||
|
||
shepherd = level.ending_actors[ "shepherd_ending" ];
|
||
shepherd gun_remove();
|
||
|
||
if( !flag( "test_ending_body_toss" ) )
|
||
{
|
||
//Wake up to find Ghost dragging you to your feet, drag to Pave Low
|
||
|
||
wait 2;
|
||
|
||
//overlay thread restoreVision( 4, 0 );
|
||
overlay delayThread( 0.5, ::restoreVision, 3, 0 );
|
||
|
||
level.player delayCall( 0.5, ::FreezeControls, false );
|
||
|
||
level.player LerpViewAngleClamp( 1, 1, 1, 3, 3, 3, 3 );
|
||
|
||
level.player setBlurForPlayer( 0, 16 );
|
||
|
||
//thread temp_music_ending_delay();
|
||
|
||
flag_set( "made_it_to_lz" );
|
||
|
||
node thread anim_single( guys, "estate_ending_part1" );
|
||
node thread anim_single_solo( playerview, "estate_ending_part1" );
|
||
node thread anim_single_solo( pavelow, "estate_ending_part1" );
|
||
node thread anim_single_solo( playerBody, "estate_ending_part1" );
|
||
|
||
thread ending_eq_reset();
|
||
|
||
//Come on, get up!
|
||
ghost thread dialogue_queue( "est_gst_comeongetup" );
|
||
|
||
//Get up! Get up! We're almost there!
|
||
ghost thread dialogue_queue( "est_gst_getupgetup" );
|
||
|
||
level.player LerpViewAngleClamp( 7, 1, 1, 30, 30, 30, 15 );
|
||
|
||
level.endingTimeRef = gettime();
|
||
|
||
thread ending_shadow_fader_mover( 0.12, 20, 14 );
|
||
|
||
level.ending_actors[ "guy1_ending" ] hide();
|
||
level.ending_actors[ "guy2_ending" ] hide();
|
||
|
||
thread temp_shepherd_dialogue( shepherd, ghost );
|
||
|
||
shepherd waittill_notetrack_or_damage( "pistol_pullout" );
|
||
pistol = spawn( "script_model", (0, 0, 0) );
|
||
pistol setmodel( "weapon_colt_anaconda" );
|
||
pistol linkto( shepherd, "tag_weapon_right", (0, 0, 0), (0, 0, 0) );
|
||
|
||
level.player LerpViewAngleClamp( 1, 1, 1, 20, 20, 10, 2 );
|
||
|
||
level.ending_actors[ "guy1_ending" ] show();
|
||
level.ending_actors[ "guy2_ending" ] show();
|
||
|
||
shepherd waittill_notetrack_or_damage( "shepherd_fire2" );
|
||
pistol playsound( "weap_deserteagle_fire_plr" );
|
||
playfxOnTag( getfx( "anaconda_muzzle_flash" ), pistol, "tag_flash" );
|
||
|
||
level.player PlayRumbleOnEntity( "shepherd_pistol" );
|
||
|
||
//level.player notify ( "damage" );
|
||
//level.player notify ( "pain" );
|
||
|
||
level.player delaycall( 1.3, ::PlayRumbleOnEntity, "shot_collapse" );
|
||
|
||
level.player SetNormalHealth( 1 );
|
||
gunpos = shepherd geteye();
|
||
level.player DoDamage( 99 / level.player.damagemultiplier, gunpos );
|
||
|
||
level.player delayThread( 0.3, ::ending_player_fullhealth );
|
||
|
||
level notify ( "stop_player_breathing" );
|
||
|
||
SetSavedDvar( "g_friendlyNameDist", 0 );
|
||
|
||
//"NO!"
|
||
ghost delaythread( 1, ::dialogue_queue, "est_gst_no" ); //1.25 original
|
||
|
||
if( flag( "no_slow_mo" ) )
|
||
{
|
||
delaythread( 1.5, ::ending_slowmo, 3 );
|
||
}
|
||
|
||
shepherd waittill_notetrack_or_damage( "shepherd_fire1" );
|
||
pistol playsound( "weap_cheytac_fire_plr" );
|
||
playfxOnTag( getfx( "anaconda_muzzle_flash" ), pistol, "tag_flash" );
|
||
|
||
shepherd waittill_notetrack_or_damage( "pistol_putaway" );
|
||
pistol delete();
|
||
|
||
//thread ending_shadow_fader_mover( 0.02, 2, 0.8, 0.1 );
|
||
|
||
level.player delaycall( 0.8, ::PlayRumbleOnEntity, "dsm_rummage" );
|
||
|
||
shepherd waittill_notetrack_or_damage( "dsm_pullout" );
|
||
dsm = spawn( "script_model", (0, 0, 0) );
|
||
dsm setmodel( "mil_wireless_dsm_small" );
|
||
dsm linkto( shepherd, "tag_inhand", (0, 0, 0), (0, 0, 0) );
|
||
|
||
shepherd waittill_notetrack_or_damage( "dsm_putaway" );
|
||
dsm delete();
|
||
|
||
//Shepherd's men start picking up your body
|
||
|
||
overlay thread blackOut( 7, 6 );
|
||
|
||
wait 8;
|
||
}
|
||
|
||
//Set up the body toss section
|
||
throwingGuy = level.ending_actors[ "guy1_ending" ];
|
||
throwingHelperGuy = level.ending_actors[ "guy2_ending" ];
|
||
|
||
node = getstruct( "ending_chopper_node2", "targetname" );
|
||
|
||
guys = [];
|
||
guys[ guys.size ] = throwingGuy;
|
||
guys[ guys.size ] = throwingHelperGuy;
|
||
|
||
array_thread( level.ending_actors, ::gun_remove );
|
||
|
||
node anim_first_frame_solo( playerview, "estate_ending_part2" );
|
||
level.player PlayerLinkToDelta( playerview, "tag_player", 1, 10, 10, 5, 5 );
|
||
|
||
node anim_first_frame_solo( playerBody, "estate_ending_part2" );
|
||
|
||
overlay thread restoreVision( 3, 0 );
|
||
|
||
level.player LerpViewAngleClamp( 1, 1, 1, 20, 20, 10, 0 );
|
||
|
||
//Anims are set to play simultaneously but I want to try a different pacing
|
||
//Set the gasoline anims to go on delayed standby in a separate thread
|
||
|
||
thread ending_gasoline_sequence( gasolineGuy, shepherd, overlay );
|
||
|
||
//Shepherd's throwers toss your body into the pit
|
||
|
||
node thread anim_single_solo( playerview, "estate_ending_part2" );
|
||
node thread anim_single_solo( playerBody, "estate_ending_part2" );
|
||
node thread anim_single( guys, "estate_ending_part2" );
|
||
|
||
wait 1;
|
||
|
||
flag_set( "begin_overlapped_gasoline_sequence" );
|
||
|
||
wait 1.8;
|
||
|
||
//level.player thread play_sound_on_entity( "scn_estate_player_bodyfall" );
|
||
level.player PlayRumbleOnEntity( "bodytoss_impact" );
|
||
|
||
wait 1.3;
|
||
|
||
playerBody hide();
|
||
|
||
//guys[ guys.size ] = level.ending_actors[ "ghost_ending" ];
|
||
|
||
//switch to the bloodied corpse model of Ghost
|
||
|
||
level.ending_actors[ "ghost_ending" ] hide();
|
||
deadGhost show();
|
||
|
||
//guys[ guys.size ] = level.ending_actors[ "ghost_ending_dead" ];
|
||
guys[ guys.size ] = deadGhost;
|
||
|
||
node anim_first_frame( guys, "estate_ending_part2_2ndbody" );
|
||
node thread anim_single( guys, "estate_ending_part2_2ndbody" );
|
||
|
||
throwingGuy waittill_notetrack_or_damage( "ghost_throw_release" );
|
||
|
||
if( !flag( "no_slow_mo" ) )
|
||
{
|
||
thread ending_slowmo( 10.5 );
|
||
}
|
||
|
||
thread ending_shadow_fader_mover( 0.05, 2, 1, 0.1 );
|
||
|
||
wait 2.2;
|
||
|
||
overlay thread blackOut( 0.8, 3 );
|
||
|
||
thread ending_shadow_fader_mover( 0.12, 2, 1, 0.1 );
|
||
|
||
wait 0.8;
|
||
|
||
//throwingGuy delete();
|
||
//throwingHelperGuy delete();
|
||
|
||
throwingGuy hide();
|
||
throwingHelperGuy hide();
|
||
|
||
gasolineGuy show();
|
||
shepherd show();
|
||
gasolineGuy attach( "accessories_gas_canister_highrez", "tag_inhand");
|
||
|
||
overlay thread restoreVision( 5, 0 );
|
||
setBlur( 3, 3 );
|
||
wait 3;
|
||
setBlur( 0, 3 );
|
||
}
|
||
|
||
ending_player_fullhealth()
|
||
{
|
||
self SetNormalHealth( 1 );
|
||
}
|
||
|
||
ending_pavelow_fakearrival()
|
||
{
|
||
//This thread controls the timing for when the player is forcibly killed by mortars and not getting to the LZ fast enough
|
||
//Total time of flight path is currently 40 seconds
|
||
|
||
level endon ( "finish_line" );
|
||
|
||
flag_wait( "point_of_no_return" );
|
||
|
||
//wait 20;
|
||
|
||
level.pavelow = spawn_vehicle_from_targetname( "final_pavelow_liftoff_1" );
|
||
level.pavelow.animname = "pavelow";
|
||
|
||
level.pavelow vehicle_setspeed( 15 );
|
||
|
||
node1 = getstruct( level.pavelow.target, "targetname" );
|
||
level.pavelow setvehgoalpos( node1.origin, 0 );
|
||
|
||
level.pavelow waittill_any( "goal", "near_goal" );
|
||
|
||
node2 = getstruct( node1.target, "targetname" );
|
||
level.pavelow setvehgoalpos( node2.origin, 0 );
|
||
|
||
level.pavelow waittill_any( "goal", "near_goal" );
|
||
|
||
//pavelow vehicle_setspeed( 15 );
|
||
|
||
node3 = getstruct( node2.target, "targetname" );
|
||
level.pavelow setvehgoalpos( node3.origin, 1 );
|
||
|
||
level.pavelow waittill_any( "goal", "near_goal" );
|
||
|
||
if( !flag( "finish_line" ))
|
||
{
|
||
thread mortar_in_face_killplayer();
|
||
}
|
||
}
|
||
|
||
ending_thunderone_heli_sequence()
|
||
{
|
||
flag_wait( "thunderone_heli" );
|
||
|
||
heli = spawn_vehicle_from_targetname( "ending_treecutter_heli_1" );
|
||
|
||
heli vehicle_setspeed( 12 );
|
||
|
||
node1 = getstruct( heli.target, "targetname" );
|
||
heli setvehgoalpos( node1.origin, 0 );
|
||
|
||
heli setTargetYaw ( 195 );
|
||
|
||
//heli thread ending_thunderone_manual_chainguns();
|
||
|
||
//heli waittill_any( "goal", "near_goal" );
|
||
heli waittill( "goal" );
|
||
|
||
heli vehicle_setspeed( 8 );
|
||
|
||
wait 0.6;
|
||
|
||
heli setTargetYaw ( 210 );
|
||
|
||
node2 = getstruct( node1.target, "targetname" );
|
||
heli setvehgoalpos( node2.origin, 1 );
|
||
|
||
heli waittill_any( "goal", "near_goal" );
|
||
|
||
wait 1;
|
||
|
||
node3 = getstruct( node2.target, "targetname" );
|
||
heli setvehgoalpos( node3.origin, 0 );
|
||
|
||
wait 0.5;
|
||
|
||
heli setTargetYaw ( 190 );
|
||
|
||
heli waittill_any( "goal", "near_goal" );
|
||
|
||
wait 2;
|
||
|
||
node4 = getstruct( node3.target, "targetname" );
|
||
heli setvehgoalpos( node4.origin );
|
||
|
||
heli vehicle_setspeed( 50 );
|
||
|
||
heli clearTargetYaw();
|
||
}
|
||
|
||
ending_shadow_fader()
|
||
{
|
||
//use a script_origin's x-position to update sm_sunSampleSizeNear smoothly at will
|
||
|
||
level.shadowfader = spawn( "script_origin", ( 0.25, 0, 0 ) );
|
||
|
||
while( 1 )
|
||
{
|
||
SetSavedDvar( "sm_sunSampleSizeNear", level.shadowfader.origin[ 0 ] );
|
||
wait 0.05;
|
||
}
|
||
}
|
||
|
||
ending_shadow_fader_mover( setting, fadeTime, accelTime, decelTime )
|
||
{
|
||
if( !isdefined( setting ) )
|
||
setting = 0.25;
|
||
|
||
assertEX( setting <= 0.25, "Specified value for sm_sunSampleSizeNear is out of range." );
|
||
assertEX( setting >= 0.015625, "Specified value for sm_sunSampleSizeNear is out of range." );
|
||
|
||
if( !isdefined( fadeTime ) )
|
||
fadeTime = 1;
|
||
|
||
if( !isdefined( accelTime ) )
|
||
accelTime = 1;
|
||
|
||
if( !isdefined( decelTime ) )
|
||
decelTime = 1;
|
||
|
||
level.shadowfader MoveTo( ( setting, 0, 0 ), fadeTime, accelTime, decelTime );
|
||
}
|
||
|
||
/*
|
||
ending_thunderone_manual_chainguns()
|
||
{
|
||
org = getstruct( "redsmoke", "targetname" );
|
||
faketarget = spawn( "script_origin", org.origin );
|
||
|
||
foreach ( turret in self.mgturret )
|
||
{
|
||
|
||
baddudes = getaiarray( "axis" );
|
||
if( baddudes.size )
|
||
{
|
||
turret SetMode( "manual" );
|
||
turret StartFiring();
|
||
}
|
||
else
|
||
{
|
||
|
||
turret SetTargetEntity( faketarget );
|
||
turret SetMode( "manual" );
|
||
turret StartFiring();
|
||
}
|
||
}
|
||
|
||
wait 4.5;
|
||
|
||
foreach ( turret in self.mgturret )
|
||
{
|
||
|
||
baddudes = getaiarray( "axis" );
|
||
if( baddudes.size )
|
||
{
|
||
turret SetMode( "auto_ai" );
|
||
turret StartFiring();
|
||
}
|
||
}
|
||
|
||
wait 9;
|
||
|
||
//self mgoff();
|
||
|
||
foreach ( turret in self.mgturret )
|
||
{
|
||
turret StopFiring();
|
||
}
|
||
}
|
||
*/
|
||
|
||
ending_shadowops_heli_sequence()
|
||
{
|
||
flag_wait( "enter_the_littlebirds" );
|
||
|
||
heli1 = delayThread( 1, ::spawn_vehicle_from_targetname_and_drive, "ending_shadowops_heli_1" );
|
||
heli2 = delayThread( 3, ::spawn_vehicle_from_targetname_and_drive, "ending_shadowops_heli_2" );
|
||
heli3 = delayThread( 4, ::spawn_vehicle_from_targetname_and_drive, "ending_shadowops_heli_3" );
|
||
heli4 = delayThread( 2, ::spawn_vehicle_from_targetname_and_drive, "ending_shadowops_heli_4" );
|
||
|
||
trig = getent( "ending_shouter_trig", "targetname" );
|
||
trig waittill ( "trigger" );
|
||
|
||
speakers = getentarray( "ending_shouter", "targetname" );
|
||
array_randomize( speakers );
|
||
|
||
foreach( index, ent in speakers )
|
||
{
|
||
if( index > 2 )
|
||
break;
|
||
|
||
if( index == 0 )
|
||
{
|
||
//Cover them! Move, move!
|
||
ent play_sound_on_entity( "est_tf2_coverthem" );
|
||
}
|
||
|
||
if( index == 1 )
|
||
{
|
||
//Spread out!
|
||
ent play_sound_on_entity( "est_tf2_spreadout" );
|
||
}
|
||
|
||
if( index == 2 )
|
||
{
|
||
//Go! Go! Go!
|
||
ent play_sound_on_entity( "est_tf1_gogogo" );
|
||
}
|
||
|
||
if( index == 3 )
|
||
{
|
||
//Get 'em to strafe that ridgeline!
|
||
ent play_sound_on_entity( "est_tf3_straferidgeline" );
|
||
}
|
||
|
||
if( index == 4 )
|
||
{
|
||
//Roger that!
|
||
ent play_sound_on_entity( "est_tf4_rogerthat" );
|
||
}
|
||
|
||
if( index == 5 )
|
||
{
|
||
//Secure this landing zone! Gold Eagle is touching down, I repeat, Gold Eagle is touching down!
|
||
ent play_sound_on_entity( "est_tf1_goldeagle" );
|
||
}
|
||
}
|
||
}
|
||
|
||
temp_shepherd_dialogue( shepherd, ghost )
|
||
{
|
||
wait 6.5;
|
||
|
||
//Gold Eagle is on the ground. Watch for snipers on thermal, over.
|
||
thread radio_dialogue( "est_hp2_watchforsnipers" );
|
||
|
||
wait 10.5;
|
||
|
||
//Shepherd: Do you have the DSM?
|
||
//shepherd waittillmatch( "single anim", "shepherd_dsm_talk" );
|
||
//shepherd dialogue_queue( "est_shp_havethedsm" );
|
||
|
||
//Ghost: We got it, sir!
|
||
ghost dialogue_queue( "est_gst_wegotit" );
|
||
wait 0.85;
|
||
|
||
//Shepherd: Well done, soldier.
|
||
//shepherd dialogue_queue( "est_shp_welldone" );
|
||
|
||
//Shepherd: Good. That's one less loose end.
|
||
//shepherd dialogue_queue( "est_shp_looseend" );
|
||
|
||
wait 1.5;
|
||
|
||
wait 12;
|
||
|
||
//Area is sanitized. All targets destroyed.
|
||
radio_dialogue( "est_hp2_sanitized" );
|
||
|
||
//Solid copy, no movement detected. Two-six going into holding pattern.
|
||
radio_dialogue( "est_hp1_holdingpattern" );
|
||
}
|
||
|
||
ending_redsmoke_sequence()
|
||
{
|
||
//dialogue from Ghost
|
||
//start the redsmoke fx
|
||
|
||
smokepot = getstruct( "redsmoke", "targetname" );
|
||
playFX( getfx( "redsmoke" ), smokepot.origin );
|
||
|
||
//I've got you Roach, hang on!
|
||
radio_dialogue( "est_gst_gotyouroach" );
|
||
|
||
//Thunder Two-One, I've popped red smoke in the treeline! Standby to engage on my mark!
|
||
radio_dialogue( "est_gst_redsmoke" );
|
||
|
||
//Roger that, I have a visual on the red smoke. Standing by.
|
||
radio_dialogue( "est_fp1_visual" );
|
||
|
||
flag_set( "drag_sequence_slacker_check" );
|
||
|
||
//Thunder Two-One, cleared hot!
|
||
radio_dialogue( "est_gst_clearedhot" );
|
||
|
||
//Roger that cleared hot.
|
||
radio_dialogue( "est_fp1_clearedhot" );
|
||
|
||
flag_set( "thunderone_heli" );
|
||
|
||
//Guns guns guns.
|
||
radio_dialogue( "est_hp1_gunsgunsguns" );
|
||
|
||
wait 9;
|
||
|
||
//This is Viper Two-Six, standby for rocket attack, over.
|
||
radio_dialogue( "est_hp1_rocketattck" );
|
||
|
||
//Uh, roger<65>hit 'em hard on that hill, make sure they're down.
|
||
radio_dialogue( "est_hp2_hitemhard" );
|
||
|
||
//Roger I'm on it. Coming around on heading two-five-zero.
|
||
radio_dialogue( "est_hp1_imonit" );
|
||
|
||
//Roger, I got 'em lined up.
|
||
radio_dialogue( "est_hp1_linedup" );
|
||
}
|
||
|
||
ending_mortarhit_ghost_sequence()
|
||
{
|
||
thread ending_mortarhit( "ending_mortarhit_a" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "left" );
|
||
wait 1;
|
||
thread ending_mortarhit( "ending_mortarhit_b" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "right" );
|
||
wait 0.75;
|
||
thread ending_mortarhit( "ending_mortarhit_c" );
|
||
level.player thread maps\_gameskill::grenade_dirt_on_screen( "right" );
|
||
|
||
wait 0.6;
|
||
thread ending_mortarhit( "ending_mortarhit_d" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "left" );
|
||
wait 1;
|
||
thread ending_mortarhit( "ending_mortarhit_e" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "left" );
|
||
wait 0.5;
|
||
thread ending_mortarhit( "ending_mortarhit_f" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "left" );
|
||
wait 0.25;
|
||
thread ending_mortarhit( "ending_mortarhit_g" );
|
||
//level.player thread maps\_gameskill::grenade_dirt_on_screen( "right" );
|
||
wait 0.6;
|
||
thread ending_mortarhit( "ending_mortarhit_h" );
|
||
level.player thread maps\_gameskill::grenade_dirt_on_screen( "left" );
|
||
wait 0.45;
|
||
thread ending_mortarhit( "ending_mortarhit_i" );
|
||
}
|
||
|
||
ending_mortarhit( mortarname )
|
||
{
|
||
hit = getstruct( mortarname, "targetname" );
|
||
hit play_sound_in_space( level.scr_sound[ "mortar" ][ "incomming" ] );
|
||
|
||
earthquake( 0.5, 1.4, level.player.origin, 2000 );
|
||
playRumbleOnPosition( "artillery_rumble", hit.origin );
|
||
hit thread play_sound_in_space( level.scr_sound[ "mortar" ][ "dirt" ] );
|
||
playfx( level._effect[ "mortar" ][ "dirt" ], hit.origin );
|
||
}
|
||
|
||
temp_music_ending_delay()
|
||
{
|
||
if( !flag( "no_slow_mo" ) )
|
||
{
|
||
musicStop( 6 );
|
||
wait 7;
|
||
musicPlay( "estate_betrayal" );
|
||
}
|
||
else
|
||
{
|
||
musicStop( 1 );
|
||
wait 1.5;
|
||
musicPlay( "estate_betrayal" );
|
||
}
|
||
}
|
||
|
||
ending_gasoline_sequence( gasolineGuy, shepherd, overlay )
|
||
{
|
||
//Make sure that the gasoline anims are playing by this point
|
||
|
||
flag_wait( "begin_overlapped_gasoline_sequence" );
|
||
|
||
thread ending_gasoline_price_radio();
|
||
|
||
node = getstruct( "ending_chopper_node2", "targetname" );
|
||
|
||
guys = [];
|
||
guys[ guys.size ] = gasolineGuy;
|
||
guys[ guys.size ] = shepherd;
|
||
|
||
shepherd thread ending_smoking_fx();
|
||
|
||
node = getstruct( "ending_chopper_node2", "targetname" );
|
||
node thread anim_single( guys, "estate_ending_part3" );
|
||
|
||
gasolineGuy waittill_notetrack_or_damage( "pour_on_player" );
|
||
level.player SetWaterSheeting( 1, 7 );
|
||
|
||
gasolineGuy waittill_notetrack_or_damage( "pour_on_player" );
|
||
level.player SetWaterSheeting( 1, 4.0 );
|
||
|
||
flag_wait( "cigar_flicked" );
|
||
|
||
//level.player thread play_sound_on_entity ( "scn_estate_player_ignite" );
|
||
|
||
wait 0.15; //dramatic timing for cigar freefall
|
||
|
||
flag_set( "cigar_flareup" ); //one last dramatic cigar glow pulse at the onset of slowmo
|
||
|
||
flyOverHeli = spawn_vehicles_from_targetname( "final_pavelow_liftoff_2" );
|
||
flyOverHeliNode = getent( "final_pavelow_flyover", "targetname" );
|
||
flyOverHeli[ 0 ] thread set_heli_goal( flyOverHeliNode );
|
||
|
||
wait 0.1;
|
||
|
||
if( !flag( "no_slow_mo" ) )
|
||
{
|
||
thread ending_slowmo( 140, 0.1 );
|
||
}
|
||
|
||
//wait 0.7;
|
||
wait 0.6;
|
||
|
||
playFX( getfx( "gasoline_fire_on_player_ignite" ), level.player.origin + ( -66, 56, 64 ) );
|
||
playFX( getfx( "gasoline_fire_on_player" ), level.player.origin + ( -6, 56, 54 ) );
|
||
playFX( getfx( "gasoline_fire_on_player" ), level.player.origin + ( -116, 56, 64 ) );
|
||
|
||
wait 0.1;
|
||
|
||
setblur( 2, 3 );
|
||
|
||
wait 1.2;
|
||
|
||
//mainHeli = getent( "final_pavelow_liftoff_1", "targetname" );
|
||
heliNode = getent( "final_heli_goal_1", "targetname" );
|
||
//mainHeli thread set_heli_goal( heliNode );
|
||
level.pavelow thread set_heli_goal( heliNode );
|
||
|
||
wait 0.5;
|
||
|
||
wait 1;
|
||
|
||
heliNode = getent( "final_pavelow_liftoff_exit", "targetname" );
|
||
level.pavelow thread set_heli_goal( heliNode );
|
||
|
||
overlay thread blackOut( 2, 6 );
|
||
|
||
wait 2;
|
||
|
||
flag_set( "end_the_mission" );
|
||
}
|
||
|
||
ending_gasoline_price_radio()
|
||
{
|
||
wait 2;
|
||
|
||
level.player LerpViewAngleClamp( 1, 1, 1, 3, 3, 3, 3 );
|
||
|
||
//level.player thread play_sound_on_entity( "scn_estate_ghost_bodyfall_breath" );
|
||
|
||
wait 5;
|
||
|
||
//Ghost, come in, this is Price! We're under attack by Shepherd's men at the boneyard!
|
||
//(off mike) Soap, hold the left flank!
|
||
//Do not trust Shepherd - I say again, do not trust Shepherd!
|
||
//(off mike) Soap get dowwwwn!!!
|
||
|
||
radio_dialogue( "est_pri_underattack" );
|
||
|
||
/*
|
||
//Ghost, come in, this is Price! We're under attack by Shepherd's men at the boneyard!
|
||
radio_dialogue( "est_pri_comein" );
|
||
|
||
//(off mike) Soap, hold the left flank!
|
||
radio_dialogue( "est_pri_holdleftflank" );
|
||
|
||
//Do not trust Shepherd - I say again, do not trust Shepherd!
|
||
radio_dialogue( "est_pri_donottrust" );
|
||
|
||
//(off mike) Soap get dowwwwn!!!
|
||
radio_dialogue( "est_pri_getdown" );
|
||
*/
|
||
}
|
||
|
||
ending_smoking_fx()
|
||
{
|
||
self waittill_notetrack_or_damage( "cigar_box_pullout" );
|
||
cigarBox = spawn( "script_model", (0, 0, 0) );
|
||
cigarBox setmodel( "prop_cigarette_pack" );
|
||
cigarBox linkto( self, "j_thumb_le_3", (0, 0, 0), (0, 0, 0) );
|
||
|
||
wait 0.25;
|
||
|
||
cigar = spawn( "script_model", (0, 0, 0) );
|
||
cigar setmodel( "prop_price_cigar" );
|
||
cigar linkto( self, "tag_inhand", (0, 0, 0), (0, 0, 0) );
|
||
|
||
self waittill_notetrack_or_damage( "lighter_pullout" );
|
||
cigarBox delete();
|
||
|
||
self waittill_notetrack_or_damage( "lighter_on" );
|
||
playfxOnTag( getfx( "cigar_glow_puff" ), cigar, "tag_cigarglow" );
|
||
wait 1;
|
||
playfxOnTag( getfx( "cigar_smoke_puff" ), self, "tag_eye" );
|
||
|
||
self waittill_notetrack_or_damage( "shepherd_exhale" );
|
||
playfxOnTag( getfx( "cigar_exhale_estate" ), self, "tag_eye" );
|
||
|
||
self waittill_notetrack_or_damage( "shepherd_exhale" );
|
||
playfxOnTag( getfx( "cigar_glow_puff" ), cigar, "tag_cigarglow" );
|
||
wait 1;
|
||
playfxOnTag( getfx( "cigar_smoke_puff" ), self, "tag_eye" );
|
||
|
||
self waittill_notetrack_or_damage( "shepherd_exhale" );
|
||
playfxOnTag( getfx( "cigar_exhale_estate" ), self, "tag_eye" );
|
||
|
||
self waittill_notetrack_or_damage( "shepher_flick" );
|
||
flag_set( "cigar_flicked" );
|
||
|
||
flag_wait( "cigar_flareup" );
|
||
playfxOnTag( getfx( "cigar_glow" ), cigar, "tag_cigarglow" );
|
||
}
|
||
|
||
ending_slowmo( duration, speed )
|
||
{
|
||
slomoLerpTime_in = 0.1; //1.5
|
||
slomoLerpTime_out = 1; //0.65
|
||
slomobreachplayerspeed = 0.1; //0.1
|
||
slomoSpeed = 0.31; //0.25
|
||
|
||
if( isdefined( speed ) )
|
||
{
|
||
slowmoSpeed = speed;
|
||
}
|
||
|
||
slomoDuration = duration; //24
|
||
|
||
//level.player thread play_sound_on_entity( "slomo_whoosh" );
|
||
|
||
slowmo_start();
|
||
slowmo_setspeed_slow( slomoSpeed );
|
||
slowmo_setlerptime_in( slomoLerpTime_in );
|
||
slowmo_lerp_in();
|
||
|
||
level.player SetMoveSpeedScale( slomobreachplayerspeed );
|
||
|
||
wait slomoDuration * slomoSpeed;
|
||
|
||
slowmo_setlerptime_out( slomoLerpTime_out );
|
||
slowmo_lerp_out();
|
||
slowmo_end();
|
||
level.player SetMoveSpeedScale( 1.0 );
|
||
}
|
||
|
||
ending_actors_think()
|
||
{
|
||
if ( !isdefined( level.ending_actors ) )
|
||
level.ending_actors = [];
|
||
|
||
self.animname = self.script_noteworthy;
|
||
self.team = "allies";
|
||
|
||
level.ending_actors[ self.script_noteworthy ] = self;
|
||
|
||
self thread magic_bullet_shield();
|
||
}
|
||
|
||
end_of_level()
|
||
{
|
||
flag_wait( "end_the_mission" );
|
||
|
||
wait 2.6;
|
||
|
||
nextmission();
|
||
} |