2402 lines
55 KiB
Text
2402 lines
55 KiB
Text
|
#include maps\_hud_util;
|
||
|
#include maps\_utility;
|
||
|
#include maps\_debug;
|
||
|
#include animscripts\utility;
|
||
|
#include maps\_vehicle;
|
||
|
#include maps\sniperescape;
|
||
|
#include common_scripts\utility;
|
||
|
#include maps\_anim;
|
||
|
#include maps\_stealth_logic;
|
||
|
#include maps\sniperescape_code;
|
||
|
#include maps\sniperescape_wounding;
|
||
|
|
||
|
exchange_turret_org()
|
||
|
{
|
||
|
turret = getent( "turret2", "targetname" );
|
||
|
return turret.origin;
|
||
|
}
|
||
|
|
||
|
exchange_turret()
|
||
|
{
|
||
|
turret = getent( "turret2", "targetname" );
|
||
|
targ = getent( turret.target, "targetname" );
|
||
|
turret MakeTurretUnusable();
|
||
|
turret hide();
|
||
|
turret.origin = targ.origin;
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( isdefined( turret getturretowner() ) )
|
||
|
break;
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
|
||
|
level.player_can_fire_turret_time = gettime() + 1000;
|
||
|
setsaveddvar( "sv_znear", "100" ); // 100
|
||
|
setsaveddvar( "sm_sunShadowCenter", getent( "blood_pool", "targetname" ).origin );
|
||
|
flag_set( "player_is_on_turret" );
|
||
|
level.player allowCrouch( false );
|
||
|
level.player allowStand( false );
|
||
|
|
||
|
if ( !flag( "player_used_zoom" ) )
|
||
|
{
|
||
|
thread display_hint( "barrett" );
|
||
|
}
|
||
|
|
||
|
level.level_specific_dof = true;
|
||
|
player_org = level.player.origin + (0,0,60); // compensate for intro view in the ground, simulating prone
|
||
|
|
||
|
flag_wait( "player_gets_off_turret" );
|
||
|
|
||
|
level.player EnableTurretDismount();
|
||
|
barrett_trigger = getent( "barrett_trigger", "targetname" );
|
||
|
barrett_trigger delete();
|
||
|
// turret useby( level.player );
|
||
|
turret delete();
|
||
|
|
||
|
setsaveddvar( "compass", 1 );
|
||
|
SetSavedDvar( "ammoCounterHide", "0" );
|
||
|
setsaveddvar( "ui_hideMap", "0" );
|
||
|
SetSavedDvar( "hud_showStance", 1 );
|
||
|
setsaveddvar( "sv_znear", "0" );
|
||
|
setsaveddvar( "sm_sunShadowCenter", ( 0, 0, 0 ) );
|
||
|
flag_clear( "player_is_on_turret" );
|
||
|
level.player allowCrouch( true );
|
||
|
level.player allowStand( true );
|
||
|
level.level_specific_dof = false;
|
||
|
|
||
|
// clear blur in case we were on min spec pc and holding key
|
||
|
setblur( 0, 0.05 );
|
||
|
|
||
|
|
||
|
level.player setorigin( level.player.original_org + (0,0,90));
|
||
|
}
|
||
|
|
||
|
|
||
|
update_goal_yaw( target_ent )
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
level endon( "stop_updating_goal_yaw" );
|
||
|
for ( ;; )
|
||
|
{
|
||
|
angles = vectortoangles( target_ent.origin - self.origin );
|
||
|
self setGoalyaw( angles[ 1 ] );
|
||
|
wait( 0.1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
track_ent_chain( targetname )
|
||
|
{
|
||
|
ent = getent( targetname, "targetname" );
|
||
|
target_ent = spawn( "script_model", ent.origin );
|
||
|
thread update_goal_yaw( target_ent );
|
||
|
|
||
|
dist_ratio = 4926.532227;
|
||
|
time_ratio = 2.5;
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( !isdefined( ent.target ) )
|
||
|
break;
|
||
|
|
||
|
nextent = getent( ent.target, "targetname" );
|
||
|
dist = distance( nextent.origin, ent.origin );
|
||
|
|
||
|
timer = ( dist * time_ratio ) / dist_ratio;
|
||
|
|
||
|
if ( timer < 0.05 )
|
||
|
timer = 0.05;
|
||
|
|
||
|
target_ent moveto( nextent.origin, timer );
|
||
|
wait( timer );
|
||
|
|
||
|
ent = nextent;
|
||
|
}
|
||
|
|
||
|
target_ent delete();
|
||
|
level notify( "stop_updating_goal_yaw" );
|
||
|
}
|
||
|
|
||
|
exchange_heli_tracking()
|
||
|
{
|
||
|
vehicle_flag_arrived( "block_heli_arrives" );
|
||
|
/#
|
||
|
level endon( "pentest" );
|
||
|
#/
|
||
|
wait( 1.5 );
|
||
|
track_ent_chain( "heli_search_org" );
|
||
|
flag_set( "block_heli_moves" );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
tracer()
|
||
|
{
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
angles = level.player getplayerangles();
|
||
|
start = level.player geteye();
|
||
|
|
||
|
forward = anglestoforward( angles );
|
||
|
end = start + vectorscale( forward, 5000 );
|
||
|
level.trace = BulletTrace( start, end, false, undefined );
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
exchange_trace_converter()
|
||
|
{
|
||
|
// there is a plane blocking the action so we can control where the bullets hit and add a fake bullet travel time
|
||
|
bullet_block = getent( "bullet_block", "targetname" );
|
||
|
bullet_block hide();
|
||
|
/#
|
||
|
// if ( getdvar( "pentest" ) == "on" )
|
||
|
// bullet_block delete();
|
||
|
#/
|
||
|
firetime = -5000;
|
||
|
|
||
|
|
||
|
// bullet_block_trigger = getent( "bullet_block_trigger", "targetname" );
|
||
|
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
// bullet_block_trigger waittill( "trigger", one, two, three, four, five, six );
|
||
|
flag_wait( "player_is_on_turret" );
|
||
|
wait_for_buffer_time_to_pass( firetime, 1.0 );
|
||
|
|
||
|
if ( !level.player attackbuttonpressed() )
|
||
|
{
|
||
|
wait( 0.05 );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
thread exchange_player_fires();
|
||
|
firetime = gettime();
|
||
|
|
||
|
// wait for the player to release the fire, as its a semi auto weapon
|
||
|
while ( level.player attackbuttonpressed() )
|
||
|
{
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_player_fires()
|
||
|
{
|
||
|
if ( gettime() < level.player_can_fire_turret_time )
|
||
|
return;
|
||
|
|
||
|
min_zoom = 1.5;
|
||
|
max_zoom = 20;
|
||
|
min_eq = 0.15;
|
||
|
max_eq = 0.80;
|
||
|
|
||
|
zoom = getdvarfloat( "turretScopeZoom" );
|
||
|
eq = ( zoom - min_zoom ) * ( max_eq - min_eq ) / ( max_zoom - min_zoom );
|
||
|
eq += min_eq;
|
||
|
|
||
|
// Earthquake( eq, 1, level.player geteye(), 1000 );
|
||
|
level.player shellshock( "barrett", 1.3 );
|
||
|
level.fired_barrett = true;
|
||
|
|
||
|
angles = level.player getplayerangles();
|
||
|
start = level.player geteye();
|
||
|
// println( "eye " + start );
|
||
|
// 2412.51 -14950.3, 66.33
|
||
|
|
||
|
forward = anglestoforward( angles );
|
||
|
end = start + vectorscale( forward, 15000 );
|
||
|
|
||
|
// thread linedraw( eye, end, (1,0,1), 25 );
|
||
|
|
||
|
trace = BulletTrace( start, end, false, undefined );
|
||
|
level.trace = trace;
|
||
|
|
||
|
if ( trace[ "surfacetype" ] != "default" )
|
||
|
{
|
||
|
// thread Linedraw( start, trace[ "position" ], (0,1,0) );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// thread Linedraw( start, trace[ "position" ], (1,0,0) );
|
||
|
|
||
|
start = trace[ "position" ] + vectorscale( forward, 10 );
|
||
|
|
||
|
end = trace[ "position" ] + vectorscale( forward, 15000 );
|
||
|
|
||
|
skill_drift = [];
|
||
|
skill_drift[ 0 ] = 0.03;
|
||
|
skill_drift[ 1 ] = 0.07;
|
||
|
skill_drift[ 2 ] = 0.085;
|
||
|
skill_drift[ 3 ] = 0.10;
|
||
|
|
||
|
skill_drift[ 0 ] = 0.025;
|
||
|
skill_drift[ 1 ] = 0.025;
|
||
|
skill_drift[ 2 ] = 0.025;
|
||
|
skill_drift[ 3 ] = 0.025;
|
||
|
|
||
|
|
||
|
pos = start;
|
||
|
move_distance = 314.245;
|
||
|
move_vec = vectorscale( forward, move_distance );
|
||
|
/*
|
||
|
setdvar( "ay", "0" );
|
||
|
setdvar( "az", "60" );
|
||
|
setdvar( "ax", "-0.1" );
|
||
|
setdvar( "az", "16.56" );
|
||
|
*/
|
||
|
waittillframeend;
|
||
|
// eye = level.player.origin + ( -3.62, 0, -66 );
|
||
|
turret = getent( "turret2", "targetname" );
|
||
|
if ( !isdefined( turret ) )
|
||
|
return;
|
||
|
// eye = turret.origin + ( getdvarfloat( "ax" ), getdvarfloat( "ay" ), getdvarfloat( "az" ) );
|
||
|
eye = turret.origin + ( -0.1, 0, 15 );
|
||
|
// eye = level.player.origin + ( getdvarfloat( "ax" ), getdvarfloat( "ay" ), getdvarfloat( "az" ) );
|
||
|
|
||
|
|
||
|
bullet = spawn( "script_model", eye );
|
||
|
bullet setmodel( "tag_origin" );
|
||
|
|
||
|
playfxontag( getfx( "bullet_geo" ), bullet, "tag_origin" );
|
||
|
// println( "start " + start + " firetime " + gettime() );
|
||
|
count_max = 10;
|
||
|
count = 0;
|
||
|
|
||
|
bullet_last_org = bullet.origin;
|
||
|
|
||
|
trace = undefined;
|
||
|
tried_lock = false;
|
||
|
lock_on_steps = undefined;
|
||
|
achieved_lock = false;
|
||
|
current_step = 0;
|
||
|
zak_org = undefined;
|
||
|
drift = (0,0,0);
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( isalive( level.zakhaev ) && !tried_lock )
|
||
|
{
|
||
|
zak_org = level.zakhaev gettagorigin( "J_Shoulder_LE" );
|
||
|
dist_to_impact = distance( zak_org, bullet.origin );
|
||
|
if ( dist_to_impact < 3000 )
|
||
|
{
|
||
|
// thread linedraw( zak_org, bullet.origin, ( 1, 0.2, 0 ), 50 );
|
||
|
// thread linedraw( bullet_last_org, bullet.origin, ( 0 , 0.2, 1 ), 50 );
|
||
|
tried_lock = true;
|
||
|
angles = vectorToAngles( zak_org - bullet.origin );
|
||
|
dotforward = anglesToForward( angles );
|
||
|
angles = vectorToAngles( bullet.origin - bullet_last_org );
|
||
|
forward = anglesToForward( angles );
|
||
|
level.zak_dot = vectordot( dotforward, forward );
|
||
|
|
||
|
achieved_lock = level.zak_dot > 0.99998;
|
||
|
lock_on_steps = dist_to_impact / move_distance;
|
||
|
achieved_lock = false;
|
||
|
}
|
||
|
}
|
||
|
endpos = pos + move_vec;
|
||
|
|
||
|
if ( !tried_lock || !achieved_lock )
|
||
|
drift = vectorscale( level.wind_vec, skill_drift[ level.gameskill ] );
|
||
|
|
||
|
|
||
|
|
||
|
// println( "drift " + count + " " + distance( (0,0,0), drift ) );
|
||
|
// endpos += drift;
|
||
|
|
||
|
// thread linedraw( pos, endpos, ( 1, 0.2, 0 ), 5 );
|
||
|
|
||
|
trace = bullettrace( pos, endpos, true, undefined );
|
||
|
final_origin = trace[ "position" ];
|
||
|
if ( trace[ "fraction" ] < 1 )
|
||
|
{
|
||
|
exchange_impact_alert( trace[ "position" ] );
|
||
|
angles = vectortoangles( endpos - pos );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
view_frac = count / count_max;
|
||
|
// view_frac -= 0.1;
|
||
|
if ( view_frac < 0 )
|
||
|
view_frac = 0;
|
||
|
if ( view_frac > 1.0 )
|
||
|
view_frac = 1.0;
|
||
|
count++;
|
||
|
|
||
|
level.view_frac = view_frac;
|
||
|
oldorg = bullet.origin;
|
||
|
|
||
|
oldeye = eye;
|
||
|
eye += move_vec;
|
||
|
// thread linedraw( oldeye, eye, (1,0,0), 25 );
|
||
|
|
||
|
if ( achieved_lock )
|
||
|
{
|
||
|
if ( isalive( level.zakhaev ) )
|
||
|
zak_org = level.zakhaev gettagorigin( "J_Shoulder_LE" );
|
||
|
|
||
|
merge_point = zak_org;
|
||
|
|
||
|
lock_frac = current_step / lock_on_steps;
|
||
|
lock_frac = lock_frac * lock_frac;
|
||
|
bullet.origin = vectorscale( final_origin, 1.0 - lock_frac ) + vectorscale( merge_point, lock_frac );
|
||
|
|
||
|
// thread linedraw( oldorg, bullet.origin, (lock_frac,lock_frac,lock_frac), 25 );
|
||
|
|
||
|
current_step++;
|
||
|
if ( current_step > lock_on_steps )
|
||
|
{
|
||
|
achieved_lock = false;
|
||
|
// update the actual bullet position
|
||
|
pos = zak_org;
|
||
|
if ( isalive( level.zakhaev ) )
|
||
|
level.zakhaev notify( "fake_damage" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bullet_last_org = bullet.origin;
|
||
|
bullet.origin = vectorscale( final_origin, view_frac ) + vectorscale( eye, 1.0 - view_frac );
|
||
|
}
|
||
|
|
||
|
|
||
|
pos += move_vec + drift;
|
||
|
|
||
|
// line( eye, bullet.origin, (1,1,1) );
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
|
||
|
println( "hittime " + gettime() );
|
||
|
forward = anglestoforward( angles );
|
||
|
// scale it way out for bullet penetration purposes
|
||
|
pop_vec = vectorscale( forward, 5 );
|
||
|
move_vec = vectorscale( forward, 15000 );
|
||
|
MagicBullet( "barrett_fake", pos, pos + move_vec );
|
||
|
|
||
|
wait( 0.25 );
|
||
|
bullet delete();
|
||
|
|
||
|
if ( flag( "exchange_success" ) )
|
||
|
{
|
||
|
if ( flag( "price_comments_on_zak_hit" ) )
|
||
|
return;
|
||
|
price_clears_dialogue();
|
||
|
flag_set( "price_comments_on_zak_hit" );
|
||
|
|
||
|
//* Target down. I think I saw his arm fly off. Nice work Leftenant. We got him. target_down_1
|
||
|
//* Target down. I think you blew off his arm. Shock and blood loss'll take care of the rest. target_down_2
|
||
|
//* Target is down! Nice shot Leftenant. target_down_3
|
||
|
|
||
|
the_line = "target_down_" + ( randomint( 3 ) + 1 );
|
||
|
price_line( the_line );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// price comments on the shot
|
||
|
if ( flag( "price_comments_on_zak_miss" ) )
|
||
|
return;
|
||
|
flag_set( "price_comments_on_zak_miss" );
|
||
|
price_clears_dialogue();
|
||
|
|
||
|
if ( price_thinks_you_are_insane( pos ) )
|
||
|
{
|
||
|
// are you insane?
|
||
|
price_line( "are_you_insane" );
|
||
|
}
|
||
|
else
|
||
|
if ( level.wind_setting == "end" )
|
||
|
{
|
||
|
// The target's still standing! Keep firing!
|
||
|
price_line( "target_still_standing" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Damn, it went wide! Probably should've waited for the wind to die down.
|
||
|
price_line( "went_wide" );
|
||
|
}
|
||
|
|
||
|
|
||
|
// kill_ai_along_path( pos, pos + move_vec, pop_vec );
|
||
|
// thread linedraw( pos, pos + move_vec, ( 0, 0.5, 1 ), 5 );
|
||
|
|
||
|
// below here lies ye old bullet tracing magic
|
||
|
if ( 1 )
|
||
|
return;
|
||
|
|
||
|
ent = spawnstruct();
|
||
|
ent.traces = [];
|
||
|
|
||
|
trace = BulletTrace( start, end, true, undefined );
|
||
|
|
||
|
dist = distance( start, trace[ "position" ] );
|
||
|
timer = dist * 1.432 / 9000;
|
||
|
dist_modifier = dist / 9000;
|
||
|
|
||
|
ent thread exchange_turret_traces( start, end, dist_modifier );
|
||
|
ent thread exchange_sniper_windmod( end );
|
||
|
wait( timer );
|
||
|
ent notify( "stop_gathering_traces" );
|
||
|
|
||
|
// thread drawtrace( trace, start );
|
||
|
exchange_impact_alert( trace[ "position" ] );
|
||
|
|
||
|
|
||
|
/*
|
||
|
if ( flag( "wind_died_down" ) )
|
||
|
{
|
||
|
// shot hits straight on if the wind has died down
|
||
|
MagicBullet( "barrett_fake", start, end );
|
||
|
return;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// assertex( ent.traces.size, "Failed to make a legit trace that didnt hit zakhaev" );
|
||
|
|
||
|
dest = ent.sniper_shot;
|
||
|
if ( flag( "exchange_success" ) )
|
||
|
{
|
||
|
// once zak has been hit you shouldnt hit him again
|
||
|
new_dest = ent exchange_get_safe_shot( start );
|
||
|
if ( !isdefined( new_dest ) )
|
||
|
return;
|
||
|
dest = new_dest;
|
||
|
}
|
||
|
|
||
|
MagicBullet( "barrett_fake", start, dest );
|
||
|
/#
|
||
|
if ( getdebugdvar( "debug_barrett" ) == "on" )
|
||
|
thread Linedraw( start, dest, (1,0,0) );
|
||
|
#/
|
||
|
}
|
||
|
|
||
|
|
||
|
exchange_impact_alert( pos )
|
||
|
{
|
||
|
ai = getaiarray( "axis" );
|
||
|
if ( !ai.size )
|
||
|
return;
|
||
|
closestGuy = getclosest( pos, ai );
|
||
|
dist = distance( pos, closestGuy.origin );
|
||
|
if ( dist < 900 )
|
||
|
{
|
||
|
flag_set( "player_attacks_exchange" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_sniper_windmod( pos )
|
||
|
{
|
||
|
self endon( "stop_gathering_traces" );
|
||
|
// move the shot a bit each frame for the wind
|
||
|
self.sniper_shot = pos;
|
||
|
lastpos = pos;
|
||
|
for( ;; )
|
||
|
{
|
||
|
vec = vectorscale( level.wind_vec, 0.20 );
|
||
|
self.sniper_shot += vec;
|
||
|
|
||
|
// line( self.sniper_shot, lastpos, (1, 0, 0 ) );
|
||
|
lastpos = pos;
|
||
|
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_get_safe_shot( start )
|
||
|
{
|
||
|
|
||
|
for ( i = 0; i < self.traces.size; i++ )
|
||
|
{
|
||
|
trace = bullettrace( start, self.traces[ i ], true, undefined );
|
||
|
|
||
|
hit_zakhaev = false;
|
||
|
if ( isalive( level.zakhaev ) )
|
||
|
{
|
||
|
// extend the trace if it hits guys standing in front of zakhaev
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( !isalive( trace[ "entity" ] ) )
|
||
|
break;
|
||
|
if ( trace[ "entity" ] == level.zakhaev )
|
||
|
{
|
||
|
hit_zakhaev = true;
|
||
|
break;
|
||
|
}
|
||
|
if ( isdefined( trace[ "entity" ].heli ) )
|
||
|
{
|
||
|
// kill heli pilots
|
||
|
trace[ "entity" ] dodamage( trace[ "entity" ].health + 150, (0,0,0) );
|
||
|
}
|
||
|
|
||
|
trace = bullettrace( trace[ "position" ], self.traces[ i ], true, trace[ "entity" ] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( hit_zakhaev )
|
||
|
continue;
|
||
|
|
||
|
/#
|
||
|
if ( getdebugdvar( "debug_barrett" ) == "on" )
|
||
|
thread Linedraw( start, trace[ "position" ], (1,1,1) );
|
||
|
#/
|
||
|
|
||
|
return trace[ "position" ];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_turret_traces( start, end, dist_modifier )
|
||
|
{
|
||
|
self endon( "stop_gathering_traces" );
|
||
|
trace = BulletTrace( start, end, true, undefined );
|
||
|
center = trace[ "position" ];
|
||
|
ent = spawn( "script_origin", (0,0,0) );
|
||
|
level.trace_gather_ent = ent;
|
||
|
|
||
|
local_wind = vectorscale( level.wind_vec, dist_modifier );
|
||
|
|
||
|
ent.origin = center + local_wind;
|
||
|
ent.angles = vectortoangles( start - end );
|
||
|
// ent thread maps\_debug::drawOrgForever();
|
||
|
dist = 0.5;
|
||
|
|
||
|
// the amount to spread on eah check
|
||
|
range_additive = dist_modifier * 0.75;
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
ent devaddroll( randomint( 360 ) );
|
||
|
forward = anglestoup( ent.angles );
|
||
|
forward = vectorscale( forward, dist );
|
||
|
|
||
|
angles = vectortoangles( ( ent.origin + forward ) - start );
|
||
|
forward = anglestoforward( angles );
|
||
|
forward = vectorscale( forward, 25000 );
|
||
|
|
||
|
trace = BulletTrace( start, start + forward, true, undefined );
|
||
|
// thread linedraw( start, start + forward, ( 0.8, 0.4, 0 ) );
|
||
|
// thread drawHit( center, ent.origin + forward );
|
||
|
if ( !hit_zak( trace ) )
|
||
|
{
|
||
|
self.traces[ self.traces.size ] = start + forward;
|
||
|
}
|
||
|
|
||
|
dist = dist + range_additive;
|
||
|
|
||
|
wait( 0.025 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
drawHit( start, end )
|
||
|
{
|
||
|
for ( ;; )
|
||
|
{
|
||
|
line( start, end, ( 1, 0, 0 ) );
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hit_zak( trace )
|
||
|
{
|
||
|
if ( !isalive( trace[ "entity" ] ) )
|
||
|
return false;
|
||
|
if ( !isalive( level.zakhaev ) )
|
||
|
return false;
|
||
|
return trace[ "entity" ] == level.zakhaev;
|
||
|
}
|
||
|
|
||
|
drawtrace( trace, start )
|
||
|
{
|
||
|
timer = 6*20;
|
||
|
|
||
|
for ( i = 0; i < timer; i++ )
|
||
|
{
|
||
|
line( start, trace[ "position" ], ( 1, 0.3, 0 ) );
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_bored_idle()
|
||
|
{
|
||
|
if ( isdefined( self.script_noteworthy ) )
|
||
|
{
|
||
|
// this guy will get a custom anim
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
self anim_generic_loop( self, "bored_idle" );
|
||
|
}
|
||
|
|
||
|
lean_and_smoke()
|
||
|
{
|
||
|
targ = getent( self.target, "targetname" );
|
||
|
targ anim_generic_loop( self, "smoke_idle" );
|
||
|
}
|
||
|
|
||
|
stand_and_smoke()
|
||
|
{
|
||
|
targ = getent( self.target, "targetname" );
|
||
|
targ anim_generic_loop( self, "smoking" );
|
||
|
}
|
||
|
|
||
|
exchange_barrett_trigger()
|
||
|
{
|
||
|
flag_wait( "can_use_turret" );
|
||
|
barrett_trigger = getent( "barrett_trigger", "targetname" );
|
||
|
barrett_trigger sethintstring( &"SNIPERESCAPE_BARRETT_USE" );
|
||
|
turret = getent( "turret2", "targetname" );
|
||
|
|
||
|
barrett_trigger waittill( "trigger" );
|
||
|
barrett_trigger trigger_off();
|
||
|
|
||
|
blendtime = 5;
|
||
|
smooth_in = 0.4;
|
||
|
smooth_out = 0.45;
|
||
|
level.view_org moveto( ( 781.86, -11719.7, 953.57 ), blendtime, blendtime * smooth_in, blendtime * smooth_out );
|
||
|
level.view_org rotateto( ( 8.48, -56.48, 0 ), blendtime, blendtime * smooth_in, blendtime * smooth_out );
|
||
|
thread blackscreen( blendtime );
|
||
|
wait( blendtime );
|
||
|
|
||
|
level.view_org moveto( level.view_org.origin + (0,0,260), 0.1 );
|
||
|
level.view_org delete();
|
||
|
|
||
|
level.player SetPlayerAngles( ( 5.5, -65.06, 0 ) );
|
||
|
level.player.original_org = level.player.origin;
|
||
|
|
||
|
turret useby( level.player );
|
||
|
thread autosave_now( "beginning", true );
|
||
|
|
||
|
wait( 1 );
|
||
|
thread sniper_text( &"SNIPERESCAPE_TARGET", 0, 0 ); // "Target: "
|
||
|
wait( 0.5 );
|
||
|
thread sniper_text( &"SNIPERESCAPE_ZAKHAEV", 70, 0 ); // "Imran Zakhaev"
|
||
|
wait( 1.5 );
|
||
|
thread sniper_text( &"SNIPERESCAPE_DISTANCE", 0, 1 ); // "Distance to target: "
|
||
|
wait( 0.85 );
|
||
|
thread sniper_text_countup( 896.7, &"SNIPERESCAPE_M", 158, 1 ); // "m"
|
||
|
wait( 1.5 );
|
||
|
thread sniper_text( &"SNIPERESCAPE_BULLET_TRAVEL", 0, 2 ); // "Bullet travel time: "
|
||
|
wait( 0.80 );
|
||
|
thread sniper_text_countup( 1.05, &"SNIPERESCAPE_S", 155, 2 ); // "s"
|
||
|
}
|
||
|
|
||
|
sniper_text_countup( count, msg, x, offset )
|
||
|
{
|
||
|
hudelem = sniper_text_init( msg, x, offset );
|
||
|
hudelem setText( msg );
|
||
|
|
||
|
if ( 1 ) return;
|
||
|
|
||
|
hudelem = sniper_text_init( msg, x, offset );
|
||
|
num = 0;
|
||
|
rate = 0.11;
|
||
|
if ( count > 10 )
|
||
|
rate = 110.11;
|
||
|
for ( ;; )
|
||
|
{
|
||
|
level.player playsound( "ui_pulse_text_type" );
|
||
|
num += rate;
|
||
|
if ( num > count )
|
||
|
num = count;
|
||
|
hudelem setText( num );
|
||
|
if ( num == count )
|
||
|
return;
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
wait( 5 );
|
||
|
|
||
|
}
|
||
|
|
||
|
sniper_text( msg, x, offset )
|
||
|
{
|
||
|
hudelem = sniper_text_init( msg, x, offset );
|
||
|
hudelem setText( msg );
|
||
|
}
|
||
|
|
||
|
sniper_text_init( msg, x, offset )
|
||
|
{
|
||
|
y = 20 * offset;
|
||
|
hudelem = newHudElem();
|
||
|
hudelem.x = x + 10;
|
||
|
hudelem.y = y;
|
||
|
hudelem.alignX = "left";
|
||
|
hudelem.alignY = "top";
|
||
|
hudelem.horzAlign= "left";
|
||
|
hudelem.vertAlign = "top";
|
||
|
hudelem.sort = 1; // force to draw after the background
|
||
|
hudelem.foreground = true;
|
||
|
hudelem.alpha = 0;
|
||
|
hudelem fadeOverTime( 0.2 );
|
||
|
hudelem.alpha = 1;
|
||
|
|
||
|
hudelem.hidewheninmenu = true;
|
||
|
hudelem.fontScale = 1.2; //was 1.6 and 2.4, larger font change
|
||
|
hudelem.color = (0.8, 1.0, 0.8);
|
||
|
hudelem.font = "objective";
|
||
|
hudelem.glowColor = (0.3, 0.6, 0.3);
|
||
|
hudelem.glowAlpha = 1;
|
||
|
duration = 10000;
|
||
|
hudelem SetPulseFX( 30, duration, 700 );
|
||
|
thread hudelem_destroyer( hudelem );
|
||
|
return hudelem;
|
||
|
}
|
||
|
|
||
|
hudelem_destroyer( hudelem )
|
||
|
{
|
||
|
wait( 10 );
|
||
|
hudelem destroy();
|
||
|
}
|
||
|
|
||
|
blackscreen( timer )
|
||
|
{
|
||
|
overlay = newHudElem();
|
||
|
overlay.x = 0;
|
||
|
overlay.y = 0;
|
||
|
overlay setshader( "black", 640, 480 );
|
||
|
overlay.alignX = "left";
|
||
|
overlay.alignY = "top";
|
||
|
overlay.horzAlign = "fullscreen";
|
||
|
overlay.vertAlign = "fullscreen";
|
||
|
overlay.alpha = 0;
|
||
|
wait( timer - 1 );
|
||
|
overlay fadeOverTime( 1 );
|
||
|
overlay.alpha = 1;
|
||
|
wait( 1.2 );
|
||
|
overlay fadeOverTime( 1 );
|
||
|
overlay.alpha = 0;
|
||
|
wait( 1 );
|
||
|
overlay destroy();
|
||
|
}
|
||
|
|
||
|
whitescreen()
|
||
|
{
|
||
|
overlay = newHudElem();
|
||
|
overlay.x = 0;
|
||
|
overlay.y = 0;
|
||
|
overlay setshader( "white", 640, 480 );
|
||
|
overlay.alignX = "left";
|
||
|
overlay.alignY = "top";
|
||
|
overlay.horzAlign = "fullscreen";
|
||
|
overlay.vertAlign = "fullscreen";
|
||
|
overlay.alpha = 1;
|
||
|
wait( 0.05 );
|
||
|
|
||
|
setsaveddvar( "ui_hideMap", "1" );
|
||
|
setsaveddvar( "compass", 0 );
|
||
|
SetSavedDvar( "ammoCounterHide", "1" );
|
||
|
SetSavedDvar( "hud_showStance", 0 );
|
||
|
|
||
|
overlay fadeOverTime( 1 );
|
||
|
overlay.alpha = 0;
|
||
|
wait( 1 );
|
||
|
overlay destroy();
|
||
|
}
|
||
|
|
||
|
stop_loop()
|
||
|
{
|
||
|
// tell our target to stop looping us
|
||
|
if ( !isdefined( self.target ) )
|
||
|
{
|
||
|
self notify( "stop_loop" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
targ = getent( self.target, "targetname" );
|
||
|
if ( isdefined( targ ) )
|
||
|
{
|
||
|
targ notify( "stop_loop" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
targ = getnode( self.target, "targetname" );
|
||
|
if ( isdefined( targ ) )
|
||
|
{
|
||
|
targ notify( "stop_loop" );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_baddie_main_think()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
|
||
|
if ( !isdefined( self.drivingVehicle ) )
|
||
|
self.allowdeath = true;
|
||
|
self ent_flag_init( "run_to_car" );
|
||
|
|
||
|
thread exchange_guy_dies();
|
||
|
|
||
|
if ( isdefined( self.ridingvehicle ) )
|
||
|
{
|
||
|
exchange_rider_gets_out();
|
||
|
}
|
||
|
|
||
|
if ( isdefined( self.script_linkto ) )
|
||
|
{
|
||
|
thread exchange_baddie_runs_to_car();
|
||
|
}
|
||
|
|
||
|
flag_wait( "player_attacks_exchange" );
|
||
|
|
||
|
if ( isdefined( self.ridingvehicle ) )
|
||
|
{
|
||
|
self notify( "riding_still" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
surprise_anim = "exchange_surprise_" + randomint( level.surprise_anims );
|
||
|
if ( is_zak() )
|
||
|
{
|
||
|
surprise_anim = "exchange_surprise_zakhaev";
|
||
|
delaythread( 1.8, ::send_notify, "stop_animmode" );
|
||
|
}
|
||
|
|
||
|
if ( !isdefined( self.zak_got_hit ) )
|
||
|
{
|
||
|
if ( isdefined( self.main_baddie ) )
|
||
|
{
|
||
|
wait( level.exchanger_surprise_time );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
wait( randomfloatrange( 0.2, 0.4 ) );
|
||
|
}
|
||
|
|
||
|
if ( !isdefined( self.drivingVehicle ) )
|
||
|
{
|
||
|
stop_loop();
|
||
|
self stopanimscripted();
|
||
|
self anim_generic_custom_animmode( self, "gravity", surprise_anim );
|
||
|
self clear_run_anim();
|
||
|
self.disableexits = false;
|
||
|
}
|
||
|
|
||
|
self ent_flag_set( "run_to_car" );
|
||
|
}
|
||
|
|
||
|
self notify( "run_to_car" );
|
||
|
}
|
||
|
|
||
|
exchange_baddie_flags_on_death( delete_targ )
|
||
|
{
|
||
|
self waittill_either( "death", "riding_still" );
|
||
|
delete_targ ent_flag_set( "passenger_got_in" );
|
||
|
}
|
||
|
|
||
|
exchange_waittill_time_to_go_to_car()
|
||
|
{
|
||
|
self endon( "run_to_car" );
|
||
|
level endon( "heli_moves_again" );
|
||
|
|
||
|
flag_wait( "player_attacks_exchange" );
|
||
|
}
|
||
|
|
||
|
exchange_baddie_runs_to_car()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
delete_targ = getent( self.script_linkto, "script_linkname" );
|
||
|
if ( !isdefined( delete_targ ) )
|
||
|
{
|
||
|
node = getnode( self.script_linkto, "script_linkname" );
|
||
|
self setgoalnode( node );
|
||
|
self.goalradius = 32;
|
||
|
return;
|
||
|
}
|
||
|
thread exchange_baddie_flags_on_death( delete_targ );
|
||
|
|
||
|
exchange_waittill_time_to_go_to_car();
|
||
|
|
||
|
if ( flag( "player_attacks_exchange" ) )
|
||
|
{
|
||
|
// player attacked so wait until we noticed before we run
|
||
|
if ( is_zak() && isdefined( self.zak_got_hit ) )
|
||
|
{
|
||
|
flag_wait( "wounded_zak_runs_for_car" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
self ent_flag_wait( "run_to_car" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// player hasnt attacked so walk back to the car
|
||
|
self.disableexits = true;
|
||
|
if ( is_zak() )
|
||
|
{
|
||
|
set_generic_run_anim( "patrol_jog" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
self.run_noncombatanim = getAnim_generic( "stealth_walk" );
|
||
|
set_generic_run_anim( "stealth_walk" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( is_zak() )
|
||
|
{
|
||
|
self setgoalpos( delete_targ.origin );
|
||
|
self.goalradius = 16;
|
||
|
self waittill( "goal" );
|
||
|
}
|
||
|
|
||
|
// self delete();
|
||
|
|
||
|
uaz = undefined;
|
||
|
if ( isdefined( self.script_vehicleride ) )
|
||
|
{
|
||
|
uaz = maps\_vehicle_aianim::get_my_vehicleride();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
uaz = get_shared_linkto();
|
||
|
self.script_vehicleride = uaz.script_vehicleride;
|
||
|
}
|
||
|
|
||
|
guys[ 0 ] = self;
|
||
|
|
||
|
if ( is_zak() )
|
||
|
{
|
||
|
self notify( "got_in_car" );
|
||
|
delete_targ ent_flag_set( "passenger_got_in" );
|
||
|
self delete();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
uaz maps\_vehicle_aianim::load_ai( guys );
|
||
|
self waittill( "enteredvehicle" );
|
||
|
delete_targ ent_flag_set( "passenger_got_in" );
|
||
|
self notify( "got_in_car" );
|
||
|
|
||
|
self waittill( "jumpedout" );
|
||
|
self delete();
|
||
|
}
|
||
|
|
||
|
get_shared_linkto()
|
||
|
{
|
||
|
// gets the vehicle that links to the same ent I link to
|
||
|
mylinks = strtok( self.script_linkto, " " );
|
||
|
assertex( mylinks.size == 1, "Too many links!" );
|
||
|
mylink = mylinks[ 0 ];
|
||
|
|
||
|
vehicles = getentarray( "script_vehicle", "classname" );
|
||
|
for ( i = 0; i < vehicles.size; i++ )
|
||
|
{
|
||
|
vehicle = vehicles[ i ];
|
||
|
if ( !isdefined( vehicle.script_linkto ) )
|
||
|
continue;
|
||
|
links = strtok( vehicle.script_linkto, " " );
|
||
|
for ( k = 0; k < links.size; k++ )
|
||
|
{
|
||
|
if ( links[ k ] == mylink )
|
||
|
return vehicle;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
is_zak()
|
||
|
{
|
||
|
return isalive( level.zakhaev ) && self == level.zakhaev;
|
||
|
}
|
||
|
|
||
|
exchange_guy_dies()
|
||
|
{
|
||
|
self endon( "got_in_car" );
|
||
|
self waittill( "death" );
|
||
|
flag_set( "player_attacks_exchange" );
|
||
|
}
|
||
|
|
||
|
exchange_rider_gets_out()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
level endon( "player_attacks_exchange" );
|
||
|
self waittill( "jumpedout" );
|
||
|
targ = getnode( self.target, "targetname" );
|
||
|
if ( !isdefined( targ ) )
|
||
|
{
|
||
|
// zaks drivers dont have a place to go stand
|
||
|
return;
|
||
|
}
|
||
|
self.walkdist = 1000;
|
||
|
self.fixednode = true;
|
||
|
self setgoalnode( targ );
|
||
|
self.disableexits = true;
|
||
|
self.disablearrivals = true;
|
||
|
self set_generic_run_anim( "stealth_walk" ); //"stealth_jog", false );
|
||
|
self.goalradius = 16;
|
||
|
}
|
||
|
|
||
|
exchange_uaz_preps_for_escape()
|
||
|
{
|
||
|
flag_init( self.script_flag );
|
||
|
self ent_flag_init( "time_to_go" );
|
||
|
self godon();
|
||
|
self.enter_count = 0;
|
||
|
keys = strtok( self.script_linkto, " " );
|
||
|
array_levelthread( keys, ::exchange_vehicle_waits_for_passengers );
|
||
|
|
||
|
path = undefined;
|
||
|
if ( !isdefined( self.script_vehiclespawngroup ) )
|
||
|
{
|
||
|
// these start spawned
|
||
|
path = get_path_from_array( keys );
|
||
|
self attachpath( path );
|
||
|
}
|
||
|
|
||
|
self ent_flag_wait( "time_to_go" );
|
||
|
|
||
|
if ( self.script_flag == "uaz4" )
|
||
|
self setspeed( 25, 10 );
|
||
|
|
||
|
if ( isdefined( self.script_vehiclespawngroup ) )
|
||
|
{
|
||
|
ownflag = "vehicle_go_" + self.script_vehiclespawngroup;
|
||
|
if ( isdefined( level.flag[ ownflag ] ) )
|
||
|
{
|
||
|
exchange_wait_until_other_spawned_uazs_go();
|
||
|
// gogogo!
|
||
|
flag_set( ownflag );
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
exchange_wait_until_other_base_uazs_go();
|
||
|
|
||
|
self startpath();
|
||
|
|
||
|
// cleanup vehicle
|
||
|
self waittill( "reached_end_node" );
|
||
|
riders = self maps\_vehicle_aianim::vehicle_get_riders();
|
||
|
array_thread( riders, ::delete_living );
|
||
|
self delete();
|
||
|
}
|
||
|
|
||
|
get_path_from_array( keys )
|
||
|
{
|
||
|
for ( i = 0; i < keys.size; i++ )
|
||
|
{
|
||
|
node = getvehiclenode( keys[ i ], "script_linkname" );
|
||
|
if ( isdefined( node ) )
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
assertmsg( "Tried to get vehicle path but couldnt find it! " + self.origin );
|
||
|
}
|
||
|
|
||
|
exchange_vehicle_waits_for_passengers( key )
|
||
|
{
|
||
|
ent = getent( key, "script_linkname" );
|
||
|
|
||
|
if ( !isdefined( ent ) )
|
||
|
{
|
||
|
// could be vehiclenode key
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ent ent_flag_init( "passenger_got_in" );
|
||
|
|
||
|
self.enter_count++;
|
||
|
ent ent_flag_wait( "passenger_got_in" );
|
||
|
self.enter_count--;
|
||
|
|
||
|
if ( !self.enter_count )
|
||
|
{
|
||
|
wait( 2 );
|
||
|
self ent_flag_set( "time_to_go" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
draworg2()
|
||
|
{
|
||
|
println( " " );
|
||
|
println( int( self.origin[ 0 ] * 100 ) * 0.01 + " " + int( self.origin[ 1 ] * 100 ) * 0.01 + " " + int( self.origin[ 2 ] * 100 ) * 0.01 );
|
||
|
println( int( self.angles[ 0 ] * 100 ) * 0.01 + " " + int( self.angles[ 1 ] * 100 ) * 0.01 + " " + int( self.angles[ 2 ] * 100 ) * 0.01 );
|
||
|
}
|
||
|
|
||
|
exchange_zaks_car_door()
|
||
|
{
|
||
|
// zak spawns but doesnt ride in, so he has to do some special script to play nice with the other scripts.
|
||
|
level endon( "zak_spawns" );
|
||
|
zak_car_org = getent( "zak_car_org", "script_noteworthy" );
|
||
|
flag_wait( "player_attacks_exchange" );
|
||
|
zak_car_org ent_flag_set( "passenger_got_in" );
|
||
|
}
|
||
|
|
||
|
arm_detach()
|
||
|
{
|
||
|
self setmodel( getmodel( "zak_one_arm" ) );
|
||
|
self hidepart( "J_Shoulder_LE" );
|
||
|
arm_goes_flying( self gettagorigin( "J_Shoulder_LE" ) );
|
||
|
}
|
||
|
|
||
|
arm_goes_flying( org )
|
||
|
{
|
||
|
arm = spawn( "script_model", (0,0,0) );
|
||
|
arm.origin = org;
|
||
|
arm setmodel( getmodel( "zak_left_arm" ) );
|
||
|
if ( getdvar( "ax" ) == "" )
|
||
|
{
|
||
|
setdvar( "ax", "-0.01" );
|
||
|
}
|
||
|
if ( getdvar( "ay" ) == "" )
|
||
|
{
|
||
|
setdvar( "ay", "-0.07" );
|
||
|
}
|
||
|
if ( getdvar( "az" ) == "" )
|
||
|
{
|
||
|
setdvar( "az", "0.2" );
|
||
|
}
|
||
|
ax = -0.01;
|
||
|
ay = -0.07;
|
||
|
az = 0.2;
|
||
|
vec = ( ax, ay, az );
|
||
|
vec = vectorscale( vec, 50000 );
|
||
|
midpoint = arm gettagorigin( "J_Elbow_LE" );
|
||
|
// arm thread maps\_debug::drawtagforever( "J_Elbow_LE" );
|
||
|
// wait( 1 );
|
||
|
arm PhysicsLaunch( midpoint, vec );
|
||
|
}
|
||
|
|
||
|
zak_blood()
|
||
|
{
|
||
|
level endon( "stop_zak_blood" );
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
playfxontag( getfx( "blood" ), self, "J_Shoulder_LE" );
|
||
|
wait( 0.1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
zak_arm_blood()
|
||
|
{
|
||
|
/*
|
||
|
tags = [];
|
||
|
tags[ tags.size ] = "J_Clavicle_LE";
|
||
|
tags[ tags.size ] = "TAG_INHAND";
|
||
|
tags[ tags.size ] = "J_Shoulder_LE";
|
||
|
tags[ tags.size ] = "J_Elbow_Bulge_LE";
|
||
|
tags[ tags.size ] = "J_Elbow_LE";
|
||
|
tags[ tags.size ] = "J_ShoulderTwist_LE";
|
||
|
tags[ tags.size ] = "J_Wrist_LE";
|
||
|
tags[ tags.size ] = "J_WristTwist_LE";
|
||
|
tags[ tags.size ] = "TAG_WEAPON_LEFT";
|
||
|
|
||
|
self array_levelthread( tags, maps\_debug::drawtagforever );
|
||
|
*/
|
||
|
|
||
|
// self thread maps\_debug::drawtagforever( "J_Shoulder_LE" );
|
||
|
|
||
|
rate = 0.2;
|
||
|
timer = 0.5;
|
||
|
zak_arm_blood_pump( timer, self, rate );
|
||
|
wait( 0.5 );
|
||
|
zak_arm_blood_pump( timer, self, rate );
|
||
|
wait( 0.5 );
|
||
|
zak_arm_blood_pump( timer, self, rate );
|
||
|
wait( 0.5 );
|
||
|
zak_arm_blood_pump( timer, self, rate * 0.5 );
|
||
|
wait( 0.5 );
|
||
|
zak_arm_blood_pump( timer, self, rate * 0.25 );
|
||
|
wait( 0.5 );
|
||
|
|
||
|
if ( 1 )
|
||
|
return;
|
||
|
// self thread maps\_debug::drawtagforever( "J_Shoulder_LE" );
|
||
|
|
||
|
model = spawn( "script_model", (0,0,0) );
|
||
|
model setmodel( "tag_origin" );
|
||
|
model linkto( self, "J_Shoulder_LE", (0,0,0), (0,0,0) );
|
||
|
model thread maps\_debug::drawtagforever( "tag_origin" );
|
||
|
|
||
|
|
||
|
for ( i = 0; i < timer; i++ )
|
||
|
{
|
||
|
playfxontag( getfx( "blood" ), model, "tag_origin" );
|
||
|
wait( rate );
|
||
|
}
|
||
|
|
||
|
wait( 5 );
|
||
|
model delete();
|
||
|
}
|
||
|
|
||
|
zak_arm_blood_pump( timer, model, rate )
|
||
|
{
|
||
|
timer = timer * ( 1 / rate );
|
||
|
for ( i = 0; i < timer; i++ )
|
||
|
{
|
||
|
playfxontag( getfx( "blood" ), model, "J_Shoulder_LE" );
|
||
|
wait( rate );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
zak_blood_pool()
|
||
|
{
|
||
|
self endon( "stop_blood" );
|
||
|
wait( 1 );
|
||
|
blood_pool = getent( "blood_pool", "targetname" );
|
||
|
z = blood_pool.origin[ 2 ];
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
start = self gettagorigin( "J_Shoulder_LE" ) + (0,0,50);
|
||
|
end = start + (0,0,-250);
|
||
|
trace = bullettrace( start, end, false, undefined );
|
||
|
pos = ( trace[ "position" ][ 0 ], trace[ "position" ][ 1 ], z );
|
||
|
playfx( getfx( "blood_pool" ), pos, ( 0, 0, 1 ) );
|
||
|
wait( 0.35 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
blood_pool()
|
||
|
{
|
||
|
pool = self;
|
||
|
// spreads from under the table
|
||
|
count = 5;
|
||
|
for ( ;; )
|
||
|
{
|
||
|
playfx( getfx( "blood_pool" ), pool.origin + (0,0,1), ( 0, 0, 1 ) );
|
||
|
count--;
|
||
|
if ( count <= 0 )
|
||
|
wait( 0.3 );
|
||
|
if ( !isdefined( pool.target ) )
|
||
|
return;
|
||
|
pool = getent( pool.target, "targetname" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
zak_dies()
|
||
|
{
|
||
|
self.health = 50000;
|
||
|
self endon( "death" );
|
||
|
self disable_long_death();
|
||
|
|
||
|
zakmodel = spawn( "script_model", (0,0,0) );
|
||
|
zakmodel character\character_sp_zakhaev_onearm::main();
|
||
|
zakmodel hide();
|
||
|
zakmodel.animname = "zakhaev";
|
||
|
zakmodel assign_animtree();
|
||
|
zakmodel linkto( self, "tag_origin", (0,0,0), (0,0,0) );
|
||
|
|
||
|
// arm_model linkto( self, "J_Shoulder_LE", (0,0,0), (0,0,0) );
|
||
|
// arm_model hide();
|
||
|
// arm_model thread manual_taglinkto( self, "J_Shoulder_LE" );
|
||
|
|
||
|
self waittill_either( "damage", "fake_damage" );
|
||
|
|
||
|
playfxontag( getfx( "blood" ), self, "J_Shoulder_LE" );
|
||
|
|
||
|
if ( !isdefined( self ) )
|
||
|
return;
|
||
|
|
||
|
arcadeMode_kill( self geteye(), "rifle", 2000 );
|
||
|
|
||
|
if ( !flag( "exchange_heli_alerted" ) )
|
||
|
{
|
||
|
thread autosave_now();
|
||
|
}
|
||
|
|
||
|
// zakmodel thread arm_detach();
|
||
|
run_thread_on_targetname( "blood_pool", ::blood_pool );
|
||
|
flag_set( "exchange_success" );
|
||
|
zakmodel unlink();
|
||
|
ent = spawn( "script_origin", (0,0,0) );
|
||
|
ent.origin = self.origin;
|
||
|
yaw = 135;
|
||
|
ent.angles = ( 0, yaw, 0 );
|
||
|
|
||
|
org = getstartorigin( ent.origin, ent.angles, level.scr_anim[ "zak_left_arm" ][ "zak_pain" ] );
|
||
|
arm_model = spawn_anim_model( "zak_left_arm", org );
|
||
|
// arm_model thread zak_arm_blood();
|
||
|
/#
|
||
|
if ( getdvar( "debug_arm" ) != "" )
|
||
|
{
|
||
|
arm_model thread zak_arm_blood();
|
||
|
}
|
||
|
#/
|
||
|
|
||
|
zakmodels = make_array( zakmodel, arm_model );
|
||
|
ent anim_first_frame_solo( arm_model, "zak_pain" );
|
||
|
ent thread anim_single_solo( zakmodel, "zak_pain" );
|
||
|
ent delaythread( 0.05, ::anim_single_solo, arm_model, "zak_pain" );
|
||
|
|
||
|
|
||
|
zakmodel thread zak_blood();
|
||
|
// zakmodel thread zak_blood_pool();
|
||
|
|
||
|
zakmodel show();
|
||
|
self delete();
|
||
|
ent waittill( "zak_pain" );
|
||
|
level notify( "stop_zak_blood" );
|
||
|
/*
|
||
|
level.zak_timer = gettime();
|
||
|
// self.zak_got_hit = true;
|
||
|
self.a.pose = "crouch";
|
||
|
self.disableexits = false;
|
||
|
self.a.movement = "stop";
|
||
|
self.a.movemode = "stop";
|
||
|
self setgoalpos( self.origin );
|
||
|
self.goalradius = 16;
|
||
|
// delaythread( 0.45, ::anim_stopanimscripted );
|
||
|
// delaythread( 1.0, ::flag_set, "wounded_zak_runs_for_car" );
|
||
|
|
||
|
if ( isdefined( self ) )
|
||
|
{
|
||
|
flag_set( "exchange_success" );
|
||
|
}
|
||
|
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
exchange_zak_and_guards_jab_it_up( node, baddies )
|
||
|
{
|
||
|
if ( flag( "player_attacks_exchange" ) )
|
||
|
return;
|
||
|
|
||
|
thread exchange_zaks_car_door();
|
||
|
|
||
|
level endon( "player_attacks_exchange" );
|
||
|
flag_wait( "player_on_barret" );
|
||
|
flag_wait( "exchange_uazs_arrive" );
|
||
|
flag_wait( "launch_zak" );
|
||
|
|
||
|
wait( 2 );
|
||
|
// the fake case gives us reliable vector for the case's movement
|
||
|
fake_case = spawn_anim_model( "briefcase" );
|
||
|
fake_case hide();
|
||
|
level.fake_case = fake_case;
|
||
|
node thread anim_single_solo( fake_case, "exchange" );
|
||
|
wait( 0.25 );
|
||
|
|
||
|
|
||
|
flag_set( "zak_spawns" );
|
||
|
zakhaev = get_guy_with_targetname_from_spawner( "exchange_zak" );
|
||
|
level.zakhaev = zakhaev;
|
||
|
zakhaev thread exchange_baddie_main_think();
|
||
|
zakhaev.a.disablePain = true;
|
||
|
zakhaev thread zak_dies();
|
||
|
zakhaev.no_magic_death = true;
|
||
|
zakhaev.main_baddie = true;
|
||
|
|
||
|
zakhaev.animname = "zakhaev";
|
||
|
zakhaev set_run_anim( "run" );
|
||
|
zakhaev.ignoreall = true;
|
||
|
zakhaev.disableexits = true;
|
||
|
zakhaev.disablearrivals = true;
|
||
|
|
||
|
zakhaev putGunAway();
|
||
|
|
||
|
briefcase = spawn_anim_model( "briefcase" );
|
||
|
baddies[ baddies.size ] = zakhaev;
|
||
|
|
||
|
briefcase thread exchange_brick_drop();
|
||
|
|
||
|
array_thread( baddies, ::set_allowdeath, true );
|
||
|
|
||
|
baddies[ baddies.size ] = briefcase;
|
||
|
|
||
|
array_thread( baddies, ::set_exchange_timings, node );
|
||
|
|
||
|
node notify( "stop_loop" );
|
||
|
node thread anim_single( baddies, "exchange" );
|
||
|
|
||
|
flag_wait( "block_heli_arrives" );
|
||
|
wait( 2 );
|
||
|
|
||
|
node2 = getent( "exchange_org2", "targetname" );
|
||
|
if ( isdefined( briefcase ) )
|
||
|
briefcase unlink();
|
||
|
// node moveto( node2.origin, 2 );
|
||
|
|
||
|
node waittill( "exchange" );
|
||
|
}
|
||
|
|
||
|
|
||
|
set_exchange_timings( node )
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
level endon( "player_attacks_exchange" );
|
||
|
// basically pause the anim while the heli is in the way
|
||
|
flag_wait( "block_heli_arrives" );
|
||
|
wait( 2 );
|
||
|
self setanim( getanim( "exchange" ), 1, 0, 0 );
|
||
|
self linkto( node );
|
||
|
self thread exchange_unlink();
|
||
|
flag_wait( "block_heli_moves" );
|
||
|
|
||
|
self setanim( getanim( "exchange" ), 1, 0, 1 );
|
||
|
self setanimtime( getanim( "exchange" ), 0.49 );
|
||
|
flag_wait( "heli_moves_again" );
|
||
|
self setanimtime( getanim( "exchange" ), 0.9 );
|
||
|
}
|
||
|
|
||
|
exchange_unlink()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
flag_wait( "block_heli_moves" );
|
||
|
self unlink();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
exchange_vehicles_flee_conflict()
|
||
|
{
|
||
|
flag_wait( "player_attacks_exchange" );
|
||
|
|
||
|
nodes = getvehiclenodearray( "unloading_node", "script_noteworthy" );
|
||
|
array_thread( nodes, ::clear_unload );
|
||
|
}
|
||
|
|
||
|
clear_unload()
|
||
|
{
|
||
|
self.script_unload = undefined;
|
||
|
}
|
||
|
|
||
|
exchange_dof()
|
||
|
{
|
||
|
for ( ;; )
|
||
|
{
|
||
|
flag_wait( "player_is_on_turret" );
|
||
|
exchange_scale_dof_while_on_turret();
|
||
|
flag_waitopen( "player_is_on_turret" );
|
||
|
level.player SetDepthOfField( 0, 0, 0, 0, 8, 8 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_scale_dof_while_on_turret()
|
||
|
{
|
||
|
level.fired_barrett = false;
|
||
|
level endon( "player_is_on_turret" );
|
||
|
// SetDepthOfField( <near start>, <near end>, <far start>, <far end>, <near blur>, <far blur> )
|
||
|
olddist = getdvarint( "turretscopezoom" );
|
||
|
|
||
|
zoom[ 9 ] = 6750;
|
||
|
|
||
|
depthdist = 500;
|
||
|
|
||
|
max_depthdist = 24000;
|
||
|
min_depthdist = 6500;
|
||
|
clear_rate = 300;
|
||
|
focus_rate = 300;
|
||
|
fog_rate = 1000;
|
||
|
|
||
|
depth_near = 6000;
|
||
|
|
||
|
max_blurring = 14000;
|
||
|
|
||
|
fired_barrett_dist = 6500;
|
||
|
|
||
|
level.blur = 0;
|
||
|
blur_barret_fired = 8.0;
|
||
|
blur_stable_rate = -0.2;
|
||
|
blur_in_rate = 0.10;
|
||
|
blur_out_rate = -0.25;
|
||
|
|
||
|
stable = false;
|
||
|
for ( ;; )
|
||
|
{
|
||
|
dist = getdvarint( "turretscopezoom" );
|
||
|
|
||
|
if ( dist < olddist )
|
||
|
{
|
||
|
if ( dist >= max_blurring )
|
||
|
{
|
||
|
dist = max_blurring;
|
||
|
}
|
||
|
|
||
|
// zooming in, so bring the fog in
|
||
|
depthdist -= fog_rate;
|
||
|
|
||
|
level.blur += blur_in_rate;
|
||
|
stable = false;
|
||
|
}
|
||
|
else
|
||
|
if ( dist == olddist )
|
||
|
{
|
||
|
if ( stable )
|
||
|
{
|
||
|
// stable, focus the eyes
|
||
|
depthdist += focus_rate;
|
||
|
|
||
|
level.blur = level.blur * 0.9;
|
||
|
if ( level.blur < 0.1 )
|
||
|
level.blur = 0;
|
||
|
}
|
||
|
stable = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
stable = false;
|
||
|
// zooming out, sharpen things up quick
|
||
|
depthdist += clear_rate;
|
||
|
|
||
|
level.blur += blur_out_rate;
|
||
|
}
|
||
|
|
||
|
if ( level.fired_barrett )
|
||
|
{
|
||
|
level.fired_barrett = false;
|
||
|
depthdist = fired_barrett_dist;
|
||
|
level.blur = blur_barret_fired;
|
||
|
}
|
||
|
|
||
|
if ( level.blur > 12 )
|
||
|
level.blur = 12;
|
||
|
if ( level.blur < 0 )
|
||
|
level.blur = 0;
|
||
|
|
||
|
far_min = depthdist - depth_near;
|
||
|
if ( far_min < 0 )
|
||
|
far_min = 0;
|
||
|
|
||
|
if ( depthdist > max_depthdist )
|
||
|
depthdist = max_depthdist;
|
||
|
else
|
||
|
if ( depthdist < min_depthdist )
|
||
|
depthdist = min_depthdist;
|
||
|
|
||
|
// println( "dofdist " + depthdist + " zoom " + dist );
|
||
|
level.player SetDepthOfField( 0, 0, far_min, depthdist, 8, 8 );
|
||
|
if ( getdvarint( "r_dof_enable" ) != true )
|
||
|
{
|
||
|
setblur( level.blur, 0.05 );
|
||
|
}
|
||
|
olddist = dist;
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
add_waiters( waiters, myflag, flag1, flag2, flag3 )
|
||
|
{
|
||
|
if ( self.script_flag != myflag )
|
||
|
return waiters;
|
||
|
|
||
|
waiters[ waiters.size ] = flag1;
|
||
|
|
||
|
if ( isdefined( flag2 ) )
|
||
|
waiters[ waiters.size ] = flag2;
|
||
|
|
||
|
if ( isdefined( flag3 ) )
|
||
|
waiters[ waiters.size ] = flag3;
|
||
|
|
||
|
return waiters;
|
||
|
}
|
||
|
|
||
|
exchange_wait_until_other_spawned_uazs_go()
|
||
|
{
|
||
|
waiters = [];
|
||
|
// waiters = add_waiters( waiters, "uaz7", "uaz6", "uaz5" );
|
||
|
waiters = add_waiters( waiters, "uaz6", "uaz5" );
|
||
|
|
||
|
exchange_wait_until_other_uazs_go( waiters );
|
||
|
}
|
||
|
|
||
|
exchange_wait_until_other_base_uazs_go()
|
||
|
{
|
||
|
waiters = [];
|
||
|
waiters = add_waiters( waiters, "uaz3", "uaz2", "uaz1" );
|
||
|
waiters = add_waiters( waiters, "uaz2", "uaz1" );
|
||
|
|
||
|
exchange_wait_until_other_uazs_go( waiters );
|
||
|
}
|
||
|
|
||
|
exchange_wait_until_other_uazs_go( waiters )
|
||
|
{
|
||
|
flag_set( self.script_flag );
|
||
|
if ( !waiters.size )
|
||
|
return;
|
||
|
|
||
|
timer = gettime();
|
||
|
for ( i = 0; i < waiters.size; i++ )
|
||
|
{
|
||
|
flag_wait( waiters[ i ] );
|
||
|
}
|
||
|
|
||
|
if ( gettime() != timer )
|
||
|
{
|
||
|
// wait until the one in front of us goes
|
||
|
wait( 0.4 );
|
||
|
|
||
|
if ( self.script_flag == "uaz6" )
|
||
|
wait( 2.2 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_uaz_that_backs_up()
|
||
|
{
|
||
|
flag_wait( "uaz_reaches_pause_spot" );
|
||
|
wait( 0.45 );
|
||
|
flag_set( "uaz_pauses_a_sec" );
|
||
|
}
|
||
|
|
||
|
exchange_case_velcalc()
|
||
|
{
|
||
|
// stores the velocity of the case for cool physics
|
||
|
level endon( "player_attacks_exchange" );
|
||
|
self endon( "death" );
|
||
|
for ( ;; )
|
||
|
{
|
||
|
// line( level.fake_case gettagorigin( "J_Case" ), self gettagorigin( "J_Case" ), ( 1,1, 0 ) );
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_brick_drop()
|
||
|
{
|
||
|
casemodel = spawn( "script_model", (0,0,0) );
|
||
|
casemodel linkto( self, "J_Case", (0,0,0), (0,0,0) );
|
||
|
|
||
|
goldbar = spawn( "script_model", (0,0,0) );
|
||
|
goldbar linkto( self, "TAG_GOLD_BRICK", (0,0,0), (0,0,0) );
|
||
|
|
||
|
flag_wait( "player_attacks_exchange" );
|
||
|
|
||
|
// line( level.fake_case gettagorigin( "J_Case" ), self gettagorigin( "J_Case" ), ( 1,1, 0 ) );
|
||
|
// thread linedraw( self gettagorigin( "J_Case" ), self gettagorigin( "J_Case" ) + vec, (0,1,0) );
|
||
|
wait( level.exchanger_surprise_time );
|
||
|
if ( !flag( "briefcase_placed" ) )
|
||
|
{
|
||
|
vec = self gettagorigin( "J_Case" ) - level.fake_case gettagorigin( "J_Case" );
|
||
|
vec = vectorscale( vec, -100 );
|
||
|
// brief case hasnt been put down yet, so it falls to the ground
|
||
|
casemodel unlink();
|
||
|
casemodel setmodel( "com_gold_brick_case" );
|
||
|
casemodel PhysicsLaunch( casemodel.origin, vec );
|
||
|
self delete();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vec = self gettagorigin( "TAG_GOLD_BRICK" ) - level.fake_case gettagorigin( "TAG_GOLD_BRICK" );
|
||
|
vec = vectorscale( vec, -50 );
|
||
|
self hidepart( "TAG_GOLD_BRICK" );
|
||
|
goldbar unlink();
|
||
|
goldbar setmodel( "com_golden_brick" );
|
||
|
goldbar PhysicsLaunch( goldbar.origin, vec );
|
||
|
|
||
|
// dont want the case to magiclose later
|
||
|
self setanim( getanim( "exchange" ), 1, 0, 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
wait_until_seaknight_gets_close( dist )
|
||
|
{
|
||
|
seaknight_node = getent( "seaknight_landing", "targetname" );
|
||
|
level.seanode = seaknight_node;
|
||
|
for ( ;; )
|
||
|
{
|
||
|
newdist = distance( level.seaknight.origin, seaknight_node.origin );
|
||
|
if ( newdist < dist )
|
||
|
return;
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
should_break_prone_hint()
|
||
|
{
|
||
|
player_snipe_spot = getent( "player_snipe_spot", "targetname" );
|
||
|
if ( distance( level.player.origin, player_snipe_spot.origin ) >= player_snipe_spot.radius )
|
||
|
return true;
|
||
|
|
||
|
return level.player getstance() == "prone";
|
||
|
}
|
||
|
|
||
|
should_break_claymores()
|
||
|
{
|
||
|
claymoreCount = getPlayerClaymores();
|
||
|
if ( claymoreCount <= 0 )
|
||
|
return true;
|
||
|
|
||
|
if ( flag( "beacon_placed" ) )
|
||
|
return true;
|
||
|
|
||
|
return level.player GetCurrentWeapon() == "claymore";
|
||
|
}
|
||
|
|
||
|
should_break_c4()
|
||
|
{
|
||
|
c4Count = getPlayerC4();
|
||
|
if ( c4Count <= 0 )
|
||
|
return true;
|
||
|
|
||
|
if ( flag( "beacon_placed" ) )
|
||
|
return true;
|
||
|
|
||
|
return level.player GetCurrentWeapon() == "c4";
|
||
|
}
|
||
|
|
||
|
should_break_c4_throw()
|
||
|
{
|
||
|
c4Count = getPlayerC4();
|
||
|
if ( level.new_c4Count > c4Count )
|
||
|
return true;
|
||
|
|
||
|
if ( flag( "beacon_placed" ) )
|
||
|
return true;
|
||
|
|
||
|
return level.player GetCurrentWeapon() != "c4";
|
||
|
}
|
||
|
|
||
|
clear_path_speed( min )
|
||
|
{
|
||
|
vnode = undefined;
|
||
|
if ( isdefined( self.target ) )
|
||
|
{
|
||
|
vnode = getvehiclenode( self.target, "targetname" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
keys = strtok( self.script_linkto, " " );
|
||
|
vnode = get_path_from_array( keys );
|
||
|
}
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( isdefined( vnode.speed ) )
|
||
|
{
|
||
|
if ( vnode.speed < min )
|
||
|
vnode.speed = min;
|
||
|
}
|
||
|
|
||
|
if ( !isdefined( vnode.target ) )
|
||
|
break;
|
||
|
|
||
|
vnode = getvehiclenode( vnode.target, "targetname" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_wind_flag()
|
||
|
{
|
||
|
wind_flag = getent( "wind_flag", "script_noteworthy" );
|
||
|
wind_flag endon( "death" );
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
forward = anglestoforward( wind_flag.angles );
|
||
|
level.wind_vec = vectorscale( forward, level.wind_vel );
|
||
|
/#
|
||
|
if ( getdvar( "nowind" ) != "" )
|
||
|
level.wind_vec = (0,0,0);
|
||
|
#/
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_flag_rotates()
|
||
|
{
|
||
|
wait( 0.1 ); // wait to get linked up and for the vehicle to settle
|
||
|
self unlink();
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
level waittill( "wind_flag_rotation", rotation, timer );
|
||
|
self rotateyaw( rotation, timer, timer * 0.25, timer * 0.25 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_wind_generator()
|
||
|
{
|
||
|
range = 140;
|
||
|
for ( ;; )
|
||
|
{
|
||
|
timer = randomfloatrange( 0.3, 0.9 );
|
||
|
level notify( "wind_flag_rotation", randomint( range ) - range * 0.5, timer );
|
||
|
wait( timer );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_flag_relinks( vehicle )
|
||
|
{
|
||
|
waittillframeend; // wait for flag to be initialized
|
||
|
vehicle ent_flag_wait( "time_to_go" );
|
||
|
flag_wait_either( "zak_uaz_leaves", "player_attacks_exchange" );
|
||
|
self.angles = ( 0, vehicle.angles[ 1 ] + 180, 0 );
|
||
|
self linkto( vehicle );
|
||
|
}
|
||
|
|
||
|
exchange_flag()
|
||
|
{
|
||
|
flag = spawn_anim_model( "flag" );
|
||
|
flag.origin = self.origin;
|
||
|
flag.angles = self.angles;
|
||
|
|
||
|
vehicle = getent( self.script_linkto, "script_linkname" );
|
||
|
self linkto( flag );
|
||
|
flag linkto( vehicle );
|
||
|
flag thread exchange_flag_rotates();
|
||
|
flag thread exchange_flag_relinks( vehicle );
|
||
|
|
||
|
// blend = randomfloatrange( 50, 99 ) * 0.01;
|
||
|
blend = 0;
|
||
|
rate = 0.5;
|
||
|
for ( ;; )
|
||
|
{
|
||
|
// blend the flag to the current wind vel
|
||
|
desired_blend = level.wind_vel / 100;
|
||
|
if ( desired_blend < 0 )
|
||
|
desired_blend = 0;
|
||
|
else
|
||
|
if ( desired_blend > 0.99 )
|
||
|
desired_blend = 0.99;
|
||
|
|
||
|
if ( blend < desired_blend )
|
||
|
{
|
||
|
blend += rate;
|
||
|
if ( blend > desired_blend )
|
||
|
blend = desired_blend;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
blend -= rate;
|
||
|
if ( blend < desired_blend )
|
||
|
blend = desired_blend;
|
||
|
}
|
||
|
|
||
|
blendtime = randomfloatrange( 0.1, 1 );
|
||
|
flag setanim( flag getanim( "up" ), blend, blendtime, 5 );
|
||
|
flag setanim( flag getanim( "down" ), 1 - blend, blendtime, 5 );
|
||
|
wait( blendtime );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exchange_heli_second_wave()
|
||
|
{
|
||
|
helis = spawn_vehicles_from_targetname_and_drive( "hotel_attack_helis" );
|
||
|
array_thread( helis, ::exchange_second_heli );
|
||
|
array_thread( helis, ::exchange_followup_heli_shoots_hotel );
|
||
|
}
|
||
|
|
||
|
exchange_heli()
|
||
|
{
|
||
|
heli = spawn_vehicle_from_targetname_and_drive( "view_block_heli" );
|
||
|
heli thread exchange_heli_tracking();
|
||
|
heli thread exchange_heli_think( 35, 35 );
|
||
|
heli thread exchange_heli_preps_missiles();
|
||
|
heli thread exchange_block_view_on_attack();
|
||
|
heli thread do_in_order( ::waittill_msg, "death_spiral", ::flag_set, "block_heli_starts" );
|
||
|
heli setenginevolume( 0 );
|
||
|
|
||
|
add_wait( ::flag_wait, "player_attacks_exchange" );
|
||
|
add_wait( ::flag_wait, "block_heli_starts" );
|
||
|
heli add_func( ::volume_up, 1 );
|
||
|
thread do_wait_any();
|
||
|
|
||
|
heli endon( "death" );
|
||
|
level endon( "player_attacks_exchange" );
|
||
|
|
||
|
flag_wait( "block_heli_moves" );
|
||
|
wait( 22.0 );
|
||
|
flag_set( "heli_blocks_zak" );
|
||
|
|
||
|
flag_wait( "zak_escape" );
|
||
|
|
||
|
// alright take the shot
|
||
|
delaythread( 4.5, ::flag_set, "heli_moves_again" );
|
||
|
wait( 4.0 );
|
||
|
if ( isalive( level.zakhaev ) )
|
||
|
{
|
||
|
level.zakhaev notify( "run_to_car" );
|
||
|
level.zakhaev anim_stopanimscripted();
|
||
|
}
|
||
|
|
||
|
wait( 10 );
|
||
|
flag_set( "zak_uaz_leaves" );
|
||
|
}
|
||
|
|
||
|
exchange_followup_heli_shoots_hotel()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
self endon( "death_spiral" );
|
||
|
vehicle_flag_arrived( "block_heli_followup" );
|
||
|
hotel_look_org = getent( "hotel_look_org", "targetname" );
|
||
|
self setlookatent( hotel_look_org );
|
||
|
|
||
|
flag_wait( "apartment_explosion" );
|
||
|
|
||
|
wait( 1.5 );
|
||
|
exchange_heli_shoots_hotel();
|
||
|
|
||
|
for ( i = 0; i < 1; i++ )
|
||
|
{
|
||
|
exchange_heli_shoots_hotel();
|
||
|
wait( randomfloatrange( 1, 3 ) );
|
||
|
}
|
||
|
wait( randomfloatrange( 18, 22 ) );
|
||
|
flag_set( "block_heli_followup" );
|
||
|
}
|
||
|
|
||
|
exchange_block_view_on_attack()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
flag_wait( "player_attacks_exchange" );
|
||
|
self notify( "newpath" );
|
||
|
heli_block_org = getent( "heli_block_org", "targetname" );
|
||
|
self setvehgoalpos( heli_block_org.origin, true );
|
||
|
hotel_look_org = getent( "hotel_look_org", "targetname" );
|
||
|
self setlookatent( hotel_look_org );
|
||
|
self waittill( "goal" );
|
||
|
self.vehicle_flags[ "block_heli_starts" ] = true;
|
||
|
self notify( "vehicle_flag_arrived", "block_heli_starts" );
|
||
|
}
|
||
|
|
||
|
exchange_heli_preps_missiles()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
self endon( "death_spiral" );
|
||
|
|
||
|
flag_wait( "player_attacks_exchange" );
|
||
|
vehicle_flag_arrived( "block_heli_starts" );
|
||
|
delaythread( 5, ::flag_set, "exchange_heli_alerted" );
|
||
|
delaythread( 5, ::flag_clear, "can_save" );
|
||
|
wait( 15 );
|
||
|
flag_set( "apartment_explosion" );
|
||
|
wait( 1.5 );
|
||
|
thread exchange_heli_shoots_hotel();
|
||
|
}
|
||
|
|
||
|
exchange_heli_shoots_hotel()
|
||
|
{
|
||
|
hotel_org = getstructarray( "hotel_org", "targetname" );
|
||
|
ent = spawn( "script_origin", (0,0,0) );
|
||
|
org = random( hotel_org );
|
||
|
ent.origin = org.origin;
|
||
|
self shoots_down( ent, 25 );
|
||
|
ent delaythread( 5, ::self_delete );
|
||
|
}
|
||
|
|
||
|
exchange_second_heli()
|
||
|
{
|
||
|
self thread helipath( self.target, 45, 45 );
|
||
|
}
|
||
|
|
||
|
exchange_heli_think( speed, accell )
|
||
|
{
|
||
|
self thread helipath( self.target, speed, accell );
|
||
|
|
||
|
self godon();
|
||
|
self thread exchange_heli_death_spiral();
|
||
|
|
||
|
spawners = self get_linked_ents();
|
||
|
assertex( spawners.size == 2, "Heli doesn't link to two pilots" );
|
||
|
self.pilots = [];
|
||
|
self thread exchange_heli_pilot( spawners[ 0 ], "tag_pilot", "gunner_idle", "tag_window_back" );
|
||
|
self thread exchange_heli_pilot( spawners[ 1 ], "tag_gunner", "pilot_idle", "tag_window_front" );
|
||
|
|
||
|
waittillframeend; // for pilots to get filled
|
||
|
self.bloodmodels = [];
|
||
|
pilots = self.pilots;
|
||
|
|
||
|
self waittill_either( "death_spiral", "death" );
|
||
|
if ( isalive( self ) )
|
||
|
{
|
||
|
bloodmodels = self.bloodmodels;
|
||
|
|
||
|
self waittill( "death" );
|
||
|
array_thread( bloodmodels, ::_delete );
|
||
|
}
|
||
|
|
||
|
array_thread( pilots, ::delete_living );
|
||
|
}
|
||
|
|
||
|
exchange_heli_pilot( spawner, tag, idle_anim, blood_tag )
|
||
|
{
|
||
|
pilot = spawner spawn_ai();
|
||
|
if ( spawn_failed( pilot ) )
|
||
|
return;
|
||
|
|
||
|
self endon( "death" );
|
||
|
pilot linkto( self, tag );
|
||
|
pilot.no_magic_death = true;
|
||
|
pilot.allowdeath = true;
|
||
|
pilot.health = 50000;
|
||
|
pilot gun_remove();
|
||
|
pilot.heli = self;
|
||
|
self.pilots[ self.pilots.size ] = pilot;
|
||
|
|
||
|
self thread anim_generic_loop( pilot, idle_anim, tag, "stop_loop" + tag );
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
pilot waittill( "damage" );
|
||
|
if ( !isdefined( pilot.damagelocation ) )
|
||
|
continue;
|
||
|
if ( pilot.damagelocation == "head" || pilot.damagelocation == "neck" )
|
||
|
{
|
||
|
level.pilot_headshot = true;
|
||
|
break;
|
||
|
}
|
||
|
if ( isdefined( level.pilot_headshot ) )
|
||
|
return;
|
||
|
if ( pilot.damagelocation == "torso_upper" )
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
model = spawn( "script_model", (0,0,0) );
|
||
|
model setmodel( level.scr_model[ tag ] );
|
||
|
model linkto( self, blood_tag, (0,0,0), (0,0,0) );
|
||
|
self.bloodmodels[ self.bloodmodels.size ] = model;
|
||
|
self notify( "death_spiral" );
|
||
|
}
|
||
|
|
||
|
exchange_heli_death_spiral()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
self waittill( "death_spiral" );
|
||
|
|
||
|
delayThread( 0.5, ::flag_set, "heli_destroyed" );
|
||
|
wait( 0.2 );
|
||
|
|
||
|
self thread kill_fx( self.model );
|
||
|
helicopter_crash_move();
|
||
|
playfx( getfx( "heli_explosion" ), self.origin );
|
||
|
self thread play_sound_in_space( "havoc_helicopter_crash", self.origin );
|
||
|
wait( 0.25 );
|
||
|
self godoff();
|
||
|
// self dodamage( self.health + 25000, (0,0,0) );
|
||
|
// RadiusDamage( self.origin, 250, 50000, 50000 );
|
||
|
self delete();
|
||
|
}
|
||
|
|
||
|
exchange_ready_to_run( guy )
|
||
|
{
|
||
|
anim_stopanimscripted();
|
||
|
}
|
||
|
|
||
|
exchange_claymore()
|
||
|
{
|
||
|
claymore_org = getent( "claymore_org", "targetname" );
|
||
|
claymore_org.origin = ( 215.199, -10977.9, 1028 );
|
||
|
claymore_org.angles = ( 0, 161.65, 0 );
|
||
|
|
||
|
level.price.grenadeweapon = "claymore";
|
||
|
level.price MagicGrenadeManual( claymore_org.origin, (0,0,0), 9000 );
|
||
|
|
||
|
grenades = getentarray( "grenade", "classname" );
|
||
|
assertex( grenades.size == 1, "Should only be 1 grenade now" );
|
||
|
|
||
|
grenade = grenades[ 0 ];
|
||
|
grenade.angles = claymore_org.angles;
|
||
|
grenade maps\_detonategrenades::playClaymoreEffects();
|
||
|
level.price.grenadeweapon = "fraggrenade";
|
||
|
// claymore = spawn( "claymore", (0,0,0) );
|
||
|
// level.price MagicGrenadeManual( <origin>, <velocity>, <time to blow> )
|
||
|
|
||
|
// claymore.origin = claymore_org.origin;
|
||
|
// claymore.angles = claymore_org.angles;
|
||
|
}
|
||
|
|
||
|
exchange_wind_flunctuates()
|
||
|
{
|
||
|
|
||
|
wind_min = [];
|
||
|
wind_max = [];
|
||
|
level.wind_setting = "start";
|
||
|
|
||
|
wind_min[ "start" ][ 0 ] = 20;
|
||
|
wind_max[ "start" ][ 0 ] = 50;
|
||
|
|
||
|
wind_min[ "start" ][ 1 ] = 20;
|
||
|
wind_max[ "start" ][ 1 ] = 50;
|
||
|
|
||
|
wind_min[ "start" ][ 2 ] = 20;
|
||
|
wind_max[ "start" ][ 2 ] = 50;
|
||
|
|
||
|
wind_min[ "start" ][ 3 ] = 20;
|
||
|
wind_max[ "start" ][ 3 ] = 50;
|
||
|
|
||
|
|
||
|
wind_min[ "middle" ][ 0 ] = 80;
|
||
|
wind_max[ "middle" ][ 0 ] = 100;
|
||
|
|
||
|
wind_min[ "middle" ][ 1 ] = 80;
|
||
|
wind_max[ "middle" ][ 1 ] = 100;
|
||
|
|
||
|
wind_min[ "middle" ][ 2 ] = 80;
|
||
|
wind_max[ "middle" ][ 2 ] = 100;
|
||
|
|
||
|
wind_min[ "middle" ][ 3 ] = 80;
|
||
|
wind_max[ "middle" ][ 3 ] = 100;
|
||
|
|
||
|
|
||
|
wind_min[ "end" ][ 0 ] = 0;
|
||
|
wind_max[ "end" ][ 0 ] = 10;
|
||
|
|
||
|
wind_min[ "end" ][ 1 ] = 0;
|
||
|
wind_max[ "end" ][ 1 ] = 10;
|
||
|
|
||
|
wind_min[ "end" ][ 2 ] = 10;
|
||
|
wind_max[ "end" ][ 2 ] = 20;
|
||
|
|
||
|
wind_min[ "end" ][ 3 ] = 40;
|
||
|
wind_max[ "end" ][ 3 ] = 60;
|
||
|
|
||
|
rate = 10;
|
||
|
count = 0;
|
||
|
target_vel = 0;
|
||
|
level.wind_vel = 0;
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( level.wind_vel < target_vel )
|
||
|
{
|
||
|
level.wind_vel += rate;
|
||
|
if ( level.wind_vel > target_vel )
|
||
|
level.wind_vel = target_vel;
|
||
|
}
|
||
|
else
|
||
|
if ( level.wind_vel > target_vel )
|
||
|
{
|
||
|
level.wind_vel -= rate;
|
||
|
if ( level.wind_vel < target_vel )
|
||
|
level.wind_vel = target_vel;
|
||
|
}
|
||
|
|
||
|
count--;
|
||
|
if ( count <= 0 )
|
||
|
{
|
||
|
count = int( randomfloatrange( 1, 2 ) * 20 );
|
||
|
min = wind_min[ level.wind_setting ][ level.gameskill ];
|
||
|
max = wind_max[ level.wind_setting ][ level.gameskill ];
|
||
|
if ( max > min )
|
||
|
target_vel = randomfloatrange( min, max );
|
||
|
else
|
||
|
target_vel = max;
|
||
|
}
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
hotel_rumble()
|
||
|
{
|
||
|
// playrumbleonposition( "crash_heli_rumble", level.player.origin );
|
||
|
// Earthquake( 0.6, 1.2, level.player.origin, 6000 );
|
||
|
}
|
||
|
|
||
|
blow_up_hotel()
|
||
|
{
|
||
|
if ( flag( "hotel_destroyed" ) )
|
||
|
return;
|
||
|
flag_set( "hotel_destroyed" );
|
||
|
delaythread( 1.75, ::flag_set, "player_gets_off_turret" );
|
||
|
|
||
|
delaythread( 1.8, ::exploder, 3 );
|
||
|
delaythreaD( 1.8, ::hotel_rumble );
|
||
|
delaythread( 4.2, ::exploder, 37 );
|
||
|
wait( 1.5 );
|
||
|
|
||
|
price_clears_dialogue();
|
||
|
wait( 0.5 );
|
||
|
|
||
|
level.player endon( "death" );
|
||
|
timer = 2.2 / 7;
|
||
|
deathtrig = getent( "explosion_death_trigger", "targetname" );
|
||
|
for ( ;; )
|
||
|
{
|
||
|
deathtrig thread deathtouch();
|
||
|
if ( !isdefined( deathtrig.target ) )
|
||
|
break;
|
||
|
deathtrig = getent( deathtrig.target, "targetname" );
|
||
|
wait( timer );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
deathtouch()
|
||
|
{
|
||
|
if ( !isalive( level.player ) )
|
||
|
return;
|
||
|
timer = 3 * 20;
|
||
|
|
||
|
for ( i = 0; i < timer; i++ )
|
||
|
{
|
||
|
if ( level.player istouching( self ) )
|
||
|
{
|
||
|
radiusdamage( level.player.origin, 16, 35, 35, level.player );
|
||
|
if ( level.player.health <= 1 )
|
||
|
{
|
||
|
level.player enableHealthShield( false );
|
||
|
level.player unlink();
|
||
|
}
|
||
|
}
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
exchange_mission_failure()
|
||
|
{
|
||
|
flag_wait( "zakhaev_escaped" );
|
||
|
if ( flag( "exchange_success" ) )
|
||
|
return;
|
||
|
|
||
|
// "Zakhaev escaped unharmed"
|
||
|
setdvar( "ui_deadquote", &"SNIPERESCAPE_ZAKHAEV_ESCAPED" );
|
||
|
maps\_utility::missionFailedWrapper();
|
||
|
}
|
||
|
|
||
|
exchange_vehicle_clip()
|
||
|
{
|
||
|
self connectpaths();
|
||
|
self delete();
|
||
|
}
|
||
|
|
||
|
wait_for_hint_destroy()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
barrett_hint()
|
||
|
{
|
||
|
original_scale = getdvarint( "turretscopezoom" );
|
||
|
for ( ;; )
|
||
|
{
|
||
|
flag_wait( "player_is_on_turret" );
|
||
|
hudelem = maps\_hud_util::createFontString( "default", 1.5 );
|
||
|
hudelem.location = 0;
|
||
|
hudelem.alignX = "center";
|
||
|
hudelem.alignY = "middle";
|
||
|
hudelem.foreground = 1;
|
||
|
hudelem.sort = 20;
|
||
|
|
||
|
hudelem.alpha = 1;
|
||
|
hudelem.x = 0;
|
||
|
hudelem.y = 40;
|
||
|
hudelem.label = "Press Towards or Back to adjust zoom";
|
||
|
hudelem.color = (1,1,1);
|
||
|
|
||
|
wait_for_hint_destroy();
|
||
|
hudelem destroy();
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
should_break_zoom_hint()
|
||
|
{
|
||
|
if ( !flag( "player_is_on_turret" ) )
|
||
|
return true;
|
||
|
|
||
|
return flag( "player_used_zoom" );
|
||
|
}
|
||
|
|
||
|
player_learns_to_zoom()
|
||
|
{
|
||
|
original_scale = getdvarint( "turretscopezoom" );
|
||
|
for ( ;; )
|
||
|
{
|
||
|
new_scale = getdvarint( "turretscopezoom" );
|
||
|
if ( abs( new_scale - original_scale ) > 5 )
|
||
|
break;
|
||
|
wait( 0.05 );
|
||
|
}
|
||
|
|
||
|
flag_set( "player_used_zoom" );
|
||
|
}
|
||
|
|
||
|
kill_ai_along_path( start, end, pop )
|
||
|
{
|
||
|
/#
|
||
|
if ( getdvar( "pentest" ) == "on" )
|
||
|
return;
|
||
|
#/
|
||
|
oldstart = (0,0,0);
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( start == end )
|
||
|
return;
|
||
|
|
||
|
trace = bullettrace( start, end, true, undefined );
|
||
|
if ( trace[ "fraction" ] == 1 )
|
||
|
return;
|
||
|
|
||
|
oldstart = start;
|
||
|
start = trace[ "position" ] + pop;
|
||
|
if ( start == oldstart )
|
||
|
return;
|
||
|
if ( !isalive( trace[ "entity" ] ) )
|
||
|
continue;
|
||
|
|
||
|
ent = trace[ "entity" ];
|
||
|
if ( !issentient( ent ) )
|
||
|
continue;
|
||
|
|
||
|
if ( isdefined( ent.no_magic_death ) )
|
||
|
{
|
||
|
ent dodamage( 50, (0,0,0) );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
ent dodamage( ent.health + 150, (0,0,0) );
|
||
|
wait( 0.05 );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
_hidepart( part )
|
||
|
{
|
||
|
self hidepart( part );
|
||
|
}
|
||
|
|
||
|
barrett_intro()
|
||
|
{
|
||
|
level.player DisableTurretDismount();
|
||
|
thread whitescreen();
|
||
|
level.player disableweapons();
|
||
|
level.player allowCrouch( false );
|
||
|
level.player allowStand( true );
|
||
|
|
||
|
org = spawn( "script_model", (0,0,0) );
|
||
|
org.origin = ( 791.70, -11707.8, 977.11 - 20 );
|
||
|
org.angles = ( 17.38, -104.33, 0 );
|
||
|
org setmodel( "tag_origin" );
|
||
|
level.view_org = org;
|
||
|
|
||
|
// level.player setorigin( org.origin );
|
||
|
// level.player setplayerangles( org.angles );
|
||
|
// level.player playerlinktodelta( org, "tag_origin", 1, 45, 45, 20, 20 );
|
||
|
org lerp_player_view_to_tag( "tag_origin", 0.1, 1, 5, 15, 10, 10 );
|
||
|
wait( 2 );
|
||
|
setsaveddvar( "phys_bulletspinscale", "0.01" );
|
||
|
flag_set( "can_use_turret" );
|
||
|
}
|
||
|
|
||
|
armtest()
|
||
|
{
|
||
|
flying_arm = getent( "flying_arm", "targetname" );
|
||
|
ent = spawn( "script_origin", (0,0,0) );
|
||
|
ent.origin = flying_arm.origin;
|
||
|
yaw = 135;
|
||
|
ent.angles = ( 0, yaw, 0 );
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
zakmodel = spawn( "script_model", (0,0,0) );
|
||
|
zakmodel character\character_sp_zakhaev_onearm::main();
|
||
|
zakmodel.animname = "zakhaev";
|
||
|
zakmodel assign_animtree();
|
||
|
wait( 0.5 );
|
||
|
|
||
|
ent thread anim_generic_first_frame( zakmodel, "zak_pain" );
|
||
|
wait( 0.1 );
|
||
|
zakmodel thread arm_detach();
|
||
|
ent thread anim_generic( zakmodel, "zak_pain" );
|
||
|
wait ( 1 );
|
||
|
zakmodel delete();
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
price_thinks_you_are_insane( pos )
|
||
|
{
|
||
|
if ( !flag( "zak_spawns" ) )
|
||
|
return true;
|
||
|
|
||
|
if ( level.wind_setting == "start" )
|
||
|
return true;
|
||
|
|
||
|
return isalive( level.zakhaev ) && distance( level.zakhaev.origin, pos ) > 600;
|
||
|
}
|