cod4-sdk/raw/maps/bog_b.gsc
2008-01-19 00:00:00 +00:00

2100 lines
No EOL
61 KiB
Text

#include maps\_utility;
#include maps\_anim;
#include common_scripts\utility;
#using_animtree( "generic_human" );
main()
{
if ( getdvar( "r_reflectionProbeGenerate" ) == "1" )
return;
setsaveddvar( "scr_dof_enable", "1" );
if ( getdvar( "bog_camerashake") == "" )
setdvar( "bog_camerashake", "1" );
if ( getdvar( "bog_disableenemies") == "" )
setdvar( "bog_disableenemies", "0" );
if ( getdvar( "bog_debug_tank") == "" )
setdvar( "bog_debug_tank", "0" );
if ( getdvar( "bog_debug_flyby") == "" )
setdvar( "bog_debug_flyby", "0" );
if ( getdvar( "bog_b_min_spec") == "1" )
makeMinSpec();
add_start( "arch", ::start_arch, &"STARTS_ARCH" );
add_start( "alley", ::start_alley, &"STARTS_ALLEY1" );
add_start( "ch46", ::start_ch46, &"STARTS_CH46" );
default_start( ::start_bog );
level.weaponClipModels = [];
level.weaponClipModels[0] = "weapon_ak47_clip";
level.weaponClipModels[1] = "weapon_m16_clip";
level.weaponClipModels[2] = "weapon_saw_clip";
level.weaponClipModels[3] = "weapon_ak74u_clip";
level.weaponClipModels[4] = "weapon_g3_clip";
level.weaponClipModels[5] = "weapon_dragunov_clip";
flag_init( "tank_clear_to_shoot" );
flag_init( "door_idle_guy_idling" );
flag_init( "price_at_spotter" );
flag_init( "ok_to_do_spotting" );
flag_init( "tank_in_final_position" );
flag_init( "tank_turret_aimed_at_t72" );
flag_init( "friendly_reactions_over" );
flag_init( "t72_in_final_position" );
flag_init( "t72_exploded" );
flag_init( "abrams_move_shoot_t72" );
flag_init( "abrams_advance_to_end_level" );
flag_init( "allowTankFire" );
flag_init( "aa_bog_b_zone_bog" );
flag_init( "aa_bog_b_zone_streets" );
flag_init( "aa_bog_b_zone_alley" );
flag_init( "dumpster_pushed" );
flag_init( "seaknight_dialog_done" );
flag_init( "alley_cleared" );
flag_init( "start_dumpster_push" );
flag_init( "player_passed_dumpster" );
level.radioForcedTransmissionQueue = [];
precacheModel( "vehicle_av8b_harrier_jet" );
precacheModel( "vehicle_t72_tank_d_animated_sequence" );
precacheItem( "m1a1_turret_blank" );
precacheString( &"BOG_B_OBJ_ESCORT_TANK" );
precacheString( &"BOG_B_OBJ_SEAKNIGHT" );
precacheString( &"BOG_B_T72_MG_DEATH" );
maps\_m1a1::main( "vehicle_m1a1_abrams" );
maps\_t72::main( "vehicle_t72_tank" );
maps\_mi17::main( "vehicle_mi17_woodland_fly_cheap" );
maps\_seaknight::main( "vehicle_ch46e" );
maps\createart\bog_b_art::main();
maps\bog_b_fx::main();
maps\_hiding_door::main();
maps\_load::main();
maps\bog_b_anim::main();
maps\_compass::setupMiniMap( "compass_map_bog_b" );
thread maps\bog_b_amb::main();
thread maps\_mortar::bog_style_mortar();
thread fog_adjust();
thread teamsSplitUp();
thread lastSequence();
thread alley_dumpster_sequence();
thread alley_cleared();
thread player_passed_dumpster();
level.cosine = [];
level.cosine[ "35" ] = cos( 35 );
level.cosine[ "65" ] = cos( 65 );
level.cosine[ "80" ] = cos( 80 );
level.customautosavecheck = ::savegame_redundancy_check;
level.minimumTimeBetweenAutosaves = 15;
level.exploderArray = [];
level.exploderArray[ 0 ][ 0 ] = setupExploder( 105 );
level.exploderArray[ 0 ][ 1 ] = setupExploder( 104 );
level.exploderArray[ 0 ][ 2 ] = setupExploder( 102 );
level.exploderArray[ 0 ][ 3 ] = setupExploder( 103 );
level.exploderArray[ 1 ][ 0 ] = setupExploder( 100, ::killSpawner, 7 );
level.exploderArray[ 1 ][ 1 ] = setupExploder( 101 );
level.exploderArray[ 2 ][ 0 ] = setupExploder( 200 );
level.exploderArray[ 2 ][ 1 ] = setupExploder( 201 );
// friendly respawn init;
flag_set( "respawn_friendlies" );
set_promotion_order( "r", "y" );
set_empty_promotion_order( "y" );
set_empty_promotion_order( "g" );
array_thread( getentarray( "stragglers_chase", "targetname" ), ::stragglers_chase );
array_thread( getentarray( "flyby", "targetname" ), ::flyby );
array_thread( getentarray( "chain_and_home", "script_noteworthy" ), ::add_spawn_function, ::chain_and_home );
array_thread( getentarray( "archway_bog_reinforcer", "targetname" ), ::add_spawn_function, ::ignored_by_tank_cannon );
array_thread( getentarray( "rpg_tank_shooter", "script_noteworthy" ), ::add_spawn_function, ::rpg_tank_shooter );
array_thread( getentarray( "rpg_tank_shooter_fall", "script_noteworthy" ), ::add_spawn_function, ::rpg_tank_shooter );
array_thread( getentarray( "rpg_tank_shooter_noignore", "script_noteworthy" ), ::add_spawn_function, ::rpg_tank_shooter );
array_thread( getentarray( "vehicle_path_disconnector", "targetname" ), ::vehicle_path_disconnector );
array_thread( getentarray( "delete_ai", "targetname" ), ::delete_ai_in_zone );
array_thread( getentarray( "autosave_when_trigger_cleared", "targetname" ), ::autosave_when_trigger_cleared );
array_thread( getentarray( "delete_all_axis", "script_noteworthy" ), ::delete_all_axis );
wait 0.05;
/#
if ( getdvar( "bog_disableenemies") == "1" )
{
array_thread( GetSpawnerTeamArray( "axis" ), ::self_delete );
array_thread( getaiarray( "axis" ), ::self_delete );
}
#/
alley_volume = getent( "alley_volume", "targetname" );
vehicles = getentarray( "destructible", "targetname" );
for ( i = 0 ; i < vehicles.size ; i++ )
{
if ( vehicles[ i ] isTouching( alley_volume ) )
vehicles[ i ].disableBadPlace = true;
}
// align the dumpster clip brush in the alley
dumpster = getent( "dumpster", "targetname" );
assert( isdefined( dumpster ) );
dumpster_clip = getent( "dumpster_clip", "targetname" );
assert( isdefined( dumpster_clip ) );
dumpster_clip.origin = dumpster.origin;
dumpster_clip.angles = ( 0, dumpster.angles[ 1 ], 0 );
clip = getent( "truck_clip_before", "targetname" );
assert( isdefined( clip ) );
clip notsolid();
clip delete();
level.abrams = getent( "abrams", "targetname" );
if ( !isdefined( level.abrams ) )
level.abrams = maps\_vehicle::waittill_vehiclespawn( "abrams" );
assert( isdefined( level.abrams ) );
level.abrams.isSquad = true;
level.abrams.forwardEnt = spawn( "script_origin", level.abrams getTagOrigin( "tag_flash" ) );
level.abrams.forwardEnt linkto( level.abrams );
assert( isdefined( level.abrams ) );
level.tire_fire = getent( "tire_fire", "targetname" );
assert( isdefined( level.tire_fire ) );
playfxontag( level._effect["firelp_large_pm"], level.tire_fire, "tag_origin" );
flag_set( "aa_bog_b_zone_bog" );
wait 6.5;
getent( "player_spawn_safety_brush", "targetname" ) delete();
wait 3.0;
objective_add( 1, "current", &"BOG_B_OBJ_ESCORT_TANK", ( 4347, -4683, 130 ) );
}
makeMinSpec()
{
spawners = getSpawnerArray();
for ( i = 0 ; i < spawners.size ; i++ )
{
if ( !isdefined( spawners[ i ].script_minspec_level ) )
{
if ( isdefined( spawners[ i ].baseaccuracy ) )
spawners[ i ].baseaccuracy *= 1.3;
else
spawners[ i ].baseaccuracy = 1.2;
continue;
}
switch( spawners[ i ].script_minspec_level )
{
case 0:
spawners[ i ] delete();
break;
}
}
}
bog_dialog()
{
wait 4;
battlechatter_off( "allies" );
excluders = [];
excluders[0] = level.price;
generic_marine1 = get_closest_ai_exclude ( level.player.origin , "allies", excluders );
assert( isdefined( generic_marine1 ) );
excluders[1] = generic_marine1;
generic_marine2 = get_closest_ai_exclude ( level.player.origin , "allies", excluders );
assert( isdefined( generic_marine2 ) );
if ( !generic_marine1 isHero() )
generic_marine1 thread magic_bullet_shield( undefined, 5.0 );
if ( !generic_marine2 isHero() )
generic_marine2 thread magic_bullet_shield( undefined, 5.0 );
generic_marine1.animname = "marine1";
generic_marine2.animname = "marine2";
generic_marine1 anim_single_solo ( generic_marine1, "getyourass" );
wait 1;
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "wereclear" ] );
flag_wait( "evemy_helicopter_reinforcement_spawned" );
wait 8;
generic_marine2 anim_single_solo ( generic_marine2, "enemyair" );
wait 0.05;
level.price anim_single_solo ( level.price, "grabrpg" );
wait 10;
generic_marine1 anim_single_solo ( generic_marine1, "rightflank" );
if ( !generic_marine1 isHero() )
generic_marine1 stop_magic_bullet_shield();
if ( !generic_marine2 isHero() )
generic_marine2 stop_magic_bullet_shield();
battlechatter_on( "allies" );
}
isHero()
{
if ( !isdefined( self ) )
return false;
if ( !isdefined( self.script_noteworthy ) )
return false;
if ( self.script_noteworthy == "hero" )
return true;
return false;
}
fog_adjust()
{
fog_in = getent( "fog_in", "targetname" );
fog_out = getent( "fog_out", "targetname" );
assert( isdefined( fog_in ) );
assert( isdefined( fog_out ) );
for(;;)
{
fog_in waittill( "trigger" );
setExpFog(0, 2842, 0.642709, 0.626383, 0.5, 3.0);
fog_out waittill( "trigger" );
setExpFog(0, 3842, 0.642709, 0.626383, 0.5, 3.0);
}
}
start_bog()
{
spawn_starting_friendlies( "friendly_starting_spawner" );
thread ignored_till_fastrope( "introchopper1" );
thread ignored_till_fastrope( "introchopper2" );
thread bog_enemies_retreat();
while( !isdefined( level.abrams ) )
wait 0.05;
thread tank_advancement_bog();
thread first_friendly_advancement_trigger();
thread bog_dialog();
level.player.ignoreme = true;
wait 6;
level.player.ignoreme = false;
}
first_friendly_advancement_trigger()
{
trigger = getent( "first_friendly_advancement_trigger", "script_noteworthy" );
assert( isdefined( trigger ) );
trigger endon( "trigger" );
wait 3;
if ( !isdefined( trigger ) )
return;
trigger notify( "trigger" );
}
start_arch()
{
spawn_starting_friendlies( "friendly_starting_spawner_arch" );
start = getent( "playerstart_arch", "targetname" );
level.player setOrigin( start.origin );
level.player setPlayerAngles( ( 0, start.angles[1], 0 ) );
wait 0.05;
ai = getaiarray( "axis" );
for( i = 0 ; i < ai.size ; i++ )
{
if ( isdefined( ai[ i ].magic_bullet_shield ) && ai[ i ].magic_bullet_shield )
ai[ i ] stop_magic_bullet_shield();
ai[ i ] delete();
}
while( !isdefined( level.abrams ) )
wait 0.05;
tank_path_2 = getVehicleNode( "tank_path_2", "targetname" );
level.abrams attachPath( tank_path_2 );
thread tank_advancement_arch();
}
start_alley()
{
spawn_starting_friendlies( "friendly_starting_spawner_alley" );
start = getent( "playerstart_alley", "targetname" );
level.player setOrigin( start.origin );
level.player setPlayerAngles( ( 0, start.angles[1], 0 ) );
waittillframeend;
ai = getaiarray( "axis" );
for( i = 0 ; i < ai.size ; i++ )
{
if ( isdefined( ai[ i ].magic_bullet_shield ) && ai[ i ].magic_bullet_shield )
{
ai[ i ] stop_magic_bullet_shield();
ai[ i ] delete();
}
}
thread friendlies_become_invulnerable();
while( !isdefined( level.abrams ) )
wait 0.05;
tank_path_2 = getVehicleNode( "tank_path_2", "targetname" );
level.abrams attachPath( tank_path_2 );
node = getvehiclenode( "stop_for_city_fight3", "script_noteworthy" );
level.abrams setWaitNode( node );
level.abrams waittill( "reached_wait_node" );
level.abrams setSpeed( 0, 10 );
thread tank_advancement_alley();
}
friendlies_become_invulnerable()
{
// all allies now become invulnerable
thread friendly_reinforcements_magic_bullet();
allies = getaiarray( "allies" );
for ( i = 0 ; i < allies.size ; i++ )
{
if ( isdefined( allies[ i ].magic_bullet_shield ) && allies[ i ].magic_bullet_shield )
continue;
allies[ i ] thread magic_bullet_shield( undefined, 5.0 );
}
}
start_ch46()
{
start = getent( "seaknight_land_location", "script_noteworthy" );
level.player setOrigin( start.origin );
level.player setPlayerAngles( ( 0, start.angles[1], 0 ) );
waittillframeend;
ai = getaiarray( "axis" );
for( i = 0 ; i < ai.size ; i++ )
{
if ( isdefined( ai[ i ].magic_bullet_shield ) && ai[ i ].magic_bullet_shield )
ai[ i ] stop_magic_bullet_shield();
ai[ i ] delete();
}
thread seaknight();
}
spawn_starting_friendlies( sTargetname )
{
spawners = getentarray( sTargetname, "targetname" );
for( i = 0 ; i < spawners.size ; i++ )
{
friend = spawners[ i ] stalingradSpawn();
if ( spawn_failed( friend ) )
assertMsg( "A friendly failed to spawn" );
friend.goalradius = 32;
if ( issubstr( friend.classname, "vasquez" ) )
level.price = friend;
if ( issubstr( friend.classname, "mark" ) )
level.grigsby = friend;
if ( friend isHero() )
friend thread magic_bullet_shield( undefined, 5.0 );
}
assert( isdefined( level.price ) );
level.price.animname = "price";
level.price make_hero();
assert( isdefined( level.grigsby ) );
level.grigsby.animname = "grigsby";
level.grigsby make_hero();
level.grigsby.suppressionThreshold = 1.0;
array_thread( getaiarray( "allies" ), ::replace_on_death );
}
ignored_till_fastrope( sTargetname )
{
vehicle = undefined;
vehicle = getent( sTargetname, "targetname" );
if ( !isdefined( vehicle ) )
vehicle = maps\_vehicle::waittill_vehiclespawn( sTargetname );
assert( isdefined( vehicle.riders ) );
for( i = 0 ; i < vehicle.riders.size ; i++ )
{
vehicle.riders[ i ].ignoreme = true;
vehicle.riders[ i ] thread ignored_by_tank_cannon();
}
vehicle waittill( "unload" );
wait 5;
if( !isdefined( vehicle ) )
return;
for( i = 0 ; i < vehicle.riders.size ; i++ )
{
if( !isdefined( vehicle.riders[ i ] ) )
continue;
if( !isAlive( vehicle.riders[ i ] ) )
continue;
vehicle.riders[ i ].ignoreme = false;
vehicle.riders[ i ] thread ignored_by_tank_cannon( false );
}
}
stragglers_chase()
{
assert( isdefined( self.target ) );
volume = getent( self.target, "targetname" );
assert( isdefined( volume ) );
self waittill( "trigger" );
enemies = getaiarray( "axis" );
for( i = 0 ; i < enemies.size ; i++ )
{
if ( !( enemies[ i ] istouching( volume ) ) )
continue;
enemies[ i ].goalradius = 600;
enemies[ i ] setgoalentity( level.player );
}
}
truck_crush_tank_in_position()
{
node = getVehicleNode( "truck_crush_node", "script_noteworthy" );
assert( isdefined( node ) );
node waittill( "trigger" );
level.abrams setSpeed( 0, 999999999, 999999999 );
flag_set( "truck_crush_tank_in_position" );
}
chain_and_home()
{
self endon( "death" );
self waittill( "reached_path_end" );
newGoalRadius = distance( self.origin, level.player.origin );
if ( newGoalRadius > 1024 )
newGoalRadius = 1024;
for(;;)
{
wait 5;
self.goalradius = newGoalRadius;
self setgoalentity ( level.player );
newGoalRadius -= 175;
if ( newGoalRadius < 512 )
{
newGoalRadius = 512;
return;
}
}
}
rpg_tank_shooter()
{
self endon( "death" );
if ( ( isdefined( self.script_noteworthy ) ) && ( self.script_noteworthy != "rpg_tank_shooter_noignore" ) )
{
// make him ignored by other AI so the player gets to shoot him and see him fall
self.ignoreme = true;
}
// when this guy spawns he tries to shoot the tank with his RPG
self waittill( "goal" );
if ( ( isdefined( self.script_noteworthy ) ) && ( self.script_noteworthy == "rpg_tank_shooter_fall" ) )
{
if( getdvar("ragdoll_enable") == "1" )
self thread roof_guy_fall_on_death();
}
self setentitytarget( level.abrams );
wait 10;
if ( isdefined( self ) )
self clearEnemy();
}
roof_guy_fall_on_death()
{
self endon( "death" );
self.health = 10;
for(;;)
{
self.deathanim = %bog_b_rpg_fall_death;
wait 0.05;
}
}
attack_troops()
{
self notify( "stop_attacking_troops" );
self endon( "stop_attacking_troops" );
self endon( "death" );
wait 1;
for(;;)
{
wait( randomfloatrange( 2, 5 ) );
eTarget = maps\_helicopter_globals::getEnemyTarget( 10000, level.cosine[ "80" ], true, false, false, true );
if ( !isdefined( eTarget ) )
continue;
zDifference = abs( eTarget.origin[ 2 ] - self.origin[ 2 ] );
dist = distance( eTarget.origin, self.origin );
angle = asin( zDifference / dist );
if ( angle > 15 )
continue;
targetLoc = eTarget.origin + ( 0, 0, 32 );
self setTurretTargetVec( targetLoc );
if ( getdvar( "bog_debug_tank") == "1" )
thread draw_line_until_notify( level.abrams.origin + ( 0, 0, 32 ), targetLoc, 1, 0, 0, self, "stop_drawing_line" );
self waittill_notify_or_timeout( "turret_rotate_stopped", 3.0 );
self clearTurretTarget();
if ( getdvar( "bog_debug_tank") == "1" )
{
self notify( "stop_drawing_line" );
thread draw_line_until_notify( level.abrams.origin + ( 0, 0, 32 ), targetLoc, 0, 1, 0, self, "stop_drawing_line" );
}
if ( getdvar( "bog_debug_tank") == "1" )
self notify( "stop_drawing_line" );
}
}
tank_turret_forward()
{
getent( "tank_turret_forward", "targetname" ) waittill( "trigger" );
self notify( "stop_attacking_troops" );
self setturrettargetent( self.forwardEnt );
self waittill_notify_or_timeout( "turret_rotate_stopped", 4.0 );
self clearTurretTarget();
}
ambush_ahead_dialog()
{
battlechatter_off( "allies" );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "possibleambush" ] );
wait 1;
// price warns about guys on rooftops
level.price anim_single_solo( level.price, "watchrooftops" );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "standclear" ] );
battlechatter_on( "allies" );
flag_set( "tank_clear_to_shoot" );
}
playRadioSound( soundAlias )
{
if ( !isdefined( level.radio_in_use ) )
level.radio_in_use = false;
soundPlayed = false;
soundPlayed = playAliasOverRadio( soundAlias );
if ( soundPlayed )
return;
level.radioForcedTransmissionQueue[ level.radioForcedTransmissionQueue.size ] = soundAlias;
while( !soundPlayed )
{
if ( level.radio_in_use )
level waittill ( "radio_not_in_use" );
soundPlayed = playAliasOverRadio( level.radioForcedTransmissionQueue[ 0 ] );
if ( !level.radio_in_use && !soundPlayed )
assertMsg( "The radio wasn't in use but the sound still did not play. This should never happen." );
}
level.radioForcedTransmissionQueue = array_remove_index( level.radioForcedTransmissionQueue, 0 );
}
playAliasOverRadio( soundAlias )
{
if ( level.radio_in_use )
return false;
level.radio_in_use = true;
level.player playLocalSound( soundAlias, "playSoundOverRadio_done" );
level.player waittill( "playSoundOverRadio_done" );
level.radio_in_use = false;
level.lastRadioTransmission = getTime();
level notify ( "radio_not_in_use" );
return true;
}
shoot_buildings( exploderGroup )
{
self notify( "stop_attacking_troops" );
flag_wait( "tank_clear_to_shoot" );
for(;;)
{
if ( level.exploderArray[ exploderGroup ].size <= 0 )
break;
nextExploderIndex = undefined;
nextExploderIndex = getNextExploder( exploderGroup );
if ( !isdefined( nextExploderIndex ) )
{
wait randomfloat( 2, 4 );
continue;
}
shoot_exploder( level.exploderArray[ exploderGroup ][ nextExploderIndex ] );
level.exploderArray[ exploderGroup ] = array_remove_index ( level.exploderArray[ exploderGroup ], nextExploderIndex );
wait randomfloat( 6, 10 );
}
self notify( "abrams_shot_explodergroup" );
}
setupExploder( exploderNum, explodedFunction, parm1 )
{
exploderStruct = spawnStruct();
exploderStruct.iNumber = int( exploderNum );
exploderStruct.sNumber = string( exploderNum );
// find the related origin
origins = getentarray( "exploder_tank_target", "targetname" );
for( i = 0 ; i < origins.size ; i++ )
{
assert( isdefined( origins[ i ].script_noteworthy ) );
if ( origins[ i ].script_noteworthy == exploderStruct.sNumber )
exploderStruct.origin = origins[ i ].origin;
}
assert( isdefined( exploderStruct.origin ) );
// find the area trigger if one exists
areatrigs = getentarray( "exploder_area", "targetname" );
for( i = 0 ; i < areatrigs.size ; i++ )
{
assert( isdefined( areatrigs[ i ].script_noteworthy ) );
if ( areatrigs[ i ].script_noteworthy == exploderStruct.sNumber )
exploderStruct.areaTrig = areatrigs[ i ];
}
exploderStruct.explodedFunction = explodedFunction;
exploderStruct.parm1 = parm1;
return exploderStruct;
}
getNextExploder( exploderGroup )
{
prof_begin( "getNextExploder" );
// try to find one that the player is looking at
// if the exploder has an area trigger make sure the player isn't touching it
validIndicies = [];
for( i = 0 ; i < level.exploderArray[ exploderGroup ].size ; i++ )
{
if ( isdefined( level.exploderArray[ exploderGroup ][ i ].areaTrig ) && level.player isTouching( level.exploderArray[ exploderGroup ][ i ].areaTrig ) )
continue;
validIndicies[ validIndicies.size ] = i;
}
if ( validIndicies.size == 0 )
{
prof_end( "getNextExploder" );
return undefined;
}
// if the player is looking at one of the valid exploders then use that one
for( i = 0 ; i < validIndicies.size ; i++ )
{
qInFOV = within_fov( level.player getEye(), level.player getPlayerAngles(), level.exploderArray[ exploderGroup ][ validIndicies[ i ] ].origin, level.cosine[ "35" ] );
if ( qInFOV )
{
prof_end( "getNextExploder" );
return validIndicies[ i ];
}
}
prof_end( "getNextExploder" );
return validIndicies[ 0 ];
}
shoot_exploder( exploderStruct )
{
level.abrams thread tank_shooting_exploder_dialog( exploderStruct.iNumber );
level.abrams waittill( "target_aquired" );
level.abrams setTurretTargetVec( exploderStruct.origin );
level.abrams waittill_notify_or_timeout( "turret_rotate_stopped", 3.0 );
level.abrams clearTurretTarget();
level.abrams.readyToFire = true;
flag_wait( "allowTankFire" );
level.abrams.readyToFire = undefined;
level.abrams notify( "turret_fire" );
flag_clear( "allowTankFire" );
wait 0.2;
//blow up the wall now
exploder( exploderStruct.iNumber );
if ( isdefined( exploderStruct.explodedFunction ) )
{
if ( isdefined( exploderStruct.parm1 ) )
level thread [[ exploderStruct.explodedFunction ]]( exploderStruct.parm1 );
else
level thread [[ exploderStruct.explodedFunction ]]();
}
wait 0.05;
SetPlayerIgnoreRadiusDamage( true );
radiusDamage( exploderStruct.origin, 300, 5000, 1000 );
wait 0.2;
SetPlayerIgnoreRadiusDamage( false );
}
tank_shooting_exploder_dialog( exploderNum )
{
assert( isdefined( exploderNum ) );
if ( exploderNum == 105 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up1" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "2story1_ground" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired1" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else if ( exploderNum == 104 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up2" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "2story1_2ndfloor" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired2" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else if ( exploderNum == 102 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up3" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "3story11_2ndfloor" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired3" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else if ( exploderNum == 103 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up4" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "3story1130_2ndfloor" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired1" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else if ( exploderNum == 100 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up1" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "3story1230_2ndfloor" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired2" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else if ( exploderNum == 101 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up1" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "3story11_2ndfloor" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired2" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else if ( exploderNum == 200 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up1" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired2" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else if ( exploderNum == 201 )
{
self.haltFire = true;
level.player playRadioSound( level.scr_sound[ "tank_loader" ][ "up3" ] );
self notify( "target_aquired" );
while( !isdefined( self.readyToFire ) )
wait 0.05;
level.player playRadioSound( level.scr_sound[ "tank_gunner" ][ "targetacquired1" ] );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "fire" ] );
}
else
{
wait 0.05;
self notify( "target_aquired" );
wait 0.05;
}
self.readyToFire = true;
flag_set( "allowTankFire" );
}
killSpawner( num )
{
thread maps\_spawner::kill_spawnerNum( num );
}
alley_dumpster_sequence()
{
trig = getent( "start_dumpster_sequence", "script_noteworthy" );
assert( isdefined( trig ) );
trig waittill( "trigger" );
arcademode_checkpoint( 2.0, "alley" );
thread friendlies_become_invulnerable();
wait 0.05;
level.alleyFriends = get_force_color_guys( "allies", "r" );
assert( level.alleyFriends.size >= 2 );
dumpsterGuy = undefined;
for ( i = 0 ; i < level.alleyFriends.size ; i++ )
{
if ( level.alleyFriends[ i ] == level.price )
continue;
dumpsterGuy = level.alleyFriends[ i ];
break;
}
assert( isdefined( level.price ) );
assert( isdefined( dumpsterGuy ) );
dumpsterGuy.animname = "dumpsterGuy";
dumpster = getent( "dumpster", "targetname" );
assert( isdefined( dumpster ) );
dumpster.animname = "dumpster";
dumpster useAnimTree( level.scr_animtree[ "dumpster" ] );
dumpster_clip = getent( "dumpster_clip", "targetname" );
assert( isdefined( dumpster_clip ) );
node = spawn( "script_origin", dumpster.origin );
node.angles = dumpster.angles;
dumpster thread updateClipPos( dumpster_clip );
dumpsterGuy thread set_ignoreSuppression( true );
level.price thread set_ignoreSuppression( true );
// Guy1 gets into position then does peek anim then push_idle anim
dumpsterGuy allowedStances( "crouch" );
node anim_reach_solo( dumpsterGuy, "dumpster_peek" );
guys = [];
guys[ guys.size ] = dumpsterGuy;
guys[ guys.size ] = dumpster;
dumpster thread play_sound_on_entity( "scn_bog_dumpster_peek" );
node anim_single( guys, "dumpster_peek" );
node thread anim_loop_solo( dumpsterGuy, "dumpster_idle2", undefined, "stop_idle" );
// wait until the player can see the sequence
level thread dumpsterGuy_push_condition1( dumpsterGuy );
level thread dumpsterGuy_push_condition2( dumpsterGuy );
level thread dumpsterGuy_push_condition3( dumpsterGuy );
flag_wait( "start_dumpster_push" );
// vasquez gets into position and once he's in position they push the dumpster
dumpster anim_reach_solo( level.price, "dumpster_push" );
dumpsterGuy notify( "stop_idle" );
node notify( "stop_idle" );
guys[ guys.size ] = level.price;
dumpster thread play_sound_on_entity( "scn_bog_dumpster_push" );
dumpster anim_single( guys, "dumpster_push" );
dumpster notify( "stop_updating_clip" );
dumpster_clip disconnectPaths();
dumpsterGuy allowedStances( "crouch", "stand", "prone" );
level.price setGoalNode( getnode( "dumpster_push_afternode_dumpsterguy", "targetname" ) );
dumpsterGuy setGoalNode( getnode( "dumpster_push_afternode_vasquez", "targetname" ) );
remove_alley_seperation_clip();
flag_set( "dumpster_pushed" );
}
remove_alley_seperation_clip()
{
alley_seperation_clip = getent( "alley_seperation_clip", "targetname" );
if ( !isdefined( alley_seperation_clip ) )
return;
alley_seperation_clip connectpaths();
alley_seperation_clip delete();
}
dumpsterGuy_push_condition1( guy )
{
// player looks at him to trigger the sequence
guy endon( "start_dumpster_push" );
guy waittill_player_lookat( level.cosine[ "65" ] );
flag_set( "start_dumpster_push" );
guy notify( "start_dumpster_push" );
}
dumpsterGuy_push_condition2( guy )
{
// all ai in the alley are killed so do the sequence
guy endon( "start_dumpster_push" );
flag_wait( "alley_cleared" );
flag_set( "start_dumpster_push" );
guy notify( "start_dumpster_push" );
}
dumpsterGuy_push_condition3( guy )
{
// player passed the dumpster so do the sequence
guy endon( "start_dumpster_push" );
flag_wait( "player_passed_dumpster" );
flag_set( "start_dumpster_push" );
guy notify( "start_dumpster_push" );
}
updateClipPos( clipBrush )
{
self endon( "stop_updating_clip" );
clipBrush.origin = self.origin;
clipBrush.angles = self.angles;
for(;;)
{
clipBrush moveto( self.origin, 0.1 );
clipBrush rotateTo( ( 0, self.angles[ 1 ], 0 ), 0.1 );
wait 0.1;
}
}
alley_cleared()
{
waittill_aigroupcleared( "0" );
flag_set( "alley_cleared" );
// decrease the ambient
thread maps\_utility::set_ambient( "exterior_level1" );
flag_wait( "dumpster_pushed" );
getent( "alley_protect_door_breech_color_trigger", "targetname" ) notify( "trigger" );
assert( isdefined( level.alleyFriends ) );
assert( level.alleyFriends.size >= 2 );
otherGuy = level.alleyFriends[ 0 ];
if ( otherGuy == level.price )
otherGuy = level.alleyFriends[ 1 ];
assert( otherGuy != level.price );
alley_door_kick( otherGuy );
thread advanceAlleyFriendliesToEnd( level.alleyFriends[ 0 ], level.alleyFriends[ 1 ] );
flag_clear( "aa_bog_b_zone_alley" );
}
alley_door_kick( guy )
{
assert( isdefined( guy ) );
guys[ 0 ] = guy;
guys[ 1 ] = level.price;
assert( guys[ 0 ] != guys[ 1 ] );
guys[ 0 ].animname = "alley_door_kicker_left";
guys[ 1 ].animname = "alley_door_kicker_right";
alley_door_scripted_node = getent( "alley_door_scripted_node", "targetname" );
assert( isdefined( alley_door_scripted_node ) );
// guy1 waits at the door until guy2 arrives
thread alley_door_guy1_idle( alley_door_scripted_node, guys[ 0 ] );
wait 1;
guys[ 1 ].animname = "alley_door_kicker_right";
alley_door_scripted_node anim_reach_solo ( guys[ 1 ], "enter" );
flag_wait( "door_idle_guy_idling" );
guys[ 0 ] notify( "stop_door_idle" );
guys[ 0 ].animname = "alley_door_kicker_left";
guys[ 1 ].animname = "alley_door_kicker_right";
alley_door_scripted_node anim_single( guys, "enter" );
getent( "last_color_order_trigger", "targetname" ) notify( "trigger" );
thread alley_door_remove_player_clip();
}
alley_door_remove_player_clip( fDelay )
{
if ( isdefined( fDelay ) )
wait fDelay;
getent( "alley_door_player_clip", "targetname" ) delete();
}
alley_door_guy1_idle( node, guy )
{
node anim_reach_and_idle_solo( guy, "idle_reach", "idle", "stop_door_idle" );
flag_set( "door_idle_guy_idling" );
}
alley_doorOpen( guy )
{
// called from a notetrack
alley_door = getent( "alley_door", "targetname" );
assert( isdefined( alley_door ) );
alley_door connectPaths();
alley_door thread play_sound_in_space( "metal_door_kick" );
alley_door rotateYaw( -140, 0.5, 0, 0 );
wait 0.5;
alley_door disconnectPaths();
}
flyby()
{
if ( getdvar( "bog_b_min_spec") == "1" )
return;
assert( isdefined( self.target ) );
origins = getentarray( self.target, "targetname" );
assert( origins.size > 0 );
for( i = 0 ; i < origins.size ; i++ )
self thread flyby_go( origins[ i ] );
}
flyby_go( origin1 )
{
assert( isdefined( origin1 ) );
assert( isdefined( origin1.target ) );
origin2 = getent( origin1.target, "targetname" );
assert( isdefined( origin2 ) );
// Get starting and ending point for the plane
center = ( ( ( origin1.origin[ 0 ] + origin2.origin[ 0 ] ) / 2 ), ( ( origin1.origin[ 1 ] + origin2.origin[ 1 ] ) / 2 ), 0 );
angle = VectorToAngles( origin2.origin - origin1.origin );
direction = ( 0, angle[ 1 ], 0 );
planeStartingDistance = -20000;
planeEndingDistance = 20000;
planeFlySpeed = 4000;
startPoint = center + vector_multiply( anglestoforward( direction ), planeStartingDistance );
startPoint += ( 0, 0, origin1.origin[ 2 ] );
endPoint = center + vector_multiply( anglestoforward( direction ), planeEndingDistance );
endPoint += ( 0, 0, origin2.origin[ 2 ] );
self waittill( "trigger" );
// Spawn the plane
plane = spawn( "script_model", startPoint );
plane setModel( "vehicle_av8b_harrier_jet" );
plane.angles = direction;
// Make the plane fly by
d = abs( planeStartingDistance - planeEndingDistance );
flyTime = ( d / planeFlySpeed );
// Draw some debug lines of the plane's path
/#
if ( getdvar( "bog_debug_flyby") == "1" )
{
thread draw_line_for_time( center, center + ( 0, 0, 200 ), 0, 0, 1, flyTime );
thread draw_line_for_time( origin1.origin, origin2.origin, .1, .2, .4, flyTime );
thread draw_line_for_time( center, startPoint, 0, .4, 0, flyTime );
thread draw_line_for_time( center, endPoint, 0, .8, 0, flyTime );
thread draw_line_to_ent_for_time( center, plane, 1, 0, 0, flyTime );
}
#/
plane moveTo( endPoint, flyTime, 0, 0 );
playfxontag( level._effect[ "contrail" ], plane, "tag_right_wingtip" );
playfxontag( level._effect[ "contrail" ], plane, "tag_left_wingtip" );
thread flyby_planeSound( plane );
// Delete the plane after it's flyby
wait flyTime;
plane notify( "delete" );
plane delete();
}
flyby_afterburner( plane )
{
plane endon( "delete" );
wait randomfloatrange( 0.5, 2.5 );
playfxontag( level._effect["afterburner"], plane, "tag_engine_right" );
playfxontag( level._effect["afterburner"], plane, "tag_engine_left" );
}
flyby_planeSound( plane )
{
plane thread play_loop_sound_on_entity( "veh_mig29_dist_loop" );
while( !maps\_mig29::playerisclose( plane ) )
wait .05;
plane notify ( "stop sound" + "veh_mig29_dist_loop" );
plane thread play_loop_sound_on_entity( "veh_mig29_close_loop" );
while( maps\_mig29::playerisinfront( plane ) )
wait .05;
wait .5;
plane thread play_sound_in_space( "veh_mig29_sonic_boom" );
thread flyby_afterburner( plane );
while( maps\_mig29::playerisclose( plane ) )
wait .05;
plane notify ( "stop sound" + "veh_mig29_close_loop" );
plane thread play_loop_sound_on_entity( "veh_mig29_dist_loop" );
plane waittill( "delete" );
plane notify ( "stop sound" + "veh_mig29_dist_loop" );
}
teamsSplitUp()
{
getent( "teams_split_up", "script_noteworthy" ) waittill( "trigger" );
area = getent( "price_inside_split_up_house", "targetname" );
for(;;)
{
area waittill( "trigger", ent );
if ( !isdefined( ent ) )
continue;
if ( ent == level.price )
break;
}
level.price.animname = "price";
anim_single_solo( level.price, "keeppinned" );
if ( isdefined( level.grigsby ) )
{
level.grigsby.animname = "grigsby";
thread anim_single_solo( level.grigsby, "staysharp" );
}
// all allies now become invulnerable
thread friendly_reinforcements_magic_bullet();
allies = getaiarray( "allies" );
for ( i = 0 ; i < allies.size ; i++ )
{
allies[ i ] set_ignoreSuppression( true );
if ( isdefined( allies[ i ].magic_bullet_shield ) && allies[ i ].magic_bullet_shield )
continue;
allies[ i ] thread magic_bullet_shield( undefined, 5.0 );
}
flag_clear( "aa_bog_b_zone_streets" );
flag_set( "aa_bog_b_zone_alley" );
}
lastSequence()
{
thread t72_kill_player_trigger();
thread t72_in_final_position();
flag_wait( "price_at_spotter" );
flag_wait( "ok_to_do_spotting" );
arcademode_checkpoint( 3.0, "t72" );
level.price.animname = "price";
level.price anim_single_solo( level.price, "casual_2_spot" );
level.price thread anim_loop_solo( level.price, "spot", undefined, "stop_idle" );
level.price thread anim_single_solo( level.price, "t72behind" );
wait 3;
flag_set( "abrams_move_shoot_t72" );
wait 3.0;
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "switchmanual" ] );
thread finalGenericDialog();
//wait for the tank to be in position and turret aligned
flag_wait( "tank_in_final_position" );
flag_wait( "tank_turret_aimed_at_t72" );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "takeshot" ] );
//-------------------------------------
// tank should be shot and explode here
//-------------------------------------
level.abrams clearTurretTarget();
level.abrams setVehWeapon( "m1a1_turret_blank" );
wait 0.05;
level.t72 notify( "exploding" );
level.t72 maps\_vehicle::mgOff();
level.abrams notify( "turret_fire" );
level notify( "t72_exploded" );
exploder( 400 );
// friendlies in the dark broken building can be seen again
level.player.ignoreme = false;
for ( i = 0 ; i < level.alleyFriends.size ; i++ )
level.alleyFriends[ i ].ignoreme = false;
end_sequence_physics_explosion = getentarray( "end_sequence_physics_explosion", "targetname" );
for( i = 0 ; i < end_sequence_physics_explosion.size ; i++ )
physicsExplosionSphere( end_sequence_physics_explosion[ i ].origin, 550, 100, 1.2 );
wait .2;
level thread t72_explosion_explode();
level thread enemies_fall_back();
//-------------------------------------
//-------------------------------------
//-------------------------------------
flag_wait( "friendly_reactions_over" );
level.price.animname = "price";
anim_single_solo( level.price, "niceshootingpig" );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "comingthrough" ] );
flag_set( "abrams_advance_to_end_level" );
wait 2;
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "wethereyet" ] );
level.player playRadioSound( level.scr_sound[ "hq_radio" ][ "statusover" ] );
level.price.animname = "price";
anim_single_solo( level.price, "cargo" );
level.price notify( "stop_idle" );
thread seaknight();
}
t72_kill_player_trigger()
{
level endon( "t72_exploded" );
trigger = getent( "t72_kill_player_trigger", "targetname" );
for(;;)
{
trigger waittill( "trigger", ent );
if ( ent != level.player )
continue;
// kill the player!
dmgAmount = ( level.player.health / 3 );
while( isalive( level.player ) )
{
wait 0.1;
if ( isdefined( level.t72 ) )
{
level.t72 thread play_sound_on_entity( "t72_fire" );
level.player doDamage ( dmgAmount, level.t72.origin );
}
else
{
thread play_sound_in_space( "t72_fire", ( 6105, -3475, -60 ) );
level.player doDamage ( dmgAmount, level.player.origin );
}
}
level notify( "new_quote_string" );
setdvar( "ui_deadquote", "@BOG_B_T72_MG_DEATH" );
}
}
t72_explosion_explode()
{
level.t72 hide();
deadT72 = spawn( "script_model", level.t72.origin );
deadT72.angles = level.t72.angles;
deadT72 setModel( level.t72.model );
level.t72 = deadT72;
deadT72 = undefined;
level.t72 thread play_sound_in_space( "bog_scn_tankturret_brew" );
level.t72 thread t72_explosionFX();
level.t72 useAnimTree( level.scr_animtree[ "tank_explosion" ] );
level.t72 setFlaggedAnim( "tank_explosion_anim1", level.scr_anim[ "tank" ][ "explosion1" ], 1, 0.1, 1 );
level.t72 waittillmatch( "tank_explosion_anim1", "end" );
level.t72 setmodel( "vehicle_t72_tank_d_animated_sequence" );
//earthquake( <scale>, <duration>, <source>, <radius> )
earthquake( 0.6, 1.0, level.t72.origin, 8000);
level.t72 SetFlaggedAnimKnobRestart( "tank_explosion_anim2", level.scr_anim[ "tank" ][ "explosion2" ], 1, 0.1, 1 );
level.t72 waittillmatch( "tank_explosion_anim2", "turret_explosion" );
level.t72 thread play_sound_in_space( "bog_scn_tankturret_exp" );
wait 1.4;
level.t72 thread play_sound_in_space( "bog_scn_tankturret_crash" );
}
t72_explosionFX()
{
// playfxontag( level._effect[ "t72_explosion" ], level.t72, "tag_deathfx" );
level.t72 thread play_sound_in_space( "explo_metal_rand" );
physicsExplosionSphere( level.t72.origin, 1000, 20, 2 );
playfxontag( level._effect[ "t72_ammo_breach" ], level.t72, "tag_deathfx" );
wait 3.5;
thread friendlyReactionAnims();
flag_set( "t72_exploded" );
playfxontag( level._effect[ "t72_ammo_explosion" ], level.t72, "tag_deathfx" );
wait .15;
physicsExplosionSphere( level.t72.origin, 1000, 100, 2 );
wait 1.4;
playfxontag( level._effect[ "firelp_large_pm" ], level.t72, "tag_deathfx" );
level.t72 thread play_loop_sound_on_entity( "fire_metal_medium" );
}
abrams_setup_t72()
{
assert( isdefined( level.t72 ) );
thread abrams_moveto_t72();
thread abrams_aimat_t72();
}
abrams_moveto_t72()
{
level.abrams.wheeldir = 1;
level.abrams resumeSpeed( 3 );
level.abrams setWaitNode( getvehiclenode( "tank_shoots_t72_node", "script_noteworthy" ) );
level.abrams waittill( "reached_wait_node" );
level.abrams setSpeed( 0, 1000, 1000 );
flag_set( "tank_in_final_position" );
}
abrams_aimat_t72()
{
flag_wait( "t72_in_final_position" );
flag_wait( "tank_in_final_position" );
level.abrams notify( "stop_attacking_troops" );
level.abrams setTurretTargetVec( level.t72.origin + ( 0, 0, 50 ) );
level.abrams waittill_notify_or_timeout( "turret_rotate_stopped", 3.0 );
flag_set( "tank_turret_aimed_at_t72" );
}
enemies_fall_back()
{
thread killSpawner( 8 );
node = getnode( "enemy_fallback_node", "targetname" );
array_thread( getaiarray( "axis" ), ::enemies_fall_back_thread, node );
array_thread( getaiarray( "allies" ), ::friendlies_become_awesome );
}
enemies_fall_back_thread( node )
{
self.goalradius = node.radius;
self.health = 1;
self setgoalnode( node );
}
friendlies_become_awesome()
{
self.baseaccuracy = 5000;
self.grenadeammo = 0;
}
friendly_reinforcements_magic_bullet()
{
level notify( "friendly_reinforcements_magic_bullet" );
level endon( "friendly_reinforcements_magic_bullet" );
for(;;)
{
level waittill( "reinforcement_spawned", reinforcement );
if ( !isdefined( reinforcement ) )
continue;
if ( !isalive( reinforcement ) )
continue;
reinforcement thread magic_bullet_shield( undefined, 5.0 );
}
}
getFiveFriendliesTimeout( timeout )
{
level endon( "got 5 friendlies" );
wait timeout;
assertMsg( "Failed to get 5 alive friendlies for a scripted sequence" );
}
finalGenericDialog()
{
// get 5 friendlies excluding price
allies = getaiarray( "allies" );
friendsToSpeak = [];
for( i = 0 ; i < allies.size ; i++ )
{
if ( allies[ i ] == level.price )
continue;
friendsToSpeak[ friendsToSpeak.size ] = allies[ i ];
}
// friendlies could be dead when this is called so we have to wait until reinforcements have spawned till we have 5 guys
// dont try for too long though, time out after say 8 seconds.
level thread getFiveFriendliesTimeout( 8.0 );
for(;;)
{
if ( friendsToSpeak.size >= 5 )
break;
level waittill( "reinforcement_spawned", reinforcement );
if ( !isdefined( reinforcement ) )
continue;
if ( !isalive( reinforcement ) )
continue;
friendsToSpeak[ friendsToSpeak.size ] = reinforcement;
}
assert( friendsToSpeak.size >= 5 );
level notify( "got 5 friendlies" );
friendsToSpeak[ 0 ].animname = "gm1";
friendsToSpeak[ 1 ].animname = "gm2";
friendsToSpeak[ 2 ].animname = "gm3";
friendsToSpeak[ 3 ].animname = "gm4";
friendsToSpeak[ 4 ].animname = "gm5";
flag_wait( "t72_exploded" );
wait 2;
friendsToSpeak[ 0 ].animname = "gm1";
friendsToSpeak[ 1 ].animname = "gm2";
friendsToSpeak[ 2 ].animname = "gm3";
friendsToSpeak[ 3 ].animname = "gm4";
friendsToSpeak[ 4 ].animname = "gm5";
thread anim_single_solo( friendsToSpeak[ 0 ], "wooyeah" );
wait 1.5;
thread anim_single_solo( friendsToSpeak[ 1 ], "holyshit" );
wait 1.75;
//thread anim_single_solo( friendsToSpeak[ 2 ], "hellyeah" );
//wait 2.1;
thread anim_single_solo( friendsToSpeak[ 3 ], "yeahwoo" );
wait 1.5;
thread anim_single_solo( friendsToSpeak[ 4 ], "talkinabout" );
wait 2.3;
flag_set( "friendly_reactions_over" );
}
friendlyReactionAnims()
{
allies = getAIArray( "allies" );
for( i = 0 ; i < allies.size ; i++ )
{
if ( !isAlive( allies[ i ] ) )
continue;
if ( allies[ i ] == level.price )
{
allies[ i ] thread price_react_and_loop();
}
else if ( ( isdefined( allies[ i ].script_noteworthy ) ) && ( allies[ i ].script_noteworthy == "doorblocker" ) )
{
allies[ i ] thread guard_react_and_celebrate();
}
else
{
allies[ i ].animname = "casualcrouch";
allies[ i ] thread anim_single_solo( allies[ i ], "react" );
}
}
}
guard_react_and_celebrate()
{
self.animname = "guard";
self anim_single_solo( self, "react" );
wait 1.0;
self thread anim_single_solo( self, "celebrate" );
}
price_react_and_loop()
{
self notify( "stop_idle" );
self anim_single_solo( self, "react" );
self thread anim_loop_solo( self, "spot", undefined, "stop_idle" );
}
advanceAlleyFriendliesToEnd( guy1, guy2 )
{
doorblocker = undefined;
if ( guy1 != level.price )
doorblocker = guy1;
else if ( guy2 != level.price )
doorblocker = guy2;
assert( isdefined( doorblocker ) );
guy1 = undefined;
guy2 = undefined;
// friendlies in the dark broken building don't get seen
// or shot at by enemies on the street with the tank
level.player.ignoreme = true;
for ( i = 0 ; i < level.alleyFriends.size ; i++ )
level.alleyFriends[ i ].ignoreme = true;
remove_alley_seperation_clip();
doorblocker set_force_color( "b" );
doorblocker.goalradius = 16;
doorblocker_node = getnode( "door_blocker_node", "targetname" );
doorblocker setGoalNode( doorblocker_node );
doorblocker thread doorblocker_anim_on_trigger( doorblocker_node );
doorblocker.script_noteworthy = "doorblocker";
level.price set_force_color( "o" );
level.price.goalradius = 16;
level.price pushPlayer( true );
level.price setGoalNode( getnode( "price_last_node1", "targetname" ) );
level.price waittill( "goal" );
wait 4.0;
level.price setGoalNode( getnode( "price_last_node2", "targetname" ) );
level.price waittill( "goal" );
flag_set( "price_at_spotter" );
level.price pushPlayer( false );
}
doorblocker_anim_on_trigger( node )
{
assert( isdefined( node ) );
trigger = getent( "door_block_trigger", "targetname" );
assert( isdefined( trigger ) );
trigger waittill( "trigger" );
self.animname = "guard";
node anim_reach_solo( self, "stop" );
node anim_single_solo( self, "stop" );
getent( "last_color_order_trigger2", "targetname" ) notify( "trigger" );
flag_set( "ok_to_do_spotting" );
}
t72_in_final_position()
{
level.t72 = maps\_vehicle::waittill_vehiclespawn( "t72" );
assert( isdefined( level.t72 ) );
level.t72 waittill( "reached_end_node" );
exploder_300_target = getent( "exploder_300_target", "targetname" );
level.t72 setTurretTargetEnt( exploder_300_target );
level.t72 waittill_notify_or_timeout( "turret_rotate_stopped", 4.0 );
level.t72 clearTurretTarget();
level.t72 notify( "turret_fire" );
exploder( 300 );
wait 2.0;
aim_location = getent( "t72_aim_at_final_building_location", "targetname" );
level.t72 setTurretTargetEnt( aim_location );
level.t72 waittill_notify_or_timeout( "turret_rotate_stopped", 4.0 );
level.t72 clearTurretTarget();
if ( getdvar( "bog_debug_tank") == "1" )
{
tag_flash_loc = level.t72 getTagOrigin( "tag_flash" );
tag_turret_loc = level.t72 getTagOrigin( "tag_turret" );
aim_location = getent( "t72_aim_at_final_building_location", "targetname" );
zDifference = abs( tag_flash_loc[ 2 ] - tag_turret_loc[ 2 ] );
dist = distance( tag_flash_loc, tag_turret_loc );
angleUp = asin( zDifference / dist );
iprintlnbold( "UP: " + angleUp );
v1 = anglesToForward( level.t72.angles );
v2 = vectorNormalize( aim_location.origin - level.t72.origin );
angleLeft = acos( vectordot( v1, v2 ) );
iprintlnbold( "LEFT: " + angleLeft );
}
flag_set( "t72_in_final_position" );
}
vehicle_path_disconnector()
{
zone = getent( self.target, "targetname" );
assert( isdefined( zone ) );
zone notsolid();
zone.origin -= ( 0, 0, 1024 );
badplaceName = "tank_bad_place_brush_" + zone getEntityNumber();
for(;;)
{
self waittill( "trigger", tank );
assert( isdefined( tank ) );
assert( isdefined( level.abrams ) );
prof_begin( "tank_path_disconnect" );
if ( tank getSpeedMPH() == 0 )
{
prof_end( "tank_path_disconnect" );
continue;
}
prof_end( "tank_path_disconnect" );
if ( !isdefined( zone.pathsDisconnected ) )
{
zone solid();
badplace_brush( badplaceName, 0, zone, "allies", "axis" );
zone notsolid();
zone.pathsDisconnected = true;
}
thread vehicle_reconnects_paths( zone, badplaceName );
}
}
vehicle_reconnects_paths( zone, badplaceName )
{
assert( isdefined( zone ) );
assert( isdefined( badplaceName ) );
zone notify( "waiting_for_path_reconnection" );
zone endon( "waiting_for_path_reconnection" );
wait 0.5;
zone solid();
badplace_delete( badplaceName );
zone notsolid();
zone.pathsDisconnected = undefined;
}
delete_ai_in_zone()
{
assert( isdefined( self.target ) );
zone = getent( self.target, "targetname" );
assert( isdefined( zone ) );
self waittill( "trigger" );
axis = getaiarray( "axis" );
for( i = 0 ; i < axis.size ; i++ )
{
if ( axis[ i ] isTouching( zone ) )
axis[ i ] delete();
}
}
delete_all_axis()
{
self waittill( "trigger" );
// delete all axis
ai = getaiarray( "axis" );
for( i = 0 ; i < ai.size ; i++ )
{
if ( isdefined( ai[ i ].magic_bullet_shield ) && ai[ i ].magic_bullet_shield )
ai[ i ] stop_magic_bullet_shield();
ai[ i ] delete();
}
}
autosave_when_trigger_cleared()
{
assert( isdefined( self.script_noteworthy ) );
for(;;)
{
self waittill( "trigger" );
if( !ai_touching_area( self ) )
break;
wait 3;
}
thread dosavegame( self.script_noteworthy );
}
dosavegame( savename )
{
if ( !savegame_redundancy_check() )
return;
autosave_by_name( savename );
}
savegame_redundancy_check()
{
if ( !isdefined( level.lastSaveTime ) )
return true;
if ( level.lastSaveTime + ( level.minimumTimeBetweenAutosaves * 1000 ) > getTime() )
{
println( "aborting autosave because an autosave just happened" );
return false;
}
return true;
}
waittill_zone_clear( sTargetname )
{
assert( isdefined( sTargetname ) );
zone = getent( sTargetname, "targetname" );
assert( isdefined( zone ) );
while( ai_touching_area( zone ) )
{
wait 2;
}
}
ai_touching_area( zone )
{
assert( isdefined( zone ) );
axis = getaiarray( "axis" );
for( i = 0 ; i < axis.size ; i++ )
{
if( axis[ i ] isTouching( zone ) )
return true;
}
return false;
}
tank_advancement_bog()
{
//--------------
// Bog Area
//--------------
flag_init( "truck_crush_tank_in_position" );
thread truck_crush_tank_in_position();
// puts the tank turret forward when it hits a trigger just before the tank crush sequence
level.abrams thread tank_turret_forward();
// abrams shoots at enemies in the bog
level.abrams thread attack_troops();
// wait till the tank is in tank crush position
flag_wait( "truck_crush_tank_in_position" );
// wait until the player hits the tank crush trigger
flag_wait( "truck_crush_player_in_position" );
thread dosavegame( "tank_crush" );
truck = getent( "crunch_truck_1", "targetname" );
// player and tank in position, wait to see if player is looking at the tank
// if player doesn't look at tank soon then timeout and do the sequence anyways
timeoutTime = 10;
for( i = 0 ; i < timeoutTime * 20 ; i++ )
{
if ( within_fov( level.player getEye(), level.player getPlayerAngles(), truck.origin, level.cosine[ "65" ] ) )
break;
wait 0.05;
}
tank_path_2 = getVehicleNode( "tank_path_2", "targetname" );
level.abrams resumeSpeed( 5 );
level.abrams maps\_vehicle::tank_crush( truck,
tank_path_2,
level.scr_anim[ "tank" ][ "tank_crush" ],
level.scr_anim[ "truck" ][ "tank_crush" ],
level.scr_animtree[ "tank_crush" ],
level.scr_sound[ "tank_crush" ] );
flag_clear( "aa_bog_b_zone_bog" );
flag_set( "aa_bog_b_zone_streets" );
arcademode_checkpoint( 7.0, "streets" );
thread tank_advancement_arch();
}
tank_advancement_arch()
{
//--------------
// Archway Road
//--------------
// tank says possible ambush positions up ahead
level.abrams thread ambush_ahead_dialog();
// tank moves up path and stops at it's stop node where it will shoot exploder group 0
node = getvehiclenode( "stop_for_city_fight1", "script_noteworthy" );
level.abrams setWaitNode( node );
level.abrams waittill( "reached_wait_node" );
level.abrams setSpeed( 0, 10 );
// tank in position, shoot exploder group 0
level.abrams thread shoot_buildings( 0 );
// wait until all exploders in the group have gone off
level.abrams waittill( "abrams_shot_explodergroup" );
// increase the ambient
thread maps\_utility::set_ambient( "exterior_level5" );
// abrams shoots at enemies until it's clear to move up
level.abrams thread attack_troops();
waittill_zone_clear( "tank_zone_1" );
// tank and price talk about it being clear to move up a bit
battlechatter_off( "allies" );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "movingup" ] );
wait 0.1;
level.price.animname = "price";
level.price thread anim_single_solo( level.price, "roger" );
battlechatter_on( "allies" );
// tank moves up a bit and stops to shoot at exploder group 1
level.abrams resumeSpeed( 3 );
node = getvehiclenode( "stop_for_city_fight2", "script_noteworthy" );
level.abrams setWaitNode( node );
level.abrams waittill( "reached_wait_node" );
level.abrams setSpeed( 0, 10 );
// tank in position, shoot exploder group 1
level.abrams thread shoot_buildings( 1 );
// wait until all exploders in the group have gone off
level.abrams waittill( "abrams_shot_explodergroup" );
// abrams shoots at enemies until it's clear to move up again
level.abrams thread attack_troops();
waittill_zone_clear( "tank_zone_2" );
// tank tells price it's moving up to the corner
thread dosavegame( "tank_progress_corner" );
battlechatter_off( "allies" );
level.player playRadioSound( level.scr_sound[ "tank_commander" ][ "cleartoadvance" ] );
wait 0.1;
level.price.animname = "price";
level.price anim_single_solo( level.price, "rogermoveup" );
wait 0.1;
level.player thread playRadioSound( level.scr_sound[ "tank_commander" ][ "rogermoving" ] );
battlechatter_on( "allies" );
// tank moves up to corner and stops to shoot at exploder group 2
level.abrams resumeSpeed( 3 );
node = getvehiclenode( "stop_for_city_fight3", "script_noteworthy" );
level.abrams setWaitNode( node );
level.abrams waittill( "reached_wait_node" );
level.abrams setSpeed( 0, 10 );
// tank in position, shoot exploder group 2
level.abrams thread shoot_buildings( 2 );
// wait until all exploders in the group have gone off
level.abrams waittill( "abrams_shot_explodergroup" );
// shoot at enemies with the MG now
level.abrams thread attack_troops();
thread tank_advancement_alley();
}
tank_advancement_alley()
{
flag_wait( "abrams_move_shoot_t72" );
thread abrams_setup_t72();
flag_wait( "abrams_advance_to_end_level" );
crushNode = getvehiclenode( "tank_crush_truck2", "script_noteworthy" );
crunch_truck_2 = getent( "crunch_truck_2", "targetname" );
tank_path_4 = getVehicleNode( "tank_path_4", "targetname" );
level.abrams notify( "stop_attacking_troops" );
wait 0.05;
level.abrams setturrettargetent( level.abrams.forwardEnt );
level.abrams waittill_notify_or_timeout( "turret_rotate_stopped", 4.0 );
level.abrams clearTurretTarget();
level.abrams resumeSpeed( 3 );
level.abrams setWaitNode( crushNode );
level.abrams waittill( "reached_wait_node" );
level.abrams maps\_vehicle::tank_crush( crunch_truck_2,
tank_path_4,
level.scr_anim[ "tank" ][ "tank_crush" ],
level.scr_anim[ "truck" ][ "tank_crush" ],
level.scr_animtree[ "tank_crush" ],
level.scr_sound[ "tank_crush2" ] );
level.abrams.wheeldir = 1;
level.abrams setturrettargetent( getent( "final_abrams_aim_spot", "targetname" ) );
level.abrams setSpeed( 0, 10, 10 );
}
seaknight()
{
seaknight_path = getent( "seaknight_path", "targetname" );
seaknight_land_location = getent( "seaknight_land_location", "script_noteworthy" );
objective_state( 1, "done" );
wait 1.0;
objective_add( 2, "current", &"BOG_B_OBJ_SEAKNIGHT", seaknight_land_location.origin );
thread dosavegame( "seaknight" );
// make friends go to seaknight
friends = getaiarray( "allies" );
for ( i = 0 ; i < friends.size ; i++ )
friends[ i ] set_force_color( "c" );
getent( "seaknight_friendly_trigger", "targetname" ) notify( "trigger" );
// spawn the helicopter
level.seaknight = maps\_vehicle::spawn_vehicle_from_targetname_and_drive( "seaknight" );
assert( isdefined( level.seaknight ) );
wait 0.05;
// make riders only crouch so their anims look good when they unload
seaknightRiders = level.seaknight.riders;
assert( seaknightRiders.size == 1 );
thread seaknight_dialog();
seaknight_land_location waittill( "trigger", helicopter );
helicopter.dontDisconnectPaths = true;
helicopter vehicle_detachfrompath();
helicopter vehicle_land();
helicopter setHoverParams( 0, 0, 0 );
helicopter thread seaknight_doors_open();
getent( "player_in_seaknight", "targetname" ) waittill( "trigger" );
wait 5.0;
flag_wait( "seaknight_dialog_done" );
nextmission();
}
seaknight_doors_open()
{
animpos = maps\_vehicle_aianim::anim_pos( self, 1 );
self thread maps\_vehicle_aianim::setanimrestart_once( animpos.vehicle_getoutanim, animpos.vehicle_getoutanim_clear );
thread maps\_utility::play_sound_in_space( animpos.vehicle_getoutsound, self.origin );
}
seaknight_dialog()
{
seaknight_almost_land_location = getent( "seaknight_almost_land_location", "script_noteworthy" );
seaknight_almost_land_location waittill( "trigger", helicopter );
wait 5.0;
// "Lt. Vasquez, this is Outlaw Two-Five. The Task Force is moving in to capture Al-Asad.
// It's all hands on deck for this one so get on board, over."
level.player playRadioSound( level.scr_sound[ "saknight" ][ "getonboard" ] );
// "Roger that! Marines! We just got a fix on Al-Asad's position! Everyone on board! Let's go!"
level.price.animname = "price";
anim_single_solo( level.price, "fixonposition" );
flag_set( "seaknight_dialog_done" );
}
/*
seaknightRiders_standInPlace()
{
if ( !isAI( self ) )
return;
self allowedStances( "crouch" );
self waittill( "jumpedout" );
self allowedStances( "crouch" );
waittillframeend;
self allowedStances( "crouch" );
self.goalradius = 16;
self setGoalPos( self.origin );
self.ignoreall = true;
}
*/
bog_enemies_retreat()
{
getent( "bog_enemies_retreat", "targetname" ) waittill( "trigger" );
thread killSpawner( 9 );
axis = getaiarray( "axis" );
nodes = getnodearray( "bog_enemies_retreat_node", "targetname" );
for( i = 0 ; i < axis.size ; i++ )
{
if ( !isdefined( axis[ i ] ) )
continue;
if ( !isalive( axis[ i ] ) )
continue;
goalnode = nodes[ randomint( nodes.size ) ];
axis[ i ] thread go_to_node_delayed( goalnode, goalnode.radius, randomfloat( 5.0 ) );
axis[ i ] thread ignored_by_tank_cannon();
}
}
go_to_node_delayed( node, goalradius, fDelay )
{
wait fDelay;
if ( !isdefined( self ) )
return;
if ( !isalive( self ) )
return;
self.goalradius = goalradius;
self set_goal_node( node );
}
ignored_by_tank_cannon( qTrue )
{
if ( !isdefined( qTrue ) )
qTrue = true;
if ( qTrue )
self.ignored_by_tank_cannon = true;
else
self.ignored_by_tank_cannon = undefined;
}
player_passed_dumpster()
{
getent( "player_passed_dumpster", "targetname" ) waittill( "trigger" );
flag_set( "player_passed_dumpster" );
}