958 lines
24 KiB
Text
958 lines
24 KiB
Text
//
|
|
// file: ber3b_event_foyer.gsc
|
|
// description: reichstag foyer event script for berlin3b
|
|
// scripter: slayback
|
|
//
|
|
|
|
#include common_scripts\utility;
|
|
#include maps\_utility;
|
|
#include maps\_anim;
|
|
#include maps\ber3b;
|
|
#include maps\ber3b_anim;
|
|
#include maps\ber3_util;
|
|
#include maps\_music;
|
|
|
|
#using_animtree( "generic_human" );
|
|
|
|
// -- STARTS --
|
|
// start at the beginning of the map, including the intro stuff
|
|
event_intro_start()
|
|
{
|
|
share_screen( get_host(), true, true );
|
|
|
|
warp_players_underworld();
|
|
|
|
thread battlechatter_off( "allies" );
|
|
|
|
// DIARY
|
|
doIntroscreen = GetDvarInt( "introscreen" );
|
|
if( IsDefined( doIntroscreen ) && doIntroscreen > 0 )
|
|
{
|
|
|
|
diary_reading();
|
|
}
|
|
|
|
thread introscene_closedoors_near();
|
|
thread foyer_spawn_redshirts_1();
|
|
|
|
level waittill( "introscene_closedoors_near_warpdone" );
|
|
|
|
warp_friendlies( "struct_foyer_frontdoor_start_friends", "targetname" );
|
|
warp_players( "struct_foyer_frontdoor_start", "targetname" );
|
|
|
|
setup_commissar();
|
|
|
|
//Kevins notify to start speech and march outisde
|
|
level notify ("hitler_speak");
|
|
|
|
thread intro_fakefire();
|
|
event_foyer_introscene();
|
|
|
|
thread battlechatter_on( "allies" );
|
|
|
|
level thread event_foyer_setup();
|
|
}
|
|
|
|
// start at the beginning of the map, skipping the intro
|
|
event_foyer_start()
|
|
{
|
|
warp_players_underworld();
|
|
|
|
thread introscene_closedoors_near();
|
|
thread foyer_spawn_redshirts_1();
|
|
|
|
level waittill( "introscene_closedoors_near_warpdone" );
|
|
|
|
setup_commissar();
|
|
warp_commissar_to_intro_spot();
|
|
|
|
warp_friendlies( "struct_foyer_frontdoor_start_friends", "targetname" );
|
|
warp_players( "struct_foyer_frontdoor_start", "targetname" );
|
|
|
|
thread intro_fakefire();
|
|
|
|
// functions otherwise called during the introscene
|
|
thread introscene_closedoors_far();
|
|
level notify( "introscene_closedoors_near_startanim" );
|
|
|
|
level thread event_foyer_setup();
|
|
}
|
|
|
|
// start at the top of the foyer steps, just before the first pacing area
|
|
event_foyer_pacing_start()
|
|
{
|
|
warp_players_underworld();
|
|
|
|
warp_friendlies( "struct_parliament_foyer_pacing_start_friends", "targetname" );
|
|
warp_players( "struct_parliament_foyer_pacing_start", "targetname" );
|
|
|
|
set_color_chain( "trig_script_color_allies_b5" );
|
|
set_objective( 1 );
|
|
|
|
// DEPRECATED
|
|
//russian_flag_teleport( groundpos( ( 1128, 15984, 754 ) ) );
|
|
|
|
level thread event_foyer_pacing_action();
|
|
}
|
|
// -- END STARTS --
|
|
|
|
|
|
// -- DIARY READING --
|
|
diary_reading()
|
|
{
|
|
// doesn't start until introscreen knows that all the players have connected
|
|
while( !IsDefined( level._introscreen ) )
|
|
{
|
|
wait( 0.05 );
|
|
}
|
|
|
|
while( !level._introscreen )
|
|
{
|
|
wait( 0.05 );
|
|
}
|
|
|
|
wait( 2 );
|
|
|
|
clientNotify( "diaryreading_start" );
|
|
//TUEY Set Music State to DIARY
|
|
setmusicstate("DIARY");
|
|
|
|
diaryLineTime = 23; // hacky, but we have no other way of knowing when the sound should end
|
|
EndTime = GetTime() + ( diaryLineTime * 1000 );
|
|
|
|
// wait for host button press
|
|
host = get_players()[0];
|
|
|
|
fadeTime = 0.5; // hud fade in/out time
|
|
|
|
// only allow skipping after the text is done fading up
|
|
level waittill( "finished final intro screen fadein" );
|
|
|
|
//share_screen( get_host(), false, false );
|
|
|
|
wait( 2.5 );
|
|
|
|
/*
|
|
host thread diary_hud( fadeTime );
|
|
|
|
while( GetTime() < endTime )
|
|
{
|
|
if( host UseButtonPressed() )
|
|
{
|
|
//println("Notifying client diaryreading_skip");
|
|
clientNotify( "diary_skip" );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
*/
|
|
|
|
while( GetTime() < endTime )
|
|
{
|
|
wait( 0.5 );
|
|
}
|
|
|
|
host notify( "fade_diary_hud" );
|
|
wait( 0.5 );
|
|
|
|
// now tell introscreen to continue
|
|
flag_set( level.introscreen_waitontext_flag );
|
|
}
|
|
|
|
/*
|
|
diary_hud( fadeTime )
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
diaryhud = NewClientHudElem( self );
|
|
diaryhud.alignX = "center";
|
|
diaryhud.alignY = "top";
|
|
diaryhud.fontScale = 1.25;
|
|
diaryhud.x = 330;
|
|
diaryhud.y = 25;
|
|
diaryhud.sort = 1;
|
|
diaryhud.foreground = true;
|
|
diaryhud.alpha = 0;
|
|
|
|
diaryhud SetText( level.diary_skip );
|
|
diaryhud FadeOverTime( fadeTime );
|
|
diaryhud.alpha = 1;
|
|
|
|
self waittill( "fade_diary_hud" );
|
|
|
|
diaryhud FadeOverTime( fadeTime );
|
|
diaryhud.alpha = 0;
|
|
|
|
wait( fadeTime + 0.05 );
|
|
diaryhud Destroy();
|
|
}
|
|
*/
|
|
// -- END DIARY READING --
|
|
|
|
|
|
// -- INTRO SCENE --
|
|
event_foyer_introscene()
|
|
{
|
|
//TUEY Set music state to INTRO
|
|
setmusicstate("INTRO");
|
|
|
|
// get players and friendlies in position
|
|
thread crouch_players();
|
|
thread align_friendlies();
|
|
|
|
flag_init( "intro_interrupt" );
|
|
thread introscene_playercheck();
|
|
|
|
// introscreen doesn't show up on checkpoint restart
|
|
doingIntroscreen = GetDvarInt( "introscreen" );
|
|
if( IsDefined( doingIntroscreen ) && doingIntroscreen )
|
|
{
|
|
// waiting on custom flag now
|
|
//level waittill( "finished final intro screen fadein" );
|
|
flag_wait( level.introscreen_waitontext_flag );
|
|
wait( 2 );
|
|
}
|
|
|
|
thread introscene_artystrikes();
|
|
|
|
level notify( "introscene_closedoors_near_startanim" );
|
|
thread introscene_closedoors_far();
|
|
|
|
sarge = level.sarge;
|
|
|
|
sarge.animname = "sarge";
|
|
|
|
//animSpot = getnode_safe( "node_intro_align", "targetname" );
|
|
animSpot = Spawn( "script_origin", sarge.origin );
|
|
animSpot.angles = ( 0, 0, 0 );
|
|
|
|
sarge thread anim_finished_notify( "intro_sarge_anim_done" );
|
|
animSpot thread anim_single_solo_earlyout( sarge, "intro_peptalk" );
|
|
|
|
level thread delayed_screen_restore( 2 );
|
|
|
|
level waittill_any( "intro_interrupt", "intro_sarge_anim_done" );
|
|
|
|
if( flag( "intro_interrupt" ) )
|
|
{
|
|
sarge anim_stopanimscripted();
|
|
}
|
|
|
|
level notify( "intro_finished" );
|
|
}
|
|
|
|
delayed_screen_restore( time )
|
|
{
|
|
wait( time );
|
|
share_screen( get_host(), false, false );
|
|
}
|
|
|
|
anim_finished_notify( notifystring )
|
|
{
|
|
level endon( "intro_interrupt" );
|
|
|
|
animtime = GetAnimLength( level.scr_anim["sarge"]["intro_peptalk"] );
|
|
//self waittillmatch( "single anim", "end" );
|
|
wait( animtime - 2 );
|
|
|
|
level notify( notifystring );
|
|
}
|
|
|
|
introscene_artystrikes()
|
|
{
|
|
level endon( "intro_finished" );
|
|
level endon( "intro_interrupt" );
|
|
|
|
minWait = 5;
|
|
maxWait = 10;
|
|
|
|
firstTime = true;
|
|
|
|
while( 1 )
|
|
{
|
|
if( firstTime )
|
|
{
|
|
firstTime = false;
|
|
}
|
|
else
|
|
{
|
|
wait( RandomFloatRange( minWait, maxWait ) );
|
|
}
|
|
//kevin adding notify. This has to be here to make these go off.
|
|
level notify( "arty_strike" );
|
|
thread arty_strike_on_players( RandomFloatRange( .2, .3 ), 3, 500 );
|
|
}
|
|
}
|
|
|
|
// called at map start to set the doors up to the appropriate angles for the animation
|
|
setup_frontdoors()
|
|
{
|
|
door1 = getent_safe( "sbmodel_frontdoor_set1_right", "targetname" );
|
|
door2 = getent_safe( "sbmodel_frontdoor_set1_left", "targetname" );
|
|
|
|
door1 ConnectPaths();
|
|
door2 ConnectPaths();
|
|
|
|
//door1.angles = ( 0, -150, 0 );
|
|
//door2.angles = ( 0, 175, 0 );
|
|
//door1.angles = ( 0, -90, 0 );
|
|
//door2.angles = ( 0, 90, 0 );
|
|
|
|
//door1 DisconnectPaths();
|
|
//door2 DisconnectPaths();
|
|
}
|
|
|
|
introscene_closedoors_far()
|
|
{
|
|
door1 = getent_safe( "sbmodel_frontdoor_set1_right", "targetname" );
|
|
door2 = getent_safe( "sbmodel_frontdoor_set1_left", "targetname" );
|
|
|
|
animSpot = getstruct_safe( "struct_intro_doors_animref_1", "targetname" );
|
|
spawner1 = getent_safe( animSpot.target, "targetname" );
|
|
spawner2 = getent_safe( spawner1.target, "targetname" );
|
|
|
|
guy1 = spawn_guy( spawner1 );
|
|
guy2 = spawn_guy( spawner2 );
|
|
|
|
guys[0] = guy1;
|
|
guys[1] = guy2;
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guy = guys[i];
|
|
guy.ignoreme = true;
|
|
guy.ignoreall = true;
|
|
guy PushPlayer( true );
|
|
}
|
|
|
|
guy1.animname = "intro_door_closer_1";
|
|
guy2.animname = "intro_door_closer_2";
|
|
|
|
animSpot anim_reach( guys, "closedoor" );
|
|
|
|
door1 thread reichstag_dooranim( "reichstag_frontdoor_1", "closedoor", "frontdoor_anim" );
|
|
door2 thread reichstag_dooranim( "reichstag_frontdoor_2", "closedoor", "frontdoor_anim" );
|
|
animSpot anim_single( guys, "closedoor" );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guy = guys[i];
|
|
guy.ignoreme = false;
|
|
guy.ignoreall = false;
|
|
guy PushPlayer( false );
|
|
|
|
node = getnode_safe( guy.target, "targetname" );
|
|
guy SetGoalNode( node );
|
|
|
|
guy thread bloody_death_after_wait( 10, true, 5 );
|
|
}
|
|
}
|
|
|
|
introscene_closedoors_near()
|
|
{
|
|
door3 = getent_safe( "sbmodel_frontdoor_set2_right", "targetname" );
|
|
door4 = getent_safe( "sbmodel_frontdoor_set2_left", "targetname" );
|
|
animSpot = getstruct_safe( "struct_intro_doors_animref_2", "targetname" );
|
|
spawner3 = getent_safe( animSpot.target, "targetname" );
|
|
spawner4 = getent_safe( spawner3.target, "targetname" );
|
|
|
|
guy3 = spawn_guy( spawner3 );
|
|
guy4 = spawn_guy( spawner4 );
|
|
|
|
guys[0] = guy3;
|
|
guys[1] = guy4;
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guy = guys[i];
|
|
guy.ignoreme = true;
|
|
guy.ignoreall = true;
|
|
guy PushPlayer( true );
|
|
}
|
|
|
|
guy3.animname = "intro_door_closer_3";
|
|
guy4.animname = "intro_door_closer_4";
|
|
|
|
guy3 maps\_anim::set_start_pos( "closedoor", animSpot.origin, animSpot.angles, undefined );
|
|
guy4 maps\_anim::set_start_pos( "closedoor", animSpot.origin, animSpot.angles, undefined );
|
|
|
|
level notify( "introscene_closedoors_near_warpdone" );
|
|
level waittill( "introscene_closedoors_near_startanim" );
|
|
|
|
door3 thread reichstag_dooranim( "reichstag_frontdoor_3", "closedoor", "frontdoor_anim" );
|
|
door4 thread reichstag_dooranim( "reichstag_frontdoor_4", "closedoor", "frontdoor_anim" );
|
|
animSpot anim_single( guys, "closedoor" );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guy = guys[i];
|
|
guy.ignoreme = false;
|
|
guy.ignoreall = false;
|
|
guy PushPlayer( false );
|
|
|
|
node = getnode_safe( guy.target, "targetname" );
|
|
guy SetGoalNode( node );
|
|
|
|
guy thread bloody_death_after_wait( 10, true, 5 );
|
|
}
|
|
}
|
|
|
|
introscene_playercheck()
|
|
{
|
|
level endon( "intro_finished" );
|
|
|
|
trig = getent_safe( "trig_script_color_allies_b1", "targetname" );
|
|
|
|
while( IsDefined( trig ) )
|
|
{
|
|
trig waittill( "trigger", guy );
|
|
|
|
if( IsPlayer( guy ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
flag_set( "intro_interrupt" );
|
|
}
|
|
|
|
crouch_players()
|
|
{
|
|
flag_wait( "warp_players_done" );
|
|
|
|
players = get_players();
|
|
|
|
for( i = 0; i < players.size; i++ )
|
|
{
|
|
player = players[i];
|
|
|
|
player SetStance( "crouch" );
|
|
}
|
|
}
|
|
|
|
align_friendlies()
|
|
{
|
|
// move players so they don't have LOS to the teleport spots
|
|
warp_players_underworld();
|
|
|
|
warp_commissar_to_intro_spot();
|
|
|
|
sargeSpot = getstruct_safe( "struct_intro_sarge_spot", "targetname" );
|
|
level.sarge Teleport( groundpos( sargeSpot.origin ), sargeSpot.angles );
|
|
|
|
// move players back
|
|
warp_players( "struct_foyer_frontdoor_start", "targetname" );
|
|
|
|
// crouch guys (not sarge)
|
|
for( i = 0; i < level.friends.size; i++ )
|
|
{
|
|
guy = level.friends[i];
|
|
|
|
if( is_active_ai( guy ) && guy != level.sarge )
|
|
{
|
|
guy AllowedStances( "crouch" );
|
|
}
|
|
}
|
|
|
|
// wait for intro scene to be over or interrupted
|
|
level waittill_any( "intro_finished", "intro_interrupt" );
|
|
|
|
reset_friendlies();
|
|
}
|
|
|
|
reset_friendlies()
|
|
{
|
|
for( i = 0; i < level.friends.size; i++ )
|
|
{
|
|
guy = level.friends[i];
|
|
|
|
if( is_active_ai( guy ) )
|
|
{
|
|
guy AllowedStances( "stand", "crouch", "prone" );
|
|
}
|
|
}
|
|
}
|
|
// -- END INTRO SCENE --
|
|
|
|
setup_commissar()
|
|
{
|
|
// set up the commissar
|
|
commissar_spawner = getent_safe( "commissar", "targetname" );
|
|
commissar = spawn_guy( commissar_spawner );
|
|
commissar.ignoreme = true;
|
|
commissar thread magic_bullet_shield_safe();
|
|
|
|
// DEPRECATED
|
|
// turn off color respawning on this guy
|
|
//commissar disable_replace_on_death();
|
|
|
|
level.commissar = commissar;
|
|
|
|
ASSERTEX( is_active_ai( level.commissar ), "setup_commissar(): couldn't assign level.commissar." );
|
|
|
|
thread commissar_action();
|
|
}
|
|
|
|
commissar_action()
|
|
{
|
|
while( !IsDefined( level.commissar.wasWarped ) )
|
|
{
|
|
wait( 0.05 );
|
|
}
|
|
|
|
level.commissar animscripts\shared::placeWeaponOn( level.commissar.primaryweapon, "none" );
|
|
level.commissar Attach( "clutter_berlin_megaphone", "tag_weapon_left" );
|
|
|
|
level.commissar.animname = "commissar";
|
|
level.commissar thread anim_loop_solo( level.commissar, "intro_idle", undefined, "idle_stop" );
|
|
|
|
level waittill_any( "intro_finished", "intro_interrupt" );
|
|
|
|
level.commissar notify( "idle_stop" );
|
|
|
|
level.commissar anim_single_solo( level.commissar, "intro" );
|
|
|
|
flag_set( "commissar_dialogue_done" );
|
|
|
|
level.commissar thread anim_loop_solo( level.commissar, "intro_idle", undefined, "idle_stop" );
|
|
|
|
wait( 10 );
|
|
level.commissar wait_while_players_can_see( 400, 5 );
|
|
|
|
level.commissar notify( "idle_stop" );
|
|
level.commissar thread stop_magic_bullet_shield_safe();
|
|
level.commissar Delete();
|
|
}
|
|
|
|
warp_commissar_to_intro_spot()
|
|
{
|
|
comSpot = getstruct_safe( "struct_intro_commissar_spot", "targetname" );
|
|
level.commissar Teleport( groundpos( comSpot.origin ), comSpot.angles );
|
|
level.commissar.wasWarped = true;
|
|
}
|
|
|
|
event_foyer_setup()
|
|
{
|
|
set_objective( 1 );
|
|
|
|
thread event_foyer_action();
|
|
thread foyer_mg();
|
|
thread foyer_bazookateam();
|
|
// DEPRECATED - commissar is no longer on a color chain
|
|
// thread cleanup_forcecolor_redshirts( "g", "trig_pacing1_kicked_door", "targetname" );
|
|
thread kill_aigroup_at_trigger( "trig_pacing1_kicked_door", "targetname", "ai_foyer_redshirts_1" );
|
|
}
|
|
|
|
event_foyer_action()
|
|
{
|
|
set_color_chain( "trig_script_color_allies_b0" );
|
|
|
|
thread foyer_intro_hallway_running_dialogue();
|
|
|
|
thread event_foyer_pacing_action();
|
|
|
|
thread foyer_force_ai_fire();
|
|
}
|
|
|
|
foyer_force_ai_fire()
|
|
{
|
|
trigger = getent( "foyer_colors_stair_base", "targetname" );
|
|
trigger waittill( "trigger" );
|
|
|
|
autosave_by_name( "Ber1 reached stair" );
|
|
|
|
enemies = GetAIArray( "axis" );
|
|
for( i = 0; i < enemies.size; i++ )
|
|
{
|
|
enemies[i].ignoreme = false;
|
|
if( enemies[i].origin[2] < 15216 )
|
|
{
|
|
enemies[i].health = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
debug_print_ber3b()
|
|
{
|
|
while( 1 )
|
|
{
|
|
print3d( self.origin + (0, 0, 40), "***", (1,1,1), 1, 3 );
|
|
wait( 0.01 );
|
|
}
|
|
}
|
|
|
|
foyer_intro_hallway_running_dialogue()
|
|
{
|
|
flag_wait( "commissar_dialogue_done" );
|
|
//kevin adding notify. This has to be here to make these go off.
|
|
level notify( "arty_strike" );
|
|
|
|
thread arty_strike_on_players( RandomFloatRange( .3, .4 ), 3, 500 );
|
|
|
|
// "The building's still being shelled!!! We could be killed!"
|
|
buddy = get_randomfriend_notsarge();
|
|
buddy playsound_generic_facial( "Ber3B_IGD_000A_RUR2" );
|
|
|
|
// "Then die with your hands around the throat of the enemy!!!"
|
|
level.sarge playsound_generic_facial( "Ber3B_IGD_001A_REZN" );
|
|
|
|
flag_set( "hallway_running_dialogue_done" );
|
|
}
|
|
|
|
event_foyer_pacing_action()
|
|
{
|
|
thread pacing1_melees_init();
|
|
thread pacing1_friendly_doorbreach();
|
|
|
|
thread pacing1_fallbackers_kill();
|
|
|
|
trigger_wait( "trig_parliament_entrance", "targetname" );
|
|
|
|
// send control to parliament script
|
|
maps\ber3b_event_parliament::event_parliament_setup();
|
|
}
|
|
|
|
pacing1_fallbackers_kill()
|
|
{
|
|
trigger_wait( "trig_pacing1_melee1", "targetname" );
|
|
|
|
enemies = get_ai_group_ai( "ai_pacing1_fallbackers" );
|
|
|
|
array_thread( enemies, ::pacing1_fallbacker_kill );
|
|
}
|
|
|
|
pacing1_fallbacker_kill()
|
|
{
|
|
self endon( "death" );
|
|
|
|
self wait_while_players_can_see( 450, 5 );
|
|
self thread bloody_death( true, 0 );
|
|
}
|
|
|
|
intro_fakefire()
|
|
{
|
|
|
|
// CODER_MOD
|
|
// DSL - Migrated fake fire over to the client side, so need to notify client scripts of state change
|
|
// to get the party started.
|
|
|
|
if(level.clientscripts)
|
|
{
|
|
maps\_utility::setClientSysState("levelNotify", "intro_fakefire_start");
|
|
}
|
|
else
|
|
{
|
|
firePoints = GetStructArray( "struct_intro_fakefire", "targetname" );
|
|
ASSERTEX( IsDefined( firePoints ) && firePoints.size > 0, "Can't find fakefire points." );
|
|
|
|
array_thread( firePoints, maps\ber3b_fx::ambient_fakefire, "intro_fakefire_end", false );
|
|
}
|
|
|
|
}
|
|
|
|
foyer_mg()
|
|
{
|
|
trig = getent_safe( "trig_foyer_mgspawn", "targetname" );
|
|
trig waittill( "trigger" );
|
|
|
|
spawner = getent_safe( trig.target, "targetname" );
|
|
node = getnode_safe( spawner.target, "targetname" );
|
|
mg = getent_safe( node.target, "targetname" );
|
|
|
|
mger = spawn_guy( spawner );
|
|
mger.ignoreme = true;
|
|
mger thread magic_bullet_shield();
|
|
|
|
mger SetGoalNode( node );
|
|
|
|
mger thread guy_stay_on_turret( mger, mg );
|
|
|
|
level waittill( "bazookateam_fire" );
|
|
mger notify( "stop magic bullet shield" );
|
|
|
|
level waittill( "bazookateam_foyer_damage_done" );
|
|
|
|
wait( 0.1 );
|
|
|
|
if( IsDefined( mger ) && is_active_ai( mger ) )
|
|
{
|
|
mger DoDamage( mger.health + 5, ( 0, 0, 0 ) );
|
|
}
|
|
|
|
wait( 0.1 );
|
|
|
|
if( IsDefined( mg ) )
|
|
{
|
|
mg Delete();
|
|
}
|
|
}
|
|
|
|
foyer_bazookateam()
|
|
{
|
|
trig = getent_safe( "trig_foyer_bazookateam", "targetname" );
|
|
trig waittill( "trigger" );
|
|
thread maps\ber3b_event_parliament::bazooka_team( trig );
|
|
|
|
thread foyer_bazookateam_dialogue();
|
|
|
|
// wait for damage trigger
|
|
dmgtrig = getent_safe( "trig_damage_foyer_bazookateam_firearea", "targetname" );
|
|
dmgtrig waittill( "trigger" );
|
|
dmgtrig Delete();
|
|
|
|
fxspot = getstruct_safe( "struct_foyer_bazookatarget_fxspot", "targetname" );
|
|
intactGeo = GetEntArray( "scripted_foyer_center_emplacement", "targetname" );
|
|
ASSERTEX( IsDefined( intactGeo ) && intactGeo.size > 0, "can't find foyer bazookateam intact geo" );
|
|
|
|
PlayFX( level._effect["sandbag_explosion_small"], fxspot.origin );
|
|
|
|
RadiusDamage( fxspot.origin, 238, 5000, 5000 );
|
|
|
|
wait( 0.2 );
|
|
|
|
for( i = 0; i < intactGeo.size; i++ )
|
|
{
|
|
intactGeo[i] Delete();
|
|
}
|
|
|
|
level notify( "bazookateam_foyer_damage_done" );
|
|
|
|
flag_clear( "bazookateam_keep_firing" );
|
|
|
|
weaponclip = getent_safe( "trig_foyer_bazooka_weaponclip", "targetname" );
|
|
weaponclip Delete();
|
|
}
|
|
|
|
foyer_bazookateam_dialogue()
|
|
{
|
|
sarge_giveorder( "positions_fortified_need_support", true );
|
|
sarge_giveorder( "want_bazooka_team", true );
|
|
}
|
|
|
|
pacing1_melees_init()
|
|
{
|
|
level thread pacing1_2man_melee( "trig_pacing1_melee1", "melee1" );
|
|
level thread pacing1_2man_melee( "trig_pacing1_melee2", "melee2" );
|
|
}
|
|
|
|
pacing1_2man_melee( triggerTN, anime )
|
|
{
|
|
beater_animname = "rtag_melee_beater";
|
|
victim_animname = "rtag_melee_victim";
|
|
|
|
trig = getent_safe( triggerTN, "targetname" );
|
|
trig waittill( "trigger" );
|
|
|
|
animSpot = getstruct_safe( trig.target, "targetname" );
|
|
spawner_beater = getent_safe( animSpot.target, "targetname" );
|
|
spawner_victim = getent_safe( spawner_beater.target, "targetname" );
|
|
beater_goalnode = getnode_safe( spawner_beater.target, "targetname" );
|
|
|
|
trig Delete();
|
|
|
|
beater = spawn_guy( spawner_beater );
|
|
victim = spawn_guy( spawner_victim );
|
|
|
|
beater thread magic_bullet_shield_safe();
|
|
|
|
victim.nodeathragdoll = true;
|
|
|
|
beater.animname = beater_animname;
|
|
victim.animname = victim_animname;
|
|
victim.deathanim = level.scr_anim[victim_animname][anime];
|
|
|
|
victim maps\_anim::set_start_pos( anime, animSpot.origin, animSpot.angles, undefined );
|
|
//beater maps\_anim::set_start_pos( anime, animSpot.origin, animSpot.angles, undefined );
|
|
|
|
//victim animscripts\shared::DropAllAIWeapons();
|
|
victim DoDamage( victim.health + 5, ( 0, 0, 0 ) );
|
|
animSpot anim_single_solo( beater, anime );
|
|
|
|
// run the beater away and kill him
|
|
beater.goalradius = 24;
|
|
beater SetGoalNode( beater_goalnode );
|
|
beater waittill( "goal" );
|
|
|
|
beater thread stop_magic_bullet_shield_safe();
|
|
beater thread bloody_death( true, 0 );
|
|
}
|
|
|
|
pacing1_friendly_doorbreach()
|
|
{
|
|
startDistance = 710;
|
|
|
|
trig = getent_safe( "trig_pacing1_kicked_door", "targetname" );
|
|
|
|
trig waittill( "trigger" );
|
|
|
|
spawners = GetEntArray( trig.target, "targetname" );
|
|
enemies = GetEntArray( "spawner_pacing1_doorkick_enemy", "targetname" );
|
|
animSpot = getstruct_safe( "struct_pacing1_kicked_door_animref", "targetname" );
|
|
door = getent_safe( "sbmodel_pacing1_kicked_door", "targetname" );
|
|
|
|
trig Delete();
|
|
|
|
enemies thread pacing1_friendly_doorbreach_enemies();
|
|
|
|
guys = [];
|
|
|
|
for( i = 0; i < spawners.size; i++ )
|
|
{
|
|
guy = spawn_guy( spawners[i] );
|
|
guy.ignoreme = true;
|
|
guy.ignoreall = true;
|
|
guy PushPlayer( true );
|
|
guys[i] = guy;
|
|
}
|
|
|
|
guys[0].animname = "pacing1_doorkick_guy1";
|
|
guys[1].animname = "pacing1_doorkick_guy2";
|
|
idle_anime = "idle";
|
|
kick_anime = "doorkick";
|
|
|
|
// idle til player shows up
|
|
animSpot anim_reach( guys, kick_anime );
|
|
animSpot thread anim_loop( guys, idle_anime, undefined, "end_loop" );
|
|
|
|
// wait for a player to get close before breaching
|
|
waittill_player_within_range( animSpot.origin, startDistance, 0.05 );
|
|
|
|
animSpot notify( "end_loop" );
|
|
door thread reichstag_dooranim( "pacing1_doorbreach_door", "doorkick", "pacing1_doorkick" );
|
|
animSpot thread anim_single_earlyout( guys, kick_anime );
|
|
|
|
goalPos1 = ( 1000, 17736, 928 );
|
|
goalPos2 = ( 968, 17616, 928 );
|
|
|
|
guys[0] thread doorbreach_guy_finish( goalPos1, kick_anime );
|
|
guys[1] thread doorbreach_guy_finish( goalPos2, kick_anime );
|
|
}
|
|
|
|
doorbreach_guy_finish( goalPos, anime )
|
|
{
|
|
self endon( "death" );
|
|
|
|
animtime = GetAnimLength( level.scr_anim[self.animname][anime] );
|
|
wait( animtime - 2 );
|
|
|
|
self.ignoreme = false;
|
|
self.ignoreall = false;
|
|
self PushPlayer( false );
|
|
|
|
//guy set_force_color( "c" );
|
|
self.goalradius = 200;
|
|
self SetGoalPos( goalPos );
|
|
self waittill( "goal" );
|
|
self thread bloody_death_after_wait( 10, true, 5 );
|
|
}
|
|
|
|
// self = an array of spawners
|
|
pacing1_friendly_doorbreach_enemies()
|
|
{
|
|
guys = [];
|
|
|
|
for( i = 0; i < self.size; i++ )
|
|
{
|
|
guy = spawn_guy( self[i] );
|
|
guy.ignoreme = true;
|
|
guy.ignoreall = true;
|
|
guy PushPlayer( true );
|
|
guy SetGoalPos( guy.origin );
|
|
guys[i] = guy;
|
|
}
|
|
|
|
level waittill( "friendly_doorbreach_dooropen" );
|
|
|
|
//do animation
|
|
guys[0].animname = "pacing1_doorkick_victim1";
|
|
guys[1].animname = "pacing1_doorkick_victim2";
|
|
anime = "surrender";
|
|
|
|
guys[0] thread anim_single_solo( guys[0], anime );
|
|
guys[1] thread anim_single_solo( guys[1], anime );
|
|
|
|
wait( 1.5 );
|
|
|
|
for( i = 0; i < guys.size; i++ )
|
|
{
|
|
guys[i] anim_stopanimscripted();
|
|
guys[i] thread bloody_death( true, 1 );
|
|
}
|
|
}
|
|
|
|
// called with addNotetrack_CustomFunction
|
|
pacing1_friendly_doorbreach_dooropen( guy )
|
|
{
|
|
level notify( "friendly_doorbreach_dooropen" );
|
|
}
|
|
|
|
foyer_spawn_redshirts_1()
|
|
{
|
|
getent_safe( "trig_spawn_foyer_redshirts_1", "targetname" ) notify( "trigger" );
|
|
|
|
wait( 0.1 );
|
|
|
|
closeGuys = get_ai_group_ai( "ai_foyer_redshirts_1_nearplayer" );
|
|
|
|
array_thread( closeGuys, ::intro_close_redshirt_think );
|
|
}
|
|
|
|
// self = a redshirt AI
|
|
intro_close_redshirt_think()
|
|
{
|
|
self endon( "death" );
|
|
|
|
playerdist = 260;
|
|
|
|
self SetGoalPos( self.origin );
|
|
self AllowedStances( "crouch" );
|
|
|
|
waittill_player_within_range( self.origin, playerdist );
|
|
|
|
self AllowedStances( "stand", "crouch", "prone" );
|
|
self SetGoalNode( getnode_safe( self.target, "targetname" ) );
|
|
|
|
self waittill( "goal" );
|
|
self bloody_death( true, 10 );
|
|
}
|
|
|
|
// spawnfunc - controls guys who get mowed down at the foyer entrance
|
|
// self = an AI
|
|
foyer_flagbearer_buddies_spawnfunc()
|
|
{
|
|
self SetGoalPos( self.origin );
|
|
self.ignoreme = true;
|
|
self thread magic_bullet_shield();
|
|
|
|
wait( RandomFloatRange( 0.4, 0.7 ) );
|
|
|
|
self notify( "stop magic bullet shield" );
|
|
|
|
self.deathanim = %exposed_death_twist;
|
|
if( self.origin[0] > 1100 ) // HACK
|
|
{
|
|
self.deathanim = %exposed_death_headtwist;
|
|
}
|
|
|
|
self DoDamage( self.health + 5, ( 0, 0, 0 ) );
|
|
|
|
shotOrigin = ( 1178, 15578, 776 );
|
|
bursts = RandomIntRange( 3, 5 );
|
|
for( i = 0; i < bursts; i++ )
|
|
{
|
|
self maps\ber3b_event_roof::ai_tracer_burst( shotOrigin );
|
|
wait( RandomFloatRange( 0.1, 0.2 ) );
|
|
}
|
|
}
|
|
|
|
// spawnfunc - controls guys who run down the hallway in front of the parliament room
|
|
// self = an AI
|
|
foyer_pacing_friendly_hallrunners_spawnfunc()
|
|
{
|
|
self waittill( "goal" );
|
|
|
|
self bloody_death( true, 2 );
|
|
}
|