5924 lines
131 KiB
Plaintext
5924 lines
131 KiB
Plaintext
#include maps\_utility;
|
|
#include common_scripts\utility;
|
|
#include maps\pel2_util;
|
|
#include maps\pel2_callbacks;
|
|
#include maps\_anim;
|
|
#include maps\_music;
|
|
|
|
|
|
|
|
main()
|
|
{
|
|
|
|
maps\_type97::main( "vehicle_jap_tracked_type97shinhoto", "type97", undefined, 2 );
|
|
maps\_aircraft::main( "vehicle_usa_aircraft_f4ucorsair", "corsair", 2 );
|
|
maps\_aircraft::main( "vehicle_usa_aircraft_f4ucorsair_dist", "corsair", 2 );
|
|
maps\_betty::main("vehicle_usa_aircraft_b17_dist");
|
|
maps\_sherman::main( "vehicle_usa_tracked_shermanm4a3_green" );
|
|
maps\_triple25::main( "artillery_jap_triple25mm" );
|
|
maps\_truck::main( "vehicle_jap_wheeled_type94", "model94" );
|
|
maps\_artillery::main("artillery_jap_47mm", "at47", true);
|
|
|
|
|
|
// weapon swapping for the flame thrower
|
|
maps\_coop_weaponswap::init();
|
|
|
|
// MikeD (5/5/2008): Vehicle Destructible Support
|
|
maps\_destructible_type94truck::init();
|
|
|
|
precache_assets();
|
|
|
|
add_start( "bunkers", ::start_bunkers, &"STARTS_PEL2_BUNKERS" );
|
|
add_start( "flame", ::start_flame, &"STARTS_PEL2_FLAME" );
|
|
add_start( "forest", ::start_forest, &"STARTS_PEL2_FOREST" );
|
|
add_start( "admin", ::start_admin, &"STARTS_PEL2_ADMIN" );
|
|
add_start( "stairs", ::start_debug_stairs, &"STARTS_PEL2_ADMIN" );
|
|
add_start( "airfield", ::start_airfield, &"STARTS_PEL2_AIRFIELD" );
|
|
add_start( "aaguns", ::start_aaguns, &"STARTS_PEL2_AAGUNS" );
|
|
add_start( "napalm", ::start_napalm, &"STARTS_PEL2_NAPALM" );
|
|
default_start( ::mangrove );
|
|
//default_start( ::start_bunkers );
|
|
|
|
createthreatbiasgroup( "players" );
|
|
|
|
init_callbacks();
|
|
|
|
// init drones
|
|
maps\_drones::init();
|
|
// init bayonet fx
|
|
maps\_bayonet::init();
|
|
|
|
maps\pel2_fx::main();
|
|
|
|
maps\_load::main();
|
|
|
|
maps\_tree_snipers::main();
|
|
|
|
level thread maps\pel2_amb::main();
|
|
maps\pel2_anim::main();
|
|
setup_drone_models();
|
|
|
|
level thread set_custom_approach();
|
|
|
|
// init banzai
|
|
maps\_banzai::init();
|
|
|
|
// weapon swapping for the flame thrower
|
|
level.onPlayerWeaponSwap = maps\_coop_weaponswap::flamethrower_swap;
|
|
|
|
}
|
|
|
|
|
|
|
|
precache_assets()
|
|
{
|
|
|
|
precachemodel( "static_peleliu_crate_jpn_clsd_char" );
|
|
precacheModel("projectile_us_smoke_grenade");
|
|
//precachemodel( "mounted_usa_bar_bipod_lmg" );
|
|
precachemodel( "char_usa_marine_radiohandset" );
|
|
|
|
// glowy bits
|
|
precachemodel( "weapon_usa_flamethrower_obj" );
|
|
precachemodel( "char_usa_marine_helmf_obj" );
|
|
precachemodel( "weapon_usa_bazooka_at_obj" );
|
|
precachemodel( "weapon_usa_m1garand_rifle_grenade_obj" );
|
|
|
|
// Tank gear
|
|
precachemodel( "vehicle_usa_tracked_sherman_setA_chassis" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setA_turret" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setB_chassis" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setB_turret" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setC_chassis" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setC_turret" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setD_chassis" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setD_turret" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setE_chassis" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setE_turret" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setF_chassis" );
|
|
precachemodel( "vehicle_usa_tracked_sherman_setF_turret" );
|
|
precachemodel( "vehicle_jap_type97_seta_chassis" );
|
|
precachemodel( "vehicle_jap_type97_seta_turret" );
|
|
precachemodel( "vehicle_jap_type97_setb_chassis" );
|
|
precachemodel( "vehicle_jap_type97_setb_turret" );
|
|
precachemodel( "vehicle_jap_type97_setc_chassis" );
|
|
precachemodel( "vehicle_jap_type97_setc_turret" );
|
|
|
|
PrecacheRumble( "explosion_generic" );
|
|
PrecacheRumble( "pel2_bomber" );
|
|
|
|
precacheshader( "hud_icon_grenade_launcher_dpad" );
|
|
|
|
// for corsair pilot
|
|
character\char_usa_pbycrew_pel2_gunner::precache();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Handles basic level initializing
|
|
//
|
|
///////////////////////////////
|
|
|
|
setup_level()
|
|
{
|
|
|
|
setup_guzzo_hud();
|
|
|
|
// mangrove flags
|
|
flag_init( "corsair_trap_about_to_explode" );
|
|
flag_init( "mangrove_click_sound" );
|
|
flag_init( "get_a_grenade_vo" );
|
|
flag_init( "mangrove_ambush_ai_dead" );
|
|
flag_init( "mangrove_ambush" );
|
|
flag_init( "mangrove_gren_lookat" );
|
|
flag_init( "all_grenaders_in_place" );
|
|
flag_init( "mangrove_grenades_thrown" );
|
|
flag_init( "mangrove_grenades_exploded" );
|
|
// bunker flags
|
|
flag_init( "smoke_grenade_on_the_scene" );
|
|
flag_init( "flamethrower_now_non_glowy" );
|
|
flag_init( "mgs_focus_on_flamer" );
|
|
flag_init( "trig_forest_friendlies" );
|
|
flag_init( "flame_bunker_rhythm_stop" );
|
|
flag_init( "player_got_flamethrower" );
|
|
flag_init( "bunker_killed_but_not_flamed" );
|
|
flag_init( "flamer_at_first_advance_node" );
|
|
flag_init( "flame_guy_killed" );
|
|
flag_init( "bunker_window_1_flamed" );
|
|
flag_init( "bunker_window_2_flamed" );
|
|
flag_init( "grass_surprise" );
|
|
flag_init( "grass_surprise_damage" );
|
|
flag_init( "marines_advance" );
|
|
flag_init( "bunkers_flamed" );
|
|
flag_init( "bunker_distract_1" );
|
|
flag_init( "bunker_distract_2" );
|
|
flag_init( "bunker_regroup_complete" );
|
|
flag_init( "flamer_advance_to_2" );
|
|
flag_init( "flamer_advance_to_3" );
|
|
flag_init( "flamer_advance_to_hide" );
|
|
flag_init( "chain_bunkers_entrance_past" );
|
|
// admin flags
|
|
flag_init( "friendly_chain_admin_last" );
|
|
flag_init( "trig_ditch_guys" );
|
|
flag_init( "admin_camo_guys_2_startled" );
|
|
flag_init( "admin_truck_exploded" );
|
|
flag_init( "flame_tree_guy_dead" );
|
|
flag_init( "flame_tree_flamed" );
|
|
flag_init( "flame_tree_affects_grass" );
|
|
flag_init( "grass_ambush_done" );
|
|
flag_init( "grass_admin_surprise" );
|
|
flag_init( "grass_admin_surprise_damage" );
|
|
flag_init( "admin_mg_done" );
|
|
flag_init( "berm_climb" );
|
|
flag_init( "admin_back" );
|
|
flag_init( "top_floor_retreat" );
|
|
flag_init( "bunker_last_ai_dead" );
|
|
// airfield flags
|
|
flag_init( "player_got_bazooka" );
|
|
flag_init( "first_tank_on_the_scene" );
|
|
flag_init( "last_tank_on_the_scene" );
|
|
flag_init( "tower_being_populated" );
|
|
flag_init( "whole_damn_convoy" );
|
|
flag_init( "so_many_reinforcements" );
|
|
flag_init( "counterattack_trucks" );
|
|
flag_init( "end_pacing_extra" );
|
|
flag_init( "end_pacing_polonsky" );
|
|
flag_init( "end_pacing_roebuck" );
|
|
flag_init( "airfield_move_vo" );
|
|
flag_init( "pacing_vignette_started" );
|
|
flag_init( "aaGun_1_cleared" );
|
|
flag_init( "aaGun_2_cleared" );
|
|
flag_init( "aaGun_3_cleared" );
|
|
flag_init( "aaGun_4_cleared" );
|
|
flag_init( "aaGun_1_destroyed" );
|
|
flag_init( "aaGun_2_destroyed" );
|
|
flag_init( "aaGun_3_destroyed" );
|
|
flag_init( "aaGun_4_destroyed" );
|
|
flag_init( "chi_1b_wave_almost_dead" );
|
|
flag_init( "chi_3c_spawned" );
|
|
flag_init( "napalm_incoming" );
|
|
flag_init( "airfield_rush_inplace" );
|
|
flag_init( "truck_hit_by_shell" );
|
|
flag_init( "sherman_1a_vulnerable" );
|
|
flag_init( "tank_spawn_n_move_2" );
|
|
flag_init( "plane_strafe" );
|
|
flag_init( "plane_strafe_shoot" );
|
|
flag_init( "airfield_last_trench" );
|
|
flag_init( "chi_1a_wave_dead" );
|
|
flag_init( "chi_1b_wave_dead" );
|
|
flag_init( "chi_1c_wave_dead" );
|
|
flag_init( "chi_3_wave_dead" );
|
|
flag_init( "chi_3a_death" );
|
|
flag_init( "chi_3b_death" );
|
|
flag_init( "chi_3c_death" );
|
|
flag_init( "shermans_1_dead" );
|
|
flag_init( "shermans_2_dead" );
|
|
flag_init( "shermans_3_dead" );
|
|
flag_init( "shermans_3b_dead" );
|
|
flag_init( "node_sherman_2a_wait_2" );
|
|
flag_init( "last_counterattack_start" );
|
|
|
|
level.current_player_speed = 1.0;
|
|
|
|
level.bunker_mg_damage_total = 0;
|
|
level.force_player_being_targetted = false;
|
|
level.last_tree_attacker = undefined;
|
|
level.ladder_wait_timer = 12000;
|
|
level.guy_going_towards_stairs = false;
|
|
level.last_defend_tanks_killed = 0;
|
|
level.last_defend_axis_killed = 0;
|
|
level.smoke_grenades_on_the_scene = 0;
|
|
level.nextmission_cleanup = maps\pel2_airfield::cleanupFadeoutHud;
|
|
|
|
// setup objectives
|
|
level thread setup_objectives();
|
|
|
|
// do objective skip if using a start
|
|
if( GetDvar( "start" ) != "" )
|
|
{
|
|
setup_objectives_skip();
|
|
}
|
|
|
|
// threatbias group setups
|
|
createthreatbiasgroup( "heroes" );
|
|
createthreatbiasgroup( "mangrove_extra_redshirt" );
|
|
createthreatbiasgroup( "mangrove_ambush_guys" );
|
|
createthreatbiasgroup( "intro_igc_guys" );
|
|
createthreatbiasgroup( "bunker_1_guys" );
|
|
createthreatbiasgroup( "intro_frontline_axis" );
|
|
createthreatbiasgroup( "admin_mg_left_threat_group" );
|
|
createthreatbiasgroup( "outro_mg_guy_threat" );
|
|
|
|
setup_friendlies();
|
|
setup_players();
|
|
|
|
// misc_turret (placed to include all the necessary stuff for bar bipod) can be deleted now
|
|
//getent( "temp_bar_bipod", "targetname" ) delete();
|
|
|
|
/#
|
|
//setsaveddvar("loc_warnings", 0 );
|
|
setdvar( "debug_triggers", "1" );
|
|
setdvar( "debug_character_count", "on" );
|
|
level thread debug_script_flag_trigs_print();
|
|
level thread draw_goal_radius();
|
|
level thread debug_ai_health();
|
|
#/
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Tuey - Sets all of the players Shellshock
|
|
set_player_shock( var1, var2 )
|
|
{
|
|
players = get_players();
|
|
for( i = 0; i < players.size; i++ )
|
|
{
|
|
players[i] Shellshock( var1, var2 );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
setup_players()
|
|
{
|
|
|
|
players = get_players();
|
|
for(i=0;i<players.size;i++)
|
|
{
|
|
// give them a little extra ammo for the colt (80 is the max in the gdt currently...)
|
|
players[i] SetWeaponAmmoStock( "colt", 80 );
|
|
players[i] setthreatbiasgroup( "players" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Entry point into the scripting of the level events
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
start_teleport_players( "orig_start_mangrove", true );
|
|
|
|
players_speed_set( 0.8, 0.1 );
|
|
|
|
battlechatter_off();
|
|
|
|
level.mangrove_extra_redshirt = simple_spawn_single( "mangrove_extra_redshirt", ::mangrove_extra_redshirt_strat );
|
|
level.mangrove_extra_redshirt thread mangrove_extra_redshirt_trap_strat();
|
|
|
|
level thread mangrove_vo_intro();
|
|
|
|
mangrove_intro_positions();
|
|
|
|
// if ( getdvarint("introscreen") != 0 )
|
|
// {
|
|
// intro_wait = 8.25;
|
|
// wait( intro_wait );
|
|
// }
|
|
|
|
wait( 8.25 );
|
|
|
|
mangrove_custom_transitions();
|
|
chain_after_vignette();
|
|
|
|
array_thread( level.heroes, ::set_pacifist_on );
|
|
array_thread( level.heroes, ::set_ignoreme_on );
|
|
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
level.heroes[i].previous_accuracy = level.heroes[i].baseaccuracy;
|
|
level.heroes[i].baseaccuracy = 0.2;
|
|
}
|
|
|
|
maps\_debug::set_event_printname( "Mangroves", true );
|
|
|
|
level thread plane_trap_vignette();
|
|
level thread grenade_vignette();
|
|
level thread bunker_friendlywave();
|
|
level thread bunker_4_47mm();
|
|
|
|
// turn color_chain near end of mangrove section off
|
|
trig = getent( "chain_bunker_1", "targetname" );
|
|
trig trigger_off();
|
|
trig = getent( "chain_bunker_2", "targetname" );
|
|
trig trigger_off();
|
|
|
|
// TUEY Sets the music state to be SWAMP
|
|
setmusicstate("SWAMP");
|
|
|
|
bunkers();
|
|
|
|
}
|
|
|
|
|
|
mangrove_intro_positions()
|
|
{
|
|
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
goal_node = getnode( level.heroes[i].target, "targetname" );
|
|
level.heroes[i] setgoalnode( goal_node );
|
|
level.heroes[i] thread enable_cqbwalk();
|
|
level.heroes[i].moveplaybackrate = 0.75;
|
|
}
|
|
|
|
goal_node = getnode( level.mangrove_extra_redshirt.target, "targetname" );
|
|
level.mangrove_extra_redshirt setgoalnode( goal_node );
|
|
level.mangrove_extra_redshirt thread enable_cqbwalk();
|
|
level.mangrove_extra_redshirt.moveplaybackrate = 0.75;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// pathing for guys throughout the mangroves
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove_custom_transitions()
|
|
{
|
|
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
level.heroes[i] thread mangrove_custom_transitions_delay();
|
|
}
|
|
|
|
level.mangrove_extra_redshirt thread mangrove_custom_transitions_delay();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// so they don't play their overridden exit transition for their very first movement after the introscreen fades away
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove_custom_transitions_delay()
|
|
{
|
|
wait( 2 );
|
|
self set_custom_approach_fields();
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// denny's setup for custom arrival/exit transitions
|
|
//
|
|
///////////////////////////////
|
|
|
|
set_custom_approach_fields()
|
|
{
|
|
|
|
//self.custom_approachType = "custom_exposed";
|
|
//self.custom_approachNumber = 0;
|
|
self.custom_approachanimrate = 0.75;
|
|
|
|
self.custom_exitType = "custom_exposed";
|
|
self.custom_exitNumber = 0;
|
|
self.custom_exitanimrate = 0.75;
|
|
|
|
}
|
|
|
|
|
|
|
|
clear_custom_approach_fields()
|
|
{
|
|
|
|
self.custom_approachType = undefined;
|
|
self.custom_approachNumber = undefined;
|
|
self.custom_exitType = undefined;
|
|
self.custom_exitNumber = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Send squad to nodes after introscreen and branch pushing anim
|
|
//
|
|
///////////////////////////////
|
|
|
|
chain_after_vignette()
|
|
{
|
|
|
|
goal_node = getnode( "node_intro_polonsky", "script_noteworthy" );
|
|
level.polonsky setgoalnode( goal_node );
|
|
|
|
goal_node = getnode( "node_intro_roebuck", "script_noteworthy" );
|
|
level.roebuck setgoalnode( goal_node );
|
|
|
|
goal_node = getnode( "node_intro_extra_hero", "script_noteworthy" );
|
|
level.extra_hero setgoalnode( goal_node );
|
|
|
|
goal_node = getnode( "node_intro_extra_redshirt", "script_noteworthy" );
|
|
level.mangrove_extra_redshirt setgoalnode( goal_node );
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_vo_intro()
|
|
{
|
|
|
|
level thread mangrove_vo_trap();
|
|
level thread mangrove_vo_2();
|
|
level thread mangrove_vo_3();
|
|
|
|
wait( 4 );
|
|
|
|
play_vo( level.roebuck, "vo", "arrangements" );
|
|
wait( 3.1 );
|
|
play_vo( level.polonsky, "vo", "i_though_sullivan" );
|
|
wait( 2.75 );
|
|
play_vo( level.roebuck, "vo", "we_let_our_guard" );
|
|
wait( 4 );
|
|
play_vo( level.polonsky, "vo", "so_what_now" );
|
|
wait( 2.5 );
|
|
play_vo( level.roebuck, "vo", "tojos_gotta_tight" );
|
|
wait( 4 );
|
|
play_vo( level.roebuck, "vo", "direct_route" );
|
|
wait( 3.35 );
|
|
play_vo( level.roebuck, "vo", "we_take_the_flank" );
|
|
wait( 7.25 );
|
|
play_vo( level.roebuck, "vo", "stay_sharp" );
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_vo_trap()
|
|
{
|
|
|
|
flag_wait( "trig_mangrove_trap" );
|
|
|
|
wait( 2 );
|
|
|
|
// VO: poor bastard must've been shot down this morning
|
|
play_vo( level.polonsky, "vo", "poor_bastard" );
|
|
wait( 3 );
|
|
play_vo( level.roebuck, "vo", "fuselage_smoking" );
|
|
|
|
wait( 4.25 );
|
|
|
|
//TUEY Had to move this notify because the grenade click and roll was not working properly anymore.
|
|
level notify ("trap_sprung");
|
|
|
|
wait( 4 );
|
|
|
|
flag_set( "mangrove_click_sound" );
|
|
|
|
|
|
|
|
flag_set( "corsair_trap_about_to_explode" ); // only set if the vignette plays out; not if the player forces the trap by running ahead
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
|
|
play_vo( level.roebuck, "vo", "booby_trap!!!" );
|
|
wait( 1.25 );
|
|
play_vo( level.polonsky, "vo", "shit!!!" );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_vo_2()
|
|
{
|
|
|
|
flag_wait( "mangrove_ambush_guys_2" );
|
|
|
|
wait( RandomFloatRange( 1.5, 2.25 ) );
|
|
|
|
play_vo( level.roebuck, "vo", "ambush!!!" );
|
|
|
|
wait( RandomFloatRange( 2.1, 2.5 ) );
|
|
|
|
play_vo( level.roebuck, "vo", "keep_em_back" );
|
|
|
|
wait( RandomFloatRange( 1.75, 2.0 ) );
|
|
|
|
play_vo( level.polonsky, "vo", "it_was_a_trap" );
|
|
|
|
}
|
|
|
|
|
|
mangrove_vo_3()
|
|
{
|
|
|
|
flag_wait( "trig_mangrove_grenades" );
|
|
|
|
play_vo( level.polonsky, "vo", "were_kinda_late" );
|
|
wait( 3.5 );
|
|
|
|
flag_wait( "trig_mangrove_grenades" );
|
|
|
|
play_vo( level.roebuck, "vo", "mgs_in_the_bunkers" );
|
|
wait( 5 );
|
|
|
|
flag_wait( "get_a_grenade_vo" );
|
|
|
|
play_vo( level.roebuck, "vo", "get_a_grenade_up" );
|
|
|
|
flag_wait( "mangrove_grenades_exploded" );
|
|
|
|
wait( 0.5 );
|
|
play_vo( level.roebuck, "vo", "everyone_move" );
|
|
wait( 1.7 );
|
|
play_vo( level.roebuck, "vo", "go_go" );
|
|
//wait( 3 );
|
|
//play_vo( level.roebuck, "vo", "take_out_those_mgs" );
|
|
|
|
}
|
|
|
|
|
|
bunkers_vo()
|
|
{
|
|
|
|
flag_wait( "trig_bunkers_paths_vo" );
|
|
|
|
play_vo( level.roebuck, "vo", "down_both_flanks" );
|
|
wait( 3.5 );
|
|
play_vo( level.roebuck, "vo", "carve_a_path" );
|
|
|
|
flag_wait( "flamer_at_first_advance_node" );
|
|
|
|
play_vo( level.polonsky, "vo", "flame_moving_up" );
|
|
wait( 2 );
|
|
play_vo( level.roebuck, "vo", "give_em_covering" );
|
|
|
|
wait( RandomIntRange( 4, 7 ) );
|
|
|
|
play_vo( level.roebuck, "vo", "stay_on_them" );
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_ambush_beat_2()
|
|
{
|
|
|
|
level thread mangrove_ambush_beat_2_timeout();
|
|
|
|
// flag set on trigger
|
|
flag_wait( "mangrove_ambush_guys_2" );
|
|
|
|
wait( 0.25 );
|
|
|
|
simple_spawn( "mangrove_ambush_guys_2b", ::mangrove_ambush_guys_2b_strat );
|
|
|
|
level thread mangrove_ambush_2_heroes_sneak();
|
|
level thread post_trap_chain_2();
|
|
|
|
wait( 1.9 );
|
|
|
|
simple_spawn( "mangrove_ambush_guys_2a", ::mangrove_ambush_guys_2a_strat );
|
|
|
|
wait_network_frame();
|
|
|
|
// piggybacking this here to save a trigger enty
|
|
// spawn first AT47
|
|
maps\_vehicle::scripted_spawn( 24 );
|
|
|
|
level thread battle_line_ambient_sound();
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_ambush_beat_2_timeout()
|
|
{
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
wait( RandomIntRange( 12, 14 ) );
|
|
|
|
trig = getent( "trig_mangrove_ambush_guys_2", "script_noteworthy" );
|
|
// it may have been hit if player rushes up
|
|
if( isdefined( trig ) )
|
|
{
|
|
trig notify( "trigger" );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_ambush_beat_3()
|
|
{
|
|
|
|
flag_wait( "mangrove_ambush_guys_2" );
|
|
|
|
simple_spawn( "mangrove_ambush_guys_3", ::mangrove_ambush_guys_3_strat );
|
|
|
|
flag_wait( "mangrove_ambush_guys_3" );
|
|
|
|
level thread mangrove_ambush_2_heroes_sneak_2();
|
|
|
|
level thread post_trap_chain_3();
|
|
|
|
wait( RandomFloatRange( 0.35, 0.65 ) );
|
|
|
|
play_vo( level.polonsky, "vo", "another_ambush" );
|
|
|
|
/////////
|
|
simple_spawn( "intro_igc_friendlies", ::intro_igc_friendlies_strat );
|
|
// have bunker_1_guys ignore intro_igc_guys
|
|
setignoremegroup( "intro_igc_guys", "bunker_1_guys" );
|
|
/////////
|
|
|
|
wait( RandomFloatRange( 2.3, 3.2 ) );
|
|
|
|
play_vo( level.polonsky, "vo", "theyre_all_around" );
|
|
|
|
wait( RandomFloatRange( 1.75, 2.0 ) );
|
|
|
|
play_vo( level.roebuck, "vo", "keep_it_tight" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Move heroes up after ambush enemies have been cleared
|
|
//
|
|
///////////////////////////////
|
|
|
|
post_trap_chain_1()
|
|
{
|
|
|
|
waittill_aigroupcleared( "mangrove_ambush_ai" );
|
|
|
|
flag_set( "mangrove_ambush_ai_dead" );
|
|
|
|
objective_position( 1, ( 2562, -13802, -135 ) );
|
|
|
|
wait_network_frame(); // let objective clear the network.
|
|
|
|
level thread battlechatter_off();
|
|
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
level.heroes[i].baseaccuracy = level.heroes[i].previous_accuracy;
|
|
}
|
|
|
|
trig = getent( "trig_chain_post_trap_1", "targetname" );
|
|
if( isdefined( trig ) )
|
|
{
|
|
trig notify( "trigger" );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
post_trap_chain_2()
|
|
{
|
|
|
|
// notify comes from flag on trigger
|
|
level endon( "trig_mangrove_grenades" );
|
|
|
|
waittill_aigroupcleared( "mangrove_ambush_ai_2" );
|
|
|
|
// move up friendlies
|
|
trig = getent( "trig_chain_post_trap_2", "targetname" );
|
|
if( isdefined( trig ) )
|
|
{
|
|
trig notify( "trigger" );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
post_trap_chain_3()
|
|
{
|
|
|
|
// notify from flag set on trigger
|
|
level endon( "trig_mangrove_grenades" );
|
|
|
|
waittill_aigroupcleared( "mangrove_ambush_ai_3" );
|
|
|
|
level.roebuck enable_ai_color();
|
|
set_color_chain( "chain_post_trap_3" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Have heroes creep forward just a bit before the 2nd beat of mangrove ambush
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove_ambush_2_heroes_sneak()
|
|
{
|
|
|
|
// have friendlies walk forward slightly
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
level.heroes[i] setgoalpos( (2944.5, -14091, -129) );
|
|
}
|
|
|
|
wait( 2 );
|
|
|
|
// then stop them so they can engage the enemy
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
level.heroes[i] setgoalpos( level.heroes[i].origin );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Have heroes creep forward just a bit before the 3rd beat of mangrove ambush
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove_ambush_2_heroes_sneak_2()
|
|
{
|
|
|
|
// polonsky_goal_pos = (2675, -13797, -129);
|
|
// roebuck_goal_pos = (2477, -13954, -129);
|
|
// extra_hero_goal_pos = (2607, -13967, -129);
|
|
|
|
node_polonksy = getnode( "node_sneak_2_polonsky", "targetname" );
|
|
node_roebuck = getnode( "node_sneak_2_roebuck", "targetname" );
|
|
node_extra_hero = getnode( "node_sneak_2_extra_hero", "targetname" );
|
|
|
|
// have friendlies walk forward slightly
|
|
level.polonsky setgoalnode( node_polonksy );
|
|
level.roebuck setgoalnode( node_roebuck );
|
|
level.extra_hero setgoalnode( node_extra_hero );
|
|
|
|
wait( 1.75 );
|
|
|
|
// then stop them so they can engage the enemy
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
if( level.heroes[i] == level.roebuck )
|
|
{
|
|
goal_node = getnode( "node_ambush_beat_3_roebuck", "targetname" );
|
|
level.roebuck disable_ai_color();
|
|
level.roebuck setgoalnode( goal_node );
|
|
}
|
|
else
|
|
{
|
|
level.heroes[i] setgoalpos(level.heroes[i].origin );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_ambush_guys_2a_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self toggleik( false );
|
|
self.ignoreme = true;
|
|
self.ignoresuppression = true;
|
|
|
|
wait( 1.5 + RandomFloat( 0.5 ) );
|
|
|
|
self.ignoreme = false;
|
|
|
|
// if they're just standing at their goal node firing, banzai charage after a little bit
|
|
if( isdefined( self.script_noteworthy ) && self.script_noteworthy == "late_banzai" )
|
|
{
|
|
|
|
wait( 2.25 + RandomFloat( 1 ) );
|
|
|
|
self thread guzzo_print_3d( "late banzai!" );
|
|
|
|
self.banzai_no_wait = 1;
|
|
self.ignoresuppression = 1;
|
|
self.script_max_banzai_distance = 2000;
|
|
self thread maps\_banzai::banzai_force();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_ambush_guys_2b_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self.ignoreme = 1;
|
|
|
|
self.banzai_no_wait = 1;
|
|
self.grenadeawareness = 0;
|
|
self.ignoresuppression = 1;
|
|
self.script_max_banzai_distance = 2000;
|
|
|
|
self thread guzzo_print_3d( "banzai!" );
|
|
|
|
self thread maps\_banzai::banzai_force();
|
|
|
|
wait( 1.75 + RandomFloat( 0.5 ) );
|
|
|
|
self.ignoreme = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Ally from other squad that is at the bend before the corsair crash
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove_bend_guy()
|
|
{
|
|
|
|
bend_guy = simple_spawn_single( "friend_trap_pre_spawner" );
|
|
bend_guy.animname = "stand";
|
|
|
|
bend_guy endon( "death" );
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
|
|
bend_guy.deathanim = level.scr_anim["stand"]["explode_stand_2"];
|
|
bend_guy dodamage( bend_guy.health + 1, (0,0,0) );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Update the objective position in the mangroves
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_friendlywave()
|
|
{
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_bunker_friendlywave" );
|
|
objective_position( 1, ( 2721, -12187, -120.7 ) );
|
|
|
|
autosave_by_name( "Pel2 before ambush 3" );
|
|
|
|
// play vo only if 2nd ambush guys are dead
|
|
ambush_beat_2_guys = get_ai_group_ai( "mangrove_ambush_ai_2" );
|
|
if( !ambush_beat_2_guys.size )
|
|
{
|
|
wait( randomfloatrange( 0.6, 1.1 ) );
|
|
play_vo( level.polonsky, "vo", "cant_believe_theyd" );
|
|
}
|
|
|
|
wait_network_frame();
|
|
|
|
level thread bunker_1_mgs();
|
|
|
|
}
|
|
|
|
|
|
|
|
plane_trap_vignette()
|
|
{
|
|
|
|
level thread mangrove_bend_guy();
|
|
level thread plane_trap_fx();
|
|
level thread mangrove_ambush_beat_2();
|
|
level thread mangrove_ambush_beat_3();
|
|
|
|
flag_wait( "trig_setup_trap" );
|
|
|
|
simple_spawn_single( "friend_trap_spawner_extra", ::friend_trap_spawner_extra_strat );
|
|
|
|
level thread trap_checkers();
|
|
// DEMO off
|
|
//level thread mangrove_walk();
|
|
level thread plane_trap_pilot();
|
|
|
|
wait_network_frame(); // CLIENTSIDE to help snapshot size
|
|
|
|
simple_spawn( "mangrove_ambush_guys", ::mangrove_ambush_guys_strat );
|
|
|
|
// wait till player is nearby (flag set on trigger)
|
|
flag_wait( "trig_mangrove_trap" );
|
|
|
|
level thread mangrove_ambush_timer();
|
|
|
|
// if the vignette plays out or if the player triggers the 2nd group of ambush guys by running ahead
|
|
flag_wait_either( "mangrove_ambush", "mangrove_ambush_guys_2" );
|
|
|
|
flag_set( "mangrove_ambush" );
|
|
|
|
// TUEY Sets the music state to be AMBUSHED
|
|
setmusicstate("AMBUSHED");
|
|
|
|
battlechatter_on();
|
|
|
|
set_color_chain( "trig_chain_trap_react" );
|
|
|
|
level thread post_trap_chain_1();
|
|
|
|
array_thread( level.heroes, ::set_pacifist_off );
|
|
wait( 1 ); // wait a bit so they target the redshirts first
|
|
array_thread( level.heroes, ::set_ignoreme_off );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_ambush_timer()
|
|
{
|
|
|
|
level endon( "mangrove_ambush_guys_2" );
|
|
wait( 12.5 );
|
|
flag_set( "mangrove_ambush" );
|
|
|
|
}
|
|
|
|
|
|
|
|
trap_checkers()
|
|
{
|
|
|
|
helper = simple_spawn_single( "friend_trap_ai_helper", ::trap_checker_strat );
|
|
checker = simple_spawn_single( "friend_trap_ai_checker", ::trap_checker_strat );
|
|
|
|
helper.animname = "trap_react_redshirt_1_idle";
|
|
checker.animname = "trap_react_redshirt_2_idle";
|
|
|
|
anim_node = getstruct( "node_anim_trap", "targetname" );
|
|
|
|
// their idle anims, before the player gets close
|
|
level thread anim_loop_solo( helper, "mangrove_trap", undefined, "stop_mangrove_trap_loop", anim_node );
|
|
level thread anim_loop_solo( checker, "mangrove_trap", undefined, "stop_mangrove_trap_loop", anim_node );
|
|
|
|
flag_wait( "trig_mangrove_trap" );
|
|
|
|
helper.animname = "trap_react_redshirt_1";
|
|
checker.animname = "trap_react_redshirt_2";
|
|
|
|
anim_guys = [];
|
|
anim_guys[0] = helper;
|
|
anim_guys[1] = checker;
|
|
|
|
level thread anim_single( anim_guys, "mangrove_trap", undefined, undefined, anim_node );
|
|
|
|
// in case the trap goes off early because the player rushed ahead
|
|
flag_wait( "mangrove_ambush_guys_2" );
|
|
|
|
if( !flag( "corsair_trap_about_to_explode" ) )
|
|
{
|
|
|
|
for( i = 0; i < anim_guys.size; i++ )
|
|
{
|
|
|
|
if( isdefined( anim_guys[i] ) && isalive( anim_guys[i] ) )
|
|
{
|
|
anim_guys[i] notify( "killanimscript" );
|
|
anim_guys[i].animname = "stand";
|
|
anim_guys[i].deathanim = level.scr_anim["stand"]["explode_back13"];
|
|
anim_guys[i] dodamage( anim_guys[i].health + 1, (0,0,0) );
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
trap_checker_strat()
|
|
{
|
|
self.ignoreall = true;
|
|
}
|
|
|
|
|
|
|
|
plane_trap_fx()
|
|
{
|
|
|
|
orig = getstruct( "orig_trap_explode", "targetname" );
|
|
temp_orig = spawn( "script_origin", orig.origin );
|
|
level thread plane_trap_click_fx( temp_orig );
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
|
|
// redundant click flag... in the case player rushes ahead, we still hear the click
|
|
flag_set( "mangrove_click_sound" );
|
|
|
|
// fx exploder
|
|
exploder( 100 );
|
|
|
|
temp_orig playsound( "mangrove_explo" );
|
|
earthquake( 0.65, 2.4, orig.origin , 1300 );
|
|
PlayRumbleOnPosition( "explosion_generic", orig.origin );
|
|
radiusdamage( orig.origin, 260, 90, 55 );
|
|
|
|
// shellshock them if they're close enough
|
|
players = get_players();
|
|
for( i = 0; i < players.size; i++ )
|
|
{
|
|
if( distanceSquared( players[i].origin, orig.origin ) < (270*270) )
|
|
{
|
|
players[i] shellshock( "default", 1.75 );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
plane_trap_click_fx( temp_orig )
|
|
{
|
|
// flag set on trigger
|
|
//flag_wait( "mangrove_click_sound" );
|
|
|
|
level waittill ("trap_sprung");
|
|
wait(1.5);
|
|
temp_orig playsound("ambush_click");
|
|
|
|
//playsoundatposition( "ambush_click", (0,0,0));
|
|
}
|
|
|
|
|
|
|
|
#using_animtree( "generic_human" );
|
|
plane_trap_pilot()
|
|
{
|
|
|
|
orig = getstruct( "orig_plane_trap_pilot", "targetname" );
|
|
|
|
pilot = spawn( "script_model", orig.origin );
|
|
pilot.angles = orig.angles;
|
|
pilot character\char_usa_pbycrew_pel2_gunner::main();
|
|
pilot UseAnimTree( #animtree );
|
|
pilot.animname = "mangrove_trap";
|
|
pilot.targetname = "script_pilot";
|
|
|
|
anim_node = getstruct( "node_anim_trap", "targetname" );
|
|
|
|
level thread anim_loop_solo( pilot, "trap_idle_pilot", undefined, "mangrove_ambush_pre", anim_node );
|
|
|
|
flag_wait( "trig_mangrove_trap" );
|
|
|
|
level thread anim_single_solo( pilot, "trap_death_pilot", undefined, anim_node );
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
|
|
wait( 0.1 );
|
|
|
|
pilot delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_extra_redshirt_strat()
|
|
{
|
|
|
|
self.pacifist = true;
|
|
self.pacifistwait = 0.05;
|
|
self.ignoreme = true;
|
|
self.ignoreall = true;
|
|
self.goalradius = 400;
|
|
|
|
self setthreatbiasgroup( "mangrove_extra_redshirt" );
|
|
|
|
}
|
|
|
|
|
|
|
|
mangrove_extra_redshirt_trap_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
//self thread delay_mangrove_walk();
|
|
|
|
flag_wait( "trig_extra_redshirt_trap_strat" );
|
|
|
|
self allowedstances( "stand" );
|
|
|
|
self disable_ai_color();
|
|
goal_node = getnode( "node_extra_redshirt_trap", "targetname" );
|
|
self setgoalnode( goal_node );
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
|
|
self.animname = "mangrove_trap";
|
|
|
|
self.baseaccuracy = 0.05;
|
|
self.pacifist = 0;
|
|
self.ignoreme = 0;
|
|
self.ignoreall = 0;
|
|
|
|
if( distance( self.origin, goal_node.origin ) < 50 )
|
|
{
|
|
self allowedstances( "crouch" );
|
|
anim_single_solo( self, "trap_react_redshirt_kneel", undefined, self );
|
|
}
|
|
else
|
|
{
|
|
println( "mangrove_extra_redshirt isn't playing reaction anim cuz he was too far from his goal node!" );
|
|
}
|
|
|
|
wait( RandomFloatRange( 2.5, 3.0 ) );
|
|
|
|
if( isalive( self ) )
|
|
{
|
|
self thread bloody_death( true );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Strategy for enemy ai that ambush out of the trees/foliage near the plane
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove_ambush_guys_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self thread magic_bullet_shield();
|
|
self setcandamage( false );
|
|
old_sight = self.maxSightDistSqrd;
|
|
self.maxSightDistSqrd = 0;
|
|
self.grenadeawareness = 0;
|
|
self.ignoreall = 1;
|
|
self.ignoresuppression = 1;
|
|
self.ignoreme = 1;
|
|
self.pacifist = 1;
|
|
self.pacifistwait = 0.05;
|
|
self.activatecrosshair = false;
|
|
self.drawoncompass = false;
|
|
self disableaimassist();
|
|
self toggleik( false );
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
|
|
self setcandamage( true );
|
|
self stop_magic_bullet_shield();
|
|
|
|
wait( RandomFloatRange( 0.5, 1.25 ) );
|
|
|
|
self.activatecrosshair = true;
|
|
self enableaimassist();
|
|
self.drawoncompass = true;
|
|
self.maxSightDistSqrd = old_sight;
|
|
self.ignoreall = 0;
|
|
self.pacifist = 0;
|
|
|
|
self setthreatbiasgroup( "mangrove_ambush_guys" );
|
|
|
|
// have mangrove_ambush_guys pay more attention to mangrove_extra_redshirt
|
|
setthreatbias( "mangrove_extra_redshirt", "mangrove_ambush_guys", 30000 );
|
|
|
|
if( self.script_noteworthy == "mangrove_banzai" )
|
|
{
|
|
self.banzai_no_wait = 1;
|
|
self.script_max_banzai_distance = 2000;
|
|
self thread maps\_banzai::banzai_force();
|
|
wait( 2.5 );
|
|
self.ignoreme = 0;
|
|
}
|
|
else
|
|
{
|
|
goal_node = getnode( self.script_noteworthy, "targetname" );
|
|
self setgoalnode( goal_node );
|
|
|
|
wait( 1.5 );
|
|
self.ignoreme = 0;
|
|
|
|
if( isdefined( goal_node.target ) )
|
|
{
|
|
wait( goal_node.script_delay );
|
|
new_goal_node = getnode( goal_node.target, "targetname" );
|
|
self setgoalnode( new_goal_node );
|
|
|
|
self waittill( "goal" );
|
|
|
|
wait( RandomFloatRange( 1.0, 2.0 ) );
|
|
|
|
self.banzai_no_wait = 1;
|
|
self.script_max_banzai_distance = 2000;
|
|
self thread maps\_banzai::banzai_force();
|
|
|
|
}
|
|
// guy that is up on the mound near the corsair will charge eventually
|
|
else if( self.script_noteworthy == "auto5301" )
|
|
{
|
|
flag_wait_or_timeout( "mangrove_ambush_guys_2", 10 );
|
|
|
|
self.goalradius = 50;
|
|
goal_node = getnode( "auto5699", "targetname" );
|
|
self setgoalnode( goal_node );
|
|
self waittill( "goal" );
|
|
|
|
self.banzai_no_wait = 1;
|
|
self.script_max_banzai_distance = 2000;
|
|
self thread maps\_banzai::banzai_force();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Strategy for enemy ai that ambush out of the trees/foliage near the plane
|
|
//
|
|
///////////////////////////////
|
|
|
|
mangrove_ambush_guys_3_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self thread magic_bullet_shield();
|
|
self setcandamage( false );
|
|
old_sight = self.maxSightDistSqrd;
|
|
self.maxSightDistSqrd = 0;
|
|
self.grenadeawareness = 0;
|
|
self.ignoreall = 1;
|
|
self.ignoresuppression = 1;
|
|
self.ignoreme = 1;
|
|
self.pacifist = 1;
|
|
self.pacifistwait = 0.05;
|
|
self.activatecrosshair = false;
|
|
self.drawoncompass = false;
|
|
self disableaimassist();
|
|
self toggleik( false );
|
|
|
|
flag_wait( "mangrove_ambush_guys_3" );
|
|
|
|
self setcandamage( true );
|
|
self stop_magic_bullet_shield();
|
|
|
|
self.activatecrosshair = true;
|
|
self enableaimassist();
|
|
self.drawoncompass = true;
|
|
self.maxSightDistSqrd = old_sight;
|
|
self.ignoreall = 0;
|
|
self.pacifist = 0;
|
|
|
|
goal_node = getnode( self.script_noteworthy, "targetname" );
|
|
self setgoalnode( goal_node );
|
|
|
|
wait( 1.5 );
|
|
self.ignoreme = 0;
|
|
|
|
wait( RandomFloatRange( 5.25, 9.0 ) );
|
|
|
|
self.banzai_no_wait = 1;
|
|
self.script_max_banzai_distance = 2000;
|
|
self thread maps\_banzai::banzai_force();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Guy that is nearby plane but doesn't play an anim in the vignette
|
|
//
|
|
///////////////////////////////
|
|
|
|
friend_trap_spawner_extra_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
// for some reason he is killed when arriving upon the scene.
|
|
// it's likely that enemy ai are firing in their first frame, before being set to pacifist
|
|
self.health = self.health + 150;
|
|
|
|
old_sight = self.maxSightDistSqrd;
|
|
self.maxSightDistSqrd = 0;
|
|
self.ignoreall = true;
|
|
self.pacifist = true;
|
|
self.ignoreme = true;
|
|
old_pacifist = self.pacifistwait;
|
|
self.pacifistwait = 0.05;
|
|
self.animname = "mangrove_trap";
|
|
|
|
flag_wait( "mangrove_ambush" );
|
|
|
|
anim_single_solo( self, "trap_react_redshirt_fall_down", undefined, self );
|
|
|
|
self.maxSightDistSqrd = old_sight;
|
|
self.ignoreme = false;
|
|
self.ignoreall = false;
|
|
self.pacifist = false;
|
|
self.pacifistwait = old_pacifist;
|
|
self.baseaccuracy = 0.05;
|
|
|
|
self.health = 10;
|
|
|
|
goal_node = getnode( self.script_noteworthy, "targetname" );
|
|
self setgoalnode( goal_node );
|
|
|
|
wait( RandomFloatRange( 3.5, 4.75 ) );
|
|
|
|
if( isalive( self ) )
|
|
{
|
|
self thread bloody_death( true );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Secondary squad takes cover and throws grenades at the at74
|
|
//
|
|
///////////////////////////////
|
|
|
|
grenade_vignette()
|
|
{
|
|
|
|
flag_wait( "trig_mangrove_grenades" );
|
|
|
|
wait_network_frame();
|
|
|
|
set_color_heroes( "b" );
|
|
set_color_chain( "trig_chain_post_trap_4" );
|
|
|
|
guys = simple_spawn( "friend_bunker_spawner", ::friend_bunker_strat );
|
|
assertex( guys.size == 3, "grenade throwers != 3" );
|
|
|
|
guys[0].animname = "gren_throw_1_in";
|
|
guys[1].animname = "gren_throw_2_in";
|
|
guys[2].animname = "gren_throw_3_in";
|
|
|
|
goal_node = getnode( "node_mangrove_align", "targetname" );
|
|
|
|
anim_single( guys, "mangrove_grenades_in", undefined, undefined, goal_node );
|
|
|
|
guys[0].animname = "gren_throw_1_wait";
|
|
guys[1].animname = "gren_throw_2_wait";
|
|
guys[2].animname = "gren_throw_3_wait";
|
|
|
|
level thread anim_loop( guys, "mangrove_grenades_wait", undefined, "mangrove_grenades", goal_node );
|
|
|
|
flag_set( "all_grenaders_in_place" );
|
|
|
|
event_text( "in place. waiting to regroup nearby" );
|
|
|
|
regroup_trig = getent( "trig_near_grenaders", "targetname" );
|
|
|
|
level thread gren_lookat_override();
|
|
|
|
// wait till player is back with squad near sandbags
|
|
while( 1 )
|
|
{
|
|
if( any_player_IsTouching( regroup_trig ) || flag( "mangrove_gren_lookat" ) || flag( "trig_box_carry" ) ) // added trig_box_carry in case they run forward, create chaos, then sprint back
|
|
{
|
|
break;
|
|
}
|
|
|
|
wait( 0.15 );
|
|
}
|
|
|
|
flag_set( "get_a_grenade_vo" );
|
|
|
|
level notify( "mangrove_grenades" );
|
|
|
|
guys[0].animname = "gren_throw_1_out";
|
|
guys[1].animname = "gren_throw_2_out";
|
|
guys[2].animname = "gren_throw_3_out";
|
|
|
|
guys[0] disable_arrivals( true, true );
|
|
guys[0] thread delay_grenade_vignette_arrivals();
|
|
guys[1] disable_arrivals( true, true );
|
|
guys[1] thread delay_grenade_vignette_arrivals();
|
|
guys[2] disable_arrivals( true, true );
|
|
guys[2] thread delay_grenade_vignette_arrivals();
|
|
|
|
// level thread grenade_vignette_temp_hack( guys[0], level.scr_anim["gren_throw_1_out"]["mangrove_grenades_out"] );
|
|
// level thread grenade_vignette_temp_hack( guys[1], level.scr_anim["gren_throw_2_out"]["mangrove_grenades_out"] );
|
|
// level thread grenade_vignette_temp_hack( guys[2], level.scr_anim["gren_throw_3_out"]["mangrove_grenades_out"] );
|
|
// level thread anim_single( guys, "mangrove_grenades_out", undefined, undefined, goal_node );
|
|
level thread anim_single_earlyout( guys, "mangrove_grenades_out", undefined, undefined, goal_node, undefined, 0.25 );
|
|
|
|
flag_wait( "mangrove_grenades_thrown" );
|
|
event_text( "mangrove_grenades_thrown" );
|
|
|
|
grenade_vignette_post();
|
|
|
|
}
|
|
|
|
|
|
|
|
delay_grenade_vignette_arrivals()
|
|
{
|
|
|
|
flag_wait( "mangrove_grenades_thrown" );
|
|
wait( 10 );
|
|
self disable_arrivals( false, false );
|
|
|
|
}
|
|
|
|
|
|
// TEMP for debug purposes only
|
|
//grenade_vignette_temp_hack( guy, anime )
|
|
//{
|
|
// /#
|
|
// animtime = getanimlength( anime );
|
|
//
|
|
// animtime -= 0.05;
|
|
// wait(animtime);
|
|
//
|
|
// guy stopanimscripted();
|
|
// #/
|
|
//
|
|
//}
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// after the grenade vignette, move up both groups of guys for the bunker battle
|
|
//
|
|
///////////////////////////////
|
|
|
|
grenade_vignette_post()
|
|
{
|
|
|
|
set_players_ignoreme( false );
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
// get color reinforcements going...
|
|
trig = getent( "trigger_bunker_wave_1", "script_noteworthy" );
|
|
trig notify( "trigger" );
|
|
|
|
// wait for grenade throws
|
|
wait( 1.75 );
|
|
|
|
flag_set( "mangrove_grenades_exploded" );
|
|
|
|
battlechatter_on();
|
|
|
|
// kill at47 guys if they survived the grenades
|
|
kill_aigroup( "bunker_gun_4_ai" );
|
|
|
|
// make squad active again
|
|
array_thread( level.heroes, ::set_pacifist_off );
|
|
array_thread( level.heroes, ::set_ignoreme_off );
|
|
|
|
// turn nearby color_chain back on
|
|
trig = getent( "chain_bunker_1", "targetname" );
|
|
trig trigger_on();
|
|
trig = getent( "chain_bunker_2", "targetname" );
|
|
trig trigger_on();
|
|
|
|
// move guys up out of mangrove swamp
|
|
set_color_chain( "trig_chain_bunkers" );
|
|
|
|
autosave_by_name( "Pel2 grenade vignette post" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// player can look at grenaders to start the vignette even if he isn't close enough
|
|
//
|
|
///////////////////////////////
|
|
|
|
gren_lookat_override()
|
|
{
|
|
trig = getent( "trig_mangrove_gren_lookat", "targetname" );
|
|
trig waittill( "trigger" );
|
|
|
|
flag_set( "mangrove_gren_lookat" );
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Strategy for squad that joins up with the player near the end of the mangrove swamp
|
|
//
|
|
///////////////////////////////
|
|
|
|
friend_bunker_strat()
|
|
{
|
|
|
|
self thread magic_bullet_shield();
|
|
self.ignoreme = true;
|
|
self.ignoreall = true;
|
|
self.pacifist = true;
|
|
self.animname = "mangrove";
|
|
self.goalradius = 50;
|
|
|
|
self.disableexits = true;
|
|
self.disablearrivals = true;
|
|
|
|
self disable_ai_color();
|
|
|
|
flag_wait( "all_grenaders_in_place" );
|
|
|
|
self.ignoreme = false;
|
|
self.ignoreall = false;
|
|
self.pacifist = false;
|
|
|
|
flag_wait( "mangrove_grenades_exploded" );
|
|
|
|
self set_force_color( "b" );
|
|
self thread replace_on_death();
|
|
self.allowdeath = true;
|
|
self stop_magic_bullet_shield();
|
|
|
|
self endon( "death" );
|
|
|
|
wait( 3 );
|
|
|
|
self.disableexits = false;
|
|
self.disablearrivals = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Anim vignette of enemies carrying an ammo box
|
|
//
|
|
///////////////////////////////
|
|
|
|
box_carry()
|
|
{
|
|
|
|
level endon( "box_carry_stop" );
|
|
|
|
box_guy_health = 30;
|
|
|
|
////// set up guys
|
|
guy_box_host = simple_spawn_single( "guy_box_host" );
|
|
guy_box_host.allowdeath = true;
|
|
guy_box_host.ignoreall = true;
|
|
guy_box_host.animname = "carry_box_host";
|
|
guy_box_host.deathanim = level.scr_anim["carry_box_host"]["carry_box_host_death"];
|
|
guy_box_host.health = box_guy_health;
|
|
guy_box_host animscripts\shared::placeWeaponOn( guy_box_host.primaryweapon, "none");
|
|
guy_box_host thread box_carry_damage();
|
|
|
|
guy_box_host thread box_carry_drop();
|
|
|
|
guy_box_helper = simple_spawn_single( "guy_box_helper" );
|
|
guy_box_helper.allowdeath = true;
|
|
guy_box_helper.ignoreall = true;
|
|
guy_box_helper.animname = "carry_box_helper";
|
|
guy_box_helper.deathanim = level.scr_anim["carry_box_helper"]["carry_box_helper_death"];
|
|
guy_box_helper.health = box_guy_health;
|
|
guy_box_helper animscripts\shared::placeWeaponOn( guy_box_helper.primaryweapon, "none");
|
|
guy_box_helper thread box_carry_damage();
|
|
|
|
carrier_guys = [];
|
|
carrier_guys[0] = guy_box_host;
|
|
carrier_guys[1] = guy_box_helper;
|
|
///////////////////////////////////
|
|
|
|
////// set up box
|
|
guy_box_host attach( "static_peleliu_crate_jpn_clsd_char", "tag_weapon_left" );
|
|
|
|
carry_node = getnode( "node_carry", "targetname" );
|
|
anim_single( carrier_guys, "carry_box", undefined, carry_node );
|
|
|
|
// if they completed their path safely
|
|
if( guy_box_helper.health == box_guy_health && guy_box_host.health == box_guy_health )
|
|
{
|
|
|
|
level notify( "box_carry_done" );
|
|
|
|
level thread box_detach_delay( guy_box_host );
|
|
|
|
// the run is done, kill them both
|
|
if( isalive( guy_box_host ) )
|
|
{
|
|
guy_box_host dodamage( 1000, ( 0, 0, 0 ) );
|
|
}
|
|
if( isalive( guy_box_helper ) )
|
|
{
|
|
guy_box_helper dodamage( 1000, ( 0, 0, 0 ) );
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Detach box from tag_weapon_left and spawn a new one where he would've dropped it
|
|
//
|
|
///////////////////////////////
|
|
|
|
box_detach_delay( guy_box_host )
|
|
{
|
|
|
|
wait( 1 );
|
|
|
|
orig = guy_box_host gettagorigin( "tag_weapon_left" );
|
|
angles = guy_box_host gettagangles( "tag_weapon_left" );
|
|
|
|
box = spawn( "script_model" , orig );
|
|
box.angles = angles;
|
|
box setmodel( "static_peleliu_crate_jpn_clsd_char" );
|
|
|
|
guy_box_host detach( "static_peleliu_crate_jpn_clsd_char", "tag_weapon_left" );
|
|
|
|
}
|
|
|
|
///////////////////
|
|
//
|
|
// Detach the box if damaged before run is done
|
|
//
|
|
///////////////////////////////
|
|
|
|
box_carry_drop()
|
|
{
|
|
|
|
level endon( "box_carry_done" );
|
|
|
|
level waittill( "box_carry_stop" );
|
|
|
|
orig = self gettagorigin( "tag_weapon_left" );
|
|
angles = self gettagangles( "tag_weapon_left" );
|
|
|
|
ground_trace = bullettrace( orig, orig - (0,0,100000), 0, undefined );
|
|
|
|
box = spawn( "script_model" , orig );
|
|
box.angles = angles;
|
|
box setmodel( "static_peleliu_crate_jpn_clsd_char" );
|
|
|
|
self detach( "static_peleliu_crate_jpn_clsd_char", "tag_weapon_left" );
|
|
|
|
box moveto( ground_trace["position"] - (0,0,2 ), 0.2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// How box carrier guys handle being damaged
|
|
//
|
|
///////////////////////////////
|
|
|
|
box_carry_damage()
|
|
{
|
|
|
|
level endon( "box_carry_damage" );
|
|
|
|
self waittill( "damage" );
|
|
|
|
level notify( "box_carry_stop" );
|
|
|
|
// send them away to die
|
|
guys = get_ai_group_ai( "box_carrier_ai" );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guys[i] notify( "killanimscript" );
|
|
guys[i] thread box_carry_death_run();
|
|
|
|
}
|
|
|
|
level notify( "box_carry_damage" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Box carriers retreat around a corner and are killed through script if they are shot during their anim
|
|
//
|
|
///////////////////////////////
|
|
|
|
box_carry_death_run()
|
|
{
|
|
|
|
self.goalradius = 40;
|
|
|
|
goal = getnode( "node_box_carry_death", "targetname" );
|
|
|
|
self setgoalnode( goal );
|
|
|
|
self waittill( "goal" );
|
|
|
|
self dodamage( self.health + 10, ( 0, 0, 0 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
//////
|
|
///////////////////
|
|
//
|
|
// STARTS
|
|
//
|
|
///////////////////////////////
|
|
//////
|
|
|
|
start_bunkers()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
getent( "trig_chain_post_trap_2", "targetname" ) delete();
|
|
|
|
level thread battle_line_ambient_sound();
|
|
|
|
players_speed_set( 0.8, 0.1 );
|
|
|
|
// turn color_chain near end of mangrove section off
|
|
trig = getent( "chain_bunker_1", "targetname" );
|
|
trig trigger_off();
|
|
trig = getent( "chain_bunker_2", "targetname" );
|
|
trig trigger_off();
|
|
|
|
maps\_vehicle::scripted_spawn( 24 );
|
|
|
|
simple_spawn( "intro_igc_friendlies", ::intro_igc_friendlies_strat );
|
|
|
|
array_thread( level.heroes, ::set_pacifist_on );
|
|
array_thread( level.heroes, ::set_ignoreme_on );
|
|
set_players_ignoreme( true );
|
|
|
|
set_color_heroes( "b" );
|
|
|
|
level thread bunker_1_mgs();
|
|
level thread bunker_4_47mm();
|
|
level thread bunker_friendlywave();
|
|
level thread grenade_vignette();
|
|
level thread mangrove_vo_3();
|
|
|
|
start_teleport( "orig_start_bunkers" );
|
|
|
|
set_color_chain( "trig_chain_post_trap_4" );
|
|
|
|
// have bunker_1_guys ignore intro_igc_guys
|
|
setignoremegroup( "intro_igc_guys", "bunker_1_guys" );
|
|
|
|
level thread bunkers();
|
|
|
|
}
|
|
|
|
start_flame()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
level thread skipto_fog_set();
|
|
|
|
BadPlacesEnable( 0 );
|
|
|
|
level thread battle_line_ambient_sound();
|
|
|
|
prepare_flame_bunker_aiming_origins();
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
// put these guys closer
|
|
//////////////////////////
|
|
|
|
amb_friends = simple_spawn( "bunker_2_ambient_friendlies" );
|
|
for( i = 0; i < amb_friends.size; i++ )
|
|
{
|
|
amb_friends[i] forceteleport( ( -125, -8808, -31.4 ) );
|
|
}
|
|
|
|
level.flamer = simple_spawn_single( "flamer_guy", ::flamer_spawn_strat );
|
|
assertex( isdefined( level.flamer ), "level.flamer not defined! bad bad bad!" );
|
|
|
|
level.flamer forceteleport( ( -125, -8808, -31.4 ) );
|
|
level.flamer thread flamer_strat();
|
|
level thread flame_squad_remainder();
|
|
////////////////////////////////////
|
|
|
|
start_teleport( "orig_start_flame" );
|
|
|
|
//////////////////////////////////////////
|
|
simple_floodspawn( "bunker_defenders", ::bunker_defenders_strat );
|
|
|
|
|
|
level thread player_flame_bunker();
|
|
|
|
level thread deadly_mgs();
|
|
level thread bunker_stop_friendly_waves();
|
|
|
|
array_thread( level.heroes, ::disable_ai_color );
|
|
array_thread( level.heroes, ::bunkers_end_heroes_strat );
|
|
|
|
}
|
|
|
|
|
|
|
|
start_flamer_setup()
|
|
{
|
|
|
|
level.flamer = simple_spawn_single( "flamer_guy" );
|
|
assertex( isdefined( level.flamer ), "level.flamer not defined! bad bad bad!" );
|
|
level.flamer.targetname = "friendly_squad";
|
|
level.flamer.goalradius = 30;
|
|
level.flamer.pacifist = 1;
|
|
level.flamer.pacifistwait = 0.05;
|
|
level.flamer.ignoreme = true;
|
|
level.flamer.ignoresuppression = true;
|
|
level.flamer.baseaccuracy = 0.05;
|
|
level.flamer.dropweapon = false;
|
|
level.flamer setcandamage( false );
|
|
level.flamer thread magic_bullet_shield();
|
|
level.flamer set_force_color( "y" );
|
|
|
|
}
|
|
|
|
|
|
start_forest()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
level thread skipto_fog_set();
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
set_color_heroes( "g" );
|
|
|
|
flag_set( "trig_forest_friendlies" );
|
|
|
|
set_color_chain( "chain_forest" );
|
|
|
|
objective_position( 5, ( 2813, -3828, 89 ) );
|
|
|
|
wait_network_frame(); // Let network clear out.
|
|
|
|
// spawn drones
|
|
if(!NumRemoteClients())
|
|
{
|
|
level thread maps\pel2_forest::forest_drones();
|
|
}
|
|
//wait( 0.1 );
|
|
|
|
wait_network_frame(); // Let network clear out.
|
|
|
|
// spawn friendlies
|
|
level thread maps\pel2_forest::forest_friendlies();
|
|
|
|
flag_set( "trig_flame_bunker_exit" );
|
|
|
|
start_teleport( "orig_start_forest" );
|
|
|
|
level thread maps\pel2_forest::forest_ambient_aa();
|
|
level thread maps\pel2_forest::main();
|
|
|
|
}
|
|
|
|
|
|
|
|
start_admin()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
level thread skipto_fog_set();
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
forest_friends = simple_spawn( "friend_forest_spawner" );
|
|
// don't want them being respawned in for any reason
|
|
for( i = 0; i < forest_friends.size; i++ )
|
|
{
|
|
forest_friends[i] disable_replace_on_death();
|
|
forest_friends[i].targetname = "forest_friendly";
|
|
forest_friends[i] set_force_color( "y" );
|
|
forest_friends[i] forceteleport( ( 3078.5, -4222.5, 38.8 ) );
|
|
}
|
|
|
|
set_color_heroes( "g" );
|
|
set_color_chain( "trig_start_admin_delete" );
|
|
|
|
start_teleport( "orig_start_admin" );
|
|
|
|
|
|
// TEMP testing rifle grenade tutorial hud
|
|
// TODO this shouldn't be done for every player
|
|
// players = get_players();
|
|
// for (i = 0; i < players.size; i++)
|
|
// {
|
|
// players[i] thread maps\pel2_forest::do_rifle_gren_hud_elem();
|
|
// }
|
|
/////////////
|
|
|
|
|
|
level thread maps\pel2_forest::admin_truck_victim();
|
|
|
|
level thread maps\pel2_forest::forest_ambient_aa();
|
|
level thread maps\pel2_forest::ambient_high_bombers();
|
|
level thread maps\pel2_forest::admin_mg_guys();
|
|
level thread maps\pel2_forest::admin_ai_pen();
|
|
level thread maps\pel2_forest::building_battle();
|
|
|
|
}
|
|
|
|
|
|
// for debug only
|
|
start_debug_stairs()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
getent( "trig_bunker_left_spawners", "targetname" ) delete();
|
|
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
set_color_heroes( "g" );
|
|
set_color_chain( "friendly_chain_admin_last" );
|
|
|
|
level thread maps\pel2_forest::admin_staircase_run_cycle();
|
|
|
|
start_teleport( "orig_start_stairs" );
|
|
|
|
}
|
|
|
|
|
|
|
|
start_airfield()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
level thread skipto_fog_set();
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
|
|
// ENTITY CLEANUP
|
|
//////////////
|
|
start_delete_garbage( -500, 4500, -6500, -13000 );
|
|
|
|
deleted_spawners = 0;
|
|
|
|
killspawner = 113;
|
|
killspawner_2 = 207;
|
|
|
|
spawners = GetSpawnerArray();
|
|
|
|
for( i = 0 ; i < spawners.size ; i++ )
|
|
{
|
|
if( ( IsDefined( spawners[i].script_killspawner ) ) &&( killspawner == spawners[i].script_killspawner || killspawner_2 == spawners[i].script_killspawner ) )
|
|
{
|
|
spawners[i] Delete();
|
|
deleted_spawners++;
|
|
}
|
|
}
|
|
|
|
println( "garbage: total deleted spawners: " + deleted_spawners );
|
|
//////////////
|
|
// END ENTITY CLEANUP
|
|
|
|
|
|
|
|
//level thread maps\pel2_forest::ambient_high_bombers();
|
|
//wait( 0.05 );
|
|
level thread maps\pel2_airfield::aa_ambient_fire();
|
|
wait( 0.05 );
|
|
level thread maps\pel2_airfield::airfield_mortars();
|
|
wait( 0.05 );
|
|
|
|
// delete spawn trigger that wouldve been hit in admin event
|
|
trig = getent( "trig_bunker_left_spawners", "targetname" );
|
|
trig delete();
|
|
trig = getent( "trig_admin_extra_middle_spawner", "script_noteworthy" );
|
|
trig delete();
|
|
|
|
|
|
set_color_heroes( "g" );
|
|
set_color_chain( "chain_admin_back" );
|
|
|
|
// reinforcements that would be with you from admin event
|
|
reinforcements = simple_spawn( "friend_admin_spawner" );
|
|
extra_guy = simple_spawn( "friend_admin_spawner_2" );
|
|
reinforcements = array_combine( reinforcements, extra_guy );
|
|
for( i = 0; i < reinforcements.size; i++ )
|
|
{
|
|
reinforcements[i] forceteleport( ( 2862, 190, 179 ) );
|
|
}
|
|
|
|
start_teleport( "orig_start_airfield" );
|
|
|
|
wait( 0.25 );
|
|
// start fire fx on airfield
|
|
level thread maps\pel2_airfield::airfield_plane_fire();
|
|
|
|
level thread maps\pel2_airfield::airfield_vo();
|
|
|
|
/#
|
|
// maps\pel2_airfield::debug_strafe_plane();
|
|
// maps\pel2_airfield::debug_pole_plane();
|
|
// level thread debug_num_vehicles();
|
|
#/
|
|
|
|
maps\pel2_airfield::main();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start_aaguns()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
level thread skipto_fog_set();
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
getent( "trig_airfield_last_trench", "script_noteworthy" ) delete();
|
|
|
|
flag_set( "chi_3_wave_dead" );
|
|
|
|
// DEBUG TEMP
|
|
/#
|
|
level thread debug_tank_health();
|
|
#/
|
|
//
|
|
|
|
// reinforcements that would be with you from admin event
|
|
reinforcements = simple_spawn( "friend_admin_spawner" );
|
|
extra_guy = simple_spawn( "friend_admin_spawner_2" );
|
|
reinforcements = array_combine( reinforcements, extra_guy );
|
|
|
|
for( i = 0; i < reinforcements.size; i++ )
|
|
{
|
|
reinforcements[i] forceteleport( ( 2932, 7240, 51.6 ) );
|
|
}
|
|
|
|
start_teleport( "start_airfield_napalm" );
|
|
|
|
set_color_heroes( "g" );
|
|
set_color_chain( "trig_past_last_trench" );
|
|
|
|
level thread maps\pel2_airfield::aa_ambient_fire();
|
|
wait( 1 ); // give aaguns time to spawn
|
|
level thread maps\pel2_airfield::trig_spawn_aa_mid_guys();
|
|
level thread maps\pel2_airfield::plane_tower();
|
|
level thread maps\pel2_airfield::tighten_up_color_chains();
|
|
level thread maps\pel2_airfield::ambient_planes();
|
|
level thread maps\pel2_airfield::last_aa_guns_objective();
|
|
level thread maps\pel2_airfield::trig_spawn_aa_early_mid_guys();
|
|
|
|
wait( 0.05 );
|
|
level thread maps\pel2_airfield::plane_tower_aa_direct_fire();
|
|
|
|
maps\pel2_airfield::last_aa_defense();
|
|
|
|
}
|
|
|
|
|
|
|
|
start_napalm()
|
|
{
|
|
|
|
setup_level();
|
|
|
|
level thread skipto_fog_set();
|
|
|
|
level.roebuck set_generic_run_anim( "roebuck_run", true );
|
|
|
|
getent( "trig_airfield_last_trench", "script_noteworthy" ) delete();
|
|
getent( "chain_center_of_aa_bunker", "targetname" ) delete();
|
|
|
|
// get reinforcements going
|
|
respawn_trig = getent( "auto5390", "target" );
|
|
respawn_trig notify( "trigger" );
|
|
|
|
// DEBUG TEMP
|
|
/#
|
|
level thread debug_tank_health();
|
|
#/
|
|
//
|
|
|
|
battlechatter_off();
|
|
|
|
// reinforcements that would be with you from admin event
|
|
reinforcements = simple_spawn( "friend_admin_spawner" );
|
|
extra_guy = simple_spawn( "friend_admin_spawner_2" );
|
|
reinforcements = array_combine( reinforcements, extra_guy );
|
|
|
|
getent( "auto2608", "target" ) delete();
|
|
|
|
for( i = 0; i < reinforcements.size; i++ )
|
|
{
|
|
reinforcements[i] forceteleport( ( 2619.5, 8199, 124 ) );
|
|
}
|
|
|
|
start_teleport( "start_airfield_napalm_2" );
|
|
|
|
// spawn aa guns
|
|
////////////
|
|
gun = maps\_vehicle::spawn_vehicle_from_targetname( "aaGun_2" );
|
|
gun makevehicleusable();
|
|
gun ClearTurretTarget();
|
|
gun notify("change target");
|
|
gun notify( "stop_friendlyfire_shield" );
|
|
gun.health = 4000;
|
|
gun = maps\_vehicle::spawn_vehicle_from_targetname( "aaGun_3" );
|
|
gun makevehicleusable();
|
|
gun ClearTurretTarget();
|
|
gun notify("change target");
|
|
gun notify( "stop_friendlyfire_shield" );
|
|
gun.health = 4000;
|
|
////////////
|
|
|
|
wait( 1.5 );
|
|
|
|
|
|
|
|
// for viewing napalm reactions
|
|
//////////////
|
|
// level.roebuck.animname = "end_vignette_roebuck";
|
|
// level.roebuck.end_node_goto = "node_end_roebuck";
|
|
//
|
|
// level.polonsky.animname = "end_vignette_polonsky";
|
|
// level.polonsky.end_node_goto = "node_end_polonsky";
|
|
//
|
|
// level.extra_hero.animname = "end_vignette_radio";
|
|
// level.extra_hero.end_node_goto = "node_end_extra_hero";
|
|
//
|
|
// maps\pel2_airfield::post_pacing_positions( level.heroes );
|
|
//
|
|
// wait( 6 );
|
|
//
|
|
// level thread maps\pel2_airfield::napalm_reaction();
|
|
//////////////
|
|
|
|
|
|
|
|
// just for tank debug
|
|
/////////////////
|
|
// maps\pel2_airfield::spawn_aa_volume_trigs();
|
|
// level thread maps\pel2_airfield::last_tanks_skipto_debug();
|
|
// wait( 10000 );
|
|
//////////////////
|
|
|
|
|
|
// for playing out the last counterattack
|
|
level thread maps\pel2_airfield::last_counterattack();
|
|
wait( 10000 );
|
|
///////////////////
|
|
|
|
// for viewing napalm drops
|
|
////////////////
|
|
// level thread maps\pel2_airfield::napalm_planes_bomb_ridge();
|
|
// level thread maps\pel2_airfield::napalm_planes();
|
|
// level thread maps\pel2_airfield::napalm_destruction();
|
|
////////////////
|
|
|
|
// viewing for outro fadeout
|
|
// maps\pel2_airfield::end_of_level();
|
|
////////////
|
|
}
|
|
|
|
|
|
|
|
|
|
skipto_fog_set()
|
|
{
|
|
get_players()[0]SetVolFog( 940, 2560, 520, -55, 0.7, 0.62, 0.52, 1 );
|
|
}
|
|
|
|
|
|
/// DEBUG !!!!!!!!
|
|
airfield_temp_kill_axis()
|
|
{
|
|
|
|
level endon( "stop_airfield_temp_kill_axis" );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
ai = getaiarray( "axis" );
|
|
|
|
for( i = 0; i < ai.size; i++ )
|
|
{
|
|
ai[i] dodamage( 70, (0,0,0) );
|
|
}
|
|
|
|
wait( 2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Sets up general friendly squad settings
|
|
//
|
|
///////////////////////////////
|
|
|
|
setup_friendlies()
|
|
{
|
|
|
|
level.heroes = [];
|
|
|
|
level.roebuck = getent( "roebuck", "script_noteworthy" );
|
|
level.roebuck.name = "Sgt. Roebuck";
|
|
level.polonsky = getent( "polonsky", "script_noteworthy" );
|
|
level.polonsky.name = "Pvt. Polonsky";
|
|
level.extra_hero = getent( "king", "script_noteworthy" );
|
|
|
|
level.heroes[0] = level.roebuck;
|
|
level.heroes[1] = level.polonsky;
|
|
level.heroes[2] = level.extra_hero;
|
|
|
|
array_thread( level.heroes, ::friendly_setup_thread );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Set up the action in/around the bunkers
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunkers()
|
|
{
|
|
|
|
level thread clean_up_bunker_chains();
|
|
|
|
level thread bunker_1_47mm();
|
|
level thread bunker_2_47mm();
|
|
level thread guys_47mm_4_radius_expand();
|
|
level thread player_flame_bunker();
|
|
level thread bunkers_vo();
|
|
level thread spawn_bunkers_pickup_weapons();
|
|
level thread save_near_first_bunker();
|
|
level thread save_near_corsair_trap();
|
|
level thread spawn_middle_at47();
|
|
level thread bunker_ambient_trucks();
|
|
|
|
// wait till players exit out of the mangroves
|
|
// flag set on trigger
|
|
flag_wait( "trig_setup_bunkers" );
|
|
|
|
// cuz reflection probes process isn't checks this flag before all flags are init'ed in setup_level
|
|
flag_set( "setup_bunkers_for_vision" );
|
|
|
|
maps\_debug::set_event_printname( "Bunkers" );
|
|
|
|
level notify( "obj_mangrove_complete" );
|
|
|
|
// TUEY Sets the music state to be ENDSWAMP
|
|
setmusicstate("ENDSWAMP");
|
|
|
|
// TODO have these guys playerseek instead?
|
|
// cleanup these guys in case there are any alive
|
|
kill_aigroup( "mangrove_ambush_ai" );
|
|
|
|
players_speed_set( 1.0, 3.5 );
|
|
|
|
simple_spawn( "intro_frontline_axis" );
|
|
|
|
// have frontline_axis pay more attention to intro_igc_guys
|
|
// TEMP OFF FOR LEIPZIG
|
|
//setthreatbias( "intro_igc_guys", "intro_frontline_axis", 600 );
|
|
|
|
// flag set on trigger. wait till player gets close to mg guys, then the beast awakens
|
|
flag_wait( "trig_box_carry" );
|
|
|
|
// TODO have these guys playerseek instead?
|
|
// cleanup these guys in case there are any alive
|
|
kill_aigroup( "mangrove_ambush_ai_2" );
|
|
kill_aigroup( "mangrove_ambush_ai_3" );
|
|
|
|
level thread box_carry();
|
|
|
|
wait_network_frame(); // CLIENTSIDE to help snapshot size
|
|
|
|
simple_floodspawn( "bunker_1_spawners" );
|
|
wait_network_frame();
|
|
simple_floodspawn( "bunker_1_pre_spawners", ::bunker_1_pre_spawners_strat );
|
|
|
|
level thread chain_bunkers_entrance();
|
|
level thread bunker_1_clear();
|
|
level thread bunker_1_retreat();
|
|
level thread spawn_bunker_2_front();
|
|
|
|
level thread trig_grass_camo_guys();
|
|
|
|
level thread guys_47mm_1_radius_expand();
|
|
level thread guys_47mm_1_force_expand();
|
|
level thread guys_47mm_2_radius_expand();
|
|
level thread guys_frontline_radius_expand();
|
|
level thread guys_frontline_radius_expand_2();
|
|
level thread intro_tank_lookat();
|
|
|
|
level notify( "on_dry_land" );
|
|
array_thread( level.heroes, ::on_dry_land );
|
|
|
|
//TEMPVO TODO
|
|
level.roebuck playsound( "bunker_clear" );
|
|
|
|
bunkers_2();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// 2nd bunker action
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunkers_2()
|
|
{
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_bunker_2_start" );
|
|
|
|
objective_position( 2, ( 669, -8859, -9 ) );
|
|
|
|
kill_noteworthy_group( "47mm_1_noteworthy" );
|
|
|
|
wait_network_frame(); // Let network clear out.
|
|
|
|
level thread bunkers_2_spawns();
|
|
level thread chain_bunkers_5();
|
|
|
|
bunkers_end();
|
|
|
|
}
|
|
|
|
|
|
|
|
bunkers_2_spawns()
|
|
{
|
|
|
|
simple_spawn( "bunker_2_mid_spawners" );
|
|
wait_network_frame();
|
|
simple_floodspawn( "far_trench_floodspawners" );
|
|
wait_network_frame();
|
|
simple_floodspawn( "bunker_2_mid_floodspawners" );
|
|
|
|
// flag set on trigger
|
|
flag_wait( "bunker_2b_mid_spawners" );
|
|
|
|
simple_floodspawn( "bunker_2b_mid_floodspawners" );
|
|
wait( 0.05 );
|
|
simple_spawn( "bunker_2b_mid_spawners" );
|
|
|
|
wait( 1 );
|
|
|
|
autosave_by_name( "Pel2 mid bunkers" );
|
|
|
|
}
|
|
|
|
|
|
|
|
spawn_bunker_2_front()
|
|
{
|
|
// flag set on trigger
|
|
flag_wait( "trig_spawn_bunker_2_front" );
|
|
simple_floodspawn( "bunker_2_front_floodspawners" );
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// ambient trucks that drive off to the right side of the battle
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_ambient_trucks()
|
|
{
|
|
|
|
trigger_wait( "trig_ambient_bunker_trucks", "targetname" );
|
|
maps\_vehicle::create_vehicle_from_spawngroup_and_gopath( 20 );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Mgs in bunkers area that hold off marines' advance
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_1_mgs()
|
|
{
|
|
|
|
simple_spawn( "intro_mg_spawners" );
|
|
|
|
// mg_1 = getent( "bunker_1_mg_1", "targetname" );
|
|
// mg_2 = getent( "bunker_1_mg_2", "targetname" );
|
|
//
|
|
// mg_1 setturretignoregoals( true );
|
|
// mg_2 setturretignoregoals( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Guys that surprise the player by emerging from the foliage on the right trench path
|
|
//
|
|
///////////////////////////////
|
|
|
|
trig_grass_camo_guys()
|
|
{
|
|
|
|
trigger_wait( "trig_grass_camo_guys_spawn", "targetname" );
|
|
|
|
quick_text( "grass spawn" );
|
|
|
|
simple_spawn( "grass_camo_guys_1", ::grass_camo_guys_1_strat );
|
|
|
|
level endon( "grass_surprise" );
|
|
|
|
// wait till player is close enough
|
|
trigger_wait( "trig_grass_camo_guys", "targetname" );
|
|
|
|
level thread trig_override( "trig_grass_lookat" );
|
|
// wait for player to look in the grass guys' direction
|
|
trigger_wait( "trig_grass_lookat", "targetname" );
|
|
|
|
quick_text( "grass surprise lookat!" );
|
|
flag_set( "grass_surprise" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// sets a bunch of fields for the prone-to-run ambush guys (to keep them stealthy)
|
|
//
|
|
///////////////////////////////
|
|
|
|
init_ambush_fields()
|
|
{
|
|
|
|
self allowedstances ( "prone" );
|
|
self disableaimassist();
|
|
self.a.pose = "prone";
|
|
self.allowdeath = 1;
|
|
self.pacifist = 1;
|
|
self.pacifistwait = 0.05;
|
|
self.ignoreall = 1;
|
|
self.ignoreme = 1;
|
|
self.ignoresuppression = 1;
|
|
self.grenadeawareness = 0;
|
|
self.disableArrivals = true;
|
|
self.disableExits = true;
|
|
self.drawoncompass = false;
|
|
self.activatecrosshair = false;
|
|
self.banzai_no_wait = 1;
|
|
self.script_max_banzai_distance = 2000;
|
|
self.animname = "bunkers";
|
|
|
|
self.pel2_startled = false;
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// resets a bunch of fields for the prone-to-run ambush guys (to make them active again)
|
|
//
|
|
///////////////////////////////
|
|
|
|
clear_ambush_fields()
|
|
{
|
|
|
|
self.activatecrosshair = true;
|
|
self enableaimassist();
|
|
self.drawoncompass = true;
|
|
self allowedstances( "stand" );
|
|
self.a.pose = "stand";
|
|
self.pacifist = 0;
|
|
self.ignoreall = 0;
|
|
self.grenadeawareness = 0.2;
|
|
self.disableArrivals = false;
|
|
self.disableExits = false;
|
|
|
|
self notify( "clear_ambush_fields" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// choose which variant prone-to-run anim to use
|
|
//
|
|
///////////////////////////////
|
|
|
|
choose_prone_to_run_anim_variant()
|
|
{
|
|
|
|
prone_anims = [];
|
|
prone_anims[prone_anims.size] = level.scr_anim["bunkers"]["prone_anim_fast_a"];
|
|
prone_anims[prone_anims.size] = level.scr_anim["bunkers"]["prone_anim_fast_b"];
|
|
prone_anims[prone_anims.size] = level.scr_anim["bunkers"]["prone_anim_fast_c"];
|
|
|
|
return prone_anims[randomint(prone_anims.size)];
|
|
|
|
}
|
|
|
|
|
|
|
|
grass_camo_guys_1_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self thread magic_bullet_shield();
|
|
//self setcandamage( false );
|
|
|
|
// keep him stealthy
|
|
self init_ambush_fields();
|
|
|
|
self thread grass_bunkers_surprise_damage( "grass_surprise_damage" );
|
|
// waittill either they receive damage or if the player gets close enough
|
|
flag_wait_either( "grass_surprise_damage", "grass_surprise" );
|
|
|
|
// stagger their emergence times if necessary
|
|
if( isdefined( self.script_float ) )
|
|
{
|
|
wait( self.script_float );
|
|
}
|
|
|
|
self setcandamage( true );
|
|
// shield may have been turned off already from grass_bunkers_surprise_damage()
|
|
if( IsDefined( self.magic_bullet_shield ) && self.magic_bullet_shield )
|
|
{
|
|
self stop_magic_bullet_shield();
|
|
}
|
|
|
|
// make him active again
|
|
self clear_ambush_fields();
|
|
|
|
self thread grass_surprise_half_shield( 4 );
|
|
self thread grass_camo_ignore_delay( 4 );
|
|
|
|
// choose which variant anim to use
|
|
prone_anim = choose_prone_to_run_anim_variant();
|
|
level.animtimefudge = 0.05;
|
|
self play_anim_end_early( prone_anim, level.animtimefudge );
|
|
|
|
self thread maps\_banzai::banzai_force();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Protect the grass guys from all damage except from the player
|
|
//
|
|
///////////////////////////////
|
|
|
|
grass_surprise_half_shield( delay_time )
|
|
{
|
|
|
|
level endon( "stop_grass_half_shields" );
|
|
self endon( "death" );
|
|
|
|
self thread grass_camo_halfshield_delay( delay_time );
|
|
|
|
self.pel2_real_health = self.health;
|
|
self.health = 10000;
|
|
|
|
attacker = undefined;
|
|
|
|
while( self.health > 0 )
|
|
{
|
|
|
|
self waittill( "damage", amount, attacker, direction_vec, point, type, modelName, tagName );
|
|
|
|
type = tolower( type );
|
|
|
|
// if it's not the player, and also a bullet weapon (non-player friendlies should still be able to kill them with their grenades)
|
|
if( !isplayer(attacker) && issubstr( type, "bullet" ) )
|
|
{
|
|
//iprintln( "attacked by non-player!" );
|
|
self.health = 10000; // give back health for these things
|
|
}
|
|
else
|
|
{
|
|
self.health = self.pel2_real_health;
|
|
self dodamage( amount, (0,0,0) );
|
|
self.pel2_real_health = self.health;
|
|
// put ff shield back on
|
|
self.health = 10000;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
grass_camo_ignore_delay( wait_time )
|
|
{
|
|
self endon( "death" );
|
|
|
|
wait( wait_time );
|
|
self.ignoreme = 0;
|
|
}
|
|
|
|
|
|
|
|
grass_camo_halfshield_delay( delay_time )
|
|
{
|
|
self endon( "death" );
|
|
|
|
wait( delay_time );
|
|
level notify( "stop_grass_half_shields" );
|
|
self.health = self.pel2_real_health;
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// sets flag(s) if guy has been damaged
|
|
//
|
|
///////////////////////////////
|
|
|
|
grass_bunkers_surprise_damage( flag_name )
|
|
{
|
|
|
|
self endon( "clear_ambush_fields" );
|
|
level endon( flag_name );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
self waittill( "damage", amount, attacker );
|
|
|
|
if( isplayer( attacker ) )
|
|
{
|
|
|
|
// if the amount is enough to kill the guy, give achievement
|
|
if( amount >= self.mbs_oldhealth )
|
|
{
|
|
attacker giveachievement_wrapper( "ANY_ACHIEVEMENT_GRASSJAP" );
|
|
}
|
|
|
|
self stop_magic_bullet_shield();
|
|
self setcandamage( true );
|
|
|
|
self dodamage( amount, (0,0,0) );
|
|
|
|
self.pel2_startled = true;
|
|
|
|
quick_text( "grass surprise damage!" );
|
|
flag_set( flag_name );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Initial values set for flamer when he spawns
|
|
//
|
|
///////////////////////////////
|
|
|
|
flamer_spawn_strat()
|
|
{
|
|
|
|
self thread magic_bullet_shield();
|
|
self setcandamage( false );
|
|
|
|
// flame settings
|
|
self.a.flamethrowerShootTime_min = 10000;
|
|
self.a.flamethrowerShootTime_max = 15000;
|
|
self.a.flamethrowerShootDelay_min = 0;
|
|
self.a.flamethrowerShootDelay_max = 1;
|
|
|
|
self.animname = "flamebunker";
|
|
self.targetname = "friendly_squad";
|
|
self.goalradius = 20;
|
|
self.pacifist = 1;
|
|
self.pacifistwait = 0.05;
|
|
self.ignoreme = true;
|
|
self.ignoresuppression = true;
|
|
self.grenadeawareness = 0;
|
|
self.baseaccuracy = 0.05;
|
|
self.dropweapon = false;
|
|
|
|
self toggleik( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Flame guy burns out bunker 2
|
|
//
|
|
///////////////////////////////
|
|
|
|
flamer_advance_bunkers()
|
|
{
|
|
|
|
self.moveplaybackrate = 1.25;
|
|
|
|
goal_node = getnode( "node_flamer_advance_1", "targetname" );
|
|
self setgoalnode( goal_node );
|
|
self waittill( "goal" );
|
|
|
|
flag_set( "flamer_at_first_advance_node" );
|
|
|
|
BadPlacesEnable( 0 );
|
|
|
|
self.moveplaybackrate = 1;
|
|
self.pacifist = 0;
|
|
|
|
fire_spot_1 = convert_aiming_struct_to_origin( "orig_flame_advance_1" );
|
|
fire_spot_2 = convert_aiming_struct_to_origin( "orig_flame_advance_2" );
|
|
fire_spot_3 = convert_aiming_struct_to_origin( "orig_flame_advance_3" );
|
|
|
|
vol = getent( "vol_flame_advance_1", "targetname" );
|
|
if( !any_player_istouching( vol ) && !flag( "flamer_advance_to_hide" ) )
|
|
{
|
|
|
|
level thread flame_move_target( fire_spot_1, 2.5 );
|
|
self thread flame_burst( fire_spot_1, "flamer_advance_to_2" );
|
|
level thread temp_advance( 7, "flamer_advance_to_2" );
|
|
|
|
flag_wait( "flamer_advance_to_2" );
|
|
self ClearEntityTarget();
|
|
|
|
}
|
|
|
|
// if he isn't needed yet at the flame truck, advance to the next bunker 2 spot
|
|
if( !flag( "flamer_advance_to_hide" ) )
|
|
{
|
|
goal_node = getnode( "node_flamer_advance_2", "targetname" );
|
|
self setgoalnode( goal_node );
|
|
self waittill( "goal" );
|
|
}
|
|
|
|
vol = getent( "vol_flame_advance_2", "targetname" );
|
|
if( !any_player_istouching( vol ) && !flag( "flamer_advance_to_hide" ) )
|
|
{
|
|
|
|
level thread flame_move_target( fire_spot_2, 2.5 );
|
|
self thread flame_burst( fire_spot_2, "flamer_advance_to_3" );
|
|
level thread flame_burst_ensure_dmg( "vol_flame_advance_2" );
|
|
level thread temp_advance( 7, "flamer_advance_to_3" );
|
|
|
|
flag_wait( "flamer_advance_to_3" );
|
|
self ClearEntityTarget();
|
|
|
|
}
|
|
|
|
// if he isn't needed yet at the flame truck, advance to the next bunker 2 spot
|
|
if( !flag( "flamer_advance_to_hide" ) )
|
|
{
|
|
goal_node = getnode( "node_flamer_advance_3", "targetname" );
|
|
self setgoalnode( goal_node );
|
|
self waittill( "goal" );
|
|
}
|
|
|
|
|
|
vol = getent( "vol_flame_advance_3", "targetname" );
|
|
if( !any_player_istouching( vol ) && !flag( "flamer_advance_to_hide" ) )
|
|
{
|
|
|
|
level thread flame_move_target( fire_spot_3, 2.5 );
|
|
self thread flame_burst( fire_spot_3, "flamer_advance_to_hide" );
|
|
level thread flame_burst_ensure_dmg( "vol_flame_advance_3" );
|
|
level thread temp_advance( 7, "flamer_advance_to_hide" );
|
|
|
|
flag_wait( "flamer_advance_to_hide" );
|
|
self ClearEntityTarget();
|
|
|
|
}
|
|
|
|
goal_node = getnode( "node_flame_hide", "targetname" );
|
|
self setgoalnode( goal_node );
|
|
|
|
// delete fire origins
|
|
fire_spot_1 notify( "stop_fakefire_mover" );
|
|
fire_spot_1 delete();
|
|
fire_spot_2 notify( "stop_fakefire_mover" );
|
|
fire_spot_2 delete();
|
|
fire_spot_3 notify( "stop_fakefire_mover" );
|
|
fire_spot_3 delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
flame_burst_ensure_dmg( vol_name )
|
|
{
|
|
wait( 1.35 );
|
|
|
|
guys = getAIarrayTouchingVolume( "axis", vol_name );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guys[i].a.forceflamedeath = 1;
|
|
guys[i] dodamage( guys[i].health + 50, (0,0,0) );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
flame_burst( fire_spot, flag_notify )
|
|
{
|
|
|
|
level endon( flag_notify );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
self SetEntityTarget( fire_spot );
|
|
wait( RandomFloatRange( 2.75, 3.75 ) );
|
|
self ClearEntityTarget();
|
|
self StopShoot();
|
|
wait( RandomFloatRange( 0.9, 1.6 ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
temp_advance( time, flag_name )
|
|
{
|
|
wait( time );
|
|
flag_set( flag_name );
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Strategy for guy that flames end bunkers
|
|
//
|
|
///////////////////////////////
|
|
|
|
flamer_strat()
|
|
{
|
|
|
|
// get him near the trucks
|
|
node_truck_flame = getnode( "node_flame_truck", "targetname" );
|
|
self setgoalnode( node_truck_flame );
|
|
self waittill( "goal" );
|
|
|
|
// get heroes in place
|
|
array_thread( level.heroes, ::disable_ai_color );
|
|
level thread bunkers_end_heros_in_place();
|
|
level thread smoke_grenade_on_the_scene();
|
|
|
|
// have him open fire on the truck
|
|
flame_truck();
|
|
|
|
level thread flame_bunker_vo();
|
|
level thread flame_bunker_vo_2();
|
|
level thread bunker_prepare_flame();
|
|
level thread flame_bunker_continue();
|
|
level thread flame_squad_remainder();
|
|
level thread bunker_killed_but_not_flamed();
|
|
level thread bunker_killed_with_barrels();
|
|
|
|
// so he transitions to his cover spot (arrivals are off by default for flame ai)
|
|
self.disablearrivals = false;
|
|
self.disableexits = false;
|
|
// have him take cover near the truck
|
|
goal_node = getnode( "node_advance_end_bunkers_flame", "targetname" );
|
|
self setgoalnode( goal_node );
|
|
self set_force_cover( "hide" );
|
|
self waittill( "goal" );
|
|
|
|
level thread mgs_targets_move();
|
|
|
|
level.current_mg_focus = "both_flamer";
|
|
if( !level.player_being_targetted )
|
|
{
|
|
level thread mgs_focus_on_origins( level.current_mg_focus );
|
|
}
|
|
|
|
// have him take cover for a second before moving up
|
|
wait( RandomFloatRange( 2.25, 3.0 ) );
|
|
|
|
level.current_mg_focus = "both_berm";
|
|
if( !level.player_being_targetted )
|
|
{
|
|
level thread mgs_focus_on_origins( level.current_mg_focus );
|
|
}
|
|
|
|
level thread mg_focus_both_berm_delay();
|
|
|
|
// send flamer to the mound
|
|
goal_node = getnode( "node_end_bunker_flame", "targetname" );
|
|
self setgoalnode( goal_node ); // get him to do his transition out first, as anim_reach won't play transitions
|
|
wait( 1.5 );
|
|
anim_reach_solo( self, "flamebunker_a", undefined, goal_node );
|
|
anim_single_solo( self, "flamebunker_a", undefined, goal_node );
|
|
level thread anim_loop_solo( self, "flamebunker_cover", undefined, "bunker_suppressed_twice", goal_node );
|
|
|
|
// reset value
|
|
level.bunker_mg_damage_total = 0;
|
|
|
|
// waittill bunker mg is distracted by suppression fire a second time
|
|
level thread bunker_distract( "bunker_distract_2" );
|
|
|
|
flag_wait( "bunker_distract_2" );
|
|
|
|
level thread mgs_focus_on_flamer();
|
|
|
|
// some time for the gunners to pick up the flamer as their target
|
|
wait( 0.75 );
|
|
|
|
|
|
|
|
quick_text( "bunker suppressed twice!", 3, true );
|
|
level notify( "bunker_suppressed_twice" );
|
|
|
|
self.pacifist = 0;
|
|
|
|
anim_single_solo( self, "flamebunker_death", undefined, goal_node );
|
|
|
|
bunker_defenders_reduce_count();
|
|
|
|
self thread flamer_strat_fake_death( goal_node );
|
|
|
|
level thread player_pickup_flamethrower( self );
|
|
|
|
flag_set( "flame_guy_killed" );
|
|
playsoundatposition("flame_stinger", (0,0,0));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
flamer_strat_fake_death( goal_node )
|
|
{
|
|
|
|
level endon( "stop_flamer_fake_death" );
|
|
|
|
|
|
|
|
self thread anim_loop_solo( self, "flamebunker_death_loop", undefined, "stop_flamebunker_death_loop", goal_node );
|
|
self.deathanim = level.scr_anim["flamebunker"]["flamebunker_death_loop"][0];
|
|
|
|
flag_wait( "player_got_flamethrower" );
|
|
|
|
//tuey sets music state to PLAYER_GETS_FLAMETHROWER
|
|
setmusicstate("PLAYER_GETS_FLAMETHROWER");
|
|
|
|
// remove glowy flamethrower; player just took it
|
|
if( flag( "flamethrower_now_non_glowy" ) )
|
|
{
|
|
self detach( "char_usa_marine_helmf" );
|
|
}
|
|
else
|
|
{
|
|
self detach( "char_usa_marine_helmf_obj" );
|
|
}
|
|
|
|
// detach the actual weapon model (separate than the gearmodel, which includes the tank on the back)
|
|
self animscripts\shared::placeWeaponOn( self.primaryweapon, "none");
|
|
|
|
self notify( "stop_flamebunker_death_loop" );
|
|
|
|
self setcandamage( true );
|
|
self stop_magic_bullet_shield();
|
|
self dodamage( self.health + 1, (0,0,0) );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// allow player to pickup flamethrower off flamer. he's not actually killed here, it's just faked. he needs to be alive in order
|
|
// to do the glowy model swap. he'll be killed through script as soon as the player grabs the weapon, or if they proceed to the middle
|
|
// of the next event
|
|
//
|
|
///////////////////////////////
|
|
|
|
player_pickup_flamethrower( guy )
|
|
{
|
|
|
|
// so he doesn't try any funny business
|
|
guy.pacifist = true;
|
|
guy.pacifistwait = 0.05;
|
|
guy.ignoreall = true;
|
|
guy.ignoreme = 1;
|
|
|
|
// make flamethrower glowy so player notices it
|
|
guy detach( "char_usa_marine_helmf" );
|
|
guy attach( "char_usa_marine_helmf_obj" );
|
|
|
|
// spawn glowy flamethrower for player to pickup & use
|
|
flamethrower_origin = (-308, -7685.3, -15);
|
|
flamethrower_pickup = spawn( "weapon_m2_flamethrower", flamethrower_origin, 1 );
|
|
flamethrower_pickup.angles = (0, 249, -90);
|
|
flamethrower_pickup hide();
|
|
|
|
objective_string( 3, &"PEL2_RETRIEVE_FLAME" );
|
|
objective_position( 3, flamethrower_origin );
|
|
objective_ring( 3 );
|
|
|
|
autosave_by_name( "Pel2 pickup flamethrower" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// if player manages to kill all the enemies in the flame bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_killed_but_not_flamed()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
waittill_aigroupcleared( "last_bunker_ai_1" );
|
|
waittill_aigroupcleared( "last_bunker_ai_2" );
|
|
|
|
// destroy barrels to start chain reaction
|
|
radiusdamage( (-377.5, -6863.5, -31), 100, 100, 100 );
|
|
|
|
wait( RandomFloatRange( 0.9, 1.7 ) );
|
|
|
|
flag_set( "bunker_killed_but_not_flamed" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// if player starts a chain-reaction by shooting the barrels inside the bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_killed_with_barrels()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
barrels = getentarray( "bunker_barrels", "script_noteworthy" );
|
|
barrels_with_health = 0;
|
|
|
|
// check if any of the barrels have been shot/destroyed
|
|
for( i = 0; i < barrels.size; i++ )
|
|
{
|
|
if( barrels[i].health >= 0 )
|
|
{
|
|
barrels_with_health++;
|
|
}
|
|
}
|
|
|
|
if( barrels_with_health == 0 )
|
|
{
|
|
break;
|
|
}
|
|
// others might not have been damaged by the initial splash, so give em a chance to explode and then do it manually if needed
|
|
else if( barrels_with_health <= 3 )
|
|
{
|
|
wait( 2 );
|
|
radiusdamage( (-377.5, -6863.5, -31), 100, 100, 100 );
|
|
break;
|
|
}
|
|
|
|
wait( 0.25 );
|
|
|
|
}
|
|
|
|
quick_text( "bunker_killed_with_barrels !!!" );
|
|
//println( "bunker_killed_with_barrels !!!" );
|
|
|
|
flag_wait( "flame_guy_killed" );
|
|
|
|
flag_set( "bunker_killed_but_not_flamed" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Once the flamethrower is retrievable, lower the mg defenders' count so the player can kill them all and still proceed
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_defenders_reduce_count()
|
|
{
|
|
|
|
bunker_defender_spawners = getentarray( "bunker_defenders", "targetname" );
|
|
for( i = 0; i < bunker_defender_spawners.size; i++ )
|
|
{
|
|
if( bunker_defender_spawners[i].count > 2 )
|
|
{
|
|
bunker_defender_spawners[i].count = 2;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// want mgs to eventually start re-target flamer & berm
|
|
//
|
|
///////////////////////////////
|
|
|
|
mg_focus_both_berm_delay()
|
|
{
|
|
|
|
level endon( "bunker_window_1_flamed" );
|
|
level endon( "bunker_distract_2" );
|
|
|
|
wait( 6.5 );
|
|
|
|
level.current_mg_focus = "left_flamer_right_berm";
|
|
if( !level.player_being_targetted )
|
|
{
|
|
level thread mgs_focus_on_origins( level.current_mg_focus );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Moves script origins back and forth (that the flame bunker mgs target)
|
|
//
|
|
///////////////////////////////
|
|
|
|
mgs_targets_move()
|
|
{
|
|
|
|
// start moving mg script origins
|
|
mg_targets = [];
|
|
mg_targets[0] = getent( "bunker_end_target_1_converted", "targetname" );
|
|
mg_targets[1] = getent( "bunker_end_target_2_converted", "targetname" );
|
|
mg_targets[2] = getent( "bunker_end_target_3_converted", "targetname" );
|
|
mg_targets[3] = getent( "bunker_end_target_1a_converted", "targetname" );
|
|
mg_targets[4] = getent( "bunker_end_target_2a_converted", "targetname" );
|
|
|
|
level thread flame_move_target( mg_targets[0], 3.75 );
|
|
level thread flame_move_target( mg_targets[1], 4.75 );
|
|
level thread flame_move_target( mg_targets[2], 3.75 );
|
|
level thread flame_move_target( mg_targets[3], 3.75 );
|
|
level thread flame_move_target( mg_targets[4], 3.25 );
|
|
|
|
flag_wait( "bunkers_flamed" );
|
|
|
|
// stop moving script origins
|
|
for( i = 0; i < mg_targets.size; i++ )
|
|
{
|
|
mg_targets[i] notify( "stop_fakefire_mover" );
|
|
mg_targets[i] delete();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bunker_distract( which_flag )
|
|
{
|
|
|
|
damage_total = 0;
|
|
damage_trig = getent( "trig_damage_end_bunker", "targetname" );
|
|
|
|
// make sure player hits the bunker at least a few times
|
|
while( level.bunker_mg_damage_total < 500 )
|
|
{
|
|
|
|
damage_trig waittill( "damage", damage_amount, attacker );
|
|
|
|
// only register damage from the player or heroes
|
|
if( IsPlayer( attacker ) )
|
|
{
|
|
level.bunker_mg_damage_total += damage_amount;
|
|
quick_text( "damage_total: " + level.bunker_mg_damage_total );
|
|
}
|
|
else if( (level.roebuck == attacker) || (level.polonsky == attacker) || (level.extra_hero == attacker) )
|
|
{
|
|
level.bunker_mg_damage_total += damage_amount/6;
|
|
quick_text( "damage_total: " + level.bunker_mg_damage_total );
|
|
}
|
|
|
|
}
|
|
|
|
flag_set( which_flag );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Player has arrived at end bunker area
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunkers_end()
|
|
{
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_end_bunkers" );
|
|
|
|
level notify( "obj_bunkers_complete" );
|
|
|
|
// prepare aiming origins
|
|
prepare_flame_bunker_aiming_origins();
|
|
|
|
flag_set( "flamer_advance_to_hide" );
|
|
|
|
simple_spawn( "forest_truck_spawners", ::forest_truck_spawners_strat );
|
|
wait_network_frame(); // CLIENTSIDE to help snapshot size
|
|
simple_floodspawn( "bunker_defenders", ::bunker_defenders_strat );
|
|
wait_network_frame();
|
|
level thread flame_truck_setup();
|
|
level thread bunker_stop_friendly_waves();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
prepare_flame_bunker_aiming_origins()
|
|
{
|
|
convert_aiming_struct_to_origin( "bunker_end_target_1" );
|
|
convert_aiming_struct_to_origin( "bunker_end_target_2" );
|
|
convert_aiming_struct_to_origin( "bunker_end_target_3" );
|
|
convert_aiming_struct_to_origin( "bunker_end_target_1a" );
|
|
convert_aiming_struct_to_origin( "bunker_end_target_2a" );
|
|
}
|
|
|
|
|
|
|
|
forest_truck_spawners_strat()
|
|
{
|
|
self endon( "death" );
|
|
self.ignoresuppression = 1;
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// MGs in bunker that gets flamed
|
|
//
|
|
///////////////////////////////
|
|
|
|
deadly_mgs()
|
|
{
|
|
|
|
level thread bunker_mg_killzone();
|
|
|
|
turret = getent( "flame_bunker_mg_r", "targetname" );
|
|
turret setTurretTeam( "axis" );
|
|
turret SetMode( "auto_ai" );
|
|
turret setturretignoregoals( true );
|
|
turret thread maps\_mgturret::burst_fire_unmanned();
|
|
|
|
turret = getent( "flame_bunker_mg_l", "targetname" );
|
|
turret setTurretTeam( "axis" );
|
|
turret SetMode( "auto_ai" );
|
|
turret setturretignoregoals( true );
|
|
turret thread maps\_mgturret::burst_fire_unmanned();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Truck that gets flamed
|
|
//
|
|
///////////////////////////////
|
|
|
|
flame_truck_setup()
|
|
{
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_flame_truck" );
|
|
|
|
autosave_by_name("Pel2 flame truck" );
|
|
|
|
|
|
|
|
level thread deadly_mgs();
|
|
|
|
quick_text( "flame_truck", 3, true );
|
|
|
|
assertex( isdefined( level.flamer ), "bunker_flamer not defined! bad bad bad!" );
|
|
|
|
level.flamer thread flamer_strat();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Handles the event where the player flames the bunker to progress to the dunes pacing area
|
|
//
|
|
///////////////////////////////
|
|
|
|
player_flame_bunker()
|
|
{
|
|
|
|
level endon( "bunker_killed_but_not_flamed" );
|
|
|
|
flag_wait( "flame_guy_killed" );
|
|
|
|
//tuey sets music state to FLAME_THROWER_GUY_DEAD
|
|
setmusicstate("FLAMER_DIED");
|
|
|
|
damage_total = 0;
|
|
damage_trig = getent( "trig_damage_end_bunker_flame", "targetname" );
|
|
|
|
flame_bunker_mg_damage_total = 0;
|
|
|
|
// make sure player hits the bunker at least a few times
|
|
while( flame_bunker_mg_damage_total < 35000 )
|
|
{
|
|
|
|
damage_trig waittill( "damage", damage_amount, attacker, direction_vec, point, type );
|
|
|
|
type = tolower( type );
|
|
|
|
// only register fire damage from the player
|
|
if( IsPlayer( attacker ) && type == "mod_burned" && damage_amount >= 5 )
|
|
{
|
|
flame_bunker_mg_damage_total += damage_amount;
|
|
quick_text( "damage_total: " + flame_bunker_mg_damage_total + " amount: " + damage_amount, undefined, true);
|
|
}
|
|
|
|
}
|
|
|
|
flag_set( "bunker_window_1_flamed" );
|
|
|
|
level thread bunker_window_1_flamed_delay();
|
|
|
|
while( flame_bunker_mg_damage_total < 70000 )
|
|
{
|
|
|
|
damage_trig waittill( "damage", damage_amount, attacker, direction_vec, point, type );
|
|
|
|
type = tolower( type );
|
|
|
|
// only register fire damage from the player
|
|
if( IsPlayer( attacker ) && type == "mod_burned" && damage_amount >= 5 )
|
|
{
|
|
flame_bunker_mg_damage_total += damage_amount;
|
|
quick_text( "damage_total: " + flame_bunker_mg_damage_total + " amount: " + damage_amount, undefined, true);
|
|
}
|
|
|
|
}
|
|
|
|
flag_set( "bunker_window_2_flamed" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// MGs target player briefly after he does some damage with the flamethrower
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_window_1_flamed_delay()
|
|
{
|
|
|
|
level.force_player_being_targetted = true;
|
|
|
|
wait( RandomIntRange( 3, 5 ) );
|
|
|
|
level.force_player_being_targetted = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// action that occurs during bunker flaming and afterwards
|
|
//
|
|
///////////////////////////////
|
|
|
|
flame_bunker_continue()
|
|
{
|
|
|
|
flag_wait_either( "bunker_window_1_flamed", "bunker_killed_but_not_flamed" );
|
|
|
|
// turn off turret 1
|
|
turret = getent( "flame_bunker_mg_l", "targetname" );
|
|
turret cleartargetentity();
|
|
turret SetMode( "auto_ai" );
|
|
turret notify( "death" );
|
|
|
|
maps\_spawner::kill_spawnernum( 111 );
|
|
|
|
flag_wait_either( "bunker_window_2_flamed", "bunker_killed_but_not_flamed" );
|
|
|
|
// turn off turret 2
|
|
turret = getent( "flame_bunker_mg_r", "targetname" );
|
|
turret cleartargetentity();
|
|
turret SetMode( "auto_ai" );
|
|
turret notify( "death" );
|
|
|
|
maps\_spawner::kill_spawnernum( 112 );
|
|
|
|
flag_set( "bunkers_flamed" );
|
|
|
|
BadPlacesEnable( 1 );
|
|
|
|
bunkers_flame_pre_explosions();
|
|
|
|
|
|
guy_1 = get_ai_group_ai( "last_bunker_ai_1" );
|
|
guy_2 = get_ai_group_ai( "last_bunker_ai_2" );
|
|
guys = array_combine( guy_1, guy_2 );
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guys[i].a.special = "none";
|
|
guys[i].a.forceflamedeath = 1;
|
|
}
|
|
|
|
|
|
kill_aigroup( "last_bunker_ai_1" );
|
|
kill_aigroup( "last_bunker_ai_2" );
|
|
|
|
// bunker explodes, creating a hole in the wall
|
|
level thread blow_hole_in_bunker_wall();
|
|
|
|
level notify( "obj_flame_complete" );
|
|
|
|
// turn off glowy flamethrower if not off already
|
|
if( !flag( "player_got_flamethrower" ) )
|
|
{
|
|
level.flamer detach( "char_usa_marine_helmf_obj" );
|
|
level.flamer attach( "char_usa_marine_helmf" );
|
|
flag_set( "flamethrower_now_non_glowy" );
|
|
level thread player_got_flamethrower_after_obj();
|
|
}
|
|
|
|
level thread bunkers_flamed_fx();
|
|
level thread flame_bunker_inside();
|
|
level thread chain_bunker_flame_back();
|
|
|
|
// bunkers are flamed, set guys back to normal
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
level.heroes[i].pacifist = 0;
|
|
level.heroes[i].ignoreall = 0;
|
|
level.heroes[i].ignoresuppression = 0;
|
|
}
|
|
|
|
set_color_heroes( "g" );
|
|
set_color_chain( "bunker_end_cleanup_chain" );
|
|
|
|
// make no one ignored
|
|
guys = getaiarray( "allies" );
|
|
array_thread( guys, ::set_ignoreme_off );
|
|
set_players_ignoreme( false );
|
|
|
|
wait( 1.5 );
|
|
|
|
autosave_by_name( "Pel2 bunkers flamed" );
|
|
|
|
wait( 4.5 );
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_near_bunker_door" );
|
|
|
|
set_color_chain( "chain_inside_flame_bunker" );
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_flame_bunker_exit" );
|
|
|
|
objective_position( 3, ( 2813, -3828, 89 ) );
|
|
|
|
wait_network_frame(); // let network clear out.
|
|
|
|
maps\pel2_forest::main();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// in case the player picks up the flamethrower after the bunker has been destroyed
|
|
//
|
|
///////////////////////////////
|
|
|
|
player_got_flamethrower_after_obj()
|
|
{
|
|
|
|
level endon( "stop_flamer_fake_death" );
|
|
|
|
// wait till a guy gets the flamethrower
|
|
while( !flag( "player_got_flamethrower" ) )
|
|
{
|
|
|
|
players = get_players();
|
|
for( i = 0; i < players.size; i++ )
|
|
{
|
|
if( players[i] HasWeapon( "m2_flamethrower" ) )
|
|
{
|
|
flag_set( "player_got_flamethrower" );
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
wait( 0.5 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// chain reaction explosions before the big one that blows the doorway open
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunkers_flame_pre_explosions()
|
|
{
|
|
|
|
level thread chain_reaction_fx();
|
|
|
|
// destroy barrels if they're not already blown up
|
|
radiusdamage( (-377.5, -6863.5, -31), 170, 200, 150 );
|
|
radiusdamage( (-126.7, -6883.5, -47.8), 30, 200, 150 );
|
|
|
|
orig = getstruct( "orig_bunker_flame_fx_1", "targetname" );
|
|
|
|
earthquake( 0.4, 1.0, orig.origin, 800 );
|
|
PlayRumbleOnPosition( "explosion_generic", orig.origin );
|
|
playsoundatposition ("bomb_far_falloff_1", orig.origin);
|
|
|
|
level thread bunkers_flame_pre_explosions_vo();
|
|
|
|
wait( RandomFloatRange( 1.3, 1.7 ) );
|
|
|
|
earthquake( 0.5, 1.2, orig.origin, 900 );
|
|
PlayRumbleOnPosition( "explosion_generic", orig.origin );
|
|
playsoundatposition ("bomb_far_falloff_2", orig.origin);
|
|
|
|
wait( RandomFloatRange( 1.25, 1.5 ) );
|
|
|
|
// TUEY Sets the music state to be AFTERBUNKER
|
|
setmusicstate("AFTERBUNKER");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
chain_reaction_fx()
|
|
{
|
|
|
|
level endon( "obj_flame_complete" );
|
|
|
|
fx_origins = getstructarray( "orig_bunker_chain_reaction", "targetname" );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
fx_orig = fx_origins[randomint(fx_origins.size)];
|
|
playfx( level._effect["bunker_chain_reaction"], fx_orig.origin, anglestoforward(fx_orig.angles) );
|
|
|
|
wait( 0.5 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bunkers_flame_pre_explosions_vo()
|
|
{
|
|
|
|
play_vo( level.roebuck, "vo", "its_gonna_blow" );
|
|
wait( 1 );
|
|
play_vo( level.roebuck, "vo", "get_outta_here" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// fx and brush deletion for the entryway into the flame bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
blow_hole_in_bunker_wall()
|
|
{
|
|
|
|
wall = getent( "brush_flame_bunker", "targetname" );
|
|
wall connectpaths();
|
|
wall delete();
|
|
|
|
fx_orig = getstruct( "orig_bunker_flame_explode", "targetname" );
|
|
//playfx( level._effect["orig_mortar_airfield_sw"], fx_orig.origin, anglestoforward(fx_orig.angles ) );
|
|
exploder( 202 );
|
|
exploder( 201 );
|
|
|
|
temp_sound_orig = spawn( "script_origin", fx_orig.origin );
|
|
temp_sound_orig playsound( "wall_explo", "wall_explo_done" );
|
|
temp_sound_orig waittill( "wall_explo_done" );
|
|
temp_sound_orig delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// canned guys spawned inside the flame bunker right after it explodes
|
|
//
|
|
///////////////////////////////
|
|
|
|
flame_bunker_inside()
|
|
{
|
|
|
|
flag_wait( "trig_flame_bunker_inside" );
|
|
simple_spawn( "flame_bunker_defenders_2" );
|
|
wait( 1 );
|
|
level thread maps\pel2_forest::forest_friendlies();
|
|
|
|
}
|
|
|
|
|
|
|
|
chain_bunker_flame_back()
|
|
{
|
|
|
|
level endon( "trig_flame_bunker_exit" );
|
|
|
|
waittill_aigroupcleared( "flame_bunker_defenders_ai_2" );
|
|
|
|
chain_trig = getent( "chain_bunker_flame_back", "targetname" );
|
|
if( isdefined( chain_trig ) )
|
|
{
|
|
chain_trig notify( "trigger" );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bunkers_flamed_fx()
|
|
{
|
|
|
|
// TODO
|
|
// sometimes this has gotten hung up at
|
|
// spawn waittill( "finished spawning" );
|
|
// in spawn_failed() in _utility.gsc. not sure why that would happen only here, but i'm gonna thread this just to be safe. if
|
|
// the scene ever plays out without the guys burning on the inside, then the spawn probably failed somehow
|
|
level thread simple_spawn( "bunker_post_flame_spawners", ::bunker_post_flame_strat );
|
|
|
|
// TEMP FX
|
|
orig = getstruct( "orig_bunker_flame_fx_1", "targetname" );
|
|
|
|
earthquake( 0.75, 1.75, orig.origin, 1500 );
|
|
PlayRumbleOnPosition( "explosion_generic", orig.origin );
|
|
|
|
}
|
|
|
|
|
|
|
|
bunker_post_flame_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self.health = 1;
|
|
self.ignoreme = true;
|
|
self.ignoreall = true;
|
|
|
|
if( !isdefined( self.finished_spawning ) )
|
|
{
|
|
wait( 0.05 );
|
|
println( "*** GUZZO FIX THIS IF IT'S SPAMMING! --- bunker_post_flame_strat()" );
|
|
}
|
|
|
|
if( isdefined( self.script_noteworthy ) && self.script_noteworthy == "table_climb_guy" )
|
|
{
|
|
|
|
self animscripts\shared::placeWeaponOn( self.primaryweapon, "none");
|
|
|
|
self.animname = "bunkers";
|
|
|
|
self.allowdeath = true;
|
|
self.a.nodeath = true;
|
|
|
|
level thread stop_table_death( self );
|
|
|
|
// fire that spawns on the guy & charring behavior
|
|
self thread animscripts\death::flame_death_fx();
|
|
|
|
anim_node = getnode( "node_flame_bunker_explode", "targetname" );
|
|
|
|
anim_single_solo( self, "dazed_table", undefined, anim_node );
|
|
self dodamage( self.health + 1, (0,0,0) );
|
|
|
|
}
|
|
else
|
|
{
|
|
self.a.special = "none";
|
|
self.a.forceflamedeath = true;
|
|
self dodamage( self.health + 1, (0,0,0) );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
stop_table_death( guy )
|
|
{
|
|
guy waittill( "death" );
|
|
guy startRagdoll();
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// VO for flaming the flame bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
flame_bunker_vo()
|
|
{
|
|
|
|
level endon( "bunker_window_1_flamed" );
|
|
level endon( "bunker_killed_but_not_flamed" );
|
|
|
|
flag_wait( "flame_guy_killed" );
|
|
|
|
wait( 2.0 );
|
|
|
|
level thread flame_bunker_get_flame_vo();
|
|
level thread bunker_defenders_rhythm_stop();
|
|
|
|
// wait till a guy gets the flamethrower
|
|
while( !flag( "player_got_flamethrower" ) )
|
|
{
|
|
|
|
players = get_players();
|
|
for( i = 0; i < players.size; i++ )
|
|
{
|
|
if( players[i] HasWeapon( "m2_flamethrower" ) )
|
|
{
|
|
flag_set( "player_got_flamethrower" );
|
|
|
|
objective_string( 3, &"PEL2_FLAME_BUNKER" );
|
|
objective_position( 3, (-281, -7098, -26) );
|
|
objective_ring( 3 );
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
wait( 0.5 );
|
|
|
|
}
|
|
|
|
// give VO support on what to do
|
|
while( !flag( "bunker_window_1_flamed" ) )
|
|
{
|
|
|
|
random_int = randomint( 100 );
|
|
// choose which VO variation to play
|
|
if( random_int > 66 )
|
|
{
|
|
play_vo( level.roebuck, "vo", "burn_those_mgs" );
|
|
}
|
|
else if( random_int > 33 )
|
|
{
|
|
play_vo( level.roebuck, "vo", "get_that_flamethrower_on" );
|
|
}
|
|
else
|
|
{
|
|
play_vo( level.roebuck, "vo", "burn_em_out" );
|
|
}
|
|
|
|
objective_ring( 3 );
|
|
wait( RandomIntRange( 10, 17 ) );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
flame_bunker_get_flame_vo()
|
|
{
|
|
|
|
wait( 1 );
|
|
|
|
play_vo( level.roebuck, "vo", "get_the_flamethrower" );
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
wait( 5 );
|
|
|
|
vo_just_played = false;
|
|
|
|
while( !flag( "player_got_flamethrower" ) )
|
|
{
|
|
|
|
flag_wait( "flame_bunker_rhythm_stop" );
|
|
|
|
if( !vo_just_played )
|
|
{
|
|
wait( 1.75 );
|
|
|
|
if( RandomInt( 2 ) )
|
|
{
|
|
play_vo( level.roebuck, "vo", "get_the_flamethrower" );
|
|
}
|
|
else
|
|
{
|
|
play_vo( level.roebuck, "vo", "use_that_flamethrower" );
|
|
}
|
|
|
|
vo_just_played = true;
|
|
}
|
|
else
|
|
{
|
|
vo_just_played = false;
|
|
}
|
|
|
|
objective_ring( 3 );
|
|
|
|
wait( RandomIntRange( 5, 7 ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
flame_bunker_vo_2()
|
|
{
|
|
|
|
flag_wait( "bunkers_flamed" );
|
|
|
|
wait( 1.55 );
|
|
|
|
// only say this VO if the bunkers were actually flamed
|
|
if( !flag( "bunker_killed_but_not_flamed" ) )
|
|
{
|
|
play_vo( level.polonsky, "vo", "hell_yeah_burn" );
|
|
wait( 3 );
|
|
play_vo( level.roebuck, "vo", "okay_move_up" );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Clean up color chains
|
|
//
|
|
///////////////////////////////
|
|
|
|
clean_up_bunker_chains()
|
|
{
|
|
flag_wait( "trig_bunker_2_start" );
|
|
delete_noteworthy_ents( "friendly_chain_bunkers_2" );
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// don't advance friendlies near bunker 1's entrance until it's mostly clear
|
|
//
|
|
///////////////////////////////
|
|
|
|
chain_bunkers_entrance()
|
|
{
|
|
|
|
far_trig = getent( "trig_chain_bunkers_entrance_past", "targetname" );
|
|
level thread set_flag_on_trigger( far_trig, "chain_bunkers_entrance_past" );
|
|
|
|
// end this check if the player advances far enough ahead
|
|
level endon( "chain_bunkers_entrance_past" );
|
|
|
|
// give enemies some time to get in place
|
|
wait( 5 );
|
|
|
|
waittill_aigroupcount( "bunker_1_pre_ai", 2 );
|
|
|
|
main_trig = getent( "trig_chain_bunkers_entrance", "targetname" );
|
|
main_trig notify( "trigger" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// don't advance friendlies near bunker 2's back until it's mostly clear
|
|
//
|
|
///////////////////////////////
|
|
|
|
chain_bunkers_5()
|
|
{
|
|
// notify comes from flag set on trigger
|
|
level endon( "trig_chain_bunkers_5" );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
guys_count = get_specific_ai( "47mm_2_noteworthy" ).size;
|
|
guys_count += get_ai_group_count( "bunker_2_back_ai" );
|
|
|
|
if( guys_count < 2 )
|
|
{
|
|
break;
|
|
}
|
|
|
|
wait( 0.4 );
|
|
|
|
}
|
|
|
|
chain_trig = getent( "friendly_chain_bunkers_5", "script_noteworthy" );
|
|
chain_trig notify( "trigger" );
|
|
|
|
// delete other triggers that are further back
|
|
delete_noteworthy_ents( "friendly_chain_bunkers_4" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Get heroes in cover from mg bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunkers_end_heros_in_place()
|
|
{
|
|
|
|
hero_nodes = getnodearray( "node_heroes_bunkers_end", "targetname" );
|
|
assertex( hero_nodes.size >= level.heroes.size, "not enough goal_nodes for heroes!" );
|
|
|
|
suppression_target = convert_aiming_struct_to_origin( "orig_flame_bunker_heroes_targ" );
|
|
level thread flame_move_target( suppression_target, 4 );
|
|
|
|
for( i = 0; i < level.heroes.size; i++ )
|
|
{
|
|
level.heroes[i].goalradius = 20;
|
|
level.heroes[i] setgoalnode( hero_nodes[i] );
|
|
level.heroes[i] thread bunkers_end_heroes_strat( hero_nodes[i] );
|
|
}
|
|
|
|
play_vo( level.roebuck, "vo", "everyone_on_me" );
|
|
|
|
flag_wait( "bunkers_flamed" );
|
|
|
|
// stop moving script origins
|
|
suppression_target notify( "stop_fakefire_mover" );
|
|
suppression_target delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Heroes strategy for firing at flame bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunkers_end_heroes_strat( goal )
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
self setcandamage( false );
|
|
self waittill( "goal" );
|
|
|
|
self.pacifist = 1;
|
|
self.pacifistwait = 0.05;
|
|
|
|
// TODO technically if guys weren't at their position when this happened then this waittill would never be satisfied (if this happens something
|
|
// else is really wrong, but i should fix this setup anyway)
|
|
level waittill( "suppressing_fire" );
|
|
|
|
if( self == level.roebuck )
|
|
{
|
|
play_vo( self, "vo", "suppressing_fire_on_mgs" );
|
|
}
|
|
|
|
suppression_target = getent( "orig_flame_bunker_heroes_targ_converted", "targetname" );
|
|
self SetEntityTarget( suppression_target );
|
|
|
|
self.pacifist = 0;
|
|
self.ignoreall = 0;
|
|
self.ignoresuppression = 1;
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
wait( 5.25 + RandomFloat( 0.5 ) );
|
|
|
|
self.bulletsinclip = 0;
|
|
|
|
self ClearEntityTarget();
|
|
|
|
self.pacifist = 1;
|
|
self.ignoreall = 1;
|
|
self.ignoresuppression = 0;
|
|
|
|
level waittill( "suppressing_fire" );
|
|
|
|
wait( RandomFloat( 0.35 ) );
|
|
|
|
self SetEntityTarget( suppression_target );
|
|
|
|
self.pacifist = 0;
|
|
self.ignoreall = 0;
|
|
self.ignoresuppression = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// VO for end bunker section
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunkers_end_heroes_vo()
|
|
{
|
|
|
|
level endon( "bunker_suppressed_twice" );
|
|
|
|
wait( 4 );
|
|
|
|
wait( 1 );
|
|
|
|
while( !flag( "bunkers_flamed" ) )
|
|
{
|
|
level notify( "suppressing_fire" );
|
|
wait( 10 );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Handles the mgs in the flame bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_mg_killzone()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
level endon( "mgs_focus_on_flamer" );
|
|
|
|
level.player_being_targetted = false;
|
|
|
|
killzone_trigger = getent( "trig_bunker_mg_killzone", "targetname" );
|
|
killzone_trigger_extra = getent( "trig_bunker_mg_killzone_extra", "targetname" );
|
|
|
|
while( !flag( "bunkers_flamed" ) )
|
|
{
|
|
|
|
player_touching = get_player_touching( killzone_trigger );
|
|
player_touching_2 = undefined;
|
|
|
|
// sometimes check this extra volume
|
|
if( !RandomInt( 9 ) )
|
|
{
|
|
player_touching_2 = get_player_touching( killzone_trigger_extra );
|
|
}
|
|
|
|
// if the player is touching either volume but isn't yet being targeted, or if he should be force targetted
|
|
if( ( ( IsDefined( player_touching ) || IsDefined( player_touching_2 ) ) && !level.player_being_targetted ) || level.force_player_being_targetted )
|
|
{
|
|
|
|
if( level.smoke_grenades_on_the_scene )
|
|
{
|
|
wait( 2 );
|
|
continue;
|
|
}
|
|
|
|
level.player_being_targetted = true;
|
|
|
|
// player is in the open, so fire at him now
|
|
quick_text( "player is in the open", 2, false );
|
|
level thread mgs_focus_on_ai();
|
|
wait( 2 );
|
|
|
|
}
|
|
// if the player is no longer touching the volume but is still being targeted
|
|
else if( !IsDefined( player_touching ) && level.player_being_targetted )
|
|
{
|
|
|
|
wait( RandomFloatRange( 1.0, 2.25 ) );
|
|
|
|
if( flag( "bunkers_flamed" ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
level.player_being_targetted = false;
|
|
level thread mgs_focus_on_origins();
|
|
|
|
}
|
|
|
|
wait( 0.25 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
smoke_grenade_on_the_scene()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
trig = getent( "trig_bunker_regroup", "targetname" );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
grenades = GetEntArray( "grenade", "classname" );
|
|
|
|
for( i = 0 ; i < grenades.size; i++ )
|
|
{
|
|
if( grenades[i].model == "projectile_us_smoke_grenade" && grenades[i] istouching( trig ) && !isdefined( grenades[i].pel2_counted ) )
|
|
{
|
|
grenades[i].pel2_counted = true;
|
|
level.smoke_grenades_on_the_scene++;
|
|
level thread smoke_grenade_check_decrement();
|
|
}
|
|
}
|
|
|
|
wait( 0.75 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
smoke_grenade_check_decrement()
|
|
{
|
|
wait( 34 ); // length of time for smoke to dissipate
|
|
level.smoke_grenades_on_the_scene--;
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// If all japanese defenders around the gun area are killed, these guys should hop off the gun
|
|
//
|
|
///////////////////////////////
|
|
|
|
guys_47mm_1_force_expand()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
trig = getent( "trig_47mm_1_radius_expand", "targetname" );
|
|
trig endon( "trigger" );
|
|
|
|
waittill_aigroupcleared( "bunker_1_pre_ai" );
|
|
|
|
trig notify( "trigger" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// When nearby trig radius is hit, get guys off the gun and expand their goal radius so they can join the fight
|
|
//
|
|
///////////////////////////////
|
|
|
|
guys_47mm_1_radius_expand()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
trigger_wait( "trig_47mm_1_radius_expand", "targetname" );
|
|
|
|
change_noteworthy_goalradii( "47mm_1_noteworthy", 465 );
|
|
|
|
at_gun = getent( "bunker_gun_1", "targetname" );
|
|
at_gun notify ("shut down arty");
|
|
|
|
//give guns
|
|
for (i = 0; i < at_gun.arty_crew.size; i++)
|
|
{
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
at_gun.arty_crew[i] animscripts\shared::placeWeaponOn( at_gun.arty_crew[i].primaryweapon, "right");
|
|
}
|
|
}
|
|
|
|
array_thread( at_gun.arty_crew, ::set_pacifist_off );
|
|
|
|
}
|
|
|
|
|
|
|
|
guys_47mm_2_radius_expand()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
flag_wait( "marines_advance" );
|
|
|
|
nodes = getnodearray( "node_at47_retreat", "script_noteworthy" );
|
|
|
|
guys = get_specific_ai( "47mm_2_noteworthy" );
|
|
|
|
// kill off one if all four are alive
|
|
if( guys.size == 4 )
|
|
{
|
|
guys[0] thread bloody_death( true );
|
|
}
|
|
|
|
wait( 0.05 );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
if( !isdefined( guys[i] ) || !isalive( guys[i] ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
guys[i] notify( "killanimscript" );
|
|
guys[i].goalradius = 40;
|
|
guys[i].health = 40;
|
|
guys[i].ignoresuppression = 1;
|
|
guys[i] setgoalnode( nodes[i] );
|
|
|
|
// we want this guy's goalradius to expand after he gets there
|
|
if( nodes[i].targetname == "auto1998" )
|
|
{
|
|
guys[i] thread delay_at47_retreat_goalradius();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
at_gun = getent( "bunker_gun_2", "targetname" );
|
|
at_gun notify ("shut down arty");
|
|
|
|
//give guns
|
|
for (i = 0; i < at_gun.arty_crew.size; i++)
|
|
{
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
at_gun.arty_crew[i] animscripts\shared::placeWeaponOn( at_gun.arty_crew[i].primaryweapon, "right");
|
|
}
|
|
}
|
|
|
|
array_thread( at_gun.arty_crew, ::set_pacifist_off );
|
|
|
|
}
|
|
|
|
|
|
|
|
delay_at47_retreat_goalradius()
|
|
{
|
|
self endon( "death" );
|
|
self waittill( "goal" );
|
|
self.goalradius = 300;
|
|
}
|
|
|
|
|
|
|
|
guys_47mm_4_radius_expand()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
trigger_wait( "trig_47mm_4_radius_expand", "targetname" );
|
|
|
|
change_noteworthy_goalradii( "47mm_4_noteworthy", 450 );
|
|
|
|
at_gun = getent( "bunker_gun_4", "targetname" );
|
|
at_gun notify ("shut down arty");
|
|
|
|
//give guns
|
|
for (i = 0; i < at_gun.arty_crew.size; i++)
|
|
{
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
at_gun.arty_crew[i] animscripts\shared::placeWeaponOn( at_gun.arty_crew[i].primaryweapon, "right");
|
|
}
|
|
}
|
|
|
|
array_thread( at_gun.arty_crew, ::set_pacifist_off );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Expand the goal radii of the axis guys on the frontline when the player surprises them from behind
|
|
//
|
|
///////////////////////////////
|
|
|
|
guys_frontline_radius_expand() {
|
|
|
|
|
|
trigger_wait( "trig_frontline_radius_expand", "targetname" );
|
|
|
|
level notify( "frontline_radius_expand" );
|
|
|
|
change_noteworthy_goalradii( "frontline_axis_ai", 550 );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// This guy is near the at47 as backup; we want his goalradius expanding sooner than the others
|
|
//
|
|
///////////////////////////////
|
|
|
|
guys_frontline_radius_expand_2() {
|
|
|
|
|
|
wait( 3.75 );
|
|
|
|
change_ai_group_goalradii( "frontline_axis_ai_2", 350 );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Guy that notices marines' ambush and signals the alarm
|
|
//
|
|
///////////////////////////////
|
|
|
|
alarm_mg_guy()
|
|
{
|
|
|
|
alarm_guy = get_specific_single_ai( "bunker_gun_1_notifier" );
|
|
|
|
if( isdefined( alarm_guy ) && isalive( alarm_guy ) )
|
|
{
|
|
|
|
alarm_guy endon( "death" );
|
|
|
|
alarm_guy.ignoreme = true;
|
|
alarm_guy.goalradius = 40;
|
|
alarm_guy.pacifist = 1;
|
|
alarm_guy.pacifistwait = 0.05;
|
|
|
|
wait( 1.0 );
|
|
|
|
alarm_guy.ignoreall = 1;
|
|
goal_node = getnode( "auto793", "targetname" );
|
|
alarm_guy setgoalnode( goal_node );
|
|
|
|
alarm_guy waittill( "goal" );
|
|
|
|
alarm_guy.ignoreall = 0;
|
|
alarm_guy.pacifist = 0;
|
|
alarm_guy.goalradius = 200;
|
|
alarm_guy.ignoreme = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bunker_1_pre_spawners_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self thread end_pacifist( 4 );
|
|
|
|
self.ignoresuppression = 1;
|
|
|
|
self waittill_either( "goal", "end_pacifist" );
|
|
|
|
self.ignoresuppression = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Sends a notify to stop pacifist on very specific ai
|
|
//
|
|
///////////////////////////////
|
|
|
|
end_pacifist( wait_time )
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
if( isdefined( wait_time ) )
|
|
{
|
|
wait( wait_time );
|
|
}
|
|
else
|
|
{
|
|
wait( 3 );
|
|
}
|
|
|
|
self notify( "end_pacifist" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Have bunker 1 back spawners retreat back near bunker 2
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_1_retreat()
|
|
{
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_mid_bunker_retreat" );
|
|
|
|
extra_text( "bunker_1_retreat" );
|
|
|
|
guys = get_ai_group_ai( "bunker_1_back_ai" );
|
|
//goal_spots = getstructarray( "orig_bunker_1_back", "targetname" );
|
|
// hard-coding these to save script vars (script_structs cost several script_vars each)
|
|
goal_spots = [];
|
|
goal_spots[goal_spots.size] = ((802, -8973, 3.5));
|
|
goal_spots[goal_spots.size] = ((1078, -9089, -18.5));
|
|
goal_spots[goal_spots.size] = ((1033, -9211, 7.5));
|
|
goal_spots[goal_spots.size] = ((786, -9236, 5.5));
|
|
goal_spots[goal_spots.size] = ((654, -9201, -12.5));
|
|
goal_spots[goal_spots.size] = ((532, -9395, 1.5));
|
|
|
|
goal_spots = array_randomize( goal_spots );
|
|
|
|
assertex( goal_spots.size >= guys.size, "not enough goal_pos for guys!" );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
if( isalive( guys[i] ) )
|
|
{
|
|
guys[i] thread bunker_1_retreat_strat_b( goal_spots[i] );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bunker_1_retreat_strat_b( goal_pos )
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
wait( randomfloatrange( 0.4, 3.0 ) );
|
|
|
|
self.goalradius = 50;
|
|
self.ignoreall = 1;
|
|
self.ignoresuppression = 1;
|
|
|
|
self setgoalpos( goal_pos );
|
|
|
|
self waittill( "goal" );
|
|
|
|
self.goalradius = 450;
|
|
self.ignoreall = 0;
|
|
self.ignoresuppression = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Stop current color reinforcements
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_stop_friendly_waves()
|
|
{
|
|
|
|
trigger_wait( "friendly_respawn_clear_bunkers", "script_noteworthy" );
|
|
|
|
flag_set( "trig_forest_friendlies" );
|
|
|
|
// TODO can get rid of this now?
|
|
//unless this is here, friendly_spawner_vision_checker() in _colors.gsc will still spawn reinforcements in some instances
|
|
level.respawn_spawner = undefined;
|
|
|
|
// to stop guys from being respawned in as blue guys when the next friendly_respawn_trigger is hit (also done in lastSequence() in bog_b.gsc)
|
|
allies = getaiarray( "allies" );
|
|
for( i = 0; i < allies.size; i++ )
|
|
{
|
|
allies[i] disable_replace_on_death();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// When player clears bunkers, have pinned down allies move up to join the battle
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_1_clear()
|
|
{
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_marines_advance" );
|
|
|
|
quick_text( "marines advance!", 3, true );
|
|
flag_set( "marines_advance" );
|
|
|
|
maps\_spawner::kill_spawnernum( 109 );
|
|
|
|
level thread bunker_1_mgs_off();
|
|
|
|
// stop allied drones in mangrove section
|
|
level notify( "end_mangrove_drones" );
|
|
|
|
// reinforcements now come from the main group of marines
|
|
new_respawn_trig = getent( "trigger_bunker_wave_4", "script_noteworthy" );
|
|
new_respawn_trig notify( "trigger" );
|
|
|
|
// intro guys advance from cover
|
|
intro_guys_advance();
|
|
|
|
// spawn guys held off by bunker 2
|
|
|
|
// Wii optimizations
|
|
if( !level.wii )
|
|
{
|
|
simple_spawn( "bunker_2_ambient_friendlies", ::bunker_2_ambient_friendlies_approach );
|
|
}
|
|
|
|
// spawn flame dude
|
|
level.flamer = simple_spawn_single( "flamer_guy", ::flamer_spawn_strat );
|
|
assertex( isdefined( level.flamer ), "level.flamer not defined! bad bad bad!" );
|
|
|
|
level.flamer thread flamer_advance_bunkers();
|
|
|
|
level thread bunker_1_axis_banzai();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// if player is mostly pass bunker 1, have 2 inside defenders run out and banzai charge
|
|
// (prevents ai from shooting backwards into the bunker once they've moved up)
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_1_axis_banzai()
|
|
{
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_marines_advance" );
|
|
|
|
wait( RandomIntRange( 2, 4 ) );
|
|
|
|
guys = get_ai_group_ai( "bunker_1_ai_chargers" );
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guys[i].banzai_no_wait = 1;
|
|
guys[i].ignoresuppression = 1;
|
|
guys[i] thread maps\_banzai::banzai_force();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// intro guys advance from cover and join the bunkers battle
|
|
//
|
|
///////////////////////////////
|
|
|
|
intro_guys_advance()
|
|
{
|
|
|
|
intro_guys = get_ai_group_ai( "intro_igc_ai" );
|
|
|
|
for( i = 0; i < intro_guys.size; i++ )
|
|
{
|
|
|
|
intro_guys[i] setcandamage( true );
|
|
|
|
if( isdefined( intro_guys[i].script_noteworthy ) )
|
|
{
|
|
intro_guys[i].moveplaybackrate = 1.3;
|
|
intro_guys[i] thread maps\_spawner::go_to_node( getnode( intro_guys[i].script_noteworthy, "targetname" ) );
|
|
}
|
|
|
|
intro_guys[i] thread intro_guys_ai_stop_shield();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// turn off mgs in the first bunker
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_1_mgs_off()
|
|
{
|
|
|
|
wait( 3 );
|
|
|
|
guys = get_ai_group_ai( "intro_mg_ai" );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guys[i] StopUSeturret();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
bunker_2_ambient_friendlies_approach()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self.health = 200;
|
|
|
|
flag_wait( "flamer_advance_to_3" );
|
|
|
|
goal_node = getnode( self.script_noteworthy, "targetname" );
|
|
self setgoalnode( goal_node );
|
|
|
|
}
|
|
|
|
|
|
|
|
intro_guys_ai_stop_shield()
|
|
{
|
|
|
|
self waittill( "goal" );
|
|
|
|
self.moveplaybackrate = 1;
|
|
|
|
if( IsDefined( self.magic_bullet_shield ) && self.magic_bullet_shield )
|
|
{
|
|
self stop_magic_bullet_shield();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// When player clears bunkers, have pinned down allies move up to join the battle
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_prepare_flame()
|
|
{
|
|
|
|
event_text( "waiting to clear end bunkers" );
|
|
|
|
regroup_trig = getent( "trig_bunker_regroup", "targetname" );
|
|
|
|
event_text( "waiting to regroup" );
|
|
|
|
// wait till player is back with squad near sandbags
|
|
while( 1 )
|
|
{
|
|
if( any_player_IsTouching( regroup_trig ) )
|
|
{
|
|
break;
|
|
}
|
|
wait( 0.5 );
|
|
}
|
|
|
|
level notify( "obj_bunker_regroup_complete" );
|
|
flag_set( "bunker_regroup_complete" );
|
|
level thread bunkers_end_heroes_vo();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Paces out shooting of the mgs so it appears as if they take a break to reload once in a while
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_defenders_rhythm_stop()
|
|
{
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
turret_left = getent( "flame_bunker_mg_l", "targetname" );
|
|
turret_right = getent( "flame_bunker_mg_r", "targetname" );
|
|
|
|
while( 1 )
|
|
{
|
|
|
|
wait( RandomIntRange( 11, 13 ) );
|
|
|
|
guy_1 = get_ai_group_ai( "last_bunker_ai_1" );
|
|
guy_2 = get_ai_group_ai( "last_bunker_ai_2" );
|
|
|
|
// don't do the stop when the flamer death vignette is about to happen
|
|
if( flag( "mgs_focus_on_flamer" ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// only stop when both guys are alive and ready to stop
|
|
if( isdefined( guy_1[0] ) && isdefined( guy_2[0] ) && guy_1[0].pel2_rhythm_stop && guy_2[0].pel2_rhythm_stop )
|
|
{
|
|
|
|
quick_text( "rhythm stop!" );
|
|
flag_set( "flame_bunker_rhythm_stop" );
|
|
|
|
turret_left notify( "stop_burst_fire_unmanned" );
|
|
turret_left notify( "turretstatechange" );
|
|
wait( RandomFloatRange( 1.0, 1.5 ) );
|
|
turret_right notify( "stop_burst_fire_unmanned" );
|
|
turret_right notify( "turretstatechange" );
|
|
|
|
guy_1[0].pacifist = true;
|
|
guy_2[0].pacifist = true;
|
|
|
|
wait( RandomFloatRange( 3.5, 4.5 ) );
|
|
|
|
quick_text( "rhythm start!" );
|
|
flag_clear( "flame_bunker_rhythm_stop" );
|
|
|
|
turret_left thread maps\_mgturret::burst_fire_unmanned();
|
|
wait( RandomFloatRange( 1.0, 1.5 ) );
|
|
turret_right thread maps\_mgturret::burst_fire_unmanned();
|
|
|
|
if( isdefined( guy_1[0] ) && isalive( guy_1[0] ) )
|
|
{
|
|
guy_1[0].pacifist = false;
|
|
}
|
|
if( isdefined( guy_2[0] ) && isalive( guy_2[0] ) )
|
|
{
|
|
guy_2[0].pacifist = false;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Guys on mgs in last bunker of E2
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_defenders_strat()
|
|
{
|
|
|
|
self thread bunker_defenders_death_watch();
|
|
|
|
self endon( "death" );
|
|
|
|
self.pel2_rhythm_stop = false;
|
|
self.grenadeawareness = 0;
|
|
self.ignoresuppression = true;
|
|
self.ignoreall = true;
|
|
|
|
self waittill( "goal" );
|
|
|
|
self.ignoreall = false;
|
|
|
|
wait( RandomIntRange( 5, 7 ) );
|
|
|
|
self.pel2_rhythm_stop = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// take it as an act of suppression towards the bunker if one of the mg guys is killed
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_defenders_death_watch()
|
|
{
|
|
self waittill( "death" );
|
|
level.bunker_mg_damage_total += 150;
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Ambient tanks in the distance get blown up from the at47s
|
|
//
|
|
///////////////////////////////
|
|
|
|
intro_tank_lookat()
|
|
{
|
|
|
|
level thread trig_override( "trig_intro_tank_lookat" );
|
|
// wait for player to look in the tanks' direction
|
|
trigger_wait( "trig_intro_tank_lookat", "targetname" );
|
|
|
|
maps\_vehicle::create_vehicle_from_spawngroup_and_gopath( 200 );
|
|
|
|
vnode = getvehiclenode( "node_intro_tank_die", "script_noteworthy" );
|
|
vnode waittill( "trigger" );
|
|
|
|
tank = getent( "intro_tank_1", "targetname" );
|
|
|
|
playfx( level._effect["arty_dirt"], tank.origin, (1,0,0) );
|
|
|
|
radiusdamage( tank.origin, 10, tank.health, tank.health );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Strategy for guys that are pinned down in the intro igc
|
|
//
|
|
///////////////////////////////
|
|
|
|
intro_igc_friendlies_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self thread magic_bullet_shield();
|
|
self setcandamage( false );
|
|
self.pacifist = true;
|
|
self.ignoresuppression = true;
|
|
self.baseAccuracy = 0.05;
|
|
// self.drawoncompass = false; broken because of networking stuff
|
|
|
|
level waittill( "obj_mangrove_complete" );
|
|
|
|
wait( 8 );
|
|
|
|
// self.drawoncompass = true;
|
|
self.pacifist = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// flamethrower guy flames the truck near the flame bunkers
|
|
//
|
|
///////////////////////////////
|
|
|
|
flame_truck()
|
|
{
|
|
|
|
level notify( "start_flame_truck" );
|
|
|
|
self.pacifist = 0;
|
|
|
|
// set up the spot (script_origin) where he fires at
|
|
truck_spot = convert_aiming_struct_to_origin( "orig_flame_truck_2" );
|
|
level thread flame_move_target( truck_spot, 3 );
|
|
self SetEntityTarget( truck_spot );
|
|
|
|
wait( 3.5 );
|
|
|
|
// in case flames didnt blow up truck, do it manually
|
|
truck = getent( "flame_truck", "script_noteworthy" );
|
|
if( truck.health > 0 )
|
|
{
|
|
radiusdamage( truck.origin, 1, truck.health + 1, truck.health + 1 );
|
|
}
|
|
|
|
self ClearEntityTarget();
|
|
truck_spot notify( "stop_fakefire_mover" );
|
|
self.pacifist = 1;
|
|
|
|
// make sure they're all dead
|
|
kill_aigroup( "forest_truck_ai" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Flamebunker MGs fire towards the hero squad/flame guy
|
|
//
|
|
///////////////////////////////
|
|
|
|
mgs_focus_on_origins( focus )
|
|
{
|
|
|
|
//mgs focus fire on script origins
|
|
mg_left = getent( "flame_bunker_mg_l", "targetname" );
|
|
mg_right = getent( "flame_bunker_mg_r", "targetname" );
|
|
|
|
targ_1 = getent( "bunker_end_target_1_converted", "targetname" );
|
|
targ_1a = getent( "bunker_end_target_1a_converted", "targetname" );
|
|
targ_2 = getent( "bunker_end_target_2_converted", "targetname" );
|
|
targ_2a = getent( "bunker_end_target_2a_converted", "targetname" );
|
|
targ_3 = getent( "bunker_end_target_3_converted", "targetname" );
|
|
|
|
// set default old targets
|
|
mg_left.pel2_old_target_ent = targ_2a;
|
|
mg_right.pel2_old_target_ent = targ_2;
|
|
|
|
if( !isdefined( focus ) )
|
|
{
|
|
focus = "previous_targets";
|
|
}
|
|
|
|
quick_text( "mgs_focus on " + focus, 3, true );
|
|
|
|
|
|
if( focus == "both_flamer" )
|
|
{
|
|
|
|
mg_left SetTargetEntity( targ_1 );
|
|
mg_left.pel2_old_target_ent = targ_1;
|
|
|
|
mg_right SetTargetEntity( targ_1a );
|
|
mg_right.pel2_old_target_ent = targ_1a;
|
|
|
|
}
|
|
else if( focus == "both_berm" )
|
|
{
|
|
|
|
mg_left SetTargetEntity( targ_2a );
|
|
mg_left.pel2_old_target_ent = targ_2a;
|
|
|
|
mg_right SetTargetEntity( targ_2 );
|
|
mg_right.pel2_old_target_ent = targ_2;
|
|
|
|
}
|
|
else if( focus == "left_flamer_right_berm" )
|
|
{
|
|
|
|
mg_left SetTargetEntity( targ_3 );
|
|
mg_left.pel2_old_target_ent = targ_3;
|
|
|
|
mg_right SetTargetEntity( targ_2 );
|
|
mg_right.pel2_old_target_ent = targ_2;
|
|
|
|
}
|
|
else if( focus == "previous_targets" )
|
|
{
|
|
|
|
mg_left SetTargetEntity( mg_left.pel2_old_target_ent );
|
|
mg_right SetTargetEntity( mg_right.pel2_old_target_ent );
|
|
|
|
}
|
|
|
|
guys = getaiarray( "allies" );
|
|
array_thread( guys, ::set_ignoreme_on );
|
|
|
|
set_players_ignoreme( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// MGs target the flamer to kill him
|
|
//
|
|
///////////////////////////////
|
|
|
|
mgs_focus_on_flamer()
|
|
{
|
|
|
|
flag_set( "mgs_focus_on_flamer" );
|
|
|
|
set_players_ignoreme( true );
|
|
|
|
mg_left = getent( "flame_bunker_mg_l", "targetname" );
|
|
mg_right = getent( "flame_bunker_mg_r", "targetname" );
|
|
|
|
mg_left cleartargetentity();
|
|
mg_right cleartargetentity();
|
|
|
|
flamer_spot = convert_aiming_struct_to_origin( "orig_flamer_death_spot" );
|
|
|
|
mg_left SetTargetEntity( flamer_spot );
|
|
mg_right SetTargetEntity( flamer_spot );
|
|
|
|
guy_1 = get_ai_group_ai( "last_bunker_ai_1" );
|
|
for( i = 0; i < guy_1.size; i++ )
|
|
{
|
|
guy_1[i] setcandamage( false );
|
|
}
|
|
guy_2 = get_ai_group_ai( "last_bunker_ai_2" );
|
|
for( i = 0; i < guy_2.size; i++ )
|
|
{
|
|
guy_2[i] setcandamage( false );
|
|
}
|
|
|
|
flag_wait( "flame_guy_killed" );
|
|
|
|
if( isdefined( guy_1[0] ) )
|
|
{
|
|
guy_1[0] setcandamage( true );
|
|
}
|
|
if( isdefined( guy_2[0] ) )
|
|
{
|
|
guy_2[0] setcandamage( true );
|
|
}
|
|
|
|
flag_clear( "mgs_focus_on_flamer" );
|
|
|
|
level endon( "bunkers_flamed" );
|
|
|
|
level.current_mg_focus = "both_berm";
|
|
if( !level.player_being_targetted )
|
|
{
|
|
level thread mgs_focus_on_origins( level.current_mg_focus );
|
|
}
|
|
|
|
// restart the killzone
|
|
level thread bunker_mg_killzone();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Flamebunker mgs target the player because he got too close
|
|
//
|
|
///////////////////////////////
|
|
|
|
mgs_focus_on_ai()
|
|
{
|
|
|
|
mg_1 = getent( "flame_bunker_mg_l", "targetname" );
|
|
mg_2 = getent( "flame_bunker_mg_r", "targetname" );
|
|
|
|
mg_1 cleartargetentity();
|
|
mg_2 cleartargetentity();
|
|
|
|
set_players_ignoreme( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Guys that escort the flame guy into the battle
|
|
//
|
|
///////////////////////////////
|
|
|
|
flame_squad_remainder()
|
|
{
|
|
|
|
// send reinforcements up
|
|
guys = get_ai_group_ai( "bunker_2_ambient_friendlies_ai" );
|
|
goal_nodes = getnodearray( "node_advance_end_bunkers", "targetname" );
|
|
assertex( goal_nodes.size >= guys.size, "not enough goal_nodes for guys!" );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guys[i] setgoalnode( goal_nodes[i] );
|
|
guys[i] thread bunker_2_ambient_friendlies_strat();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Sets up drone character models
|
|
//
|
|
///////////////////////////////
|
|
|
|
setup_drone_models()
|
|
{
|
|
|
|
// setup drone characters
|
|
character\char_jap_pel2_rifle::precache();
|
|
character\char_usa_marine_r_rifle::precache();
|
|
// These are called everytime a drone is spawned in to set up the character.
|
|
level.drone_spawnFunction["axis"] = character\char_jap_pel2_rifle::main;
|
|
level.drone_spawnFunction["allies"] = character\char_usa_marine_r_rifle::main;
|
|
|
|
if(NumRemoteClients() > 1) // Remove all drones in coop with more than 1 remote player.
|
|
{
|
|
spawners = GetEntArray("drone_axis", "targetname");
|
|
|
|
for(i = 0; i < spawners.size; i ++)
|
|
{
|
|
spawners[i] delete();
|
|
}
|
|
|
|
spawners = GetEntArray("drone_allies", "targetname");
|
|
|
|
for(i = 0; i < spawners.size; i ++)
|
|
{
|
|
spawners[i] delete();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Strategy for guys that are spawned and run up and flame bunkers
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_2_ambient_friendlies_strat()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self.baseaccuracy = 0.05;
|
|
self.pacifist = 1;
|
|
self.ignoreme = true;
|
|
|
|
self waittill( "goal" );
|
|
|
|
self.pacifist = 0;
|
|
self.ignoreme = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Canned impact fx from the at47s in the ambient battle
|
|
//
|
|
///////////////////////////////
|
|
|
|
arty_fire_impacts( orig )
|
|
{
|
|
|
|
self endon( "shut down arty" );
|
|
self endon( "stop_arty_fire_loop" );
|
|
level endon( "obj_bunkers_complete" );
|
|
|
|
while( 1 )
|
|
{
|
|
self waittill( "arty_fire" );
|
|
wait( 0.5 );
|
|
playfx( level._effect["arty_dirt"], orig + random_vector( 40 ), (1,0,0) );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
arty_fake_fire_impacts( orig )
|
|
{
|
|
|
|
level endon( "stop_fake_arty_2" );
|
|
|
|
while( 1 )
|
|
{
|
|
wait( RandomFloatRange( 3, 4.5 ) );
|
|
playfx( level._effect["arty_dirt"], orig + random_vector( 40 ), (1,0,0) );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Set up AT crews
|
|
//
|
|
///////////////////////////////
|
|
|
|
bunker_1_47mm()
|
|
{
|
|
|
|
level waittill( "spawnvehiclegroup" + 21 );
|
|
|
|
wait( 0.05 );
|
|
|
|
at_gun = getent( "bunker_gun_1","targetname" );
|
|
|
|
//at_orig = getstruct( "orig_intro_at_impact_1", "targetname" );
|
|
at_gun thread arty_fire_impacts( (-1213.5, -11928.5, -59.7) );
|
|
|
|
array_thread( at_gun.arty_crew, ::set_ignoreme_on );
|
|
|
|
at_gun maps\_artillery::arty_fire_without_move();
|
|
|
|
|
|
// put their goalradii up so if/when they get off gun b/c of damage, they can take cover easily
|
|
for( i = 0; i < at_gun.arty_crew.size; i++ )
|
|
{
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
at_gun.arty_crew[i].goalradius = 400;
|
|
}
|
|
}
|
|
|
|
wait( 0.2 );
|
|
|
|
// kill off the commander; he isn't needed
|
|
for( i = 0; i < at_gun.arty_crew.size; i++ )
|
|
{
|
|
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
|
|
if( at_gun.arty_crew[i].animname == "commander" )
|
|
{
|
|
at_gun.arty_crew[i] dodamage( at_gun.arty_crew[i].health + 100, ( 0, 0, 0 ) );
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
wait( 1 );
|
|
|
|
at_gun maps\_artillery::arty_fire();
|
|
|
|
}
|
|
|
|
|
|
|
|
bunker_2_47mm()
|
|
{
|
|
|
|
//at_orig = getstruct( "orig_intro_at_impact_2", "targetname" );
|
|
level thread arty_fake_fire_impacts( (-1294, -12475, -57.7) );
|
|
|
|
level waittill( "spawnvehiclegroup" + 22 );
|
|
|
|
level notify( "stop_fake_arty_2" );
|
|
|
|
wait( 0.05 );
|
|
|
|
at_gun = getent( "bunker_gun_2","targetname" );
|
|
|
|
at_gun thread arty_fire_impacts( (-1294, -12475, -57.7) );
|
|
|
|
array_thread( at_gun.arty_crew, ::set_ignoreme_on );
|
|
|
|
at_gun maps\_artillery::arty_fire_without_move();
|
|
|
|
|
|
// put their goalradii up so if/when they get off gun b/c of damage, they can take cover easily
|
|
for( i = 0; i < at_gun.arty_crew.size; i++ )
|
|
{
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
at_gun.arty_crew[i].goalradius = 400;
|
|
}
|
|
}
|
|
|
|
wait( 0.2 );
|
|
|
|
// kill off the commander; he isn't needed
|
|
for( i = 0; i < at_gun.arty_crew.size; i++ )
|
|
{
|
|
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
|
|
if( at_gun.arty_crew[i].animname == "commander" )
|
|
{
|
|
at_gun.arty_crew[i] dodamage( at_gun.arty_crew[i].health + 100, ( 0, 0, 0 ) );
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
wait( 1 );
|
|
|
|
at_gun maps\_artillery::arty_fire();
|
|
|
|
}
|
|
|
|
|
|
|
|
bunker_4_47mm()
|
|
{
|
|
|
|
level waittill( "spawnvehiclegroup" + 24 );
|
|
|
|
wait( 0.05 );
|
|
|
|
at_gun = getent( "bunker_gun_4","targetname" );
|
|
|
|
for( i = 0; i < at_gun.arty_crew.size; i++ )
|
|
{
|
|
at_gun.arty_crew[i].goalradius = 30;
|
|
at_gun.arty_crew[i].ignoreme = true;
|
|
at_gun.arty_crew[i].ignoreall = true;
|
|
at_gun.arty_crew[i].pacifist = true;
|
|
at_gun.arty_crew[i].pacifistwait = 0.05;
|
|
}
|
|
|
|
at_gun maps\_artillery::arty_fire_without_move();
|
|
|
|
|
|
// put their goalradii up so if/when they get off gun b/c of damage, they can take cover easily
|
|
for( i = 0; i < at_gun.arty_crew.size; i++ )
|
|
{
|
|
if( isdefined( at_gun.arty_crew[i] ) && isalive( at_gun.arty_crew[i] ) )
|
|
{
|
|
at_gun.arty_crew[i].goalradius = 400;
|
|
}
|
|
}
|
|
|
|
wait( 0.2 );
|
|
|
|
at_gun maps\_artillery::arty_fire();
|
|
|
|
}
|
|
|
|
|
|
|
|
battle_line_ambient_sound()
|
|
{
|
|
|
|
temp_sound_orig = spawn( "script_origin", ( -1167.89, -8756.53, -51.1988 ) );
|
|
temp_sound_orig playloopsound( "battle_line_jap" );
|
|
|
|
temp_sound_orig_2 = spawn( "script_origin", ( -2394.69, -8158.39, -51.1988 ) );
|
|
temp_sound_orig_2 playloopsound( "battle_line_us" );
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_flame_bunker_exit" );
|
|
|
|
temp_sound_orig delete();
|
|
temp_sound_orig_2 delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
spawn_bunkers_pickup_weapons()
|
|
{
|
|
|
|
flag_wait( "trig_bunker_2_start" );
|
|
|
|
bunker_weapons = [];
|
|
|
|
// weapons in flame bunker
|
|
bunker_weapons[0] = spawnstruct();
|
|
bunker_weapons[0].weapon_name = "weapon_type97_frag";
|
|
bunker_weapons[0].origin = (-118.8, -6946.6, -23);
|
|
bunker_weapons[0].angles = (270, 240.6, 0);
|
|
|
|
bunker_weapons[1] = spawnstruct();
|
|
bunker_weapons[1].weapon_name = "weapon_type97_frag";
|
|
bunker_weapons[1].origin = (-120.7, -6933.9, -23);
|
|
bunker_weapons[1].angles = (270, 318.4, 0);
|
|
|
|
bunker_weapons[2] = spawnstruct();
|
|
bunker_weapons[2].weapon_name = "weapon_nambu";
|
|
bunker_weapons[2].origin = (-234, -6898.3, -12.5);
|
|
bunker_weapons[2].angles = (0, 70.1, -90.0001);
|
|
|
|
bunker_weapons[3] = spawnstruct();
|
|
bunker_weapons[3].weapon_name = "weapon_type99_rifle";
|
|
bunker_weapons[3].origin = (-405.6, -6903.9, -25.9);
|
|
bunker_weapons[3].angles = (295.642, 99.2652, -72.4286);
|
|
|
|
bunker_weapons[4] = spawnstruct();
|
|
bunker_weapons[4].weapon_name = "weapon_type99_rifle";
|
|
bunker_weapons[4].origin = (-407.7, -6898, -25.6);
|
|
bunker_weapons[4].angles = (294.595, 149.005, 167.911);
|
|
|
|
|
|
// grenades in bunker #2 in bunker event
|
|
bunker_weapons[5] = spawnstruct();
|
|
bunker_weapons[5].weapon_name = "weapon_type97_frag";
|
|
bunker_weapons[5].origin = (84.8, -8512.4, -26.5);
|
|
bunker_weapons[5].angles = (270, 318.4, 0);
|
|
|
|
bunker_weapons[6] = spawnstruct();
|
|
bunker_weapons[6].weapon_name = "weapon_type97_frag";
|
|
bunker_weapons[6].origin = (-7.3, -8511.1, -27);
|
|
bunker_weapons[6].angles = (270, 240.6, 0);
|
|
|
|
spawn_pickup_weapons( bunker_weapons );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Sets up specific friendly squad settings
|
|
//
|
|
///////////////////////////////
|
|
|
|
friendly_setup_thread()
|
|
{
|
|
self thread magic_bullet_shield();
|
|
self setthreatbiasgroup( "heroes" );
|
|
self.goalradius = 400;
|
|
self.script_noteworthy = "friendly_squad_ai";
|
|
self pushplayer( true );
|
|
self.dontavoidplayer = true;
|
|
}
|
|
|
|
|
|
|
|
on_dry_land()
|
|
{
|
|
|
|
self endon( "death" );
|
|
|
|
self.isinwater = 0;
|
|
// if( self != level.roebuck )
|
|
// {
|
|
// self clear_run_anim();
|
|
// }
|
|
//
|
|
// self.disableArrivals = false;
|
|
|
|
self disable_cqbwalk();
|
|
self clear_custom_approach_fields();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// piggybacking autosaves onto other triggers, to save entities
|
|
//
|
|
///////////////////////////////
|
|
|
|
save_near_first_bunker()
|
|
{
|
|
|
|
trigger_wait( "trig_chain_bunkers_entrance_past", "targetname" );
|
|
autosave_by_name( "Pel2 near bunker 1" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// piggybacking autosaves onto other triggers, to save entities
|
|
//
|
|
///////////////////////////////
|
|
|
|
save_near_corsair_trap()
|
|
{
|
|
|
|
trigger_wait( "trig_save_before_trap", "targetname" );
|
|
autosave_by_name( "Pel2 near corsair trap" );
|
|
|
|
}
|
|
|
|
|
|
|
|
spawn_middle_at47()
|
|
{
|
|
|
|
trigger_wait( "trig_spawn_middle_at47", "targetname" );
|
|
|
|
// piggybacking this here to save a trigger enty
|
|
// spawn AT47 between bunker 1 and 2
|
|
maps\_vehicle::scripted_spawn( 22 );
|
|
|
|
}
|
|
|
|
|
|
|
|
set_custom_approach()
|
|
{
|
|
|
|
if( !IsDefined( anim.NotFirstTime ) )
|
|
{
|
|
wait( 0.1 );
|
|
}
|
|
|
|
add_custom_exposed_approach( 0, %run_2_crouch_F );
|
|
add_custom_exposed_exit( 0, %crouch_2_runCQB );
|
|
//add_custom_exposed_exit( 0, %crouch_2run_F );
|
|
}
|
|
|
|
|
|
|
|
add_custom_exposed_approach( index, approach_anim )
|
|
{
|
|
type = "custom_exposed";
|
|
anim.coverTrans[type][index] = approach_anim;
|
|
anim.coverTransDist[type][index] = getMoveDelta ( anim.coverTrans[type][index], 0, 1 );
|
|
anim.coverTransAngles[type][index] = getAngleDelta( anim.coverTrans[type][index], 0, 1 );
|
|
}
|
|
|
|
|
|
|
|
add_custom_exposed_exit( index, approach_anim )
|
|
{
|
|
type = "custom_exposed";
|
|
anim.coverExit[type][index] = approach_anim;
|
|
anim.coverExitDist[type][index] = getMoveDelta ( anim.coverExit[type][index], 0, 1 );
|
|
anim.coverExitAngles[type][index] = getAngleDelta( anim.coverExit[type][index], 0, 1 );
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// handles coop players connecting/disconnecting as well as spawned/killed
|
|
//
|
|
///////////////////////////////
|
|
|
|
init_callbacks()
|
|
{
|
|
level thread onFirstPlayerConnect();
|
|
level thread onPlayerConnect();
|
|
level thread onPlayerDisconnect();
|
|
level thread onPlayerSpawned();
|
|
level thread onPlayerKilled();
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Sets up objectives
|
|
//
|
|
///////////////////////////////
|
|
|
|
setup_objectives()
|
|
{
|
|
|
|
|
|
objective_add( 1, "active", &"PEL2_SECURE_MANGROVE_AREA", ( 4032, -14250, -47 ) );
|
|
objective_current ( 1 );
|
|
|
|
level waittill( "obj_mangrove_complete" );
|
|
|
|
objective_state ( 1, "done" );
|
|
|
|
// wait_network_frame();
|
|
// wait_network_frame();
|
|
|
|
objective_add( 2, "active", &"PEL2_CLEAR_BUNKERS", ( 970, -10388, -42 ) );
|
|
objective_current ( 2 );
|
|
|
|
level waittill( "obj_bunkers_complete" );
|
|
|
|
objective_state ( 2, "done" );
|
|
|
|
// wait_network_frame();
|
|
// wait_network_frame();
|
|
|
|
|
|
objective_add( 3, "active", &"PEL2_FLAME_MG", ( -244.7, -6972.4, -31 ) );
|
|
objective_current ( 3 );
|
|
|
|
level waittill( "obj_flame_complete" );
|
|
|
|
objective_string( 3, &"PEL2_ADVANCE_TOWARDS_AIRFIELD" );
|
|
objective_position( 3, ( -301, -6976, -260 ) );
|
|
|
|
level waittill( "obj_forest_complete" );
|
|
|
|
objective_state ( 3, "done" );
|
|
|
|
// wait_network_frame();
|
|
// wait_network_frame();
|
|
|
|
|
|
objective_add( 4, "active", &"PEL2_CLEAR_THE_BUILDING", ( 2605, -602, 37 ) );
|
|
objective_current ( 4 );
|
|
|
|
level waittill( "obj_building_complete" );
|
|
|
|
objective_string( 4, &"PEL2_ASSAULT_AIRFIELD" );
|
|
objective_position( 4, ( 2755, 8112.7, 127 ) );
|
|
|
|
level waittill( "obj_assault_airfield_complete" );
|
|
|
|
objective_string( 4, &"PEL2_GET_BAZOOKA" );
|
|
objective_position( 4, ( 2704.9, 4525.2, -23.1 ) );
|
|
// Objective_additionalPosition( 4, 3, ( 2704.9, 4525.2, -23.1 ) );
|
|
objective_ring( 4 );
|
|
|
|
level waittill( "obj_airfield_tanks_complete" );
|
|
|
|
|
|
|
|
objective_add( 5, "active", &"PEL2_AA_BUNKER", (4091, 7782, 58) );
|
|
objective_current ( 5 );
|
|
|
|
// flag set on trigger
|
|
flag_wait( "trig_last_aa_guys" );
|
|
|
|
objective_string( 5, &"PEL2_DESTROY_AA_GUNS_4" );
|
|
wait_network_frame(); // Space out the objective set, from the following spawn a little.
|
|
level thread maps\pel2_airfield::last_aa_guns_objective();
|
|
|
|
level waittill( "obj_airfield_complete" );
|
|
|
|
objective_state ( 5, "done" );
|
|
|
|
|
|
|
|
flag_wait( "last_counterattack_start" );
|
|
|
|
|
|
|
|
objective_add( 6, "active", &"PEL2_COUNTERATTACK", ( 2251.1, 8557.9, 124 ) );
|
|
objective_current ( 6 );
|
|
|
|
level waittill( "obj_counterattack_complete" );
|
|
|
|
objective_state ( 6, "done" );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
//
|
|
// Sets up objectives when used with starts
|
|
//
|
|
///////////////////////////////
|
|
|
|
setup_objectives_skip()
|
|
{
|
|
|
|
wait ( 0.05 );
|
|
|
|
obj_complete = 0;
|
|
|
|
start_string = GetDvar( "start" );
|
|
|
|
// determine how far to skip
|
|
switch( start_string )
|
|
{
|
|
|
|
case "flame":
|
|
|
|
obj_complete = 2;
|
|
break;
|
|
|
|
case "forest":
|
|
|
|
obj_complete = 4;
|
|
break;
|
|
|
|
case "admin":
|
|
|
|
obj_complete = 4;
|
|
break;
|
|
|
|
case "airfield":
|
|
|
|
obj_complete = 5;
|
|
break;
|
|
|
|
case "aaguns":
|
|
|
|
obj_complete = 7;
|
|
break;
|
|
|
|
case "napalm":
|
|
|
|
obj_complete = 9;
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
|
|
}
|
|
|
|
obj_index = 1;
|
|
|
|
|
|
// actually send out notifies that the setup_objectives() thread will receive so it can skip objectives
|
|
while( obj_index <= obj_complete )
|
|
{
|
|
|
|
if( obj_index == 1 )
|
|
{
|
|
level notify( "obj_mangrove_complete" );
|
|
}
|
|
else if( obj_index == 2 )
|
|
{
|
|
level notify( "obj_bunkers_complete" );
|
|
}
|
|
else if( obj_index == 3 )
|
|
{
|
|
level notify( "obj_bunker_regroup_complete" );
|
|
wait( 0.05 );
|
|
level notify( "obj_ready_to_suppress_bunker" );
|
|
}
|
|
else if( obj_index == 4 )
|
|
{
|
|
level notify( "obj_flame_complete" );
|
|
}
|
|
else if( obj_index == 5 )
|
|
{
|
|
level notify( "obj_forest_complete" );
|
|
}
|
|
else if( obj_index == 6 )
|
|
{
|
|
level notify( "obj_building_complete" );
|
|
}
|
|
else if( obj_index == 7 )
|
|
{
|
|
level notify( "obj_assault_airfield_complete" );
|
|
}
|
|
else if( obj_index == 8 )
|
|
{
|
|
level notify( "obj_airfield_tanks_complete" );
|
|
}
|
|
else if( obj_index == 9 )
|
|
{
|
|
flag_set( "trig_last_aa_guys" );
|
|
wait( 0.05 );
|
|
level notify( "obj_airfield_complete" );
|
|
}
|
|
|
|
obj_index++;
|
|
wait ( 0.05 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|