cod5-sdk/raw/maps/ber3b.gsc
2008-11-20 00:00:00 +00:00

1361 lines
34 KiB
Text

//
// file: ber3b.gsc
// description: main level script for berlin3b
// scripter: slayback
//
#include common_scripts\utility;
#include maps\_utility;
#include maps\ber3_util;
#include maps\_music;
#using_animtree( "generic_human" );
main()
{
init_flags();
build_starts();
thread introscreen_override();
build_threatbias_groups();
precache_assets();
thread onPlayerConnect();
maps\ber3b_fx::main();
maps\_stuka::main( "vehicle_stuka_flying" );
maps\_aircraft::main( "vehicle_rus_airplane_il2", "il2" );
setup_friendlies();
maps\ber3b_event_foyer::setup_frontdoors();
maps\_load::main(); // COD magic
setup_drones();
thread maps\ber3b_amb::main();
maps\ber3b_anim::ber3b_anim_init();
maps\_mganim::main(); // anims for portable MG guys
setup_strings();
setup_spawn_functions();
russian_flag_init();
thread random_arty_strikes();
thread chandeliers_shake();
thread eagle_setup();
thread maps\ber3b_anim::roof_flag_init();
thread collectible_corpse();
//thread debug_ents();
// TEMP for development
doDebug = GetDvarInt( "debug_ai" );
if( IsDefined( doDebug ) && doDebug > 0 )
{
thread debug_ai();
}
thread difficulty_scale();
thread honorguard_combat_dialogue();
}
/*
debug_ents()
{
while( 1 )
{
smodels = GetEntArray( "script_model", "classname" );
sbmodels = GetEntArray( "script_brushmodel", "classname" );
test = "test";
wait( 1 );
}
}
*/
precache_assets()
{
PrecacheModel( "tag_origin" );
PrecacheModel( "tag_origin_animate" );
PrecacheModel( "weapon_ger_panzershreck_rocket" );
PrecacheModel( "katyusha_rocket" );
PrecacheModel( "clutter_berlin_megaphone" );
PrecacheModel( "anim_berlin_russian_flag" );
//PrecacheModel( "anim_berlin_russian_flag_obj" );
PrecacheModel( "anim_berlin_rus_flag_rolled" );
PrecacheModel( "anim_berlin_rus_flag_rolled_obj" );
PrecacheModel( "ber3b_3rd_person_flag" );
PrecacheModel( "anim_nazi_flag_burnt_rope" );
PrecacheModel( "viewmodel_usa_player" );
PrecacheModel( "viewmodel_russian_flag" );
PrecacheModel( "static_berlin_eagle_statue_wall_swastika" );
PrecacheModel( "projectile_rus_molotov_grenade" );
PrecacheModel( "weapon_rus_reznov_knife" );
PrecacheItem( "russian_flag" );
PrecacheItem( "napalmblob" ); // for the molotovs
precacheItem( "napalmbloblight" );
PrecacheRumble( "explosion_generic" );
PrecacheRumble( "explosion_generic_no_broadcast" );
}
build_starts()
{
// foyer event starts
add_start( "intro", maps\ber3b_event_foyer::event_intro_start, &"STARTS_BER3B_INTRO" );
add_start( "foyer", maps\ber3b_event_foyer::event_foyer_start, &"STARTS_BER3B_FOYER" );
// pacing area 1 start
add_start( "foyer_pacing", maps\ber3b_event_foyer::event_foyer_pacing_start, &"STARTS_BER3B_FOYER_PACING" );
// parliament event starts
add_start( "parliament", maps\ber3b_event_parliament::event_parliament_start, &"STARTS_BER3B_PARLIAMENT" );
add_start( "parliament_doors", maps\ber3b_event_parliament::event_parliament_doors_start, &"STARTS_BER3B_PARLIAMENT_DOORS" );
// roof event starts
add_start( "roof", maps\ber3b_event_roof::event_roof_start, &"STARTS_BER3B_ROOF" );
add_start( "roof_midpoint", maps\ber3b_event_roof::event_roof_midpoint_start, &"STARTS_BER3B_ROOF_MIDPOINT" );
add_start( "roof_flagplant", maps\ber3b_event_roof::event_roof_flagplant_start, &"STARTS_BER3B_ROOF_FLAGPLANT" );
// default start
add_start( "default", level.start_functions[ "intro" ] );
//add_start( "default", level.start_functions[ "roof_flagplant" ] );
default_start( level.start_functions[ "intro" ] );
}
introscreen_override()
{
if ( GetDvar( "createfx" ) != "" )
{
return;
}
start = undefined;
while( !IsDefined( start ) )
{
waittillframeend;
start = level.start_point;
}
// start-specific introscreen disable
if( IsDefined( start ) && start != "" && start != "default" && start != "intro" && !IsSubStr( start, "**" ) )
{
SetDvar( "introscreen", "0" ); // disable the introscreen
}
// always want our intro start to include the introscreen
if( IsDefined( start ) && start == "intro" )
{
SetDvar( "introscreen", "1" );
}
}
build_threatbias_groups()
{
CreateThreatBiasGroup( "players" );
CreateThreatBiasGroup( "friends" );
CreateThreatBiasGroup( "parliament_floor_enemies" );
CreateThreatBiasGroup( "parliament_redshirts" );
}
init_flags()
{
// makes introscreen wait for our flag before showing text
level.introscreen_waitontext_flag = "ber3b_introscreen_finish";
flag_init( level.introscreen_waitontext_flag );
flag_init( "friends_setup" );
flag_init( "warp_players_done" );
flag_init( "hallway_running_dialogue_done" );
flag_init( "commissar_dialogue_done" );
flag_init( "russian_flag_setup" );
flag_init( "russian_flag_dropped" );
flag_set( "russian_flag_dropped" );
flag_init( "flagbearer_mantled" );
flag_init( "bazookateam_keep_firing" );
flag_init( "first_balcony_russians_moveup" );
flag_init( "first_balcony_doors_startopen" );
flag_init( "eagle_fall" );
flag_init( "parliament_backdoor_used" );
flag_init( "player_downstairs" );
flag_init( "roof_rockets_done" );
flag_init( "statue_fall_done" );
flag_init( "fall" );
}
setup_strings()
{
level.obj1_string = &"BER3B_OBJ_1"; // storm the reichstag
level.obj2_string = &"BER3B_OBJ_2A"; // get up to balcony and cover Russian troops
level.obj2b_string = &"BER3B_OBJ_2B"; // shoot Germans on opposite balcony
level.obj3_string = &"BER3B_OBJ_2"; // get out of parliament room
level.obj4_string = &"BER3B_OBJ_3"; // keep clearing
level.obj5_string = &"BER3B_OBJ_4"; // pick up flag
level.obj6_string = &"BER3B_OBJ_5"; // raise flag
level.diary_skip = &"BER3B_DIARY_SKIP"; // "(Press USE to skip.)"
level.obj_flag_carry_string = &"BER3B_OBJ_FLAG_CARRY"; // "Carry the Russian flag to the roof."
level.obj_flag_retrieve_string = &"BER3B_OBJ_FLAG_RETRIEVE"; // "Retrieve the Russian flag."
level.hint_flag_pickup_string = &"BER3B_HINT_FLAG_PICKUP"; // "Hold [use] to pick up the flag."
level.hint_flag_drop_string = &"BER3B_HINT_FLAG_DROP"; // "Hold [use] to drop the flag."
level.flag_fail_warning = &"BER3B_FLAG_FAIL_WARNING"; // "Comrade, do not leave our flag behind!"
level.flag_fail_deadquote = &"BER3B_FLAG_FAIL_DEADQUOTE"; // "You left the flag behind!"
level.flag_plant_trigger_string = &"BER3B_FLAG_PLANT_TRIGGER_HINT"; // "Press [use] to plant the flag."
}
set_objective( num )
{
// storm the reichstag
if( num == 1 )
{
marker = GetStruct( "struct_objective8_marker", "targetname" );
objective_add( 1, "active", level.obj1_string, marker.origin );
objective_current( 1 );
level.nonFlagObjective = 1;
}
// get up to balcony and provide fire support for Russian troops
else if( num == 2 )
{
objective_state( 1, "done" );
objective_add( 2, "active", level.obj2_string, ( 2222, 19037, 1170 ) );
objective_add( 10, "invisible", level.obj2b_string ); // shoot Germans on opposite balcony
objective_current( 2 );
level.nonFlagObjective = 2;
}
// get out of parliament room
else if( num == 3 )
{
marker = GetStruct( "struct_objective9_marker", "targetname" );
objective_state( 2, "done" );
objective_state( 10, "invisible" );
objective_add( 3, "active", level.obj3_string, marker.origin );
objective_current( 3 );
level.nonFlagObjective = 3;
}
// keep clearing
else if( num == 4 )
{
marker = getent_safe( "trig_roof_mantlearea", "targetname" );
objective_state( 3, "done" );
objective_add( 4, "active", level.obj4_string, marker.origin );
objective_current( 4 );
level.nonFlagObjective = 4;
}
// pick up flag
else if( num == 5 )
{
marker = GetStruct( "struct_objective11_marker", "targetname" );
objective_state( 4, "done" );
objective_add( 5, "active", level.obj5_string, marker.origin );
objective_current( 5 );
}
// raise flag
else if( num == 6 )
{
marker = GetStruct( "struct_objective12_marker", "targetname" );
objective_state( 5, "done" );
objective_add( 6, "active", level.obj6_string, marker.origin );
objective_current( 6 );
level.nonFlagObjective = 6;
}
}
// skips past objectives that should have already happened (for skiptos)
objectives_skip( numToSkipPast )
{
for( i = 1; i <= numToSkipPast; i++ )
{
set_objective( i );
}
}
warp_players_underworld()
{
// get the spot under the world for temp placement
underworld = GetStruct( "struct_player_teleport_underworld", "targetname" );
if( !IsDefined( underworld ) )
{
ASSERTMSG( "warp_players_underworld(): can't find the underworld warp spot! aborting." );
return;
}
players = get_players();
for( i = 0; i < players.size; i++ )
{
players[i] SetOrigin( underworld.origin );
}
}
// warp players to a given set of points
warp_players( startValue, startKey )
{
// get start points
starts = GetStructArray( startValue, startKey );
ASSERT( starts.size == 4 );
players = get_players();
for( i = 0; i < players.size; i++ )
{
// Set the players' origin to each start point
players[i] setOrigin( starts[i].origin );
// Set the players' angles to face the right way.
players[i] setPlayerAngles( starts[i].angles );
}
set_breadcrumbs(starts);
flag_set( "warp_players_done" );
}
setup_friendlies()
{
// used by _colors system
level.friendly_startup_thread = ::ber3b_friendly_startup_thread;
friends = grab_starting_friends();
ASSERTEX( IsDefined( friends ) && friends.size > 0, "setup_friendlies(): can't find any friendlies!" );
for( i = 0; i < friends.size; i++ )
{
guy = friends[i];
guy.followmin = -1;
guy friend_add();
if( IsDefined( guy.script_noteworthy ) )
{
// Sgt. Zeitzev
if( guy.script_noteworthy == "sarge" )
{
level.sarge = guy;
level.sarge.animname = "sarge"; // set up a default
}
// guys with script_noteworthy set are heroes and need a bullet shield
guy thread magic_bullet_shield();
}
}
ASSERTEX( is_active_ai( level.sarge ), "setup_friendlies(): couldn't assign level.sarge." );
flag_set( "friends_setup" );
}
// used to get _colors reinforcements set up properly
ber3b_friendly_startup_thread()
{
// if you're in the player squad..
if( IsDefined( self.script_forcecolor ) && self.script_forcecolor == "b" )
{
// add to level.friends
self friend_add();
}
}
// warp friendlies to a given set of points
warp_friendlies( startValue, startKey )
{
ASSERTEX( flag( "friends_setup" ), "warp_friendlies(): level.friends needs to be set up before this runs." );
// get start points
friendlyStarts = GetStructArray( startValue, startKey );
ASSERTEX( friendlyStarts.size > 0, "warp_friendlies(): didn't find enough friendly start points!" );
for( i = 0; i < level.friends.size; i++ )
{
level.friends[i] Teleport( groundpos( friendlyStarts[i].origin ), friendlyStarts[i].angles );
}
}
setup_drones()
{
// TODO these character model names may change as art makes new variants
character\char_ger_honorguard_mp44::precache();
character\char_rus_r_rifle::precache();
level.drone_spawnFunction["axis"] = character\char_ger_honorguard_mp44::main;
level.drone_spawnFunction["allies"] = character\char_rus_r_rifle::main;
level.drone_weaponlist_axis[0] = "gewehr43";
level.drone_weaponlist_axis[0] = "stg44";
// Call this before maps\_load::main(); to allow drone usage.
maps\_drones::init();
}
random_arty_strikes()
{
ender = "stop_random_arty_strikes";
level endon( ender );
level.pauseArtyStrikes = false;
minWait = 15;
maxWait = 35;
thread random_arty_strikes_sound( ender );
while( 1 )
{
wait( RandomIntRange( minWait, maxWait ) );
if( !level.pauseArtyStrikes )
{
thread arty_strike_on_players( RandomFloatRange( .2, .3 ), 3, 500 );
//Kevins notify for sound
//level notify( "int_strike" );
}
}
}
arty_strike_on_players( intensity, duration, radius, switchLevelVar )
{
if( !IsDefined( switchLevelVar ) )
{
switchLevelVar = true;
}
if( switchLevelVar )
{
level.pauseArtyStrikes = true;
}
players = get_players();
level notify( "arty_strike" );
for( i = 0; i < players.size; i++ )
{
players[i] thread arty_strike_rumble( duration * 0.5 );
Earthquake( intensity, duration, players[i].origin, radius );
}
wait( duration );
if( switchLevelVar )
{
level.pauseArtyStrikes = false;
}
}
arty_strike_rumble( duration )
{
self endon( "death" );
self endon( "disconnect" );
self PlayRumbleOnEntity( "explosion_generic" );
wait( 0.2 );
stopTime = GetTime() + ( duration * 1000 );
while( GetTime() <= stopTime )
{
self PlayRumbleOnEntity( "damage_light" );
wait( 0.05 );
}
}
random_arty_strikes_sound( ender )
{
level endon( ender );
level.arty_soundSpot = Spawn( "script_origin", ( 872, 14728, 3064 ) );
level.arty_soundSpot thread random_arty_strikes_cleanup_soundspot( ender );
// TODO: Kevin can move the soundSpot around as players move through the level, if he wants
while( 1 )
{
level waittill( "arty_strike" );
level.arty_soundSpot PlaySound( "art_int" );
}
}
random_arty_strikes_cleanup_soundspot( ender )
{
level waittill( ender );
wait( 1 );
if( IsDefined( self ) )
{
self Delete();
}
}
chandeliers_shake()
{
level endon( "stop_chandeliers_shake" );
animDistance = 1500;
shake_maxWait = 0.25;
chandeliers = GetEntArray( "smodel_chandelier", "targetname" );
if( !IsDefined( chandeliers ) || chandeliers.size <= 0 )
{
return;
}
/* DEPRECATED - since removing the spotlights and optimizing chandelier count we don't need this
// SRS 5/30/2008: HACK for entity count reduction
for( i = 0; i < chandeliers.size; i++ )
{
chandeliers[i] Delete();
}
if( 1 )
{
return;
}
// end HACK
*/
array_thread( chandeliers, ::chandelier_rotate_random );
while( 1 )
{
level waittill( "arty_strike" );
for( i = 0; i < chandeliers.size; i++ )
{
chandelier = chandeliers[i];
isCloseEnough = false;
players = get_players();
for( j = 0; j < players.size; j++ )
{
if( Distance( chandelier.origin, players[j].origin ) <= animDistance )
{
isCloseEnough = true;
break;
}
}
if( !isCloseEnough )
{
continue;
}
else
{
chandelier thread maps\ber3b_anim::chandelier_anim( "reichstag_chandelier", "shake", "chandelier_anim", shake_maxWait );
}
}
}
}
// self = a chandelier
chandelier_rotate_random()
{
rotateMin = 0;
rotateMax = 180;
self RotateYaw( RandomIntRange( rotateMin, rotateMax ), 0.05 );
}
// attaches a swastika to the eagle which can be swapped for another asset in other SKUs
eagle_setup()
{
eagle = getent_safe( "smodel_parliament_eagle", "targetname" );
eagle Attach( "static_berlin_eagle_statue_wall_swastika", "eagle_base_jnt" );
}
collectible_corpse()
{
orig = getstruct_safe( "struct_collectible_loop", "targetname" );
orig.origin = groundpos( orig.origin );
corpse = Spawn( "script_model", orig.origin );
corpse.angles = orig.angles;
corpse maps\ber3b_anim::setup_axis_char_model();
corpse Detach( corpse.gearModel );
corpse UseAnimTree( #animtree );
corpse.animname = "collectible";
corpse.targetname = "collectible_corpse";
corpse thread maps\_anim::anim_loop_solo( corpse, "collectible_loop", undefined, "stop_collectible_loop", orig );
level waittill( "stop_collectible_loop" );
corpse notify( "stop_collectible_loop" );
wait( 0.1 );
corpse Delete();
}
// --- FLAG CARRYING ---
russian_flag_init()
{
flag_wait( "all_players_connected" );
level.useButtonHoldTime = 0.4;
level.requiredFlagProximity = 1300;
// model is set up like a weapon so we have to re-orient it in script
level.russianFlagOriginOffset = ( 0, 0, 27 );
level.russianFlagAnglesOffset = ( 270, 0, 0 );
russian_flag_hud_init();
russianFlag = Spawn( "script_model", ( 1136, 13288, 392 ) );
russianFlag.origin += level.russianFlagOriginOffset;
russianFlag.angles += level.russianFlagAnglesOffset;
russianFlag SetModel( "anim_berlin_rus_flag_rolled" );
russianFlag Hide();
level.russianFlag = russianFlag;
flag_set( "russian_flag_setup" );
}
russian_flag_startthink()
{
if( IsDefined( level.russian_flag_startthink ) )
{
return;
}
level.russian_flag_startthink = true;
level.russianFlag Show();
level thread russian_flag_objectives( level.russianFlag );
/* DEPRECATED proxcheck is annoying when the flag is only at the end of the level
flag_disable_proxcheck = GetDvarInt( "flag_disable_proxcheck" );
if( IsDefined( flag_disable_proxcheck ) && flag_disable_proxcheck <= 0 )
{
level thread russian_flag_proxcheck( level.russianFlag );
}
*/
flag_set( "russian_flag_dropped" );
level.russianFlag thread russian_flag_think();
level.russianFlag thread spawn_highlight();
}
russian_flag_hud_init()
{
level.russianFlagHudFadeTime = 0.1;
players = get_players();
for( i = 0; i < players.size; i++ )
{
players[i].russian_flag_hud = NewClientHudElem( players[i] );
players[i].russian_flag_hud.alignX = "left";
players[i].russian_flag_hud.fontScale = 1.5;
players[i].russian_flag_hud.x = 210;
players[i].russian_flag_hud.y = 200;
players[i].russian_flag_hud.alpha = 0;
}
level.russian_flag_timer_hud = NewHudElem();
level.russian_flag_timer_hud.alignX = "left";
level.russian_flag_timer_hud.fontScale = 1.5;
level.russian_flag_timer_hud.x = 180;
level.russian_flag_timer_hud.y = 215;
level.russian_flag_timer_hud.alpha = 0;
}
russian_flag_hud_fadeout()
{
if( !IsDefined( self.russian_flag_hud ) )
{
return;
}
if( self.russian_flag_hud.alpha != 0 )
{
self.russian_flag_hud FadeOverTime( level.russianFlagHudFadeTime );
self.russian_flag_hud.alpha = 0;
}
}
russian_flag_objectives( russianFlag )
{
objective_state( 1, "done" );
objective_state( 2, "done" );
objective_state( 3, "done" );
objective_state( 4, "done" );
objective_state( 5, "done" );
objective_add( 6, "active", level.obj_flag_retrieve_string, russianFlag get_offset_origin() );
while( 1 )
{
// wait for the flag to change
level waittill( "russian_flag_dropped" );
if( !flag( "russian_flag_dropped" ) )
{
objective_string_nomessage( 6, level.obj_flag_carry_string );
objective_state( 6, "active" );
objective_position( 6, (1136, 11768, 1604) );
//objective_current( level.nonFlagObjective );
objective_current( 6 );
}
else
{
objective_string( 6, level.obj_flag_retrieve_string );
objective_position( 6, russianFlag get_offset_origin() );
objective_current( 6 );
}
}
}
russian_flag_proxcheck( russianFlag )
{
timer = undefined;
while( 1 )
{
while( !flag( "russian_flag_dropped" ) )
{
wait( 0.5 );
}
players = get_players();
playerInRange = false;
for( i = 0; i < players.size; i++ )
{
player = players[i];
// if in the radius...
if( Distance( player.origin, russianFlag get_offset_origin() ) <= level.requiredFlagProximity )
{
playerInRange = true;
timer = undefined;
level.russian_flag_timer_hud.alpha = 0;
break;
}
}
// if nobody was in range...
if( !playerInRange )
{
if( !IsDefined( timer ) )
{
timer = GetTime();
// warn player
sarge_giveorder( "protect_the_flag" );
level.russian_flag_timer_hud SetText( level.flag_fail_warning );
level.russian_flag_timer_hud.alpha = 1;
}
else
{
if( GetTime() - timer >= 5000 )
{
// turn off the text
level.russian_flag_timer_hud.alpha = 0;
// mission fail
level thread russian_flag_mission_fail();
// don't have to watch anymore since the mission failed
break;
}
}
}
wait( 0.5 );
}
}
russian_flag_mission_fail()
{
SetDvar( "ui_deadquote", level.flag_fail_deadquote );
maps\_utility::missionFailedWrapper();
}
// mostly handles catching input
// self = the flag
russian_flag_think()
{
level endon( "kill_flagcarry" );
level thread kill_enemies_in_dome_after_flag_pickup();
while( 1 )
{
// wait for flag to drop
while( !flag( "russian_flag_dropped" ) )
{
wait( 0.1 );
}
// spawn the trigger
flagtrig = Spawn( "trigger_radius", self get_offset_origin(), 0, 64, 200 );
flagtrig EnableLinkTo();
flagtrig LinkTo( self ); // so we can teleport it if we want
// while it's on the ground...
while( flag( "russian_flag_dropped" ) )
{
players = get_players();
for( i = 0; i < players.size; i++ )
{
player = players[i];
// if they previously picked up the flag, make sure we're not waiting on button release
if( IsDefined( player.allowFlagPickup ) && !player.allowFlagPickup )
{
continue;
}
// when in trigger...
if( player IsTouching( flagtrig ) )
{
if( player isthrowinggrenade() )
{
if( player.russian_flag_hud.alpha != 0 )
{
player.russian_flag_hud FadeOverTime( level.russianFlagHudFadeTime );
player.russian_flag_hud.alpha = 0;
}
}
else
{
if( player.russian_flag_hud.alpha != 1 )
{
// HUD tip
player.russian_flag_hud SetText( level.hint_flag_pickup_string );
player.russian_flag_hud FadeOverTime( level.russianFlagHudFadeTime );
player.russian_flag_hud.alpha = 1;
}
}
// if pressing use...
if( player UseButtonPressed() && player isthrowinggrenade() == false )
{
if( !IsDefined( player.useButtonHoldTimer ) || player.useButtonHoldTimer == 0 )
{
player.useButtonHoldTimer = GetTime();
}
// make sure we've been holding the button long enough
if( ( GetTime() - player.useButtonHoldTimer ) >= ( level.useButtonHoldTime * 1000 ) )
{
// turn off the highlight, if necessary
if( IsDefined( self.highlight ) )
{
self.highlight Delete();
}
// kick off flag carrying
self thread russian_flag_player_carry( player );
flag_clear( "russian_flag_dropped" );
flagtrig Unlink();
flagtrig Delete();
// wait for player to release button before waiting for more input
while( player UseButtonPressed() )
{
wait( 0.05 );
}
// turn off HUD
array_thread( get_players(), ::russian_flag_hud_fadeout );
break;
}
}
// if not pressing use...
else
{
// reset the HUD and timer
player.useButtonHoldTimer = 0;
}
}
// if not in the trigger...
else
{
player thread russian_flag_hud_fadeout();
}
}
wait( 0.05 );
}
}
}
kill_enemies_in_dome_after_flag_pickup()
{
level waittill( "russian_flag_dropped" );
while( flag( "russian_flag_dropped" ) )
{
wait( 0.1 );
}
tags = [];
tags[0] = "j_hip_le";
tags[1] = "j_hip_ri";
tags[2] = "j_head";
tags[3] = "j_spine4";
tags[4] = "j_spineupper";
tags[5] = "j_spinelower";
tags[6] = "j_clavicle_le";
tags[7] = "j_clavicle_ri";
axis_ai = GetAiArray( "axis" );
while( axis_ai.size > 0 )
{
// randomly kill 1 enemy every second, as long as there are still enemies left
i = randomint( axis_ai.size );
tag = get_random( tags );
if( is_mature() )
{
bloodFX = undefined; // if we pass undefined it'll do the default flesh_hit
if( RandomInt( 100 ) < 65 )
{
bloodFX = level._effect["flesh_hit_large"];
}
axis_ai[i] thread bloody_death_fx( tag, bloodFX );
}
axis_ai[i] dodamage( axis_ai[i].health + 100, ( 0, 0, 0 ) );
wait( 2 );
axis_ai = GetAiArray( "axis" );
}
}
// self = the flag
russian_flag_player_carry( player )
{
level endon( "kill_flagcarry" );
useButtonHoldTimer = 0;
// hide the worldmodel
self Hide();
level.lastFlagBearer = player;
player.allowFlagPickup = false;
// take weapons and give flag
//player take_player_weapons();
player TakeWeapon( "molotov" );
//player.lastActiveWeapon = player GetCurrentWeapon();
player GiveWeapon( "russian_flag" );
player SwitchToWeapon( "russian_flag" );
player DisableWeaponCycling();
player DisableOffhandWeapons();
if( is_coop() )
{
player Attach( "ber3b_3rd_person_flag", "tag_weapon_right" );
// make him not look so bad from 3rd person
//player Attach( GetWeaponModel( player.lastActiveWeapon ), "tag_weapon_right" );
level thread fail_mission_on_flag_carrier_death( player );
}
arcademode_assignpoints( "arcademode_score_generic500", player );
// if holding button, wait for it to be released
while( player UseButtonPressed() )
{
wait( 0.05 );
}
/* DEPRECATED - player can't drop flag once he picks it up
while( IsAlive( player ) && IsDefined( player ) )
{
if( player UseButtonPressed() )
{
if( useButtonHoldTimer == 0 )
{
useButtonHoldTimer = GetTime();
}
// make sure we've been holding the button long enough
if( ( GetTime() - useButtonHoldTimer ) >= ( level.useButtonHoldTime * 1000 ) )
{
break;
}
}
else
{
useButtonHoldTimer = 0;
}
wait( 0.05 );
}
// move flag to player position, stick in the ground, and unhide the worldmodel
self.origin = player.origin + ( 0, 0, 50 );
self.origin = ( groundpos( self get_offset_origin() ) + level.russianFlagOriginOffset ) + ( 0, 0, -6 );
self.angles = level.russianFlagAnglesOffset + ( 13, 349, -20 );
self Show();
self thread spawn_highlight();
// notify that we dropped the flag
flag_set( "russian_flag_dropped" );
if( IsAlive( player ) && IsDefined( player ) )
{
// take flag and give player weapons back
player TakeWeapon( "russian_flag" );
player EnableWeaponCycling();
player EnableOffhandWeapons();
//player giveback_player_weapons();
// if we can't figure out what the last active weapon was, try to switch a primary weapon
if( player.lastActiveWeapon != "none" )
{
player SwitchToWeapon( player.lastActiveWeapon );
}
else
{
primaryWeapons = player GetWeaponsListPrimaries();
if( IsDefined( primaryWeapons ) && primaryWeapons.size > 0 )
{
player SwitchToWeapon( primaryWeapons[0] );
}
}
// wait for player to release button
while( player UseButtonPressed() )
{
wait( 0.05 );
}
// let player pick up the flag again
player.allowFlagPickup = true;
}
*/
}
fail_mission_on_flag_carrier_death( player )
{
if( level.onlineGame || level.systemLink )
{
player waittill( "disconnect" );
if( isDefined(level.hands) )
{
level.hands Hide();
}
missionfailed();
}
}
// self = the flag
spawn_highlight()
{
highlight = Spawn( "script_model", self.origin );
highlight.angles = self.angles;
//highlight SetModel( "anim_berlin_russian_flag_obj" );
highlight SetModel( "anim_berlin_rus_flag_rolled_obj" );
self.highlight = highlight;
}
// self = the flag
get_offset_origin()
{
return self.origin + level.russianFlagOriginOffset;
}
// self = the flag
get_offset_angles()
{
return self.angles + level.russianFlagAnglesOffset;
}
// used for moving the flag to start spots
russian_flag_teleport( moveSpot )
{
if( !flag( "russian_flag_setup" ) )
{
flag_wait( "russian_flag_setup" );
}
level.russianFlag.origin = moveSpot + ( level.russianFlagOriginOffset );
if( !IsDefined( level.russian_flag_startthink ) )
{
maps\ber3b::russian_flag_startthink();
}
}
// --- END FLAG CARRYING ---
// --- CUSTOM SPAWN FUNCTION SETUP ---
//does add_spawn_function on all the spawners that need custom behavior.
setup_spawn_functions()
{
// foyer: redshirts in a line, already fighting at the first cover area
group_add_spawn_function( "spawner_foyer_redshirts_1", ::ai_safe_until_trigger, "trig_foyer_entrance", "targetname", 5 );
// foyer: redshirts who die at the entrance to the foyer
group_add_spawn_function( "spawner_foyer_flagbearer_buddy", maps\ber3b_event_foyer::foyer_flagbearer_buddies_spawnfunc );
// foyer pacing area: redshirts who run down the hall in front of the player
group_add_spawn_function( "spawner_foyer_pacing_friendly_hallrunners", maps\ber3b_event_foyer::foyer_pacing_friendly_hallrunners_spawnfunc );
// parliament: guys spawning during balcony objective
array_thread( GetEntArray( "spawner_parliament_enemy", "script_noteworthy"), ::add_spawn_function, maps\ber3b_event_parliament::parliament_enemy_spawnfunc );
// parliament: flamethrower dudes
group_add_spawn_function( "spawner_parliament_flamer", maps\ber3b_event_parliament::flamer_setup );
array_thread( GetEntArray( "spawner_parliament_flamer", "script_noteworthy"), ::add_spawn_function, maps\ber3b_event_parliament::flamer_setup );
}
group_add_spawn_function( groupTN, spawnFunc, param1, param2, param3 )
{
group = GetEntArray( groupTN, "targetname" );
ASSERTEX( IsDefined( group ) && group.size > 0, "Couldn't find group with targetname of '" + groupTN + "'." );
for( i = 0; i < group.size; i++ )
{
group[i] add_spawn_function( spawnFunc, param1, param2, param3 );
}
}
// --- END CUSTOM SPAWN FUNCTION SETUP ---
// --- DIFFICULTY SCALING ---
difficulty_scale()
{
removeWeapons = false;
switch( GetDifficulty() )
{
case "easy":
level.ber3b_superenemy_frac = 0.15;
level.ber3b_friendly_accuracy = 0.2;
level.ber3b_player_threatbias = 7000;
level.ber3b_friendly_suppression_wait = 2000;
break;
case "medium":
level.ber3b_superenemy_frac = 0.4;
level.ber3b_friendly_accuracy = 0.1;
level.ber3b_player_threatbias = 20000;
level.ber3b_friendly_suppression_wait = 3000;
break;
case "hard":
removeWeapons = true;
level.ber3b_superenemy_frac = 0.55;
level.ber3b_friendly_accuracy = 0.08;
level.ber3b_player_threatbias = 40000;
level.ber3b_friendly_suppression_wait = 4000;
break;
case "fu":
removeWeapons = true;
level.ber3b_superenemy_frac = 0.65;
level.ber3b_friendly_accuracy = 0.05;
level.ber3b_player_threatbias = 45000;
level.ber3b_friendly_suppression_wait = 5500;
break;
}
if( removeWeapons )
{
pickups = GetEntArray( "weapon_diff_remove", "targetname" );
array_thread( pickups, ::scr_delete );
}
array_thread( get_players(), ::player_set_threatbias );
level thread super_enemies();
level thread gimp_friendlies();
}
player_set_threatbias()
{
while( !IsDefined( level.ber3b_player_threatbias ) )
{
wait( 0.05 );
}
self.threatbias = level.ber3b_player_threatbias;
}
super_enemies()
{
level endon( "stop_super_enemies" );
level.superenemies = [];
while( 1 )
{
ais = GetAIArray( "axis" );
if( array_validate( ais ) )
{
while( level.superenemies.size < ( ais.size * level.ber3b_superenemy_frac ) )
{
level thread superenemy_create( ais );
}
}
wait( 2.5 );
}
}
superenemy_create( ais )
{
guy = undefined;
for( i = 0; i < ais.size; i++ )
{
if( !IsDefined( ais[i] ) || IsDefined( ais[i].isSuperEnemy ) )
{
continue;
}
else
{
guy = ais[i];
}
}
guy.isSuperEnemy = true;
guy.accuracy = RandomFloatRange( 0.65, 0.85 );
guy.suppressionwait = RandomIntRange( 0, 1000 );
level.superenemies[level.superenemies.size] = guy;
guy thread superenemy_remove_on_death();
}
superenemy_remove_on_death()
{
self waittill( "death" );
level.superenemies = array_remove( level.superenemies, self );
}
gimp_friendlies()
{
level endon( "stop_gimping_friendlies" );
while( 1 )
{
ais = GetAIArray( "allies" );
if( array_validate( ais ) )
{
for( i = 0; i < ais.size; i++ )
{
if( ais[i].suppressionwait != level.ber3b_friendly_suppression_wait )
{
ais[i].suppressionwait = level.ber3b_friendly_suppression_wait;
}
if( ais[i].accuracy != level.ber3b_friendly_accuracy )
{
ais[i].accuracy = level.ber3b_friendly_accuracy;
}
}
}
wait( 1.5 );
}
}
// --- END DIFFICULTY SCALING ---
// --- HONORGUARD SPECIAL COMBAT DIALOGUE ---
honorguard_combat_dialogue()
{
trigger_wait( "trig_roof_entrance", "targetname" );
lines[0] = "fur_deutschland";
lines[1] = "give_lives_for_germany";
lines[2] = "fur_das_fuhrer";
lines[3] = "deutschland_uber_alles";
lines[4] = "fur_den_ruhm";
lines[5] = "give_lives_for_fuhrer";
lines[6] = "berlin_never_yours";
lines[7] = "take_them_with_you";
lines_ogsize = lines.size;
while( 1 )
{
temp_lines = lines;
while( array_validate( temp_lines ) )
{
theLine = temp_lines[RandomInt( temp_lines.size )];
enemy = waittill_enemy_in_range_of_player( 375 );
enemy say_dialogue( "honorguard_misc", theLine, true, false );
temp_lines = array_remove( temp_lines, theLine );
wait( RandomFloatRange( 5, 10 ) );
}
}
}
// --- HONORGUARD SPECIAL COMBAT DIALOGUE ---
// --- COOP FUNCTIONS ---
onPlayerConnect()
{
while( 1 )
{
// initial server connection
level waittill( "connecting", player );
player thread onPlayerSpawned();
}
}
// self = a player connected to the server
onPlayerSpawned()
{
// need to loop because potentially this can happen more than once per player, since
// last stand just respawns the downed player when they're rezzed.
while( 1 )
{
// waittill the player spawns
self waittill("spawned_player");
self thread player_set_threatbias();
}
}
// --- END COOP FUNCTIONS ---