uploading 119 patch_mp scripts and 23 patch_zm scripts as a baseline

This commit is contained in:
JezuzLizard
2020-05-29 07:55:47 -07:00
parent b044bba3c2
commit 89fa02ab7f
144 changed files with 75534 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,948 @@
#include maps/mp/gametypes/_weapons;
#include common_scripts/utility;
#include maps/mp/_utility;
initairsupport()
{
if ( !isDefined( level.airsupportheightscale ) )
{
level.airsupportheightscale = 1;
}
level.airsupportheightscale = getdvarintdefault( "scr_airsupportHeightScale", level.airsupportheightscale );
level.noflyzones = [];
level.noflyzones = getentarray( "no_fly_zone", "targetname" );
airsupport_heights = getstructarray( "air_support_height", "targetname" );
/#
if ( airsupport_heights.size > 1 )
{
error( "Found more then one 'air_support_height' structs in the map" );
#/
}
airsupport_heights = getentarray( "air_support_height", "targetname" );
/#
if ( airsupport_heights.size > 0 )
{
error( "Found an entity in the map with an 'air_support_height' targetname. There should be only structs." );
#/
}
heli_height_meshes = getentarray( "heli_height_lock", "classname" );
/#
if ( heli_height_meshes.size > 1 )
{
error( "Found more then one 'heli_height_lock' classname in the map" );
#/
}
}
finishhardpointlocationusage( location, usedcallback )
{
self notify( "used" );
wait 0,05;
return self [[ usedcallback ]]( location );
}
finishdualhardpointlocationusage( locationstart, locationend, usedcallback )
{
self notify( "used" );
wait 0,05;
return self [[ usedcallback ]]( locationstart, locationend );
}
endselectionongameend()
{
self endon( "death" );
self endon( "disconnect" );
self endon( "cancel_location" );
self endon( "used" );
self endon( "host_migration_begin" );
level waittill( "game_ended" );
self notify( "game_ended" );
}
endselectiononhostmigration()
{
self endon( "death" );
self endon( "disconnect" );
self endon( "cancel_location" );
self endon( "used" );
self endon( "game_ended" );
level waittill( "host_migration_begin" );
self notify( "cancel_location" );
}
endselectionthink()
{
/#
assert( isplayer( self ) );
#/
/#
assert( isalive( self ) );
#/
/#
assert( isDefined( self.selectinglocation ) );
#/
/#
assert( self.selectinglocation == 1 );
#/
self thread endselectionongameend();
self thread endselectiononhostmigration();
event = self waittill_any_return( "death", "disconnect", "cancel_location", "game_ended", "used", "weapon_change", "emp_jammed" );
if ( event != "disconnect" )
{
self endlocationselection();
self.selectinglocation = undefined;
}
if ( event != "used" )
{
self notify( "confirm_location" );
}
}
stoploopsoundaftertime( time )
{
self endon( "death" );
wait time;
self stoploopsound( 2 );
}
calculatefalltime( flyheight )
{
gravity = getDvarInt( "bg_gravity" );
time = sqrt( ( 2 * flyheight ) / gravity );
return time;
}
calculatereleasetime( flytime, flyheight, flyspeed, bombspeedscale )
{
falltime = calculatefalltime( flyheight );
bomb_x = flyspeed * bombspeedscale * falltime;
release_time = bomb_x / flyspeed;
return ( flytime * 0,5 ) - release_time;
}
getminimumflyheight()
{
airsupport_height = getstruct( "air_support_height", "targetname" );
if ( isDefined( airsupport_height ) )
{
planeflyheight = airsupport_height.origin[ 2 ];
}
else
{
/#
println( "WARNING: Missing air_support_height entity in the map. Using default height." );
#/
planeflyheight = 850;
if ( isDefined( level.airsupportheightscale ) )
{
level.airsupportheightscale = getdvarintdefault( "scr_airsupportHeightScale", level.airsupportheightscale );
planeflyheight *= getdvarintdefault( "scr_airsupportHeightScale", level.airsupportheightscale );
}
if ( isDefined( level.forceairsupportmapheight ) )
{
planeflyheight += level.forceairsupportmapheight;
}
}
return planeflyheight;
}
callstrike( flightplan )
{
level.bomberdamagedents = [];
level.bomberdamagedentscount = 0;
level.bomberdamagedentsindex = 0;
/#
assert( flightplan.distance != 0, "callStrike can not be passed a zero fly distance" );
#/
planehalfdistance = flightplan.distance / 2;
path = getstrikepath( flightplan.target, flightplan.height, planehalfdistance );
startpoint = path[ "start" ];
endpoint = path[ "end" ];
flightplan.height = path[ "height" ];
direction = path[ "direction" ];
d = length( startpoint - endpoint );
flytime = d / flightplan.speed;
bombtime = calculatereleasetime( flytime, flightplan.height, flightplan.speed, flightplan.bombspeedscale );
if ( bombtime < 0 )
{
bombtime = 0;
}
/#
assert( flytime > bombtime );
#/
flightplan.owner endon( "disconnect" );
requireddeathcount = flightplan.owner.deathcount;
side = vectorcross( anglesToForward( direction ), ( 1, 1, 1 ) );
plane_seperation = 25;
side_offset = vectorScale( side, plane_seperation );
level thread planestrike( flightplan.owner, requireddeathcount, startpoint, endpoint, bombtime, flytime, flightplan.speed, flightplan.bombspeedscale, direction, flightplan.planespawncallback );
wait flightplan.planespacing;
level thread planestrike( flightplan.owner, requireddeathcount, startpoint + side_offset, endpoint + side_offset, bombtime, flytime, flightplan.speed, flightplan.bombspeedscale, direction, flightplan.planespawncallback );
wait flightplan.planespacing;
side_offset = vectorScale( side, -1 * plane_seperation );
level thread planestrike( flightplan.owner, requireddeathcount, startpoint + side_offset, endpoint + side_offset, bombtime, flytime, flightplan.speed, flightplan.bombspeedscale, direction, flightplan.planespawncallback );
}
planestrike( owner, requireddeathcount, pathstart, pathend, bombtime, flytime, flyspeed, bombspeedscale, direction, planespawnedfunction )
{
if ( !isDefined( owner ) )
{
return;
}
plane = spawnplane( owner, "script_model", pathstart );
plane.angles = direction;
plane moveto( pathend, flytime, 0, 0 );
thread debug_plane_line( flytime, flyspeed, pathstart, pathend );
if ( isDefined( planespawnedfunction ) )
{
plane [[ planespawnedfunction ]]( owner, requireddeathcount, pathstart, pathend, bombtime, bombspeedscale, flytime, flyspeed );
}
wait flytime;
plane notify( "delete" );
plane delete();
}
determinegroundpoint( player, position )
{
ground = ( position[ 0 ], position[ 1 ], player.origin[ 2 ] );
trace = bullettrace( ground + vectorScale( ( 1, 1, 1 ), 10000 ), ground, 0, undefined );
return trace[ "position" ];
}
determinetargetpoint( player, position )
{
point = determinegroundpoint( player, position );
return clamptarget( point );
}
getmintargetheight()
{
return level.spawnmins[ 2 ] - 500;
}
getmaxtargetheight()
{
return level.spawnmaxs[ 2 ] + 500;
}
clamptarget( target )
{
min = getmintargetheight();
max = getmaxtargetheight();
if ( target[ 2 ] < min )
{
target[ 2 ] = min;
}
if ( target[ 2 ] > max )
{
target[ 2 ] = max;
}
return target;
}
_insidecylinder( point, base, radius, height )
{
if ( isDefined( height ) )
{
if ( point[ 2 ] > ( base[ 2 ] + height ) )
{
return 0;
}
}
dist = distance2d( point, base );
if ( dist < radius )
{
return 1;
}
return 0;
}
_insidenoflyzonebyindex( point, index, disregardheight )
{
height = level.noflyzones[ index ].height;
if ( isDefined( disregardheight ) )
{
height = undefined;
}
return _insidecylinder( point, level.noflyzones[ index ].origin, level.noflyzones[ index ].radius, height );
}
getnoflyzoneheight( point )
{
height = point[ 2 ];
origin = undefined;
i = 0;
while ( i < level.noflyzones.size )
{
if ( _insidenoflyzonebyindex( point, i ) )
{
if ( height < level.noflyzones[ i ].height )
{
height = level.noflyzones[ i ].height;
origin = level.noflyzones[ i ].origin;
}
}
i++;
}
if ( !isDefined( origin ) )
{
return point[ 2 ];
}
return origin[ 2 ] + height;
}
insidenoflyzones( point, disregardheight )
{
noflyzones = [];
i = 0;
while ( i < level.noflyzones.size )
{
if ( _insidenoflyzonebyindex( point, i, disregardheight ) )
{
noflyzones[ noflyzones.size ] = i;
}
i++;
}
return noflyzones;
}
crossesnoflyzone( start, end )
{
i = 0;
while ( i < level.noflyzones.size )
{
point = closestpointonline( level.noflyzones[ i ].origin + ( 0, 0, 0,5 * level.noflyzones[ i ].height ), start, end );
dist = distance2d( point, level.noflyzones[ i ].origin );
if ( point[ 2 ] > ( level.noflyzones[ i ].origin[ 2 ] + level.noflyzones[ i ].height ) )
{
i++;
continue;
}
else
{
if ( dist < level.noflyzones[ i ].radius )
{
return i;
}
}
i++;
}
return undefined;
}
crossesnoflyzones( start, end )
{
zones = [];
i = 0;
while ( i < level.noflyzones.size )
{
point = closestpointonline( level.noflyzones[ i ].origin, start, end );
dist = distance2d( point, level.noflyzones[ i ].origin );
if ( point[ 2 ] > ( level.noflyzones[ i ].origin[ 2 ] + level.noflyzones[ i ].height ) )
{
i++;
continue;
}
else
{
if ( dist < level.noflyzones[ i ].radius )
{
zones[ zones.size ] = i;
}
}
i++;
}
return zones;
}
getnoflyzoneheightcrossed( start, end, minheight )
{
height = minheight;
i = 0;
while ( i < level.noflyzones.size )
{
point = closestpointonline( level.noflyzones[ i ].origin, start, end );
dist = distance2d( point, level.noflyzones[ i ].origin );
if ( dist < level.noflyzones[ i ].radius )
{
if ( height < level.noflyzones[ i ].height )
{
height = level.noflyzones[ i ].height;
}
}
i++;
}
return height;
}
_shouldignorenoflyzone( noflyzone, noflyzones )
{
if ( !isDefined( noflyzone ) )
{
return 1;
}
i = 0;
while ( i < noflyzones.size )
{
if ( isDefined( noflyzones[ i ] ) && noflyzones[ i ] == noflyzone )
{
return 1;
}
i++;
}
return 0;
}
_shouldignorestartgoalnoflyzone( noflyzone, startnoflyzones, goalnoflyzones )
{
if ( !isDefined( noflyzone ) )
{
return 1;
}
if ( _shouldignorenoflyzone( noflyzone, startnoflyzones ) )
{
return 1;
}
if ( _shouldignorenoflyzone( noflyzone, goalnoflyzones ) )
{
return 1;
}
return 0;
}
gethelipath( start, goal )
{
startnoflyzones = insidenoflyzones( start, 1 );
thread debug_line( start, goal, ( 1, 1, 1 ) );
goalnoflyzones = insidenoflyzones( goal );
if ( goalnoflyzones.size )
{
goal = ( goal[ 0 ], goal[ 1 ], getnoflyzoneheight( goal ) );
}
goal_points = calculatepath( start, goal, startnoflyzones, goalnoflyzones );
if ( !isDefined( goal_points ) )
{
return undefined;
}
/#
assert( goal_points.size >= 1 );
#/
return goal_points;
}
followpath( path, donenotify, stopatgoal )
{
i = 0;
while ( i < ( path.size - 1 ) )
{
self setvehgoalpos( path[ i ], 0 );
thread debug_line( self.origin, path[ i ], ( 1, 1, 1 ) );
self waittill( "goal" );
i++;
}
self setvehgoalpos( path[ path.size - 1 ], stopatgoal );
thread debug_line( self.origin, path[ i ], ( 1, 1, 1 ) );
self waittill( "goal" );
if ( isDefined( donenotify ) )
{
self notify( donenotify );
}
}
setgoalposition( goal, donenotify, stopatgoal )
{
if ( !isDefined( stopatgoal ) )
{
stopatgoal = 1;
}
start = self.origin;
goal_points = gethelipath( start, goal );
if ( !isDefined( goal_points ) )
{
goal_points = [];
goal_points[ 0 ] = goal;
}
followpath( goal_points, donenotify, stopatgoal );
}
clearpath( start, end, startnoflyzone, goalnoflyzone )
{
noflyzones = crossesnoflyzones( start, end );
i = 0;
while ( i < noflyzones.size )
{
if ( !_shouldignorestartgoalnoflyzone( noflyzones[ i ], startnoflyzone, goalnoflyzone ) )
{
return 0;
}
i++;
}
return 1;
}
append_array( dst, src )
{
i = 0;
while ( i < src.size )
{
dst[ dst.size ] = src[ i ];
i++;
}
}
calculatepath_r( start, end, points, startnoflyzones, goalnoflyzones, depth )
{
depth--;
if ( depth <= 0 )
{
points[ points.size ] = end;
return points;
}
noflyzones = crossesnoflyzones( start, end );
i = 0;
while ( i < noflyzones.size )
{
noflyzone = noflyzones[ i ];
if ( !_shouldignorestartgoalnoflyzone( noflyzone, startnoflyzones, goalnoflyzones ) )
{
return undefined;
}
i++;
}
points[ points.size ] = end;
return points;
}
calculatepath( start, end, startnoflyzones, goalnoflyzones )
{
points = [];
points = calculatepath_r( start, end, points, startnoflyzones, goalnoflyzones, 3 );
if ( !isDefined( points ) )
{
return undefined;
}
/#
assert( points.size >= 1 );
#/
debug_sphere( points[ points.size - 1 ], 10, ( 1, 1, 1 ), 1, 1000 );
point = start;
i = 0;
while ( i < points.size )
{
thread debug_line( point, points[ i ], ( 1, 1, 1 ) );
debug_sphere( points[ i ], 10, ( 1, 1, 1 ), 1, 1000 );
point = points[ i ];
i++;
}
return points;
}
_getstrikepathstartandend( goal, yaw, halfdistance )
{
direction = ( 0, yaw, 0 );
startpoint = goal + vectorScale( anglesToForward( direction ), -1 * halfdistance );
endpoint = goal + vectorScale( anglesToForward( direction ), halfdistance );
noflyzone = crossesnoflyzone( startpoint, endpoint );
path = [];
if ( isDefined( noflyzone ) )
{
path[ "noFlyZone" ] = noflyzone;
startpoint = ( startpoint[ 0 ], startpoint[ 1 ], level.noflyzones[ noflyzone ].origin[ 2 ] + level.noflyzones[ noflyzone ].height );
endpoint = ( endpoint[ 0 ], endpoint[ 1 ], startpoint[ 2 ] );
}
else
{
}
path[ "start" ] = startpoint;
path[ "end" ] = endpoint;
path[ "direction" ] = direction;
return path;
}
getstrikepath( target, height, halfdistance, yaw )
{
noflyzoneheight = getnoflyzoneheight( target );
worldheight = target[ 2 ] + height;
if ( noflyzoneheight > worldheight )
{
worldheight = noflyzoneheight;
}
goal = ( target[ 0 ], target[ 1 ], worldheight );
path = [];
if ( !isDefined( yaw ) || yaw != "random" )
{
i = 0;
while ( i < 3 )
{
path = _getstrikepathstartandend( goal, randomint( 360 ), halfdistance );
if ( !isDefined( path[ "noFlyZone" ] ) )
{
break;
}
else
{
i++;
}
}
}
else path = _getstrikepathstartandend( goal, yaw, halfdistance );
path[ "height" ] = worldheight - target[ 2 ];
return path;
}
doglassdamage( pos, radius, max, min, mod )
{
wait randomfloatrange( 0,05, 0,15 );
glassradiusdamage( pos, radius, max, min, mod );
}
entlosradiusdamage( ent, pos, radius, max, min, owner, einflictor )
{
dist = distance( pos, ent.damagecenter );
if ( ent.isplayer || ent.isactor )
{
assumed_ceiling_height = 800;
eye_position = ent.entity geteye();
head_height = eye_position[ 2 ];
debug_display_time = 4000;
trace = maps/mp/gametypes/_weapons::weapondamagetrace( ent.entity.origin, ent.entity.origin + ( 0, 0, assumed_ceiling_height ), 0, undefined );
indoors = trace[ "fraction" ] != 1;
if ( indoors )
{
test_point = trace[ "position" ];
debug_star( test_point, ( 1, 1, 1 ), debug_display_time );
trace = maps/mp/gametypes/_weapons::weapondamagetrace( ( test_point[ 0 ], test_point[ 1 ], head_height ), ( pos[ 0 ], pos[ 1 ], head_height ), 0, undefined );
indoors = trace[ "fraction" ] != 1;
if ( indoors )
{
debug_star( ( pos[ 0 ], pos[ 1 ], head_height ), ( 1, 1, 1 ), debug_display_time );
dist *= 4;
if ( dist > radius )
{
return 0;
}
}
else
{
debug_star( ( pos[ 0 ], pos[ 1 ], head_height ), ( 1, 1, 1 ), debug_display_time );
trace = maps/mp/gametypes/_weapons::weapondamagetrace( ( pos[ 0 ], pos[ 1 ], head_height ), pos, 0, undefined );
indoors = trace[ "fraction" ] != 1;
if ( indoors )
{
debug_star( pos, ( 1, 1, 1 ), debug_display_time );
dist *= 4;
if ( dist > radius )
{
return 0;
}
}
else
{
debug_star( pos, ( 1, 1, 1 ), debug_display_time );
}
}
}
else
{
debug_star( ent.entity.origin + ( 0, 0, assumed_ceiling_height ), ( 1, 1, 1 ), debug_display_time );
}
}
ent.damage = int( max + ( ( ( min - max ) * dist ) / radius ) );
ent.pos = pos;
ent.damageowner = owner;
ent.einflictor = einflictor;
return 1;
}
debug_no_fly_zones()
{
/#
i = 0;
while ( i < level.noflyzones.size )
{
debug_cylinder( level.noflyzones[ i ].origin, level.noflyzones[ i ].radius, level.noflyzones[ i ].height, ( 1, 1, 1 ), undefined, 5000 );
i++;
#/
}
}
debug_plane_line( flytime, flyspeed, pathstart, pathend )
{
thread debug_line( pathstart, pathend, ( 1, 1, 1 ) );
delta = vectornormalize( pathend - pathstart );
i = 0;
while ( i < flytime )
{
thread debug_star( pathstart + vectorScale( delta, i * flyspeed ), ( 1, 1, 1 ) );
i++;
}
}
debug_draw_bomb_explosion( prevpos )
{
self notify( "draw_explosion" );
wait 0,05;
self endon( "draw_explosion" );
self waittill( "projectile_impact", weapon, position );
thread debug_line( prevpos, position, ( 0,5, 1, 0 ) );
thread debug_star( position, ( 1, 1, 1 ) );
}
debug_draw_bomb_path( projectile, color, time )
{
/#
self endon( "death" );
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
if ( !isDefined( color ) )
{
color = ( 0,5, 1, 0 );
}
while ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
prevpos = self.origin;
while ( isDefined( self.origin ) )
{
thread debug_line( prevpos, self.origin, color, time );
prevpos = self.origin;
if ( isDefined( projectile ) && projectile )
{
thread debug_draw_bomb_explosion( prevpos );
}
wait 0,2;
#/
}
}
}
debug_print3d_simple( message, ent, offset, frames )
{
/#
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
if ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
if ( isDefined( frames ) )
{
thread draw_text( message, vectorScale( ( 1, 1, 1 ), 0,8 ), ent, offset, frames );
return;
}
else
{
thread draw_text( message, vectorScale( ( 1, 1, 1 ), 0,8 ), ent, offset, 0 );
#/
}
}
}
draw_text( msg, color, ent, offset, frames )
{
/#
if ( frames == 0 )
{
while ( isDefined( ent ) && isDefined( ent.origin ) )
{
print3d( ent.origin + offset, msg, color, 0,5, 4 );
wait 0,05;
}
}
else i = 0;
while ( i < frames )
{
if ( !isDefined( ent ) )
{
return;
}
else
{
print3d( ent.origin + offset, msg, color, 0,5, 4 );
wait 0,05;
i++;
#/
}
}
}
debug_print3d( message, color, ent, origin_offset, frames )
{
/#
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
if ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
self thread draw_text( message, color, ent, origin_offset, frames );
#/
}
}
debug_line( from, to, color, time, depthtest )
{
/#
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
if ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
if ( !isDefined( time ) )
{
time = 1000;
}
if ( !isDefined( depthtest ) )
{
depthtest = 1;
}
line( from, to, color, 1, depthtest, time );
#/
}
}
debug_star( origin, color, time )
{
/#
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
if ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
if ( !isDefined( time ) )
{
time = 1000;
}
if ( !isDefined( color ) )
{
color = ( 1, 1, 1 );
}
debugstar( origin, time, color );
#/
}
}
debug_circle( origin, radius, color, time )
{
/#
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
if ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
if ( !isDefined( time ) )
{
time = 1000;
}
if ( !isDefined( color ) )
{
color = ( 1, 1, 1 );
}
circle( origin, radius, color, 1, 1, time );
#/
}
}
debug_sphere( origin, radius, color, alpha, time )
{
/#
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
if ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
if ( !isDefined( time ) )
{
time = 1000;
}
if ( !isDefined( color ) )
{
color = ( 1, 1, 1 );
}
sides = int( 10 * ( 1 + int( radius / 100 ) ) );
sphere( origin, radius, color, alpha, 1, sides, time );
#/
}
}
debug_cylinder( origin, radius, height, color, mustrenderheight, time )
{
/#
level.airsupport_debug = getdvarintdefault( "scr_airsupport_debug", 0 );
subdivision = 600;
if ( isDefined( level.airsupport_debug ) && level.airsupport_debug == 1 )
{
if ( !isDefined( time ) )
{
time = 1000;
}
if ( !isDefined( color ) )
{
color = ( 1, 1, 1 );
}
count = height / subdivision;
i = 0;
while ( i < count )
{
point = origin + ( 0, 0, i * subdivision );
circle( point, radius, color, 1, 1, time );
i++;
}
if ( isDefined( mustrenderheight ) )
{
point = origin + ( 0, 0, mustrenderheight );
circle( point, radius, color, 1, 1, time );
#/
}
}
}
getpointonline( startpoint, endpoint, ratio )
{
nextpoint = ( startpoint[ 0 ] + ( ( endpoint[ 0 ] - startpoint[ 0 ] ) * ratio ), startpoint[ 1 ] + ( ( endpoint[ 1 ] - startpoint[ 1 ] ) * ratio ), startpoint[ 2 ] + ( ( endpoint[ 2 ] - startpoint[ 2 ] ) * ratio ) );
return nextpoint;
}
cantargetplayerwithspecialty()
{
if ( self hasperk( "specialty_nottargetedbyairsupport" ) || isDefined( self.specialty_nottargetedbyairsupport ) && self.specialty_nottargetedbyairsupport )
{
if ( !isDefined( self.nottargettedai_underminspeedtimer ) || self.nottargettedai_underminspeedtimer < getDvarInt( "perk_nottargetedbyai_graceperiod" ) )
{
return 0;
}
}
return 1;
}
monitorspeed( spawnprotectiontime )
{
self endon( "death" );
self endon( "disconnect" );
if ( self hasperk( "specialty_nottargetedbyairsupport" ) == 0 )
{
return;
}
getDvar( #"B46C7AAF" );
graceperiod = getDvarInt( "perk_nottargetedbyai_graceperiod" );
minspeed = getDvarInt( "perk_nottargetedbyai_min_speed" );
minspeedsq = minspeed * minspeed;
waitperiod = 0,25;
waitperiodmilliseconds = waitperiod * 1000;
if ( minspeedsq == 0 )
{
return;
}
self.nottargettedai_underminspeedtimer = 0;
if ( isDefined( spawnprotectiontime ) )
{
wait spawnprotectiontime;
}
while ( 1 )
{
velocity = self getvelocity();
speedsq = lengthsquared( velocity );
if ( speedsq < minspeedsq )
{
self.nottargettedai_underminspeedtimer += waitperiodmilliseconds;
}
else
{
self.nottargettedai_underminspeedtimer = 0;
}
wait waitperiod;
}
}
clearmonitoredspeed()
{
if ( isDefined( self.nottargettedai_underminspeedtimer ) )
{
self.nottargettedai_underminspeedtimer = 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,590 @@
#include maps/mp/killstreaks/_emp;
#include maps/mp/_tacticalinsertion;
#include maps/mp/gametypes/_weaponobjects;
#include maps/mp/gametypes/_hostmigration;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_killstreaks;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
level._effect[ "emp_flash" ] = loadfx( "weapon/emp/fx_emp_explosion" );
_a9 = level.teams;
_k9 = getFirstArrayKey( _a9 );
while ( isDefined( _k9 ) )
{
team = _a9[ _k9 ];
level.teamemping[ team ] = 0;
_k9 = getNextArrayKey( _a9, _k9 );
}
level.empplayer = undefined;
level.emptimeout = 40;
level.empowners = [];
if ( level.teambased )
{
level thread emp_teamtracker();
}
else
{
level thread emp_playertracker();
}
level thread onplayerconnect();
registerkillstreak( "emp_mp", "emp_mp", "killstreak_emp", "emp_used", ::emp_use );
registerkillstreakstrings( "emp_mp", &"KILLSTREAK_EARNED_EMP", &"KILLSTREAK_EMP_NOT_AVAILABLE", &"KILLSTREAK_EMP_INBOUND" );
registerkillstreakdialog( "emp_mp", "mpl_killstreak_emp_activate", "kls_emp_used", "", "kls_emp_enemy", "", "kls_emp_ready" );
registerkillstreakdevdvar( "emp_mp", "scr_giveemp" );
maps/mp/killstreaks/_killstreaks::createkillstreaktimer( "emp_mp" );
/#
set_dvar_float_if_unset( "scr_emp_timeout", 40 );
set_dvar_int_if_unset( "scr_emp_damage_debug", 0 );
#/
}
onplayerconnect()
{
for ( ;; )
{
level waittill( "connected", player );
player thread onplayerspawned();
}
}
onplayerspawned()
{
self endon( "disconnect" );
for ( ;; )
{
self waittill( "spawned_player" );
if ( level.teambased || emp_isteamemped( self.team ) && !level.teambased && isDefined( level.empplayer ) && level.empplayer != self )
{
self setempjammed( 1 );
}
}
}
emp_isteamemped( check_team )
{
_a64 = level.teams;
_k64 = getFirstArrayKey( _a64 );
while ( isDefined( _k64 ) )
{
team = _a64[ _k64 ];
if ( team == check_team )
{
}
else
{
if ( level.teamemping[ team ] )
{
return 1;
}
}
_k64 = getNextArrayKey( _a64, _k64 );
}
return 0;
}
emp_use( lifeid )
{
/#
assert( isDefined( self ) );
#/
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( "emp_mp", self.team, 0, 1 );
if ( killstreak_id == -1 )
{
return 0;
}
myteam = self.pers[ "team" ];
if ( level.teambased )
{
self thread emp_jamotherteams( myteam, killstreak_id );
}
else
{
self thread emp_jamplayers( self, killstreak_id );
}
self.emptime = getTime();
self notify( "used_emp" );
self playlocalsound( "mpl_killstreak_emp_activate" );
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "emp_mp", self.pers[ "team" ] );
level.globalkillstreakscalled++;
self addweaponstat( "emp_mp", "used", 1 );
return 1;
}
emp_jamotherteams( teamname, killstreak_id )
{
level endon( "game_ended" );
overlays = [];
/#
assert( isDefined( level.teams[ teamname ] ) );
#/
level notify( "EMP_JamOtherTeams" + teamname );
level endon( "EMP_JamOtherTeams" + teamname );
level.empowners[ teamname ] = self;
_a121 = level.players;
_k121 = getFirstArrayKey( _a121 );
while ( isDefined( _k121 ) )
{
player = _a121[ _k121 ];
if ( player.team == teamname )
{
}
else
{
player playlocalsound( "mpl_killstreak_emp_blast_front" );
}
_k121 = getNextArrayKey( _a121, _k121 );
}
visionsetnaked( "flash_grenade", 1,5 );
thread empeffects();
wait 0,1;
visionsetnaked( "flash_grenade", 0 );
if ( isDefined( level.nukedetonated ) )
{
visionsetnaked( level.nukevisionset, 5 );
}
else
{
visionsetnaked( getDvar( "mapname" ), 5 );
}
level.teamemping[ teamname ] = 1;
level notify( "emp_update" );
level destroyotherteamsactivevehicles( self, teamname );
level destroyotherteamsequipment( self, teamname );
/#
level.emptimeout = getDvarFloat( #"35E553D4" );
#/
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpauseemp( level.emptimeout );
level.teamemping[ teamname ] = 0;
maps/mp/killstreaks/_killstreakrules::killstreakstop( "emp_mp", teamname, killstreak_id );
level notify( "emp_update" );
level notify( "emp_end" + teamname );
}
emp_jamplayers( owner, killstreak_id )
{
level notify( "EMP_JamPlayers" );
level endon( "EMP_JamPlayers" );
overlays = [];
/#
assert( isDefined( owner ) );
#/
_a180 = level.players;
_k180 = getFirstArrayKey( _a180 );
while ( isDefined( _k180 ) )
{
player = _a180[ _k180 ];
if ( player == owner )
{
}
else
{
player playlocalsound( "mpl_killstreak_emp_blast_front" );
}
_k180 = getNextArrayKey( _a180, _k180 );
}
visionsetnaked( "flash_grenade", 1,5 );
thread empeffects();
wait 0,1;
visionsetnaked( "flash_grenade", 0 );
if ( isDefined( level.nukedetonated ) )
{
visionsetnaked( level.nukevisionset, 5 );
}
else
{
visionsetnaked( getDvar( "mapname" ), 5 );
}
level notify( "emp_update" );
level.empplayer = owner;
level.empplayer thread empplayerffadisconnect();
level destroyactivevehicles( owner );
level destroyequipment( owner );
level notify( "emp_update" );
/#
level.emptimeout = getDvarFloat( #"35E553D4" );
#/
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpause( level.emptimeout );
maps/mp/killstreaks/_killstreakrules::killstreakstop( "emp_mp", level.empplayer.team, killstreak_id );
level.empplayer = undefined;
level notify( "emp_update" );
level notify( "emp_ended" );
}
empplayerffadisconnect()
{
level endon( "EMP_JamPlayers" );
level endon( "emp_ended" );
self waittill( "disconnect" );
level notify( "emp_update" );
}
empeffects()
{
_a241 = level.players;
_k241 = getFirstArrayKey( _a241 );
while ( isDefined( _k241 ) )
{
player = _a241[ _k241 ];
playerforward = anglesToForward( player.angles );
playerforward = ( playerforward[ 0 ], playerforward[ 1 ], 0 );
playerforward = vectornormalize( playerforward );
empdistance = 20000;
empent = spawn( "script_model", ( player.origin + vectorScale( ( 0, 0, 1 ), 8000 ) ) + ( playerforward * empdistance ) );
empent setmodel( "tag_origin" );
empent.angles += vectorScale( ( 0, 0, 1 ), 270 );
empent thread empeffect( player );
_k241 = getNextArrayKey( _a241, _k241 );
}
}
empeffect( player )
{
player endon( "disconnect" );
self setinvisibletoall();
self setvisibletoplayer( player );
wait 0,5;
playfxontag( level._effect[ "emp_flash" ], self, "tag_origin" );
self playsound( "wpn_emp_bomb" );
self deleteaftertime( 11 );
}
emp_teamtracker()
{
level endon( "game_ended" );
for ( ;; )
{
level waittill_either( "joined_team", "emp_update" );
_a279 = level.players;
_k279 = getFirstArrayKey( _a279 );
while ( isDefined( _k279 ) )
{
player = _a279[ _k279 ];
if ( player.team == "spectator" )
{
}
else
{
emped = emp_isteamemped( player.team );
player setempjammed( emped );
if ( emped )
{
player notify( "emp_jammed" );
}
}
_k279 = getNextArrayKey( _a279, _k279 );
}
}
}
emp_playertracker()
{
level endon( "game_ended" );
for ( ;; )
{
level waittill_either( "joined_team", "emp_update" );
_a306 = level.players;
_k306 = getFirstArrayKey( _a306 );
while ( isDefined( _k306 ) )
{
player = _a306[ _k306 ];
if ( player.team == "spectator" )
{
}
else if ( isDefined( level.empplayer ) && level.empplayer != player )
{
player setempjammed( 1 );
player notify( "emp_jammed" );
}
else
{
player setempjammed( 0 );
}
_k306 = getNextArrayKey( _a306, _k306 );
}
}
}
destroyotherteamsequipment( attacker, teamemping )
{
_a328 = level.teams;
_k328 = getFirstArrayKey( _a328 );
while ( isDefined( _k328 ) )
{
team = _a328[ _k328 ];
if ( team == teamemping )
{
}
else
{
destroyequipment( attacker, team );
destroytacticalinsertions( attacker, team );
}
_k328 = getNextArrayKey( _a328, _k328 );
}
}
destroyequipment( attacker, teamemped )
{
i = 0;
while ( i < level.missileentities.size )
{
item = level.missileentities[ i ];
if ( !isDefined( item.name ) )
{
i++;
continue;
}
else if ( !isDefined( item.owner ) )
{
i++;
continue;
}
else if ( isDefined( teamemped ) && item.owner.team != teamemped )
{
i++;
continue;
}
else if ( item.owner == attacker )
{
i++;
continue;
}
else if ( !isweaponequipment( item.name ) && item.name != "proximity_grenade_mp" )
{
i++;
continue;
}
else
{
watcher = item.owner getwatcherforweapon( item.name );
if ( !isDefined( watcher ) )
{
i++;
continue;
}
else
{
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( item, 0, attacker, "emp_mp" );
}
}
i++;
}
}
destroytacticalinsertions( attacker, victimteam )
{
i = 0;
while ( i < level.players.size )
{
player = level.players[ i ];
if ( !isDefined( player.tacticalinsertion ) )
{
i++;
continue;
}
else if ( level.teambased && player.team != victimteam )
{
i++;
continue;
}
else
{
if ( attacker == player )
{
i++;
continue;
}
else
{
player.tacticalinsertion thread maps/mp/_tacticalinsertion::fizzle();
}
}
i++;
}
}
getwatcherforweapon( weapname )
{
if ( !isDefined( self ) )
{
return undefined;
}
if ( !isplayer( self ) )
{
return undefined;
}
i = 0;
while ( i < self.weaponobjectwatcherarray.size )
{
if ( self.weaponobjectwatcherarray[ i ].weapon != weapname )
{
i++;
continue;
}
else
{
return self.weaponobjectwatcherarray[ i ];
}
i++;
}
return undefined;
}
destroyotherteamsactivevehicles( attacker, teamemping )
{
_a431 = level.teams;
_k431 = getFirstArrayKey( _a431 );
while ( isDefined( _k431 ) )
{
team = _a431[ _k431 ];
if ( team == teamemping )
{
}
else
{
destroyactivevehicles( attacker, team );
}
_k431 = getNextArrayKey( _a431, _k431 );
}
}
destroyactivevehicles( attacker, teamemped )
{
turrets = getentarray( "auto_turret", "classname" );
destroyentities( turrets, attacker, teamemped );
targets = target_getarray();
destroyentities( targets, attacker, teamemped );
rcbombs = getentarray( "rcbomb", "targetname" );
destroyentities( rcbombs, attacker, teamemped );
remotemissiles = getentarray( "remote_missile", "targetname" );
destroyentities( remotemissiles, attacker, teamemped );
remotedrone = getentarray( "remote_drone", "targetname" );
destroyentities( remotedrone, attacker, teamemped );
planemortars = getentarray( "plane_mortar", "targetname" );
_a458 = planemortars;
_k458 = getFirstArrayKey( _a458 );
while ( isDefined( _k458 ) )
{
planemortar = _a458[ _k458 ];
if ( isDefined( teamemped ) && isDefined( planemortar.team ) )
{
if ( planemortar.team != teamemped )
{
}
else }
else if ( planemortar.owner == attacker )
{
}
else
{
planemortar notify( "emp_deployed" );
}
_k458 = getNextArrayKey( _a458, _k458 );
}
satellites = getentarray( "satellite", "targetname" );
_a477 = satellites;
_k477 = getFirstArrayKey( _a477 );
while ( isDefined( _k477 ) )
{
satellite = _a477[ _k477 ];
if ( isDefined( teamemped ) && isDefined( satellite.team ) )
{
if ( satellite.team != teamemped )
{
}
else }
else if ( satellite.owner == attacker )
{
}
else
{
satellite notify( "emp_deployed" );
}
_k477 = getNextArrayKey( _a477, _k477 );
}
if ( isDefined( level.missile_swarm_owner ) )
{
if ( level.missile_swarm_owner isenemyplayer( attacker ) )
{
level.missile_swarm_owner notify( "emp_destroyed_missile_swarm" );
}
}
}
destroyentities( entities, attacker, team )
{
meansofdeath = "MOD_EXPLOSIVE";
weapon = "killstreak_emp_mp";
damage = 5000;
direction_vec = ( 0, 0, 1 );
point = ( 0, 0, 1 );
modelname = "";
tagname = "";
partname = "";
_a515 = entities;
_k515 = getFirstArrayKey( _a515 );
while ( isDefined( _k515 ) )
{
entity = _a515[ _k515 ];
if ( isDefined( team ) && isDefined( entity.team ) )
{
if ( entity.team != team )
{
}
else }
else if ( entity.owner == attacker )
{
}
else
{
entity notify( "damage" );
}
_k515 = getNextArrayKey( _a515, _k515 );
}
}
drawempdamageorigin( pos, ang, radius )
{
/#
while ( getDvarInt( #"D04570F2" ) )
{
line( pos, pos + ( anglesToForward( ang ) * radius ), ( 0, 0, 1 ) );
line( pos, pos + ( anglesToRight( ang ) * radius ), ( 0, 0, 1 ) );
line( pos, pos + ( anglesToUp( ang ) * radius ), ( 0, 0, 1 ) );
line( pos, pos - ( anglesToForward( ang ) * radius ), ( 0, 0, 1 ) );
line( pos, pos - ( anglesToRight( ang ) * radius ), ( 0, 0, 1 ) );
line( pos, pos - ( anglesToUp( ang ) * radius ), ( 0, 0, 1 ) );
wait 0,05;
#/
}
}
isenemyempkillstreakactive()
{
if ( level.teambased || maps/mp/killstreaks/_emp::emp_isteamemped( self.team ) && !level.teambased && isDefined( level.empplayer ) && level.empplayer != self )
{
return 1;
}
return 0;
}
isempweapon( weaponname )
{
if ( isDefined( weaponname ) && weaponname != "emp_mp" || weaponname == "emp_grenade_mp" && weaponname == "emp_grenade_zm" )
{
return 1;
}
return 0;
}
isempkillstreakweapon( weaponname )
{
if ( isDefined( weaponname ) && weaponname == "emp_mp" )
{
return 1;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,796 @@
#include maps/mp/gametypes/_hostmigration;
#include maps/mp/_heatseekingmissile;
#include maps/mp/gametypes/_spawning;
#include maps/mp/killstreaks/_helicopter;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_airsupport;
#include maps/mp/killstreaks/_killstreaks;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
precachestring( &"MP_CIVILIAN_AIR_TRAFFIC" );
precachestring( &"MP_AIR_SPACE_TOO_CROWDED" );
precachevehicle( "heli_guard_mp" );
precachemodel( "veh_t6_drone_overwatch_light" );
precachemodel( "veh_t6_drone_overwatch_dark" );
precacheturret( "littlebird_guard_minigun_mp" );
precachemodel( "veh_iw_littlebird_minigun_left" );
precachemodel( "veh_iw_littlebird_minigun_right" );
registerkillstreak( "helicopter_guard_mp", "helicopter_guard_mp", "killstreak_helicopter_guard", "helicopter_used", ::tryuseheliguardsupport, 1 );
registerkillstreakaltweapon( "helicopter_guard_mp", "littlebird_guard_minigun_mp" );
registerkillstreakstrings( "helicopter_guard_mp", &"KILLSTREAK_EARNED_HELICOPTER_GUARD", &"KILLSTREAK_HELICOPTER_GUARD_NOT_AVAILABLE", &"KILLSTREAK_HELICOPTER_GUARD_INBOUND" );
registerkillstreakdialog( "helicopter_guard_mp", "mpl_killstreak_lbguard_strt", "kls_littlebird_used", "", "kls_littlebird_enemy", "", "kls_littlebird_ready" );
registerkillstreakdevdvar( "helicopter_guard_mp", "scr_givehelicopterguard" );
setkillstreakteamkillpenaltyscale( "helicopter_guard_mp", 0 );
shouldtimeout = setdvar( "scr_heli_guard_no_timeout", 0 );
debuglittlebird = setdvar( "scr_heli_guard_debug", 0 );
level._effect[ "heli_guard_light" ][ "friendly" ] = loadfx( "light/fx_vlight_mp_escort_eye_grn" );
level._effect[ "heli_guard_light" ][ "enemy" ] = loadfx( "light/fx_vlight_mp_escort_eye_red" );
/#
set_dvar_float_if_unset( "scr_lbguard_timeout", 60 );
#/
level.heliguardflyovernfz = 0;
if ( level.script == "mp_hydro" )
{
level.heliguardflyovernfz = 1;
}
}
register()
{
registerclientfield( "helicopter", "vehicle_is_firing", 1, 1, "int" );
}
tryuseheliguardsupport( lifeid )
{
if ( isDefined( level.civilianjetflyby ) )
{
self iprintlnbold( &"MP_CIVILIAN_AIR_TRAFFIC" );
return 0;
}
if ( self isremotecontrolling() )
{
return 0;
}
if ( !isDefined( level.heli_paths ) || level.heli_paths.size <= 0 )
{
self iprintlnbold( &"MP_UNAVAILABLE_IN_LEVEL" );
return 0;
}
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( "helicopter_guard_mp", self.team, 0, 1 );
if ( killstreak_id == -1 )
{
return 0;
}
heliguard = createheliguardsupport( lifeid, killstreak_id );
if ( !isDefined( heliguard ) )
{
return 0;
}
self thread startheliguardsupport( heliguard, lifeid );
return 1;
}
createheliguardsupport( lifeid, killstreak_id )
{
hardpointtype = "helicopter_guard_mp";
closeststartnode = heliguardsupport_getcloseststartnode( self.origin );
if ( isDefined( closeststartnode.angles ) )
{
startang = closeststartnode.angles;
}
else
{
startang = ( 0, 0, 1 );
}
closestnode = heliguardsupport_getclosestnode( self.origin );
flyheight = max( self.origin[ 2 ] + 1600, getnoflyzoneheight( self.origin ) );
forward = anglesToForward( self.angles );
targetpos = ( ( self.origin * ( 0, 0, 1 ) ) + ( ( 0, 0, 1 ) * flyheight ) ) + ( forward * -100 );
startpos = closeststartnode.origin;
heliguard = spawnhelicopter( self, startpos, startang, "heli_guard_mp", "veh_t6_drone_overwatch_light" );
if ( !isDefined( heliguard ) )
{
return;
}
target_set( heliguard, vectorScale( ( 0, 0, 1 ), 50 ) );
heliguard setenemymodel( "veh_t6_drone_overwatch_dark" );
heliguard.speed = 150;
heliguard.followspeed = 40;
heliguard setcandamage( 1 );
heliguard.owner = self;
heliguard.team = self.team;
heliguard setmaxpitchroll( 45, 45 );
heliguard setspeed( heliguard.speed, 100, 40 );
heliguard setyawspeed( 120, 60 );
heliguard setneargoalnotifydist( 512 );
heliguard thread heliguardsupport_attacktargets();
heliguard.killcount = 0;
heliguard.streakname = "littlebird_support";
heliguard.helitype = "littlebird";
heliguard.targettingradius = 2000;
heliguard.targetpos = targetpos;
heliguard.currentnode = closestnode;
heliguard.attract_strength = 10000;
heliguard.attract_range = 150;
heliguard.attractor = missile_createattractorent( heliguard, heliguard.attract_strength, heliguard.attract_range );
heliguard.health = 999999;
heliguard.maxhealth = level.heli_maxhealth;
heliguard.rocketdamageoneshot = heliguard.maxhealth + 1;
heliguard.crashtype = "explode";
heliguard.destroyfunc = ::lbexplode;
heliguard.targeting_delay = level.heli_targeting_delay;
heliguard.hasdodged = 0;
heliguard setdrawinfrared( 1 );
self thread maps/mp/killstreaks/_helicopter::announcehelicopterinbound( hardpointtype );
heliguard thread maps/mp/killstreaks/_helicopter::heli_targeting( 0, hardpointtype );
heliguard thread maps/mp/killstreaks/_helicopter::heli_damage_monitor( hardpointtype );
heliguard thread maps/mp/killstreaks/_helicopter::heli_kill_monitor( hardpointtype );
heliguard thread maps/mp/killstreaks/_helicopter::heli_health( hardpointtype, self, undefined );
heliguard maps/mp/gametypes/_spawning::create_helicopter_influencers( heliguard.team );
heliguard thread heliguardsupport_watchtimeout();
heliguard thread heliguardsupport_watchownerloss();
heliguard thread heliguardsupport_watchownerdamage();
heliguard thread heliguardsupport_watchroundend();
heliguard.numflares = 1;
heliguard.flareoffset = ( 0, 0, 1 );
heliguard thread maps/mp/_heatseekingmissile::missiletarget_proximitydetonateincomingmissile( "explode", "death" );
heliguard thread create_flare_ent( vectorScale( ( 0, 0, 1 ), 50 ) );
heliguard.killstreak_id = killstreak_id;
level.littlebirdguard = heliguard;
return heliguard;
}
getmeshheight( littlebird, owner )
{
if ( !owner isinsideheightlock() )
{
return maps/mp/killstreaks/_airsupport::getminimumflyheight();
}
maxmeshheight = littlebird getheliheightlockheight( owner.origin );
return max( maxmeshheight, owner.origin[ 2 ] );
}
startheliguardsupport( littlebird, lifeid )
{
level endon( "game_ended" );
littlebird endon( "death" );
littlebird setlookatent( self );
maxmeshheight = getmeshheight( littlebird, self );
height = getnoflyzoneheight( ( self.origin[ 0 ], self.origin[ 1 ], maxmeshheight ) );
playermeshorigin = ( self.origin[ 0 ], self.origin[ 1 ], height );
vectostart = vectornormalize( littlebird.origin - littlebird.targetpos );
dist = 1500;
target = littlebird.targetpos + ( vectostart * dist );
collide = crossesnoflyzone( target, playermeshorigin );
while ( isDefined( collide ) && dist > 0 )
{
dist -= 500;
target = littlebird.targetpos + ( vectostart * dist );
collide = crossesnoflyzone( target, playermeshorigin );
}
littlebird setvehgoalpos( target, 1 );
target_setturretaquire( littlebird, 0 );
littlebird waittill( "near_goal" );
target_setturretaquire( littlebird, 1 );
littlebird setvehgoalpos( playermeshorigin, 1 );
littlebird waittill( "near_goal" );
littlebird setspeed( littlebird.speed, 80, 30 );
littlebird waittill( "goal" );
/#
if ( getDvar( "scr_heli_guard_debug" ) == "1" )
{
debug_no_fly_zones();
#/
}
littlebird thread heliguardsupport_followplayer();
}
heliguardsupport_followplayer()
{
level endon( "game_ended" );
self endon( "death" );
self endon( "leaving" );
if ( !isDefined( self.owner ) )
{
self thread heliguardsupport_leave();
return;
}
self.owner endon( "disconnect" );
self.owner endon( "joined_team" );
self.owner endon( "joined_spectators" );
self setspeed( self.followspeed, 20, 20 );
while ( 1 )
{
if ( isDefined( self.owner ) && isalive( self.owner ) )
{
heliguardsupport_movetoplayer();
}
wait 3;
}
}
heliguardsupport_movetoplayer()
{
level endon( "game_ended" );
self endon( "death" );
self endon( "leaving" );
self.owner endon( "death" );
self.owner endon( "disconnect" );
self.owner endon( "joined_team" );
self.owner endon( "joined_spectators" );
self notify( "heliGuardSupport_moveToPlayer" );
self endon( "heliGuardSupport_moveToPlayer" );
maxmeshheight = getmeshheight( self, self.owner );
hovergoal = ( self.owner.origin[ 0 ], self.owner.origin[ 1 ], maxmeshheight );
/#
littlebird_debug_line( self.origin, hovergoal, ( 0, 0, 1 ) );
#/
zoneindex = crossesnoflyzone( self.origin, hovergoal );
if ( isDefined( zoneindex ) && level.heliguardflyovernfz )
{
self.intransit = 1;
noflyzoneheight = getnoflyzoneheightcrossed( hovergoal, self.origin, maxmeshheight );
self setvehgoalpos( ( hovergoal[ 0 ], hovergoal[ 1 ], noflyzoneheight ), 1 );
self waittill( "goal" );
return;
}
if ( isDefined( zoneindex ) )
{
/#
littlebird_debug_text( "NO FLY ZONE between heli and hoverGoal" );
#/
dist = distance2d( self.owner.origin, level.noflyzones[ zoneindex ].origin );
zoneorgtoplayer2d = self.owner.origin - level.noflyzones[ zoneindex ].origin;
zoneorgtoplayer2d *= ( 0, 0, 1 );
zoneorgtochopper2d = self.origin - level.noflyzones[ zoneindex ].origin;
zoneorgtochopper2d *= ( 0, 0, 1 );
zoneorgatmeshheight = ( level.noflyzones[ zoneindex ].origin[ 0 ], level.noflyzones[ zoneindex ].origin[ 1 ], maxmeshheight );
zoneorgtoadjpos = vectorScale( vectornormalize( zoneorgtoplayer2d ), level.noflyzones[ zoneindex ].radius + 150 );
adjacentgoalpos = zoneorgtoadjpos + level.noflyzones[ zoneindex ].origin;
adjacentgoalpos = ( adjacentgoalpos[ 0 ], adjacentgoalpos[ 1 ], maxmeshheight );
zoneorgtoperpendicular = ( zoneorgtoadjpos[ 1 ], zoneorgtoadjpos[ 0 ] * -1, 0 );
zoneorgtooppositeperpendicular = ( zoneorgtoadjpos[ 1 ] * -1, zoneorgtoadjpos[ 0 ], 0 );
perpendiculargoalpos = zoneorgtoperpendicular + zoneorgatmeshheight;
oppositeperpendiculargoalpos = zoneorgtooppositeperpendicular + zoneorgatmeshheight;
/#
littlebird_debug_line( self.origin, perpendiculargoalpos, ( 0, 0, 1 ) );
littlebird_debug_line( self.origin, oppositeperpendiculargoalpos, ( 0,2, 0,6, 1 ) );
#/
if ( dist < level.noflyzones[ zoneindex ].radius )
{
/#
littlebird_debug_text( "Owner is in a no fly zone, find perimeter hover goal" );
littlebird_debug_line( self.origin, adjacentgoalpos, ( 0, 0, 1 ) );
#/
zoneindex = undefined;
zoneindex = crossesnoflyzone( self.origin, adjacentgoalpos );
if ( isDefined( zoneindex ) )
{
/#
littlebird_debug_text( "adjacentGoalPos is through no fly zone, move to perpendicular edge of cyl" );
#/
hovergoal = perpendiculargoalpos;
}
else
{
/#
littlebird_debug_text( "adjacentGoalPos is NOT through fly zone, move to edge closest to player" );
#/
hovergoal = adjacentgoalpos;
}
}
else
{
/#
littlebird_debug_text( "Owner outside no fly zone, navigate around perimeter" );
littlebird_debug_line( self.origin, perpendiculargoalpos, ( 0, 0, 1 ) );
#/
hovergoal = perpendiculargoalpos;
}
}
zoneindex = undefined;
zoneindex = crossesnoflyzone( self.origin, hovergoal );
if ( isDefined( zoneindex ) )
{
/#
littlebird_debug_text( "Try opposite perimeter goal" );
#/
hovergoal = oppositeperpendiculargoalpos;
}
self.intransit = 1;
self setvehgoalpos( ( hovergoal[ 0 ], hovergoal[ 1 ], maxmeshheight ), 1 );
self waittill( "goal" );
}
heliguardsupport_movetoplayervertical( maxmeshheight )
{
height = getnoflyzoneheightcrossed( self.origin, self.owner.origin, maxmeshheight );
upperheight = max( self.origin[ 2 ], height );
acquireupperheight = ( self.origin[ 0 ], self.origin[ 1 ], upperheight );
hoveroverplayer = ( self.owner.origin[ 0 ], self.owner.origin[ 1 ], upperheight );
hovercorrectheight = ( self.owner.origin[ 0 ], self.owner.origin[ 1 ], height );
self.intransit = 1;
self setvehgoalpos( acquireupperheight, 1 );
self waittill( "goal" );
self setvehgoalpos( hoveroverplayer, 1 );
self waittill( "goal" );
self setvehgoalpos( hovercorrectheight, 1 );
self waittill( "goal" );
self.intransit = 0;
}
heliguardsupport_watchtimeout()
{
level endon( "game_ended" );
self endon( "death" );
self.owner endon( "disconnect" );
self.owner endon( "joined_team" );
self.owner endon( "joined_spectators" );
timeout = 60;
/#
timeout = getDvarFloat( #"E449EBB3" );
#/
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpause( timeout );
shouldtimeout = getDvar( "scr_heli_guard_no_timeout" );
if ( shouldtimeout == "1" )
{
return;
}
self thread heliguardsupport_leave();
}
heliguardsupport_watchownerloss()
{
level endon( "game_ended" );
self endon( "death" );
self endon( "leaving" );
self.owner waittill_any( "disconnect", "joined_team", "joined_spectators" );
self thread heliguardsupport_leave();
}
heliguardsupport_watchownerdamage()
{
level endon( "game_ended" );
self endon( "death" );
self endon( "leaving" );
self.owner endon( "disconnect" );
self.owner endon( "joined_team" );
self.owner endon( "joined_spectators" );
while ( 1 )
{
self.owner waittill( "damage", damage, attacker, direction_vec, point, meansofdeath, modelname, tagname, partname, weapon, idflags );
if ( isplayer( attacker ) )
{
if ( attacker != self.owner && distance2d( attacker.origin, self.origin ) <= self.targettingradius && attacker cantargetplayerwithspecialty() )
{
self setlookatent( attacker );
self setgunnertargetent( attacker, vectorScale( ( 0, 0, 1 ), 50 ), 0 );
self setturrettargetent( attacker, vectorScale( ( 0, 0, 1 ), 50 ) );
}
}
}
}
heliguardsupport_watchroundend()
{
level endon( "game_ended" );
self endon( "death" );
self endon( "leaving" );
self.owner endon( "disconnect" );
self.owner endon( "joined_team" );
self.owner endon( "joined_spectators" );
level waittill( "round_end_finished" );
self thread heliguardsupport_leave();
}
heliguardsupport_leave()
{
self endon( "death" );
self notify( "leaving" );
level.littlebirdguard = undefined;
self cleargunnertarget( 0 );
self clearturrettarget();
self clearlookatent();
flyheight = getnoflyzoneheight( self.origin );
targetpos = self.origin + ( anglesToForward( self.angles ) * 1500 ) + ( 0, 0, flyheight );
collide = crossesnoflyzone( self.origin, targetpos );
tries = 5;
while ( isDefined( collide ) && tries > 0 )
{
yaw = randomint( 360 );
targetpos = self.origin + ( anglesToForward( ( self.angles[ 0 ], yaw, self.angles[ 2 ] ) ) * 1500 ) + ( 0, 0, flyheight );
collide = crossesnoflyzone( self.origin, targetpos );
tries--;
}
if ( tries == 0 )
{
targetpos = self.origin + ( 0, 0, flyheight );
}
self setspeed( self.speed, 80 );
self setmaxpitchroll( 45, 180 );
self setvehgoalpos( targetpos );
self waittill( "goal" );
targetpos += anglesToForward( ( 0, self.angles[ 1 ], self.angles[ 2 ] ) ) * 14000;
self setvehgoalpos( targetpos );
self waittill( "goal" );
self notify( "gone" );
self removelittlebird();
}
helidestroyed()
{
level.littlebirdguard = undefined;
if ( !isDefined( self ) )
{
return;
}
self setspeed( 25, 5 );
self thread lbspin( randomintrange( 180, 220 ) );
wait randomfloatrange( 0,5, 1,5 );
lbexplode();
}
lbexplode()
{
self notify( "explode" );
self removelittlebird();
}
lbspin( speed )
{
self endon( "explode" );
playfxontag( level.chopper_fx[ "explode" ][ "large" ], self, "tail_rotor_jnt" );
self thread trail_fx( level.chopper_fx[ "smoke" ][ "trail" ], "tail_rotor_jnt", "stop tail smoke" );
self setyawspeed( speed, speed, speed );
while ( isDefined( self ) )
{
self settargetyaw( self.angles[ 1 ] + ( speed * 0,9 ) );
wait 1;
}
}
trail_fx( trail_fx, trail_tag, stop_notify )
{
self notify( stop_notify );
self endon( stop_notify );
self endon( "death" );
for ( ;; )
{
playfxontag( trail_fx, self, trail_tag );
wait 0,05;
}
}
removelittlebird()
{
level.lbstrike = 0;
maps/mp/killstreaks/_killstreakrules::killstreakstop( "helicopter_guard_mp", self.team, self.killstreak_id );
if ( isDefined( self.marker ) )
{
self.marker delete();
}
self delete();
}
heliguardsupport_watchsamproximity( player, missileteam, missiletarget, missilegroup )
{
level endon( "game_ended" );
missiletarget endon( "death" );
i = 0;
while ( i < missilegroup.size )
{
if ( isDefined( missilegroup[ i ] ) && !missiletarget.hasdodged )
{
missiletarget.hasdodged = 1;
newtarget = spawn( "script_origin", missiletarget.origin );
newtarget.angles = missiletarget.angles;
newtarget movegravity( anglesToRight( missilegroup[ i ].angles ) * -1000, 0,05 );
j = 0;
while ( j < missilegroup.size )
{
if ( isDefined( missilegroup[ j ] ) )
{
missilegroup[ j ] settargetentity( newtarget );
}
j++;
}
dodgepoint = missiletarget.origin + ( anglesToRight( missilegroup[ i ].angles ) * 200 );
missiletarget setspeed( missiletarget.speed, 100, 40 );
missiletarget setvehgoalpos( dodgepoint, 1 );
wait 2;
missiletarget setspeed( missiletarget.followspeed, 20, 20 );
return;
}
else
{
i++;
}
}
}
heliguardsupport_getcloseststartnode( pos )
{
closestnode = undefined;
closestdistance = 999999;
_a645 = level.heli_paths;
_k645 = getFirstArrayKey( _a645 );
while ( isDefined( _k645 ) )
{
path = _a645[ _k645 ];
_a647 = path;
_k647 = getFirstArrayKey( _a647 );
while ( isDefined( _k647 ) )
{
loc = _a647[ _k647 ];
nodedistance = distance( loc.origin, pos );
if ( nodedistance < closestdistance )
{
closestnode = loc;
closestdistance = nodedistance;
}
_k647 = getNextArrayKey( _a647, _k647 );
}
_k645 = getNextArrayKey( _a645, _k645 );
}
return closestnode;
}
heliguardsupport_getclosestnode( pos )
{
closestnode = undefined;
closestdistance = 999999;
_a667 = level.heli_loop_paths;
_k667 = getFirstArrayKey( _a667 );
while ( isDefined( _k667 ) )
{
loc = _a667[ _k667 ];
nodedistance = distance( loc.origin, pos );
if ( nodedistance < closestdistance )
{
closestnode = loc;
closestdistance = nodedistance;
}
_k667 = getNextArrayKey( _a667, _k667 );
}
return closestnode;
}
littlebird_debug_text( string )
{
/#
if ( getDvar( "scr_heli_guard_debug" ) == "1" )
{
iprintln( string );
#/
}
}
littlebird_debug_line( start, end, color )
{
/#
if ( getDvar( "scr_heli_guard_debug" ) == "1" )
{
line( start, end, color, 1, 1, 300 );
#/
}
}
heli_path_debug()
{
/#
_a703 = level.heli_paths;
_k703 = getFirstArrayKey( _a703 );
while ( isDefined( _k703 ) )
{
path = _a703[ _k703 ];
_a705 = path;
_k705 = getFirstArrayKey( _a705 );
while ( isDefined( _k705 ) )
{
loc = _a705[ _k705 ];
prev = loc;
target = loc.target;
while ( isDefined( target ) )
{
target = getent( target, "targetname" );
line( prev.origin, target.origin, ( 0, 0, 1 ), 1, 0, 50000 );
debugstar( prev.origin, 50000, ( 0, 0, 1 ) );
prev = target;
target = prev.target;
}
_k705 = getNextArrayKey( _a705, _k705 );
}
_k703 = getNextArrayKey( _a703, _k703 );
}
_a722 = level.heli_loop_paths;
_k722 = getFirstArrayKey( _a722 );
while ( isDefined( _k722 ) )
{
loc = _a722[ _k722 ];
prev = loc;
target = loc.target;
first = loc;
while ( isDefined( target ) )
{
target = getent( target, "targetname" );
line( prev.origin, target.origin, ( 0, 0, 1 ), 1, 0, 50000 );
debugstar( prev.origin, 50000, ( 0, 0, 1 ) );
prev = target;
target = prev.target;
if ( prev == first )
{
break;
}
else
{
}
}
_k722 = getNextArrayKey( _a722, _k722 );
#/
}
}
heliguardsupport_getclosestlinkednode( pos )
{
closestnode = undefined;
totaldistance = distance2d( self.currentnode.origin, pos );
closestdistance = totaldistance;
target = self.currentnode.target;
while ( isDefined( target ) )
{
nextnode = getent( target, "targetname" );
if ( nextnode == self.currentnode )
{
break;
}
else
{
nodedistance = distance2d( nextnode.origin, pos );
if ( nodedistance < totaldistance && nodedistance < closestdistance )
{
closestnode = nextnode;
closestdistance = nodedistance;
}
target = nextnode.target;
}
}
return closestnode;
}
heliguardsupport_arraycontains( array, compare )
{
if ( array.size <= 0 )
{
return 0;
}
_a783 = array;
_k783 = getFirstArrayKey( _a783 );
while ( isDefined( _k783 ) )
{
member = _a783[ _k783 ];
if ( member == compare )
{
return 1;
}
_k783 = getNextArrayKey( _a783, _k783 );
}
return 0;
}
heliguardsupport_getlinkedstructs()
{
array = [];
return array;
}
heliguardsupport_setairstartnodes()
{
level.air_start_nodes = getstructarray( "chopper_boss_path_start", "targetname" );
_a817 = level.air_start_nodes;
_k817 = getFirstArrayKey( _a817 );
while ( isDefined( _k817 ) )
{
loc = _a817[ _k817 ];
loc.neighbors = loc heliguardsupport_getlinkedstructs();
_k817 = getNextArrayKey( _a817, _k817 );
}
}
heliguardsupport_setairnodemesh()
{
level.air_node_mesh = getstructarray( "so_chopper_boss_path_struct", "script_noteworthy" );
_a828 = level.air_node_mesh;
_k828 = getFirstArrayKey( _a828 );
while ( isDefined( _k828 ) )
{
loc = _a828[ _k828 ];
loc.neighbors = loc heliguardsupport_getlinkedstructs();
_a835 = level.air_node_mesh;
_k835 = getFirstArrayKey( _a835 );
while ( isDefined( _k835 ) )
{
other_loc = _a835[ _k835 ];
if ( loc == other_loc )
{
}
else
{
if ( !heliguardsupport_arraycontains( loc.neighbors, other_loc ) && heliguardsupport_arraycontains( other_loc heliguardsupport_getlinkedstructs(), loc ) )
{
loc.neighbors[ loc.neighbors.size ] = other_loc;
}
}
_k835 = getNextArrayKey( _a835, _k835 );
}
_k828 = getNextArrayKey( _a828, _k828 );
}
}
heliguardsupport_attacktargets()
{
self endon( "death" );
level endon( "game_ended" );
self endon( "leaving" );
for ( ;; )
{
self heliguardsupport_firestart();
}
}
heliguardsupport_firestart()
{
self endon( "death" );
self endon( "leaving" );
self endon( "stop_shooting" );
level endon( "game_ended" );
for ( ;; )
{
numshots = randomintrange( 10, 21 );
if ( !isDefined( self.primarytarget ) )
{
self waittill( "primary acquired" );
}
while ( isDefined( self.primarytarget ) )
{
targetent = self.primarytarget;
self thread heliguardsupport_firestop( targetent );
self setlookatent( targetent );
self setgunnertargetent( targetent, vectorScale( ( 0, 0, 1 ), 50 ), 0 );
self setturrettargetent( targetent, vectorScale( ( 0, 0, 1 ), 50 ) );
self waittill( "turret_on_target" );
wait 0,2;
self setclientfield( "vehicle_is_firing", 1 );
i = 0;
while ( i < numshots )
{
self firegunnerweapon( 0, self );
self fireweapon();
wait 0,15;
i++;
}
}
self setclientfield( "vehicle_is_firing", 0 );
self clearturrettarget();
self cleargunnertarget( 0 );
wait randomfloatrange( 1, 2 );
}
}
heliguardsupport_firestop( targetent )
{
self endon( "death" );
self endon( "leaving" );
self notify( "heli_guard_target_death_watcher" );
self endon( "heli_guard_target_death_watcher" );
targetent waittill_any( "death", "disconnect" );
self setclientfield( "vehicle_is_firing", 0 );
self notify( "stop_shooting" );
self.primarytarget = undefined;
self setlookatent( self.owner );
self cleargunnertarget( 0 );
self clearturrettarget();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,633 @@
#include maps/mp/gametypes/_class;
#include maps/mp/_popups;
#include maps/mp/gametypes/_weapons;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_supplydrop;
#include maps/mp/gametypes/_globallogic_utils;
#include maps/mp/killstreaks/_killstreaks;
#include maps/mp/gametypes/_hud_util;
#include maps/mp/_utility;
#include common_scripts/utility;
init()
{
precacheshader( "hud_ks_minigun" );
precacheshader( "hud_ks_m32" );
maps/mp/killstreaks/_killstreaks::registerkillstreak( "inventory_minigun_mp", "inventory_minigun_mp", "killstreak_minigun", "minigun_used", ::usecarriedkillstreakweapon, 0, 1, "MINIGUN_USED" );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "inventory_minigun_mp", &"KILLSTREAK_EARNED_MINIGUN", &"KILLSTREAK_MINIGUN_NOT_AVAILABLE", &"KILLSTREAK_MINIGUN_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "inventory_minigun_mp", "mpl_killstreak_minigun", "kls_death_used", "", "kls_death_enemy", "", "kls_death_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "inventory_minigun_mp", "scr_giveminigun_drop" );
maps/mp/killstreaks/_killstreaks::registerkillstreak( "minigun_mp", "minigun_mp", "killstreak_minigun", "minigun_used", ::usecarriedkillstreakweapon, 0, 1, "MINIGUN_USED" );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "minigun_mp", &"KILLSTREAK_EARNED_MINIGUN", &"KILLSTREAK_MINIGUN_NOT_AVAILABLE", &"KILLSTREAK_MINIGUN_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "minigun_mp", "mpl_killstreak_minigun", "kls_death_used", "", "kls_death_enemy", "", "kls_death_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreak( "inventory_m32_mp", "inventory_m32_mp", "killstreak_m32", "m32_used", ::usecarriedkillstreakweapon, 0, 1, "M32_USED" );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "inventory_m32_mp", &"KILLSTREAK_EARNED_M32", &"KILLSTREAK_M32_NOT_AVAILABLE", &"KILLSTREAK_M32_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "inventory_m32_mp", "mpl_killstreak_m32", "kls_mgl_used", "", "kls_mgl_enemy", "", "kls_mgl_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "inventory_m32_mp", "scr_givem32_drop" );
maps/mp/killstreaks/_killstreaks::overrideentitycameraindemo( "inventory_m32_mp", 1 );
maps/mp/killstreaks/_killstreaks::registerkillstreak( "m32_mp", "m32_mp", "killstreak_m32", "m32_used", ::usecarriedkillstreakweapon, 0, 1, "M32_USED" );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "m32_mp", &"KILLSTREAK_EARNED_M32", &"KILLSTREAK_M32_NOT_AVAILABLE", &"KILLSTREAK_M32_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "m32_mp", "mpl_killstreak_m32", "kls_mgl_used", "", "kls_mgl_enemy", "", "kls_mgl_ready" );
maps/mp/killstreaks/_killstreaks::overrideentitycameraindemo( "m32_mp", 1 );
level.killstreakicons[ "killstreak_minigun" ] = "hud_ks_minigun";
level.killstreakicons[ "killstreak_m32" ] = "hud_ks_m32";
level.killstreakicons[ "killstreak_m202_flash_mp" ] = "hud_ks_m202";
level.killstreakicons[ "killstreak_m220_tow_drop_mp" ] = "hud_ks_tv_guided_marker";
level.killstreakicons[ "killstreak_m220_tow_mp" ] = "hud_ks_tv_guided_missile";
level thread onplayerconnect();
setdvar( "scr_HeldKillstreak_Penalty", 0 );
}
onplayerconnect()
{
for ( ;; )
{
level waittill( "connecting", player );
player thread onplayerspawned();
}
}
onplayerspawned()
{
self endon( "disconnect" );
for ( ;; )
{
self waittill( "spawned_player" );
self.firedkillstreakweapon = 0;
self.usingkillstreakheldweapon = undefined;
if ( !isfirstround() && !isoneround() )
{
if ( level.roundstartkillstreakdelay > ( maps/mp/gametypes/_globallogic_utils::gettimepassed() / 1000 ) )
{
self thread watchkillstreakweapondelay();
}
}
}
}
watchkillstreakweapondelay()
{
self endon( "disconnect" );
self endon( "death" );
while ( 1 )
{
currentweapon = self getcurrentweapon();
self waittill( "weapon_change", newweapon );
if ( level.roundstartkillstreakdelay < ( maps/mp/gametypes/_globallogic_utils::gettimepassed() / 1000 ) )
{
return;
}
while ( !maps/mp/killstreaks/_killstreaks::iskillstreakweapon( newweapon ) )
{
wait 0,5;
}
if ( maps/mp/killstreaks/_killstreaks::isdelayablekillstreak( newweapon ) && isheldkillstreakweapon( newweapon ) )
{
timeleft = int( level.roundstartkillstreakdelay - ( maps/mp/gametypes/_globallogic_utils::gettimepassed() / 1000 ) );
if ( !timeleft )
{
timeleft = 1;
}
self iprintlnbold( &"MP_UNAVAILABLE_FOR_N", " " + timeleft + " ", &"EXE_SECONDS" );
self switchtoweapon( currentweapon );
wait 0,5;
}
}
}
usekillstreakweapondrop( hardpointtype )
{
if ( self maps/mp/killstreaks/_supplydrop::issupplydropgrenadeallowed( hardpointtype ) == 0 )
{
return 0;
}
result = self maps/mp/killstreaks/_supplydrop::usesupplydropmarker();
self notify( "supply_drop_marker_done" );
if ( !isDefined( result ) || !result )
{
return 0;
}
return result;
}
usecarriedkillstreakweapon( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
self switchtoweapon( self.lastdroppableweapon );
return 0;
}
if ( !isDefined( hardpointtype ) )
{
return 0;
}
currentweapon = self getcurrentweapon();
if ( hardpointtype == "none" )
{
return 0;
}
level maps/mp/gametypes/_weapons::addlimitedweapon( hardpointtype, self, 3 );
if ( issubstr( hardpointtype, "inventory" ) )
{
isfrominventory = 1;
}
else
{
isfrominventory = 0;
}
currentammo = self getammocount( hardpointtype );
if ( hardpointtype != "minigun_mp" && hardpointtype == "inventory_minigun_mp" && isDefined( self.minigunstart ) || self.minigunstart == 0 && hardpointtype != "m32_mp" && hardpointtype == "inventory_m32_mp" || !isDefined( self.m32start ) && self.m32start == 0 )
{
if ( hardpointtype == "minigun_mp" || hardpointtype == "inventory_minigun_mp" )
{
self.minigunstart = 1;
}
else
{
self.m32start = 1;
}
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( hardpointtype, self.team, 1 );
level.globalkillstreakscalled++;
self addweaponstat( hardpointtype, "used", 1 );
level thread maps/mp/_popups::displayteammessagetoall( level.killstreaks[ hardpointtype ].inboundtext, self );
if ( weaponclipsize( hardpointtype ) > currentammo )
{
}
else
{
}
self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] = weaponclipsize( hardpointtype );
if ( isfrominventory == 0 )
{
if ( self.pers[ "killstreak_quantity" ][ hardpointtype ] > 0 )
{
ammopool = weaponmaxammo( hardpointtype );
}
else
{
ammopool = self.pers[ "held_killstreak_ammo_count" ][ hardpointtype ];
}
self setweaponammoclip( hardpointtype, self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] );
self setweaponammostock( hardpointtype, ammopool - self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] );
}
}
if ( hardpointtype == "minigun_mp" || hardpointtype == "inventory_minigun_mp" )
{
if ( !isDefined( self.minigunactive ) || !self.minigunactive )
{
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team, 0, 0 );
if ( hardpointtype == "inventory_minigun_mp" )
{
killstreak_id = self.pers[ "killstreak_unique_id" ][ self.pers[ "killstreak_unique_id" ].size - 1 ];
}
self.minigunid = killstreak_id;
self.minigunactive = 1;
}
else
{
killstreak_id = self.minigunid;
}
}
else
{
if ( !isDefined( self.m32active ) || !self.m32active )
{
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team, 0, 0 );
if ( hardpointtype == "inventory_m32_mp" )
{
killstreak_id = self.pers[ "killstreak_unique_id" ][ self.pers[ "killstreak_unique_id" ].size - 1 ];
}
self.m32id = killstreak_id;
self.m32active = 1;
}
else
{
killstreak_id = self.m32id;
}
}
/#
assert( killstreak_id != -1 );
#/
self.firedkillstreakweapon = 0;
self setblockweaponpickup( hardpointtype, 1 );
if ( isfrominventory )
{
self setweaponammoclip( hardpointtype, self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] );
self setweaponammostock( hardpointtype, self.pers[ "killstreak_ammo_count" ][ self.pers[ "killstreak_ammo_count" ].size - 1 ] - self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] );
}
notifystring = "killstreakWeapon_" + hardpointtype;
self notify( notifystring );
self thread watchkillstreakweaponswitch( hardpointtype, killstreak_id, isfrominventory );
self thread watchkillstreakweapondeath( hardpointtype, killstreak_id, isfrominventory );
self thread watchkillstreakroundchange( isfrominventory, killstreak_id );
self thread watchplayerdeath( hardpointtype );
if ( isfrominventory )
{
self thread watchkillstreakremoval( hardpointtype, killstreak_id );
}
self.usingkillstreakheldweapon = 1;
return 0;
}
usekillstreakweaponfromcrate( hardpointtype )
{
if ( !isDefined( hardpointtype ) )
{
return 0;
}
if ( hardpointtype == "none" )
{
return 0;
}
self.firedkillstreakweapon = 0;
self setblockweaponpickup( hardpointtype, 1 );
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team, 0, 0 );
/#
assert( killstreak_id != -1 );
#/
if ( issubstr( hardpointtype, "inventory" ) )
{
isfrominventory = 1;
}
else
{
isfrominventory = 0;
}
self thread watchkillstreakweaponswitch( hardpointtype, killstreak_id, isfrominventory );
self thread watchkillstreakweapondeath( hardpointtype, killstreak_id, isfrominventory );
if ( isfrominventory )
{
self thread watchkillstreakremoval( hardpointtype, killstreak_id );
}
self.usingkillstreakheldweapon = 1;
return 1;
}
watchkillstreakweaponswitch( killstreakweapon, killstreak_id, isfrominventory )
{
self endon( "disconnect" );
self endon( "death" );
while ( 1 )
{
currentweapon = self getcurrentweapon();
self waittill( "weapon_change", newweapon );
while ( level.infinalkillcam )
{
continue;
}
while ( newweapon == "none" )
{
continue;
}
currentammo = self getammocount( killstreakweapon );
currentammoinclip = self getweaponammoclip( killstreakweapon );
if ( isfrominventory && currentammo > 0 )
{
killstreakindex = self maps/mp/killstreaks/_killstreaks::getkillstreakindexbyid( killstreak_id );
if ( isDefined( killstreakindex ) )
{
self.pers[ "killstreak_ammo_count" ][ killstreakindex ] = currentammo;
self.pers[ "held_killstreak_clip_count" ][ killstreakweapon ] = currentammoinclip;
}
}
if ( maps/mp/killstreaks/_killstreaks::iskillstreakweapon( newweapon ) && !isheldkillstreakweapon( newweapon ) )
{
continue;
}
while ( isgameplayweapon( newweapon ) )
{
continue;
}
if ( isheldkillstreakweapon( newweapon ) && newweapon == self.lastnonkillstreakweapon )
{
continue;
}
killstreakid = maps/mp/killstreaks/_killstreaks::gettopkillstreakuniqueid();
self.pers[ "held_killstreak_ammo_count" ][ killstreakweapon ] = currentammo;
self.pers[ "held_killstreak_clip_count" ][ killstreakweapon ] = currentammoinclip;
if ( killstreak_id != -1 )
{
self notify( "killstreak_weapon_switch" );
}
self.firedkillstreakweapon = 0;
self.usingkillstreakheldweapon = undefined;
waittillframeend;
if ( currentammo != 0 || self.pers[ "killstreak_quantity" ][ killstreakweapon ] > 0 && isfrominventory && isDefined( killstreakid ) && killstreakid != killstreak_id )
{
maps/mp/killstreaks/_killstreakrules::killstreakstop( killstreakweapon, self.team, killstreak_id );
if ( killstreakweapon == "minigun_mp" || killstreakweapon == "inventory_minigun_mp" )
{
self.minigunstart = 0;
self.minigunactive = 0;
}
else
{
self.m32start = 0;
self.m32active = 0;
}
if ( self.pers[ "killstreak_quantity" ][ killstreakweapon ] > 0 )
{
self.pers[ "held_killstreak_ammo_count" ][ killstreakweapon ] = weaponmaxammo( killstreakweapon );
self maps/mp/gametypes/_class::setweaponammooverall( killstreakweapon, self.pers[ "held_killstreak_ammo_count" ][ killstreakweapon ] );
self.pers[ "killstreak_quantity" ][ killstreakweapon ]--;
}
}
if ( isfrominventory && currentammo == 0 )
{
self takeweapon( killstreakweapon );
self maps/mp/killstreaks/_killstreaks::removeusedkillstreak( killstreakweapon, killstreak_id );
self maps/mp/killstreaks/_killstreaks::activatenextkillstreak();
}
return;
}
}
watchkillstreakweapondeath( hardpointtype, killstreak_id, isfrominventory )
{
self endon( "disconnect" );
self endon( "killstreak_weapon_switch" );
if ( killstreak_id == -1 )
{
return;
}
oldteam = self.team;
self waittill( "death" );
penalty = getdvarfloatdefault( "scr_HeldKillstreak_Penalty", 0,5 );
maxammo = weaponmaxammo( hardpointtype );
currentammo = self getammocount( hardpointtype );
currentammoinclip = self getweaponammoclip( hardpointtype );
if ( self.pers[ "killstreak_quantity" ].size == 0 )
{
currentammo = 0;
currentammoinclip = 0;
}
maxclipsize = weaponclipsize( hardpointtype );
newammo = int( currentammo - ( maxammo * penalty ) );
killstreakid = maps/mp/killstreaks/_killstreaks::gettopkillstreakuniqueid();
if ( self.lastnonkillstreakweapon == hardpointtype )
{
if ( newammo < 0 )
{
self.pers[ "held_killstreak_ammo_count" ][ hardpointtype ] = 0;
self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] = 0;
}
else
{
self.pers[ "held_killstreak_ammo_count" ][ hardpointtype ] = newammo;
if ( maxclipsize <= newammo )
{
}
else
{
}
self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] = newammo;
}
}
self.usingkillstreakheldweapon = 0;
if ( newammo <= 0 || self.pers[ "killstreak_quantity" ][ hardpointtype ] > 0 && isfrominventory && isDefined( killstreakid ) && killstreakid != killstreak_id )
{
maps/mp/killstreaks/_killstreakrules::killstreakstop( hardpointtype, oldteam, killstreak_id );
if ( hardpointtype == "minigun_mp" || hardpointtype == "inventory_minigun_mp" )
{
self.minigunstart = 0;
self.minigunactive = 0;
}
else
{
self.m32start = 0;
self.m32active = 0;
}
if ( isDefined( self.pers[ "killstreak_quantity" ][ hardpointtype ] ) && self.pers[ "killstreak_quantity" ][ hardpointtype ] > 0 )
{
self.pers[ "held_killstreak_ammo_count" ][ hardpointtype ] = maxammo;
self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] = maxclipsize;
self setweaponammoclip( hardpointtype, self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] );
self setweaponammostock( hardpointtype, self.pers[ "held_killstreak_ammo_count" ][ hardpointtype ] - self.pers[ "held_killstreak_clip_count" ][ hardpointtype ] );
self.pers[ "killstreak_quantity" ][ hardpointtype ]--;
}
}
if ( isfrominventory && newammo <= 0 )
{
self takeweapon( hardpointtype );
self maps/mp/killstreaks/_killstreaks::removeusedkillstreak( hardpointtype, killstreak_id );
self maps/mp/killstreaks/_killstreaks::activatenextkillstreak();
}
else
{
if ( isfrominventory )
{
killstreakindex = self maps/mp/killstreaks/_killstreaks::getkillstreakindexbyid( killstreak_id );
if ( isDefined( killstreakindex ) )
{
self.pers[ "killstreak_ammo_count" ][ killstreakindex ] = self.pers[ "held_killstreak_ammo_count" ][ hardpointtype ];
}
}
}
return;
}
watchplayerdeath( killstreakweapon )
{
self endon( "disconnect" );
endonweaponstring = "killstreakWeapon_" + killstreakweapon;
self endon( endonweaponstring );
self waittill( "death" );
currentammo = self getammocount( killstreakweapon );
if ( weaponclipsize( killstreakweapon ) <= currentammo )
{
}
else
{
}
self.pers[ "held_killstreak_clip_count" ][ killstreakweapon ] = currentammo;
}
watchkillstreakremoval( killstreakweapon, killstreak_id )
{
self endon( "disconnect" );
self endon( "death" );
self endon( "killstreak_weapon_switch" );
self waittill( "oldest_killstreak_removed", removedkillstreakweapon, removed_id );
if ( killstreakweapon == removedkillstreakweapon && killstreak_id == removed_id )
{
if ( removedkillstreakweapon == "inventory_minigun_mp" )
{
self.minigunstart = 0;
self.minigunactive = 0;
return;
}
else
{
self.m32start = 0;
self.m32active = 0;
}
}
}
watchkillstreakroundchange( isfrominventory, killstreak_id )
{
self endon( "disconnect" );
self endon( "death" );
self endon( "killstreak_weapon_switch" );
self waittill( "round_ended" );
currentweapon = self getcurrentweapon();
if ( !isheldkillstreakweapon( currentweapon ) )
{
return;
}
currentammo = self getammocount( currentweapon );
maxclipsize = weaponclipsize( currentweapon );
if ( isfrominventory && currentammo > 0 )
{
killstreakindex = self maps/mp/killstreaks/_killstreaks::getkillstreakindexbyid( killstreak_id );
if ( isDefined( killstreakindex ) )
{
self.pers[ "killstreak_ammo_count" ][ killstreakindex ] = currentammo;
if ( maxclipsize <= currentammo )
{
}
else
{
}
self.pers[ "held_killstreak_clip_count" ][ currentweapon ] = currentammo;
}
}
else
{
self.pers[ "held_killstreak_ammo_count" ][ currentweapon ] = currentammo;
if ( maxclipsize <= currentammo )
{
}
else
{
}
self.pers[ "held_killstreak_clip_count" ][ currentweapon ] = currentammo;
}
}
checkifswitchableweapon( currentweapon, newweapon, killstreakweapon, currentkillstreakid )
{
switchableweapon = 1;
topkillstreak = maps/mp/killstreaks/_killstreaks::gettopkillstreak();
killstreakid = maps/mp/killstreaks/_killstreaks::gettopkillstreakuniqueid();
if ( !isDefined( killstreakid ) )
{
killstreakid = -1;
}
if ( self hasweapon( killstreakweapon ) && !self getammocount( killstreakweapon ) )
{
switchableweapon = 1;
}
else
{
if ( self.firedkillstreakweapon && newweapon == killstreakweapon && isheldkillstreakweapon( currentweapon ) )
{
switchableweapon = 1;
}
else
{
if ( isweaponequipment( newweapon ) )
{
switchableweapon = 1;
}
else if ( isDefined( level.grenade_array[ newweapon ] ) )
{
switchableweapon = 0;
}
else if ( isheldkillstreakweapon( newweapon ) && isheldkillstreakweapon( currentweapon ) || !isDefined( currentkillstreakid ) && currentkillstreakid != killstreakid )
{
switchableweapon = 1;
}
else
{
if ( maps/mp/killstreaks/_killstreaks::iskillstreakweapon( newweapon ) )
{
switchableweapon = 0;
}
else if ( isgameplayweapon( newweapon ) )
{
switchableweapon = 0;
}
else if ( self.firedkillstreakweapon )
{
switchableweapon = 1;
}
else if ( self.lastnonkillstreakweapon == killstreakweapon )
{
switchableweapon = 0;
}
else
{
if ( isDefined( topkillstreak ) && topkillstreak == killstreakweapon && currentkillstreakid == killstreakid )
{
switchableweapon = 0;
}
}
}
}
}
return switchableweapon;
}
watchkillstreakweaponusage()
{
self endon( "disconnect" );
self endon( "death" );
while ( 1 )
{
self waittill( "weapon_fired", killstreakweapon );
while ( !isheldkillstreakweapon( killstreakweapon ) )
{
wait 0,1;
}
while ( self.firedkillstreakweapon )
{
continue;
}
maps/mp/killstreaks/_killstreaks::removeusedkillstreak( killstreakweapon );
self.firedkillstreakweapon = 1;
self setactionslot( 4, "" );
waittillframeend;
maps/mp/killstreaks/_killstreaks::activatenextkillstreak();
}
}
isheldkillstreakweapon( killstreaktype )
{
switch( killstreaktype )
{
case "inventory_m32_mp":
case "inventory_minigun_mp":
case "m32_mp":
case "minigun_mp":
return 1;
}
return 0;
}
isheldinventorykillstreakweapon( killstreaktype )
{
switch( killstreaktype )
{
case "inventory_m32_mp":
case "inventory_minigun_mp":
return 1;
}
return 0;
}
isgameplayweapon( weapon )
{
switch( weapon )
{
case "briefcase_bomb_defuse_mp":
case "briefcase_bomb_mp":
case "syrette_mp":
return 1;
default:
return 0;
}
return 0;
}

View File

@ -0,0 +1,415 @@
#include maps/mp/killstreaks/_emp;
#include maps/mp/_popups;
#include common_scripts/utility;
#include maps/mp/gametypes/_hud_util;
#include maps/mp/_utility;
init()
{
level.killstreakrules = [];
level.killstreaktype = [];
level.killstreaks_triggered = [];
level.killstreak_counter = 0;
createrule( "vehicle", 7, 7 );
createrule( "firesupport", 1, 1 );
createrule( "airsupport", 1, 1 );
createrule( "playercontrolledchopper", 1, 1 );
createrule( "chopperInTheAir", 1, 1 );
createrule( "chopper", 2, 1 );
createrule( "qrdrone", 3, 2 );
createrule( "dogs", 1, 1 );
createrule( "turret", 8, 4 );
createrule( "weapon", 12, 6 );
createrule( "satellite", 20, 10 );
createrule( "supplydrop", 4, 4 );
createrule( "rcxd", 3, 2 );
createrule( "targetableent", 32, 32 );
createrule( "missileswarm", 1, 1 );
createrule( "radar", 20, 10 );
createrule( "counteruav", 20, 10 );
createrule( "emp", 2, 1 );
createrule( "ai_tank", 4, 2 );
createrule( "straferun", 1, 1 );
createrule( "planemortar", 1, 1 );
createrule( "remotemortar", 1, 1 );
createrule( "missiledrone", 3, 3 );
addkillstreaktorule( "helicopter_mp", "vehicle", 1, 1 );
addkillstreaktorule( "helicopter_mp", "chopper", 1, 1 );
addkillstreaktorule( "helicopter_mp", "playercontrolledchopper", 0, 1 );
addkillstreaktorule( "helicopter_mp", "chopperInTheAir", 1, 0 );
addkillstreaktorule( "helicopter_mp", "targetableent", 1, 1 );
addkillstreaktorule( "helicopter_x2_mp", "vehicle", 1, 1 );
addkillstreaktorule( "helicopter_x2_mp", "chopper", 1, 1 );
addkillstreaktorule( "helicopter_x2_mp", "playercontrolledchopper", 0, 1 );
addkillstreaktorule( "helicopter_x2_mp", "chopperInTheAir", 1, 0 );
addkillstreaktorule( "helicopter_x2_mp", "targetableent", 1, 1 );
addkillstreaktorule( "helicopter_comlink_mp", "vehicle", 1, 1 );
addkillstreaktorule( "helicopter_comlink_mp", "chopper", 1, 1 );
addkillstreaktorule( "helicopter_comlink_mp", "playercontrolledchopper", 0, 1 );
addkillstreaktorule( "helicopter_comlink_mp", "chopperInTheAir", 1, 0 );
addkillstreaktorule( "helicopter_comlink_mp", "targetableent", 1, 1 );
addkillstreaktorule( "helicopter_player_firstperson_mp", "vehicle", 1, 1 );
addkillstreaktorule( "helicopter_player_firstperson_mp", "playercontrolledchopper", 1, 1 );
addkillstreaktorule( "helicopter_player_firstperson_mp", "chopperInTheAir", 1, 1 );
addkillstreaktorule( "helicopter_player_firstperson_mp", "targetableent", 1, 1 );
addkillstreaktorule( "helicopter_guard_mp", "airsupport", 1, 1 );
addkillstreaktorule( "helicopter_gunner_mp", "vehicle", 1, 1 );
addkillstreaktorule( "helicopter_gunner_mp", "playercontrolledchopper", 1, 1 );
addkillstreaktorule( "helicopter_gunner_mp", "chopperInTheAir", 1, 1 );
addkillstreaktorule( "helicopter_gunner_mp", "targetableent", 1, 1 );
addkillstreaktorule( "helicopter_player_gunner_mp", "vehicle", 1, 1 );
addkillstreaktorule( "helicopter_player_gunner_mp", "playercontrolledchopper", 1, 1 );
addkillstreaktorule( "helicopter_player_gunner_mp", "chopperInTheAir", 1, 1 );
addkillstreaktorule( "helicopter_player_gunner_mp", "targetableent", 1, 1 );
addkillstreaktorule( "rcbomb_mp", "rcxd", 1, 1 );
addkillstreaktorule( "supply_drop_mp", "vehicle", 1, 1 );
addkillstreaktorule( "supply_drop_mp", "supplydrop", 1, 1 );
addkillstreaktorule( "supply_drop_mp", "targetableent", 1, 1 );
addkillstreaktorule( "supply_station_mp", "vehicle", 1, 1 );
addkillstreaktorule( "inventory_supply_drop_mp", "vehicle", 1, 1 );
addkillstreaktorule( "inventory_supply_drop_mp", "supplydrop", 1, 1 );
addkillstreaktorule( "inventory_supply_drop_mp", "targetableent", 1, 1 );
addkillstreaktorule( "supply_station_mp", "supplydrop", 1, 1 );
addkillstreaktorule( "supply_station_mp", "targetableent", 1, 1 );
addkillstreaktorule( "tow_turret_drop_mp", "vehicle", 1, 1 );
addkillstreaktorule( "turret_drop_mp", "vehicle", 1, 1 );
addkillstreaktorule( "m220_tow_drop_mp", "vehicle", 1, 1 );
addkillstreaktorule( "tow_turret_drop_mp", "supplydrop", 1, 1 );
addkillstreaktorule( "turret_drop_mp", "supplydrop", 1, 1 );
addkillstreaktorule( "m220_tow_drop_mp", "supplydrop", 1, 1 );
addkillstreaktorule( "m220_tow_killstreak_mp", "weapon", 1, 1 );
addkillstreaktorule( "autoturret_mp", "turret", 1, 1 );
addkillstreaktorule( "auto_tow_mp", "turret", 1, 1 );
addkillstreaktorule( "microwaveturret_mp", "turret", 1, 1 );
addkillstreaktorule( "minigun_mp", "weapon", 1, 1 );
addkillstreaktorule( "minigun_drop_mp", "weapon", 1, 1 );
addkillstreaktorule( "inventory_minigun_mp", "weapon", 1, 1 );
addkillstreaktorule( "m32_mp", "weapon", 1, 1 );
addkillstreaktorule( "m32_drop_mp", "weapon", 1, 1 );
addkillstreaktorule( "inventory_m32_mp", "weapon", 1, 1 );
addkillstreaktorule( "m202_flash_mp", "weapon", 1, 1 );
addkillstreaktorule( "m220_tow_mp", "weapon", 1, 1 );
addkillstreaktorule( "mp40_drop_mp", "weapon", 1, 1 );
addkillstreaktorule( "dogs_mp", "dogs", 1, 1 );
addkillstreaktorule( "dogs_lvl2_mp", "dogs", 1, 1 );
addkillstreaktorule( "dogs_lvl3_mp", "dogs", 1, 1 );
addkillstreaktorule( "artillery_mp", "firesupport", 1, 1 );
addkillstreaktorule( "mortar_mp", "firesupport", 1, 1 );
addkillstreaktorule( "napalm_mp", "vehicle", 1, 1 );
addkillstreaktorule( "napalm_mp", "airsupport", 1, 1 );
addkillstreaktorule( "airstrike_mp", "vehicle", 1, 1 );
addkillstreaktorule( "airstrike_mp", "airsupport", 1, 1 );
addkillstreaktorule( "radardirection_mp", "satellite", 1, 1 );
addkillstreaktorule( "radar_mp", "radar", 1, 1 );
addkillstreaktorule( "radar_mp", "targetableent", 1, 1 );
addkillstreaktorule( "counteruav_mp", "counteruav", 1, 1 );
addkillstreaktorule( "counteruav_mp", "targetableent", 1, 1 );
addkillstreaktorule( "emp_mp", "emp", 1, 1 );
addkillstreaktorule( "remote_mortar_mp", "targetableent", 1, 1 );
addkillstreaktorule( "remote_mortar_mp", "remotemortar", 1, 1 );
addkillstreaktorule( "remote_missile_mp", "targetableent", 1, 1 );
addkillstreaktorule( "qrdrone_mp", "vehicle", 1, 1 );
addkillstreaktorule( "qrdrone_mp", "qrdrone", 1, 1 );
addkillstreaktorule( "missile_swarm_mp", "missileswarm", 1, 1 );
addkillstreaktorule( "missile_drone_mp", "missiledrone", 1, 1 );
addkillstreaktorule( "inventory_missile_drone_mp", "missiledrone", 1, 1 );
addkillstreaktorule( "straferun_mp", "straferun", 1, 1 );
addkillstreaktorule( "ai_tank_drop_mp", "ai_tank", 1, 1 );
addkillstreaktorule( "inventory_ai_tank_drop_mp", "ai_tank", 1, 1 );
addkillstreaktorule( "planemortar_mp", "planemortar", 1, 1 );
}
createrule( rule, maxallowable, maxallowableperteam )
{
if ( !level.teambased )
{
if ( maxallowable > maxallowableperteam )
{
maxallowable = maxallowableperteam;
}
}
level.killstreakrules[ rule ] = spawnstruct();
level.killstreakrules[ rule ].cur = 0;
level.killstreakrules[ rule ].curteam = [];
level.killstreakrules[ rule ].max = maxallowable;
level.killstreakrules[ rule ].maxperteam = maxallowableperteam;
}
addkillstreaktorule( hardpointtype, rule, counttowards, checkagainst )
{
if ( !isDefined( level.killstreaktype[ hardpointtype ] ) )
{
level.killstreaktype[ hardpointtype ] = [];
}
keys = getarraykeys( level.killstreaktype[ hardpointtype ] );
/#
assert( isDefined( level.killstreakrules[ rule ] ) );
#/
if ( !isDefined( level.killstreaktype[ hardpointtype ][ rule ] ) )
{
level.killstreaktype[ hardpointtype ][ rule ] = spawnstruct();
}
level.killstreaktype[ hardpointtype ][ rule ].counts = counttowards;
level.killstreaktype[ hardpointtype ][ rule ].checks = checkagainst;
}
killstreakstart( hardpointtype, team, hacked, displayteammessage )
{
/#
assert( isDefined( team ), "team needs to be defined" );
#/
if ( self iskillstreakallowed( hardpointtype, team ) == 0 )
{
return -1;
}
/#
assert( isDefined( hardpointtype ) );
#/
if ( !isDefined( hacked ) )
{
hacked = 0;
}
if ( !isDefined( displayteammessage ) )
{
displayteammessage = 1;
}
if ( displayteammessage == 1 )
{
if ( isDefined( level.killstreaks[ hardpointtype ] ) && isDefined( level.killstreaks[ hardpointtype ].inboundtext ) && !hacked )
{
level thread maps/mp/_popups::displaykillstreakteammessagetoall( hardpointtype, self );
}
}
keys = getarraykeys( level.killstreaktype[ hardpointtype ] );
_a187 = keys;
_k187 = getFirstArrayKey( _a187 );
while ( isDefined( _k187 ) )
{
key = _a187[ _k187 ];
if ( !level.killstreaktype[ hardpointtype ][ key ].counts )
{
}
else
{
/#
assert( isDefined( level.killstreakrules[ key ] ) );
#/
level.killstreakrules[ key ].cur++;
if ( level.teambased )
{
if ( !isDefined( level.killstreakrules[ key ].curteam[ team ] ) )
{
level.killstreakrules[ key ].curteam[ team ] = 0;
}
level.killstreakrules[ key ].curteam[ team ]++;
}
}
_k187 = getNextArrayKey( _a187, _k187 );
}
level notify( "killstreak_started" );
killstreak_id = level.killstreak_counter;
level.killstreak_counter++;
killstreak_data = [];
killstreak_data[ "caller" ] = self getxuid();
killstreak_data[ "spawnid" ] = getplayerspawnid( self );
killstreak_data[ "starttime" ] = getTime();
killstreak_data[ "type" ] = hardpointtype;
killstreak_data[ "endtime" ] = 0;
level.killstreaks_triggered[ killstreak_id ] = killstreak_data;
/#
killstreak_debug_text( "Started killstreak: " + hardpointtype + " for team: " + team + " id: " + killstreak_id );
#/
return killstreak_id;
}
killstreakstop( hardpointtype, team, id )
{
/#
assert( isDefined( team ), "team needs to be defined" );
#/
/#
assert( isDefined( hardpointtype ) );
#/
/#
killstreak_debug_text( "Stopped killstreak: " + hardpointtype + " for team: " + team + " id: " + id );
#/
keys = getarraykeys( level.killstreaktype[ hardpointtype ] );
_a238 = keys;
_k238 = getFirstArrayKey( _a238 );
while ( isDefined( _k238 ) )
{
key = _a238[ _k238 ];
if ( !level.killstreaktype[ hardpointtype ][ key ].counts )
{
}
else
{
/#
assert( isDefined( level.killstreakrules[ key ] ) );
#/
level.killstreakrules[ key ].cur--;
/#
assert( level.killstreakrules[ key ].cur >= 0 );
#/
if ( level.teambased )
{
/#
assert( isDefined( team ) );
#/
/#
assert( isDefined( level.killstreakrules[ key ].curteam[ team ] ) );
#/
level.killstreakrules[ key ].curteam[ team ]--;
/#
assert( level.killstreakrules[ key ].curteam[ team ] >= 0 );
#/
}
}
_k238 = getNextArrayKey( _a238, _k238 );
}
if ( !isDefined( id ) || id == -1 )
{
killstreak_debug_text( "WARNING! Invalid killstreak id detected for " + hardpointtype );
bbprint( "mpkillstreakuses", "starttime %d endtime %d name %s team %s", 0, getTime(), hardpointtype, team );
return;
}
level.killstreaks_triggered[ id ][ "endtime" ] = getTime();
bbprint( "mpkillstreakuses", "starttime %d endtime %d spawnid %d name %s team %s", level.killstreaks_triggered[ id ][ "starttime" ], level.killstreaks_triggered[ id ][ "endtime" ], level.killstreaks_triggered[ id ][ "spawnid" ], hardpointtype, team );
if ( isDefined( level.killstreaks[ hardpointtype ].menuname ) )
{
recordstreakindex = level.killstreakindices[ level.killstreaks[ hardpointtype ].menuname ];
if ( isDefined( recordstreakindex ) )
{
if ( isDefined( self.owner ) )
{
self.owner recordkillstreakendevent( recordstreakindex );
return;
}
else
{
if ( isplayer( self ) )
{
self recordkillstreakendevent( recordstreakindex );
}
}
}
}
}
iskillstreakallowed( hardpointtype, team )
{
/#
assert( isDefined( team ), "team needs to be defined" );
#/
/#
assert( isDefined( hardpointtype ) );
#/
isallowed = 1;
keys = getarraykeys( level.killstreaktype[ hardpointtype ] );
_a308 = keys;
_k308 = getFirstArrayKey( _a308 );
while ( isDefined( _k308 ) )
{
key = _a308[ _k308 ];
if ( !level.killstreaktype[ hardpointtype ][ key ].checks )
{
}
else
{
if ( level.killstreakrules[ key ].max != 0 )
{
if ( level.killstreakrules[ key ].cur >= level.killstreakrules[ key ].max )
{
/#
killstreak_debug_text( "Exceeded " + key + " overall" );
#/
isallowed = 0;
break;
}
}
else if ( level.teambased && level.killstreakrules[ key ].maxperteam != 0 )
{
if ( !isDefined( level.killstreakrules[ key ].curteam[ team ] ) )
{
level.killstreakrules[ key ].curteam[ team ] = 0;
}
if ( level.killstreakrules[ key ].curteam[ team ] >= level.killstreakrules[ key ].maxperteam )
{
isallowed = 0;
/#
killstreak_debug_text( "Exceeded " + key + " team" );
#/
break;
}
}
}
else
{
_k308 = getNextArrayKey( _a308, _k308 );
}
}
if ( isDefined( self.laststand ) && self.laststand )
{
/#
killstreak_debug_text( "In LastStand" );
#/
isallowed = 0;
}
if ( self isempjammed() )
{
/#
killstreak_debug_text( "EMP active" );
#/
isallowed = 0;
if ( self maps/mp/killstreaks/_emp::isenemyempkillstreakactive() )
{
if ( isDefined( level.empendtime ) )
{
secondsleft = int( ( level.empendtime - getTime() ) / 1000 );
if ( secondsleft > 0 )
{
self iprintlnbold( &"KILLSTREAK_NOT_AVAILABLE_EMP_ACTIVE", secondsleft );
return 0;
}
}
}
}
if ( isallowed == 0 )
{
if ( isDefined( level.killstreaks[ hardpointtype ] ) && isDefined( level.killstreaks[ hardpointtype ].notavailabletext ) )
{
self iprintlnbold( level.killstreaks[ hardpointtype ].notavailabletext );
if ( hardpointtype != "helicopter_comlink_mp" && hardpointtype != "helicopter_guard_mp" && hardpointtype != "helicopter_player_gunner_mp" && hardpointtype != "remote_mortar_mp" && hardpointtype != "inventory_supply_drop_mp" || hardpointtype == "supply_drop_mp" && hardpointtype == "straferun_mp" )
{
pilotvoicenumber = randomintrange( 0, 3 );
soundalias = level.teamprefix[ self.team ] + pilotvoicenumber + "_" + "kls_full";
self playlocalsound( soundalias );
}
}
}
return isallowed;
}
killstreak_debug_text( text )
{
/#
level.killstreak_rule_debug = getdvarintdefault( "scr_killstreak_rule_debug", 0 );
if ( isDefined( level.killstreak_rule_debug ) )
{
if ( level.killstreak_rule_debug == 1 )
{
iprintln( "KSR: " + text + "\n" );
return;
}
else
{
if ( level.killstreak_rule_debug == 2 )
{
iprintlnbold( "KSR: " + text );
#/
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,694 @@
#include maps/mp/_challenges;
#include maps/mp/_scoreevents;
#include maps/mp/killstreaks/_dogs;
#include maps/mp/killstreaks/_missile_swarm;
#include maps/mp/_popups;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_airsupport;
#include maps/mp/killstreaks/_killstreaks;
#include common_scripts/utility;
#include maps/mp/_utility;
#using_animtree( "mp_missile_drone" );
init()
{
registerclientfield( "toplayer", "missile_drone_active", 1, 2, "int" );
registerclientfield( "missile", "missile_drone_projectile_active", 1, 1, "int" );
registerclientfield( "missile", "missile_drone_projectile_animate", 1, 1, "int" );
level.missile_drone_flyheight = 2400;
level.missile_drone_anim = %o_drone_hunter_launch;
precacheitem( "missile_drone_projectile_mp" );
loadfx( "weapon/missile/fx_missile_drone_light_red" );
registerkillstreak( "inventory_missile_drone_mp", "inventory_missile_drone_mp", "killstreak_missile_drone", "missile_drone_used", ::missile_drone_killstreak, 1 );
registerkillstreakstrings( "inventory_missile_drone_mp", &"KILLSTREAK_EARNED_MISSILE_DRONE", &"KILLSTREAK_MISSILE_DRONE_NOT_AVAILABLE", &"KILLSTREAK_MISSILE_DRONE_INBOUND" );
registerkillstreakdialog( "inventory_missile_drone_mp", "mpl_killstreak_missile_drone", "kls_hkdrone_used", "", "kls_hkdrone_enemy", "", "kls_hkdrone_ready" );
registerkillstreakdevdvar( "inventory_missile_drone_mp", "scr_givemissiledrone" );
registerkillstreak( "missile_drone_mp", "missile_drone_mp", "killstreak_missile_drone", "missile_drone_used", ::missile_drone_killstreak, 1 );
registerkillstreakaltweapon( "missile_drone_mp", "missile_drone_projectile_mp" );
registerkillstreakaltweapon( "inventory_missile_drone_mp", "missile_drone_projectile_mp" );
registerkillstreakstrings( "missile_drone_mp", &"KILLSTREAK_EARNED_MISSILE_DRONE", &"KILLSTREAK_MISSILE_DRONE_NOT_AVAILABLE", &"KILLSTREAK_MISSILE_DRONE_INBOUND" );
registerkillstreakdialog( "missile_drone_mp", "mpl_killstreak_missile_drone", "kls_hkdrone_used", "", "kls_hkdrone_enemy", "", "kls_hkdrone_ready" );
setkillstreakteamkillpenaltyscale( "missile_drone_mp", 0 );
}
missile_drone_killstreak( weaponname )
{
/#
if ( weaponname != "missile_drone_mp" )
{
assert( weaponname == "inventory_missile_drone_mp" );
}
#/
level.missile_drone_origin = level.mapcenter + ( 0, 0, level.missile_drone_flyheight );
hardpointtype = "missile_drone_mp";
result = usemissiledrone( hardpointtype );
if ( !isDefined( result ) || !result )
{
return 0;
}
return result;
}
usemissiledrone( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
self thread missiledronewatcher( hardpointtype );
missileweapon = self getcurrentweapon();
missileweapon = undefined;
currentweapon = self getcurrentweapon();
if ( ismissiledroneweapon( currentweapon ) )
{
missileweapon = currentweapon;
}
/#
assert( isDefined( missileweapon ) );
#/
notifystring = self waittill_any_return( "weapon_change", "grenade_fire", "death" );
if ( notifystring == "weapon_change" || notifystring == "death" )
{
return 0;
}
notifystring = self waittill_any_return( "weapon_change", "death" );
if ( notifystring == "death" )
{
return 1;
}
if ( !isDefined( missileweapon ) )
{
return 0;
}
self takeweapon( missileweapon );
if ( self hasweapon( missileweapon ) || self getammocount( missileweapon ) )
{
return 0;
}
return 1;
}
ismissiledroneweapon( weapon )
{
if ( weapon == "missile_drone_mp" || weapon == "inventory_missile_drone_mp" )
{
return 1;
}
return 0;
}
missiledronewatcher( hardpointtype )
{
self notify( "missileDroneWatcher" );
self endon( "missileDroneWatcher" );
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "death" );
team = self.team;
killstreak_id = maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, team, 0, 0 );
if ( killstreak_id == -1 )
{
self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon();
return;
}
self thread checkforemp();
self thread checkweaponchange( hardpointtype, team, killstreak_id );
self thread watchownerdeath( hardpointtype, team, killstreak_id );
self thread updatetargetting();
self waittill( "grenade_fire", grenade, weapname );
origin = grenade.origin;
self notify( "missile_drone_active" );
level thread maps/mp/_popups::displaykillstreakteammessagetoall( hardpointtype, self );
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( hardpointtype, self.team, 1 );
level.globalkillstreakscalled++;
self addweaponstat( "missile_drone_mp", "used", 1 );
self setclientfieldtoplayer( "missile_drone_active", 0 );
grenade thread waitthendelete( 0,05 );
grenade.origin += vectorScale( ( 0, 0, 1 ), 1000 );
self thread domissiledrone( origin, weapname, killstreak_id, hardpointtype, team );
self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon();
}
domissiledrone( origin, weapname, killstreak_id, hardpointtype, team )
{
direction = self getplayerangles();
forward = anglesToForward( direction );
target = origin + vectorScale( forward, 10000 );
debug_line( origin, target, ( 0,9, 0,1, 0,1 ) );
projectile = maps/mp/killstreaks/_missile_swarm::projectile_spawn_utility( self, target, origin, "missile_drone_projectile_mp", "drone_missile", 0 );
projectile missile_dronesetvisible( 1 );
projectile.originaltarget = target;
projectile thread maps/mp/killstreaks/_missile_swarm::projectile_abort_think();
projectile thread drone_target_search( hardpointtype );
projectile thread projectile_death_think();
projectile thread watchdamage();
projectile.targetname = "remote_drone";
projectile playsound( "wpn_hunter_ignite" );
projectile thread killstreak_stop_think( killstreak_id, hardpointtype, team );
projectile setclientfield( "missile_drone_projectile_animate", 1 );
}
waitthendelete( waittime )
{
self endon( "delete" );
self endon( "death" );
wait waittime;
self delete();
}
projectile_death_think()
{
self waittill( "death" );
self.goal delete();
}
drone_target_acquired( hardpointtype, target )
{
self endon( "death" );
self notify( "drone_target_acquired" );
self setclientfield( "missile_drone_projectile_active", 1 );
self set_drone_target( hardpointtype, target );
}
drone_target_search( hardpointtype )
{
self endon( "death" );
if ( isDefined( self.dronetarget ) )
{
self drone_target_acquired( hardpointtype, self.dronetarget );
self missile_settarget( self.goal );
}
self setclientfield( "missile_drone_projectile_active", 0 );
searchdotprodminimums = [];
searchdotprodminimums[ 0 ] = 0,9;
searchdotprodminimums[ 1 ] = 0,7071;
searchdotprodminimums[ 2 ] = 0,5;
searchdotprodminimums[ 3 ] = 0;
wait 0,1;
searchcounter = 0;
for ( ;; )
{
if ( !isDefined( self ) )
{
self notify( "death" );
}
target = self projectile_find_target( self.owner, searchdotprodminimums[ searchcounter ] );
if ( searchcounter < ( searchdotprodminimums.size - 1 ) )
{
searchcounter++;
}
else if ( level.missile_drone_origin[ 2 ] != self.goal.origin[ 2 ] )
{
currentangles = self.angles;
direction = vectornormalize( anglesToForward( self.angles ) );
direction = vecscale( direction, 1024 );
self.goal.origin = ( self.origin[ 0 ] + direction[ 0 ], self.origin[ 1 ] + direction[ 1 ], level.missile_drone_origin[ 2 ] );
/#
debug_line( self.origin, self.goal.origin, ( 0, 0, 1 ), 5000 );
#/
}
else
{
currentangles = self.angles;
direction = vectornormalize( anglesToForward( self.angles ) );
direction = vecscale( direction, 1024 );
self.goal.origin = ( level.missile_drone_origin[ 0 ] + direction[ 0 ], level.missile_drone_origin[ 1 ] + direction[ 1 ], level.missile_drone_origin[ 2 ] );
/#
debug_line( self.origin, self.goal.origin, ( 0, 1, 1 ), 5000 );
#/
}
if ( isDefined( target ) )
{
self set_drone_target( hardpointtype, target );
self missile_settarget( self.goal );
}
wait 0,25;
}
}
vecscale( vec, scalar )
{
return ( vec[ 0 ] * scalar, vec[ 1 ] * scalar, vec[ 2 ] * scalar );
}
set_drone_target( hardpointtype, target )
{
self endon( "target_lost" );
self thread check_target_lost( target );
self.swarm_target = target[ "entity" ];
target[ "entity" ].swarm = self;
debug_line( self.origin, target[ "entity" ].origin, ( 0, 0, 1 ), 5000 );
self missile_settarget( target[ "entity" ], target[ "offset" ] );
self playsound( "veh_harpy_drone_swarm_incomming" );
if ( !isDefined( target[ "entity" ].swarmsound ) || target[ "entity" ].swarmsound == 0 )
{
self thread target_sounds( target[ "entity" ] );
}
target[ "entity" ] notify( "stinger_fired_at_me" );
self setclientfield( "missile_drone_projectile_active", 1 );
target[ "entity" ] waittill_any( "death", "disconnect", "joined_team" );
self setclientfield( "missile_drone_projectile_active", 0 );
self missile_settarget( self.goal );
}
check_target_lost( target )
{
self endon( "death" );
target[ "entity" ] endon( "death" );
target[ "entity" ] endon( "disconnect" );
target[ "entity" ] endon( "joined_team" );
failurelimit = 3;
failurecount = 0;
for ( ;; )
{
/#
debug_star( target[ "entity" ].origin, ( 0, 0, 1 ), 1000 );
debug_star( self.origin, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( self.origin, target[ "entity" ].origin + target[ "offset" ], 0, target[ "entity" ] ) )
{
/#
debug_line( self.origin, target[ "entity" ].origin, ( 0, 0, 1 ), 1000 );
#/
failurecount = 0;
}
else
{
failurecount++;
if ( failurecount >= failurelimit )
{
self notify( "target_lost" );
return;
}
}
wait 0,25;
}
}
projectile_find_target( owner, mincos )
{
ks = self projectile_find_target_killstreak( owner, mincos );
player = self projectile_find_target_player( owner, mincos );
if ( isDefined( ks ) && !isDefined( player ) )
{
return ks;
}
else
{
if ( !isDefined( ks ) && isDefined( player ) )
{
return player;
}
else
{
if ( isDefined( ks ) && isDefined( player ) )
{
if ( player[ "dotprod" ] < ks[ "dotprod" ] )
{
return ks;
}
return player;
}
}
}
return undefined;
}
projectile_find_target_killstreak( owner, mincos )
{
ks = [];
ks[ "offset" ] = vectorScale( ( 0, 0, 1 ), 10 );
targets = target_getarray();
rcbombs = getentarray( "rcbomb", "targetname" );
dogs = maps/mp/killstreaks/_dogs::dog_manager_get_dogs();
targets = arraycombine( targets, rcbombs, 1, 0 );
targets = arraycombine( targets, dogs, 1, 0 );
if ( targets.size <= 0 )
{
return undefined;
}
targets = get_array_sorted_dot_prod( targets, mincos );
_a389 = targets;
_k389 = getFirstArrayKey( _a389 );
while ( isDefined( _k389 ) )
{
target = _a389[ _k389 ];
if ( isDefined( target.owner ) && target.owner == owner )
{
}
else
{
if ( isDefined( target.script_owner ) && target.script_owner == owner )
{
break;
}
else
{
if ( level.teambased && isDefined( target.team ) )
{
if ( target.team == self.team )
{
break;
}
}
else if ( level.teambased && isDefined( target.aiteam ) )
{
if ( target.aiteam == self.team )
{
break;
}
}
else if ( isDefined( target.vehicletype ) && target.vehicletype == "heli_supplydrop_mp" )
{
break;
}
else
{
if ( bullettracepassed( self.origin, target.origin, 0, target ) )
{
ks[ "entity" ] = target;
if ( isDefined( target.sorteddotprod ) )
{
ks[ "dotprod" ] = target.sorteddotprod;
}
else
{
ks[ "dotprod" ] = -1;
}
return ks;
}
}
}
}
_k389 = getNextArrayKey( _a389, _k389 );
}
return undefined;
}
projectile_find_target_player( owner, mincos )
{
target = [];
players = self get_array_sorted_dot_prod( get_players(), mincos );
if ( isplayer( self ) )
{
startoffset = self getplayerviewheight();
startorigin = ( self.origin[ 0 ], self.origin[ 1 ], self.origin[ 2 ] + startoffset );
startangles = self getplayerangles();
/#
debug_star( startorigin, ( 0, 0, 1 ), 1000 );
#/
}
else
{
startorigin = self.origin;
startangles = self.angles;
}
bestplayerrating = -1;
_a470 = players;
_k470 = getFirstArrayKey( _a470 );
while ( isDefined( _k470 ) )
{
player = _a470[ _k470 ];
if ( !player_valid_target( player, owner.team, owner ) )
{
}
else
{
currentplayeroffset = undefined;
currentplayerdotprod = undefined;
currentplayerrating = 0;
/#
debug_star( player.origin, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( startorigin, player.origin, 0, player ) )
{
/#
debug_line( startorigin, player.origin, ( 0, 0, 1 ), 1000 );
#/
if ( !isDefined( currentplayeroffset ) )
{
currentplayeroffset = ( 0, 0, 1 );
}
currentplayerrating += 4;
}
verticaloffset = player getplayerviewheight();
playerheadoffset = ( 0, 0, verticaloffset );
/#
debug_star( player.origin + playerheadoffset, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( startorigin, player.origin + playerheadoffset, 0, player ) )
{
/#
debug_line( startorigin, player.origin + playerheadoffset, ( 0, 0, 1 ), 1000 );
#/
if ( !isDefined( currentplayeroffset ) )
{
currentplayeroffset = playerheadoffset;
}
currentplayerrating += 3;
}
end = player.origin + playerheadoffset + vectorScale( ( 0, 0, 1 ), 96 );
/#
debug_star( end, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( player.origin + playerheadoffset, end, 0, player ) )
{
/#
debug_line( player.origin + playerheadoffset, end, ( 0, 0, 1 ), 1000 );
#/
if ( !isDefined( currentplayeroffset ) )
{
currentplayeroffset = vectorScale( ( 0, 0, 1 ), 30 );
}
currentplayerrating += 2;
}
if ( currentplayerrating > bestplayerrating )
{
bestplayerrating = currentplayerrating;
target[ "entity" ] = player;
target[ "offset" ] = currentplayeroffset;
if ( isDefined( player.sorteddotprod ) )
{
target[ "dotprod" ] = player.sorteddotprod;
}
else
{
target[ "dotprod" ] = -1;
}
if ( bestplayerrating >= 9 )
{
return target;
}
}
}
_k470 = getNextArrayKey( _a470, _k470 );
}
if ( bestplayerrating >= 3 )
{
return target;
}
return undefined;
}
killstreak_stop_think( killstreak_id, hardpointtype, team )
{
self waittill( "death" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( hardpointtype, team, killstreak_id );
}
checkweaponchange( hardpointtype, team, killstreak_id )
{
self endon( "spawned_player" );
self endon( "death" );
self endon( "disconnect" );
self endon( "grenade_fire" );
self waittill( "weapon_change" );
self setclientfieldtoplayer( "missile_drone_active", 0 );
maps/mp/killstreaks/_killstreakrules::killstreakstop( hardpointtype, team, killstreak_id );
}
watchownerdeath( hardpointtype, team, killstreak_id )
{
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "missile_drone_active" );
self waittill( "death" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( hardpointtype, team, killstreak_id );
}
checkforemp()
{
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "death" );
self endon( "grenade_fire" );
self waittill( "emp_jammed" );
self setclientfieldtoplayer( "missile_drone_active", 0 );
self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon();
}
watchdamage()
{
self endon( "death" );
self setcandamage( 1 );
self.maxhealth = 100000;
self.health = self.maxhealth;
for ( ;; )
{
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname );
if ( !isDefined( attacker ) || !isplayer( attacker ) )
{
continue;
}
else
{
if ( isplayer( attacker ) && level.teambased && isDefined( attacker.team ) && self.team == attacker.team && level.friendlyfire == 0 )
{
break;
}
else
{
if ( self.owner isenemyplayer( attacker ) )
{
maps/mp/_scoreevents::processscoreevent( "destroyed_missile_drone", attacker, self.owner, weaponname );
attacker maps/mp/_challenges::addflyswatterstat( weaponname, self );
break;
}
self detonate();
}
}
}
}
get_array_sorted_dot_prod( array, mincos )
{
if ( isplayer( self ) )
{
org = self.origin;
angles = self getplayerangles();
/#
assert( isDefined( angles ) );
#/
}
else
{
org = self.origin;
/#
assert( isDefined( self.angles ) );
#/
angles = self.angles;
}
forwardvec = vectornormalize( anglesToForward( angles ) );
dotprod = [];
index = [];
i = 0;
while ( i < array.size )
{
/#
assert( isDefined( forwardvec ) );
#/
/#
assert( isDefined( array[ i ] ) );
#/
/#
assert( isDefined( array[ i ].origin ) );
#/
/#
assert( isDefined( org ) );
#/
cosa = vectordot( forwardvec, vectornormalize( array[ i ].origin - org ) );
/#
assert( isDefined( cosa ) );
#/
if ( isDefined( mincos ) && cosa < mincos )
{
i++;
continue;
}
else
{
array[ i ].sorteddotprod = cosa;
dotprod[ dotprod.size ] = cosa;
index[ index.size ] = i;
}
i++;
}
for ( ;; )
{
change = 0;
i = 0;
while ( i < ( dotprod.size - 1 ) )
{
if ( dotprod[ i ] >= dotprod[ i + 1 ] )
{
i++;
continue;
}
else
{
change = 1;
temp = dotprod[ i ];
dotprod[ i ] = dotprod[ i + 1 ];
dotprod[ i + 1 ] = temp;
temp = index[ i ];
index[ i ] = index[ i + 1 ];
index[ i + 1 ] = temp;
}
i++;
}
if ( !change )
{
break;
}
else
{
}
}
newarray = [];
i = 0;
while ( i < dotprod.size )
{
newarray[ i ] = array[ index[ i ] ];
i++;
}
return newarray;
}
updatetargetting()
{
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "death" );
self endon( "grenade_fire" );
mincos = getdvarfloatdefault( "scr_missile_drone_min_cos", 0,9 );
updatewait = getdvarfloatdefault( "scr_missile_drone_update_wait", 0,5 );
for ( ;; )
{
self.dronetarget = self projectile_find_target( self, mincos );
if ( isDefined( self.dronetarget ) )
{
self thread clearinvaliddronetarget();
self setclientfieldtoplayer( "missile_drone_active", 2 );
}
else
{
self setclientfieldtoplayer( "missile_drone_active", 1 );
}
wait updatewait;
}
}
clearinvaliddronetarget()
{
self endon( "death" );
self notify( "clearInvalidDroneTarget" );
self endon( "clearInvalidDroneTarget" );
self endon( "drone_target_acquired" );
self.dronetarget[ "entity" ] waittill_any( "death", "disconnect", "joined_team" );
self.dronetarget = undefined;
}

View File

@ -0,0 +1,760 @@
#include maps/mp/killstreaks/_dogs;
#include maps/mp/_challenges;
#include maps/mp/_scoreevents;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_airsupport;
#include maps/mp/killstreaks/_killstreaks;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
level.missile_swarm_max = 6;
level.missile_swarm_flyheight = 3000;
level.missile_swarm_flydist = 5000;
set_dvar_float_if_unset( "scr_missile_swarm_lifetime", 40 );
precacheitem( "missile_swarm_projectile_mp" );
level.swarm_fx[ "swarm" ] = loadfx( "weapon/harpy_swarm/fx_hrpy_swrm_os_circle_neg_x" );
level.swarm_fx[ "swarm_tail" ] = loadfx( "weapon/harpy_swarm/fx_hrpy_swrm_exhaust_trail_close" );
level.missiledronesoundstart = "mpl_hk_scan";
registerkillstreak( "missile_swarm_mp", "missile_swarm_mp", "killstreak_missile_swarm", "missile_swarm_used", ::swarm_killstreak, 1 );
registerkillstreakaltweapon( "missile_swarm_mp", "missile_swarm_projectile_mp" );
registerkillstreakstrings( "missile_swarm_mp", &"KILLSTREAK_EARNED_MISSILE_SWARM", &"KILLSTREAK_MISSILE_SWARM_NOT_AVAILABLE", &"KILLSTREAK_MISSILE_SWARM_INBOUND" );
registerkillstreakdialog( "missile_swarm_mp", "mpl_killstreak_missile_swarm", "kls_swarm_used", "", "kls_swarm_enemy", "", "kls_swarm_ready" );
registerkillstreakdevdvar( "missile_swarm_mp", "scr_givemissileswarm" );
setkillstreakteamkillpenaltyscale( "missile_swarm_mp", 0 );
maps/mp/killstreaks/_killstreaks::createkillstreaktimer( "missile_swarm_mp" );
registerclientfield( "world", "missile_swarm", 1, 2, "int" );
/#
set_dvar_int_if_unset( "scr_missile_swarm_cam", 0 );
#/
}
swarm_killstreak( hardpointtype )
{
/#
assert( hardpointtype == "missile_swarm_mp" );
#/
level.missile_swarm_origin = level.mapcenter + ( 0, 0, level.missile_swarm_flyheight );
if ( level.script == "mp_drone" )
{
level.missile_swarm_origin += ( -5000, 0, 2000 );
}
if ( level.script == "mp_la" )
{
level.missile_swarm_origin += vectorScale( ( 0, 0, 1 ), 2000 );
}
if ( level.script == "mp_turbine" )
{
level.missile_swarm_origin += vectorScale( ( 0, 0, 1 ), 1500 );
}
if ( level.script == "mp_downhill" )
{
level.missile_swarm_origin += ( 4000, 0, 1000 );
}
if ( level.script == "mp_hydro" )
{
level.missile_swarm_origin += vectorScale( ( 0, 0, 1 ), 5000 );
}
if ( level.script == "mp_magma" )
{
level.missile_swarm_origin += ( 0, -6000, 3000 );
}
if ( level.script == "mp_uplink" )
{
level.missile_swarm_origin += ( -6000, 0, 2000 );
}
if ( level.script == "mp_bridge" )
{
level.missile_swarm_origin += vectorScale( ( 0, 0, 1 ), 2000 );
}
if ( level.script == "mp_paintball" )
{
level.missile_swarm_origin += vectorScale( ( 0, 0, 1 ), 1000 );
}
if ( level.script == "mp_dig" )
{
level.missile_swarm_origin += ( -2000, -2000, 1000 );
}
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( "missile_swarm_mp", self.team, 0, 1 );
if ( killstreak_id == -1 )
{
return 0;
}
level thread swarm_killstreak_start( self, killstreak_id );
return 1;
}
swarm_killstreak_start( owner, killstreak_id )
{
level endon( "swarm_end" );
missiles = getentarray( "swarm_missile", "targetname" );
_a102 = missiles;
_k102 = getFirstArrayKey( _a102 );
while ( isDefined( _k102 ) )
{
missile = _a102[ _k102 ];
if ( isDefined( missile ) )
{
missile detonate();
wait 0,1;
}
_k102 = getNextArrayKey( _a102, _k102 );
}
while ( isDefined( level.missile_swarm_fx ) )
{
i = 0;
while ( i < level.missile_swarm_fx.size )
{
if ( isDefined( level.missile_swarm_fx[ i ] ) )
{
level.missile_swarm_fx[ i ] delete();
}
i++;
}
}
level.missile_swarm_fx = undefined;
level.missile_swarm_team = owner.team;
level.missile_swarm_owner = owner;
owner maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "missile_swarm_mp", owner.pers[ "team" ] );
level create_player_targeting_array( owner, owner.team );
level.globalkillstreakscalled++;
owner addweaponstat( "missile_swarm_mp", "used", 1 );
level thread swarm_killstreak_abort( owner, killstreak_id );
level thread swarm_killstreak_watch_for_emp( owner, killstreak_id );
level thread swarm_killstreak_fx();
wait 2;
level thread swarm_think( owner, killstreak_id );
}
swarm_killstreak_end( owner, detonate, killstreak_id )
{
level notify( "swarm_end" );
if ( isDefined( detonate ) && detonate )
{
level setclientfield( "missile_swarm", 2 );
}
else
{
level setclientfield( "missile_swarm", 0 );
}
missiles = getentarray( "swarm_missile", "targetname" );
if ( is_true( detonate ) )
{
i = 0;
while ( i < level.missile_swarm_fx.size )
{
if ( isDefined( level.missile_swarm_fx[ i ] ) )
{
level.missile_swarm_fx[ i ] delete();
}
i++;
}
_a160 = missiles;
_k160 = getFirstArrayKey( _a160 );
while ( isDefined( _k160 ) )
{
missile = _a160[ _k160 ];
if ( isDefined( missile ) )
{
missile detonate();
wait 0,1;
}
_k160 = getNextArrayKey( _a160, _k160 );
}
}
else _a171 = missiles;
_k171 = getFirstArrayKey( _a171 );
while ( isDefined( _k171 ) )
{
missile = _a171[ _k171 ];
if ( isDefined( missile ) )
{
yaw = randomintrange( 0, 360 );
angles = ( 0, yaw, 0 );
forward = anglesToForward( angles );
if ( isDefined( missile.goal ) )
{
missile.goal.origin = missile.origin + ( forward * level.missile_swarm_flydist * 1000 );
}
}
_k171 = getNextArrayKey( _a171, _k171 );
}
wait 1;
level.missile_swarm_sound stoploopsound( 2 );
wait 2;
level.missile_swarm_sound delete();
recordstreakindex = level.killstreakindices[ level.killstreaks[ "missile_swarm_mp" ].menuname ];
if ( isDefined( recordstreakindex ) )
{
owner recordkillstreakendevent( recordstreakindex );
}
maps/mp/killstreaks/_killstreakrules::killstreakstop( "missile_swarm_mp", level.missile_swarm_team, killstreak_id );
level.missile_swarm_owner = undefined;
wait 4;
missiles = getentarray( "swarm_missile", "targetname" );
_a205 = missiles;
_k205 = getFirstArrayKey( _a205 );
while ( isDefined( _k205 ) )
{
missile = _a205[ _k205 ];
if ( isDefined( missile ) )
{
missile delete();
wait 0,1;
}
_k205 = getNextArrayKey( _a205, _k205 );
}
wait 6;
i = 0;
while ( i < level.missile_swarm_fx.size )
{
if ( isDefined( level.missile_swarm_fx[ i ] ) )
{
level.missile_swarm_fx[ i ] delete();
}
i++;
}
}
swarm_killstreak_abort( owner, killstreak_id )
{
level endon( "swarm_end" );
owner waittill_any( "disconnect", "joined_team", "joined_spectators", "emp_jammed" );
level thread swarm_killstreak_end( owner, 1, killstreak_id );
}
swarm_killstreak_watch_for_emp( owner, killstreak_id )
{
level endon( "swarm_end" );
owner waittill( "emp_destroyed_missile_swarm", attacker );
maps/mp/_scoreevents::processscoreevent( "destroyed_missile_swarm", attacker, owner, "emp_mp" );
attacker maps/mp/_challenges::addflyswatterstat( "emp_mp" );
level thread swarm_killstreak_end( owner, 1, killstreak_id );
}
swarm_killstreak_fx()
{
level endon( "swarm_end" );
level.missile_swarm_fx = [];
yaw = randomint( 360 );
level.missile_swarm_fx[ 0 ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ 0 ] setmodel( "tag_origin" );
level.missile_swarm_fx[ 0 ].angles = ( -90, yaw, 0 );
level.missile_swarm_fx[ 1 ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ 1 ] setmodel( "tag_origin" );
level.missile_swarm_fx[ 1 ].angles = ( -90, yaw, 0 );
level.missile_swarm_fx[ 2 ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ 2 ] setmodel( "tag_origin" );
level.missile_swarm_fx[ 2 ].angles = ( -90, yaw, 0 );
level.missile_swarm_fx[ 3 ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ 3 ] setmodel( "tag_origin" );
level.missile_swarm_fx[ 3 ].angles = ( -90, yaw, 0 );
level.missile_swarm_fx[ 4 ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ 4 ] setmodel( "tag_origin" );
level.missile_swarm_fx[ 4 ].angles = ( -90, yaw, 0 );
level.missile_swarm_fx[ 5 ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ 5 ] setmodel( "tag_origin" );
level.missile_swarm_fx[ 5 ].angles = ( -90, yaw, 0 );
level.missile_swarm_fx[ 6 ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ 6 ] setmodel( "tag_origin" );
level.missile_swarm_fx[ 6 ].angles = ( -90, yaw, 0 );
level.missile_swarm_sound = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_sound setmodel( "tag_origin" );
level.missile_swarm_sound.angles = ( 0, 0, 1 );
wait 0,1;
playfxontag( level.swarm_fx[ "swarm" ], level.missile_swarm_fx[ 0 ], "tag_origin" );
wait 2;
level.missile_swarm_sound playloopsound( "veh_harpy_drone_swarm_lp", 3 );
level setclientfield( "missile_swarm", 1 );
current = 1;
while ( 1 )
{
if ( !isDefined( level.missile_swarm_fx[ current ] ) )
{
level.missile_swarm_fx[ current ] = spawn( "script_model", level.missile_swarm_origin );
level.missile_swarm_fx[ current ] setmodel( "tag_origin" );
}
yaw = randomint( 360 );
if ( isDefined( level.missile_swarm_fx[ current ] ) )
{
level.missile_swarm_fx[ current ].angles = ( -90, yaw, 0 );
}
wait 0,1;
if ( isDefined( level.missile_swarm_fx[ current ] ) )
{
playfxontag( level.swarm_fx[ "swarm" ], level.missile_swarm_fx[ current ], "tag_origin" );
}
current = ( current + 1 ) % 7;
wait 1,9;
}
}
swarm_think( owner, killstreak_id )
{
level endon( "swarm_end" );
lifetime = getDvarFloat( #"4FEEA279" );
end_time = getTime() + ( lifetime * 1000 );
level.missile_swarm_count = 0;
while ( getTime() < end_time )
{
/#
assert( level.missile_swarm_count >= 0 );
#/
while ( level.missile_swarm_count >= level.missile_swarm_max )
{
wait 0,5;
}
count = 1;
level.missile_swarm_count += count;
i = 0;
while ( i < count )
{
self thread projectile_spawn( owner );
i++;
}
wait ( ( level.missile_swarm_count / level.missile_swarm_max ) + 0,4 );
}
level thread swarm_killstreak_end( owner, undefined, killstreak_id );
}
projectile_cam( player )
{
/#
player.swarm_cam = 1;
wait 0,05;
forward = anglesToForward( self.angles );
cam = spawn( "script_model", ( self.origin + vectorScale( ( 0, 0, 1 ), 300 ) ) + ( forward * -200 ) );
cam setmodel( "tag_origin" );
cam linkto( self );
player camerasetposition( cam );
player camerasetlookat( self );
player cameraactivate( 1 );
self waittill( "death" );
wait 1;
player cameraactivate( 0 );
cam delete();
player.swarm_cam = 0;
#/
}
projectile_goal_move()
{
self endon( "death" );
for ( ;; )
{
wait 0,25;
while ( distancesquared( self.origin, self.goal.origin ) < 65536 )
{
if ( distancesquared( self.origin, level.missile_swarm_origin ) > ( level.missile_swarm_flydist * level.missile_swarm_flydist ) )
{
self.goal.origin = level.missile_swarm_origin;
break;
}
else
{
enemy = projectile_find_random_player( self.owner, self.team );
if ( isDefined( enemy ) )
{
self.goal.origin = enemy.origin + ( 0, 0, self.origin[ 2 ] );
}
else
{
pitch = randomintrange( -45, 45 );
yaw = randomintrange( 0, 360 );
angles = ( 0, yaw, 0 );
forward = anglesToForward( angles );
self.goal.origin = self.origin + ( forward * level.missile_swarm_flydist );
}
nfz = crossesnoflyzone( self.origin, self.goal.origin );
tries = 20;
while ( isDefined( nfz ) && tries > 0 )
{
tries--;
pitch = randomintrange( -45, 45 );
yaw = randomintrange( 0, 360 );
angles = ( 0, yaw, 0 );
forward = anglesToForward( angles );
self.goal.origin = self.origin + ( forward * level.missile_swarm_flydist );
nfz = crossesnoflyzone( self.origin, self.goal.origin );
}
}
}
}
}
projectile_target_search( acceptskyexposure, acquiretime, allowplayeroffset )
{
self endon( "death" );
wait acquiretime;
for ( ;; )
{
wait randomfloatrange( 0,5, 1 );
target = self projectile_find_target( acceptskyexposure );
if ( isDefined( target ) )
{
self.swarm_target = target[ "entity" ];
target[ "entity" ].swarm = self;
if ( allowplayeroffset )
{
self missile_settarget( target[ "entity" ], target[ "offset" ] );
self missile_dronesetvisible( 1 );
}
else
{
self missile_settarget( target[ "entity" ] );
self missile_dronesetvisible( 1 );
}
self playsound( "veh_harpy_drone_swarm_incomming" );
if ( !isDefined( target[ "entity" ].swarmsound ) || target[ "entity" ].swarmsound == 0 )
{
self thread target_sounds( target[ "entity" ] );
}
target[ "entity" ] waittill_any( "death", "disconnect", "joined_team" );
self missile_settarget( self.goal );
self missile_dronesetvisible( 0 );
break;
}
}
}
target_sounds( targetent )
{
targetent endon( "death" );
targetent endon( "disconnect" );
targetent endon( "joined_team" );
self endon( "death" );
dist = 3000;
if ( isDefined( self.warningsounddist ) )
{
dist = self.warningsounddist;
}
while ( distancesquared( self.origin, targetent.origin ) > ( dist * dist ) )
{
wait 0,05;
}
if ( isDefined( targetent.swarmsound ) && targetent.swarmsound == 1 )
{
return;
}
targetent.swarmsound = 1;
self thread reset_sound_blocker( targetent );
self thread target_stop_sounds( targetent );
if ( isplayer( targetent ) )
{
targetent playlocalsound( level.missiledronesoundstart );
}
self playsound( level.missiledronesoundstart );
}
target_stop_sounds( targetent )
{
targetent waittill_any( "disconnect", "death", "joined_team" );
if ( isDefined( targetent ) && isplayer( targetent ) )
{
targetent stoplocalsound( level.missiledronesoundstart );
}
}
reset_sound_blocker( target )
{
wait 2;
if ( isDefined( target ) )
{
target.swarmsound = 0;
}
}
projectile_spawn( owner )
{
level endon( "swarm_end" );
upvector = ( 0, 0, randomintrange( level.missile_swarm_flyheight - 1500, level.missile_swarm_flyheight - 1000 ) );
yaw = randomintrange( 0, 360 );
angles = ( 0, yaw, 0 );
forward = anglesToForward( angles );
origin = ( level.mapcenter + upvector ) + ( forward * level.missile_swarm_flydist * -1 );
target = ( level.mapcenter + upvector ) + ( forward * level.missile_swarm_flydist );
enemy = projectile_find_random_player( owner, owner.team );
if ( isDefined( enemy ) )
{
target = enemy.origin + upvector;
}
projectile = projectile_spawn_utility( owner, target, origin, "missile_swarm_projectile_mp", "swarm_missile", 1 );
projectile thread projectile_abort_think();
projectile thread projectile_target_search( cointoss(), 1, 1 );
projectile thread projectile_death_think();
projectile thread projectile_goal_move();
wait 0,1;
if ( isDefined( projectile ) )
{
projectile setclientfield( "missile_drone_projectile_animate", 1 );
}
}
projectile_spawn_utility( owner, target, origin, weapon, targetname, movegoal )
{
goal = spawn( "script_model", target );
goal setmodel( "tag_origin" );
p = magicbullet( weapon, origin, target, owner, goal );
p.owner = owner;
p.team = owner.team;
p.goal = goal;
p.targetname = "swarm_missile";
/#
if ( !is_true( owner.swarm_cam ) && getDvarInt( #"492656A6" ) == 1 )
{
p thread projectile_cam( owner );
#/
}
return p;
}
projectile_death_think()
{
self waittill( "death" );
level.missile_swarm_count--;
self.goal delete();
}
projectile_abort_think()
{
self endon( "death" );
self.owner waittill_any( "disconnect", "joined_team" );
self detonate();
}
projectile_find_target( acceptskyexposure )
{
ks = projectile_find_target_killstreak( acceptskyexposure );
player = projectile_find_target_player( acceptskyexposure );
if ( isDefined( ks ) && !isDefined( player ) )
{
return ks;
}
else
{
if ( !isDefined( ks ) && isDefined( player ) )
{
return player;
}
else
{
if ( isDefined( ks ) && isDefined( player ) )
{
if ( cointoss() )
{
return ks;
}
return player;
}
}
}
return undefined;
}
projectile_find_target_killstreak( acceptskyexposure )
{
ks = [];
ks[ "offset" ] = vectorScale( ( 0, 0, 1 ), 10 );
targets = target_getarray();
rcbombs = getentarray( "rcbomb", "targetname" );
satellites = getentarray( "satellite", "targetname" );
dogs = maps/mp/killstreaks/_dogs::dog_manager_get_dogs();
targets = arraycombine( targets, rcbombs, 1, 0 );
targets = arraycombine( targets, satellites, 1, 0 );
targets = arraycombine( targets, dogs, 1, 0 );
if ( targets.size <= 0 )
{
return undefined;
}
targets = arraysort( targets, self.origin );
_a634 = targets;
_k634 = getFirstArrayKey( _a634 );
while ( isDefined( _k634 ) )
{
target = _a634[ _k634 ];
if ( isDefined( target.owner ) && target.owner == self.owner )
{
}
else
{
if ( isDefined( target.script_owner ) && target.script_owner == self.owner )
{
break;
}
else
{
if ( level.teambased && isDefined( target.team ) )
{
if ( target.team == self.team )
{
break;
}
}
else if ( level.teambased && isDefined( target.aiteam ) )
{
if ( target.aiteam == self.team )
{
break;
}
}
else
{
if ( bullettracepassed( self.origin, target.origin, 0, target ) )
{
ks[ "entity" ] = target;
return ks;
}
if ( acceptskyexposure && cointoss() )
{
end = target.origin + vectorScale( ( 0, 0, 1 ), 2048 );
if ( bullettracepassed( target.origin, end, 0, target ) )
{
ks[ "entity" ] = target;
return ks;
}
}
}
}
}
_k634 = getNextArrayKey( _a634, _k634 );
}
return undefined;
}
projectile_find_target_player( acceptexposedtosky )
{
target = [];
players = get_players();
players = arraysort( players, self.origin );
_a692 = players;
_k692 = getFirstArrayKey( _a692 );
while ( isDefined( _k692 ) )
{
player = _a692[ _k692 ];
if ( !player_valid_target( player, self.team, self.owner ) )
{
}
else
{
if ( bullettracepassed( self.origin, player.origin, 0, player ) )
{
target[ "entity" ] = player;
target[ "offset" ] = ( 0, 0, 1 );
return target;
}
if ( bullettracepassed( self.origin, player geteye(), 0, player ) )
{
target[ "entity" ] = player;
target[ "offset" ] = vectorScale( ( 0, 0, 1 ), 50 );
return target;
}
if ( acceptexposedtosky && cointoss() )
{
end = player.origin + vectorScale( ( 0, 0, 1 ), 2048 );
if ( bullettracepassed( player.origin, end, 0, player ) )
{
target[ "entity" ] = player;
target[ "offset" ] = vectorScale( ( 0, 0, 1 ), 30 );
return target;
}
}
}
_k692 = getNextArrayKey( _a692, _k692 );
}
return undefined;
}
create_player_targeting_array( owner, team )
{
level.playertargetedtimes = [];
players = get_players();
_a739 = players;
_k739 = getFirstArrayKey( _a739 );
while ( isDefined( _k739 ) )
{
player = _a739[ _k739 ];
if ( !player_valid_target( player, team, owner ) )
{
}
else
{
level.playertargetedtimes[ player.clientid ] = 0;
}
_k739 = getNextArrayKey( _a739, _k739 );
}
}
projectile_find_random_player( owner, team )
{
players = get_players();
lowest = 10000;
_a757 = players;
_k757 = getFirstArrayKey( _a757 );
while ( isDefined( _k757 ) )
{
player = _a757[ _k757 ];
if ( !player_valid_target( player, team, owner ) )
{
}
else
{
if ( !isDefined( level.playertargetedtimes[ player.clientid ] ) )
{
level.playertargetedtimes[ player.clientid ] = 0;
}
if ( level.playertargetedtimes[ player.clientid ] < lowest || level.playertargetedtimes[ player.clientid ] == lowest && randomint( 100 ) > 50 )
{
target = player;
lowest = level.playertargetedtimes[ player.clientid ];
}
}
_k757 = getNextArrayKey( _a757, _k757 );
}
if ( isDefined( target ) )
{
level.playertargetedtimes[ target.clientid ] += 1;
return target;
}
return undefined;
}
player_valid_target( player, team, owner )
{
if ( player.sessionstate != "playing" )
{
return 0;
}
if ( !isalive( player ) )
{
return 0;
}
if ( player == owner )
{
return 0;
}
if ( level.teambased )
{
if ( team == player.team )
{
return 0;
}
}
if ( player cantargetplayerwithspecialty() == 0 )
{
return 0;
}
if ( isDefined( player.lastspawntime ) && ( getTime() - player.lastspawntime ) < 3000 )
{
return 0;
}
/#
if ( player isinmovemode( "ufo", "noclip" ) )
{
return 0;
#/
}
return 1;
}

View File

@ -0,0 +1,367 @@
#include maps/mp/_challenges;
#include maps/mp/_scoreevents;
#include maps/mp/gametypes/_spawning;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_killstreaks;
#include maps/mp/killstreaks/_airsupport;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
precachemodel( "veh_t6_air_fa38_killstreak" );
precachemodel( "veh_t6_air_fa38_killstreak_alt" );
precachelocationselector( "map_mortar_selector" );
level.planemortarexhaustfx = loadfx( "vehicle/exhaust/fx_exhaust_f35_afterburner" );
registerclientfield( "scriptmover", "planemortar_contrail", 1, 1, "int" );
maps/mp/killstreaks/_killstreaks::registerkillstreak( "planemortar_mp", "planemortar_mp", "killstreak_planemortar", "planemortar_used", ::usekillstreakplanemortar, 1 );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "planemortar_mp", &"MP_EARNED_PLANEMORTAR", &"KILLSTREAK_PLANEMORTAR_NOT_AVAILABLE", &"MP_WAR_PLANEMORTAR_INBOUND", &"MP_WAR_PLANEMORTAR_INBOUND_NEAR_YOUR_POSITION" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "planemortar_mp", "mpl_killstreak_planemortar", "kls_planemortar_used", "", "kls_planemortar_enemy", "", "kls_planemortar_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "planemortar_mp", "scr_giveplanemortar" );
maps/mp/killstreaks/_killstreaks::setkillstreakteamkillpenaltyscale( "planemortar_mp", level.teamkillreducedpenalty );
}
usekillstreakplanemortar( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
self thread playpilotdialog( "a10_used", 1,5 );
result = self selectplanemortarlocation( hardpointtype );
if ( !isDefined( result ) || !result )
{
return 0;
}
return 1;
}
waittill_confirm_location()
{
self endon( "emp_jammed" );
self endon( "emp_grenaded" );
self waittill( "confirm_location", location );
return location;
}
selectplanemortarlocation( hardpointtype )
{
self beginlocationmortarselection( "map_mortar_selector", 800 );
self.selectinglocation = 1;
self thread endselectionthink();
locations = [];
if ( !isDefined( self.pers[ "mortarRadarUsed" ] ) || !self.pers[ "mortarRadarUsed" ] )
{
self thread singleradarsweep();
}
i = 0;
while ( i < 3 )
{
location = self waittill_confirm_location();
if ( !isDefined( self ) )
{
return 0;
}
if ( !isDefined( location ) )
{
self.pers[ "mortarRadarUsed" ] = 1;
self notify( "cancel_selection" );
return 0;
}
locations[ i ] = location;
i++;
}
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
self.pers[ "mortarRadarUsed" ] = 1;
self notify( "cancel_selection" );
return 0;
}
self.pers[ "mortarRadarUsed" ] = 0;
return self finishhardpointlocationusage( locations, ::useplanemortar );
}
playpilotdialog( dialog, waittime )
{
if ( isDefined( waittime ) )
{
wait waittime;
}
self.pilotvoicenumber = self.bcvoicenumber + 1;
soundalias = level.teamprefix[ self.team ] + self.pilotvoicenumber + "_" + dialog;
while ( isDefined( self ) )
{
while ( self.pilotisspeaking )
{
while ( self.pilotisspeaking )
{
wait 0,2;
}
}
}
if ( isDefined( self ) )
{
self playlocalsound( soundalias );
self.pilotisspeaking = 1;
self thread waitplaybacktime( soundalias );
self waittill_any( soundalias, "death", "disconnect" );
if ( isDefined( self ) )
{
self.pilotisspeaking = 0;
}
}
}
waitplaybacktime( soundalias )
{
self endon( "death" );
self endon( "disconnect" );
playbacktime = soundgetplaybacktime( soundalias );
if ( playbacktime >= 0 )
{
waittime = playbacktime * 0,001;
wait waittime;
}
else
{
wait 1;
}
self notify( soundalias );
}
singleradarsweep()
{
self endon( "disconnect" );
self endon( "cancel_selection" );
wait 0,5;
self playlocalsound( "mpl_killstreak_satellite" );
if ( level.teambased )
{
has_satellite = level.activesatellites[ self.team ] > 0;
}
else
{
has_satellite = level.activesatellites[ self.entnum ] > 0;
}
if ( self.hasspyplane == 0 && !has_satellite && !level.forceradar )
{
self thread doradarsweep();
}
}
doradarsweep()
{
self setclientuivisibilityflag( "g_compassShowEnemies", 1 );
wait 0,2;
self setclientuivisibilityflag( "g_compassShowEnemies", 0 );
}
useplanemortar( positions )
{
team = self.team;
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( "planemortar_mp", team, 0, 1 );
if ( killstreak_id == -1 )
{
return 0;
}
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "planemortar_mp", team, 1 );
level.globalkillstreakscalled++;
self addweaponstat( "planemortar_mp", "used", 1 );
self thread planemortar_watchforendnotify( team, killstreak_id );
self thread doplanemortar( positions, team, killstreak_id );
return 1;
}
doplanemortar( positions, team, killstreak_id )
{
self endon( "emp_jammed" );
self endon( "disconnect" );
yaw = randomintrange( 0, 360 );
odd = 0;
wait 1,25;
_a221 = positions;
_k221 = getFirstArrayKey( _a221 );
while ( isDefined( _k221 ) )
{
position = _a221[ _k221 ];
maps/mp/gametypes/_spawning::create_artillery_influencers( position, -1 );
self thread dobombrun( position, yaw, team );
if ( odd == 0 )
{
yaw = ( yaw + 35 ) % 360;
}
else
{
yaw = ( yaw + 290 ) % 360;
}
odd = ( odd + 1 ) % 2;
wait 0,8;
_k221 = getNextArrayKey( _a221, _k221 );
}
self notify( "planemortarcomplete" );
wait 1;
self thread plane_mortar_bda_dialog();
}
plane_mortar_bda_dialog()
{
if ( !isDefined( self.planemortarbda ) )
{
self.planemortarbda = 0;
}
if ( self.planemortarbda == 0 )
{
bdadialog = "kls_killn";
}
if ( self.planemortarbda == 1 )
{
bdadialog = "kls_kill1";
}
if ( self.planemortarbda == 2 )
{
bdadialog = "kls_kill2";
}
if ( self.planemortarbda == 3 )
{
bdadialog = "kls_kill3";
}
if ( self.planemortarbda > 3 )
{
bdadialog = "kls_killm";
}
if ( isDefined( bdadialog ) )
{
self thread playpilotdialog( bdadialog );
}
self.planemortarbda = 0;
}
planemortar_watchforendnotify( team, killstreak_id )
{
self waittill_any( "disconnect", "joined_team", "joined_spectators", "planemortarcomplete", "emp_jammed" );
planemortar_killstreakstop( team, killstreak_id );
}
planemortar_killstreakstop( team, killstreak_id )
{
maps/mp/killstreaks/_killstreakrules::killstreakstop( "planemortar_mp", team, killstreak_id );
}
dobombrun( position, yaw, team )
{
self endon( "emp_jammed" );
player = self;
angles = ( 0, yaw, 0 );
direction = anglesToForward( angles );
height = maps/mp/killstreaks/_airsupport::getminimumflyheight() + 2000;
position = ( position[ 0 ], position[ 1 ], height );
startpoint = position + vectorScale( direction, -12000 );
endpoint = position + vectorScale( direction, 18000 );
height = getnoflyzoneheightcrossed( startpoint, endpoint, height );
startpoint = ( startpoint[ 0 ], startpoint[ 1 ], height );
position = ( position[ 0 ], position[ 1 ], height );
endpoint = ( endpoint[ 0 ], endpoint[ 1 ], height );
plane = spawnplane( self, "script_model", startpoint );
plane.team = team;
plane.targetname = "plane_mortar";
plane.owner = self;
plane endon( "delete" );
plane endon( "death" );
plane thread planewatchforemp( self );
plane.angles = angles;
plane setmodel( "veh_t6_air_fa38_killstreak" );
plane setenemymodel( "veh_t6_air_fa38_killstreak_alt" );
plane setclientfield( "planemortar_contrail", 1 );
plane playsound( "mpl_lightning_flyover_boom" );
plane setdrawinfrared( 1 );
plane.killcament = spawn( "script_model", plane.origin + vectorScale( ( 0, 0, -1 ), 700 ) + vectorScale( direction, -1500 ) );
plane.killcament deleteaftertime( 2 * 3 );
plane.killcament.angles = ( 15, yaw, 0 );
plane.killcament.starttime = getTime();
plane.killcament linkto( plane );
start = ( position[ 0 ], position[ 1 ], plane.origin[ 2 ] );
impact = bullettrace( start, start + vectorScale( ( 0, 0, -1 ), 100000 ), 1, plane );
plane moveto( endpoint, ( 2 * 5 ) / 4, 0, 0 );
plane.killcament thread followbomb( plane, position, direction, impact, player );
wait ( 2 / 2 );
if ( isDefined( self ) )
{
self thread dropbomb( plane, position );
}
wait ( ( 2 * 3 ) / 4 );
plane plane_cleanupondeath();
}
followbomb( plane, position, direction, impact, player )
{
player endon( "emp_jammed" );
wait ( ( 2 * 5 ) / 12 );
plane.killcament unlink();
plane.killcament moveto( impact[ "position" ] + vectorScale( ( 0, 0, -1 ), 1000 ) + vectorScale( direction, -600 ), 0,8, 0, 0,2 );
}
lookatexplosion( bomb )
{
while ( isDefined( self ) && isDefined( bomb ) )
{
angles = vectorToAngle( vectornormalize( bomb.origin - self.origin ) );
self.angles = ( max( angles[ 0 ], 15 ), angles[ 1 ], angles[ 2 ] );
wait 0,05;
}
}
planewatchforemp( owner )
{
self endon( "delete" );
self endon( "death" );
self waittill( "emp_deployed", attacker );
thread planeawardscoreevent( attacker, self );
self plane_cleanupondeath();
}
planeawardscoreevent( attacker, victim )
{
attacker endon( "disconnect" );
attacker notify( "planeAwardScoreEvent_singleton" );
attacker endon( "planeAwardScoreEvent_singleton" );
waittillframeend;
maps/mp/_scoreevents::processscoreevent( "destroyed_plane_mortar", attacker, victim, "emp_mp" );
attacker maps/mp/_challenges::addflyswatterstat( "emp_mp" );
}
plane_cleanupondeath()
{
self delete();
}
dropbomb( plane, bombposition )
{
if ( !isDefined( plane.owner ) )
{
return;
}
targets = getplayers();
_a407 = targets;
_k407 = getFirstArrayKey( _a407 );
while ( isDefined( _k407 ) )
{
target = _a407[ _k407 ];
if ( plane.owner isenemyplayer( target ) && distance2dsquared( target.origin, bombposition ) < 250000 )
{
if ( bullettracepassed( ( target.origin[ 0 ], target.origin[ 1 ], plane.origin[ 2 ] ), target.origin, 0, plane ) )
{
bombposition = target.origin;
break;
}
}
else
{
_k407 = getNextArrayKey( _a407, _k407 );
}
}
bombposition = ( bombposition[ 0 ], bombposition[ 1 ], plane.origin[ 2 ] );
bomb = self launchbomb( "planemortar_mp", bombposition, vectorScale( ( 0, 0, -1 ), 5000 ) );
bomb playsound( "mpl_lightning_bomb_incoming" );
bomb.killcament = plane.killcament;
plane.killcament thread lookatexplosion( bomb );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,292 @@
#include maps/mp/_popups;
#include maps/mp/killstreaks/_spyplane;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_killstreaks;
#include maps/mp/gametypes/_tweakables;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
setmatchflag( "radar_allies", 0 );
setmatchflag( "radar_axis", 0 );
level.spyplane = [];
level.counterspyplane = [];
level.satellite = [];
level.spyplanetype = [];
level.satellitetype = [];
level.radartimers = [];
_a14 = level.teams;
_k14 = getFirstArrayKey( _a14 );
while ( isDefined( _k14 ) )
{
team = _a14[ _k14 ];
level.radartimers[ team ] = getTime();
_k14 = getNextArrayKey( _a14, _k14 );
}
level.spyplaneviewtime = 25;
level.counteruavviewtime = 30;
level.radarlongviewtime = 45;
if ( maps/mp/gametypes/_tweakables::gettweakablevalue( "killstreak", "allowradar" ) )
{
maps/mp/killstreaks/_killstreaks::registerkillstreak( "radar_mp", "radar_mp", "killstreak_spyplane", "uav_used", ::usekillstreakradar );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "radar_mp", &"KILLSTREAK_EARNED_RADAR", &"KILLSTREAK_RADAR_NOT_AVAILABLE", &"KILLSTREAK_RADAR_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "radar_mp", "mpl_killstreak_radar", "kls_u2_used", "", "kls_u2_enemy", "", "kls_u2_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "radar_mp", "scr_giveradar" );
maps/mp/killstreaks/_killstreaks::createkillstreaktimer( "radar_mp" );
}
if ( maps/mp/gametypes/_tweakables::gettweakablevalue( "killstreak", "allowcounteruav" ) )
{
maps/mp/killstreaks/_killstreaks::registerkillstreak( "counteruav_mp", "counteruav_mp", "killstreak_counteruav", "counteruav_used", ::usekillstreakcounteruav );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "counteruav_mp", &"KILLSTREAK_EARNED_COUNTERUAV", &"KILLSTREAK_COUNTERUAV_NOT_AVAILABLE", &"KILLSTREAK_COUNTERUAV_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "counteruav_mp", "mpl_killstreak_radar", "kls_cu2_used", "", "kls_cu2_enemy", "", "kls_cu2_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "counteruav_mp", "scr_givecounteruav" );
maps/mp/killstreaks/_killstreaks::createkillstreaktimer( "counteruav_mp" );
}
if ( maps/mp/gametypes/_tweakables::gettweakablevalue( "killstreak", "allowradardirection" ) )
{
maps/mp/killstreaks/_killstreaks::registerkillstreak( "radardirection_mp", "radardirection_mp", "killstreak_spyplane_direction", "uav_used", ::usekillstreaksatellite );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "radardirection_mp", &"KILLSTREAK_EARNED_SATELLITE", &"KILLSTREAK_SATELLITE_NOT_AVAILABLE", &"KILLSTREAK_SATELLITE_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "radardirection_mp", "mpl_killstreak_satellite", "kls_sat_used", "", "kls_sat_enemy", "", "kls_sat_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "radardirection_mp", "scr_giveradardirection" );
maps/mp/killstreaks/_killstreaks::createkillstreaktimer( "radardirection_mp" );
}
}
usekillstreakradar( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team );
if ( killstreak_id == -1 )
{
return 0;
}
return self maps/mp/killstreaks/_spyplane::callspyplane( hardpointtype, 0, killstreak_id );
}
usekillstreakcounteruav( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team );
if ( killstreak_id == -1 )
{
return 0;
}
return self maps/mp/killstreaks/_spyplane::callcounteruav( hardpointtype, 0, killstreak_id );
}
usekillstreaksatellite( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team );
if ( killstreak_id == -1 )
{
return 0;
}
return self maps/mp/killstreaks/_spyplane::callsatellite( hardpointtype, 0, killstreak_id );
}
teamhasspyplane( team )
{
return getteamspyplane( team ) > 0;
}
teamhassatellite( team )
{
return getteamsatellite( team ) > 0;
}
useradaritem( hardpointtype, team, displaymessage )
{
team = self.team;
/#
assert( isDefined( level.players ) );
#/
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( hardpointtype, team );
if ( level.teambased )
{
if ( !isDefined( level.spyplane[ team ] ) )
{
level.spyplanetype[ team ] = 0;
}
currenttypespyplane = level.spyplanetype[ team ];
if ( !isDefined( level.satellitetype[ team ] ) )
{
level.satellitetype[ team ] = 0;
}
currenttypesatellite = level.satellitetype[ team ];
}
else
{
if ( !isDefined( self.pers[ "spyplaneType" ] ) )
{
self.pers[ "spyplaneType" ] = 0;
}
currenttypespyplane = self.pers[ "spyplaneType" ];
if ( !isDefined( self.pers[ "satelliteType" ] ) )
{
self.pers[ "satelliteType" ] = 0;
}
currenttypesatellite = self.pers[ "satelliteType" ];
}
radarviewtype = 0;
normal = 1;
fastsweep = 2;
notifystring = "";
issatellite = 0;
isradar = 0;
iscounteruav = 0;
viewtime = level.spyplaneviewtime;
switch( hardpointtype )
{
case "radar_mp":
notifystring = "spyplane";
isradar = 1;
viewtime = level.spyplaneviewtime;
level.globalkillstreakscalled++;
self addweaponstat( hardpointtype, "used", 1 );
break;
case "radardirection_mp":
notifystring = "satellite";
issatellite = 1;
viewtime = level.radarlongviewtime;
level notify( "satelliteInbound" );
level.globalkillstreakscalled++;
self addweaponstat( hardpointtype, "used", 1 );
break;
case "counteruav_mp":
notifystring = "counteruav";
iscounteruav = 1;
viewtime = level.counteruavviewtime;
level.globalkillstreakscalled++;
self addweaponstat( hardpointtype, "used", 1 );
break;
}
if ( displaymessage )
{
if ( isDefined( level.killstreaks[ hardpointtype ] ) && isDefined( level.killstreaks[ hardpointtype ].inboundtext ) )
{
level thread maps/mp/_popups::displaykillstreakteammessagetoall( hardpointtype, self );
}
}
return viewtime;
}
resetspyplanetypeonend( type )
{
self waittill( type + "_timer_kill" );
self.pers[ "spyplane" ] = 0;
}
resetsatellitetypeonend( type )
{
self waittill( type + "_timer_kill" );
self.pers[ "satellite" ] = 0;
}
setteamspyplanewrapper( team, value )
{
setteamspyplane( team, value );
if ( team == "allies" )
{
setmatchflag( "radar_allies", value );
}
else
{
if ( team == "axis" )
{
setmatchflag( "radar_axis", value );
}
}
while ( level.multiteam == 1 )
{
_a205 = level.players;
_k205 = getFirstArrayKey( _a205 );
while ( isDefined( _k205 ) )
{
player = _a205[ _k205 ];
if ( player.team == team )
{
player setclientuivisibilityflag( "radar_client", value );
}
_k205 = getNextArrayKey( _a205, _k205 );
}
}
level notify( "radar_status_change" );
}
setteamsatellitewrapper( team, value )
{
setteamsatellite( team, value );
if ( team == "allies" )
{
setmatchflag( "radar_allies", value );
}
else
{
if ( team == "axis" )
{
setmatchflag( "radar_axis", value );
}
}
while ( level.multiteam == 1 )
{
_a228 = level.players;
_k228 = getFirstArrayKey( _a228 );
while ( isDefined( _k228 ) )
{
player = _a228[ _k228 ];
if ( player.team == team )
{
player setclientuivisibilityflag( "radar_client", value );
}
_k228 = getNextArrayKey( _a228, _k228 );
}
}
level notify( "radar_status_change" );
}
enemyobituarytext( type, numseconds )
{
switch( type )
{
case "radarupdate_mp":
self iprintln( &"MP_WAR_RADAR_ACQUIRED_UPDATE_ENEMY", numseconds );
break;
case "radardirection_mp":
self iprintln( &"MP_WAR_RADAR_ACQUIRED_DIRECTION_ENEMY", numseconds );
break;
case "counteruav_mp":
self iprintln( &"MP_WAR_RADAR_COUNTER_UAV_ACQUIRED_ENEMY", numseconds );
break;
default:
self iprintln( &"MP_WAR_RADAR_ACQUIRED_ENEMY", numseconds );
}
}
friendlyobituarytext( type, callingplayer, numseconds )
{
switch( type )
{
case "radarupdate_mp":
self iprintln( &"MP_WAR_RADAR_UPDATE_ACQUIRED", callingplayer, numseconds );
break;
case "radardirection_mp":
self iprintln( &"MP_WAR_RADAR_DIRECTION_ACQUIRED", callingplayer, numseconds );
break;
case "counteruav_mp":
self iprintln( &"MP_WAR_RADAR_COUNTER_UAV_ACQUIRED", numseconds );
break;
default:
self iprintln( &"MP_WAR_RADAR_ACQUIRED", callingplayer, numseconds );
}
}

View File

@ -0,0 +1,792 @@
#include maps/mp/_challenges;
#include maps/mp/gametypes/_shellshock;
#include maps/mp/killstreaks/_emp;
#include maps/mp/gametypes/_hostmigration;
#include maps/mp/gametypes/_hud;
#include maps/mp/_popups;
#include maps/mp/gametypes/_weaponobjects;
#include maps/mp/gametypes/_globallogic_utils;
#include maps/mp/_flashgrenades;
#include maps/mp/_scoreevents;
#include maps/mp/gametypes/_spawning;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_killstreaks;
#include maps/mp/gametypes/_tweakables;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
precachemodel( "veh_t6_drone_rcxd" );
precachemodel( "veh_t6_drone_rcxd_alt" );
precachevehicle( "rc_car_medium_mp" );
precacherumble( "rcbomb_engine_stutter" );
precacherumble( "rcbomb_slide" );
loadtreadfx( "dust" );
loadtreadfx( "concrete" );
loadfx( "weapon/grenade/fx_spark_disabled_rc_car" );
loadfx( "vehicle/light/fx_rcbomb_blinky_light" );
loadfx( "vehicle/light/fx_rcbomb_solid_light" );
loadfx( "vehicle/light/fx_rcbomb_light_green_os" );
loadfx( "vehicle/light/fx_rcbomb_light_red_os" );
maps/mp/_treadfx::preloadtreadfx( "rc_car_medium_mp" );
level._effect[ "rcbombexplosion" ] = loadfx( "maps/mp_maps/fx_mp_exp_rc_bomb" );
car_size = getDvar( "scr_rcbomb_car_size" );
if ( car_size == "" )
{
setdvar( "scr_rcbomb_car_size", "1" );
}
setdvar( "scr_rcbomb_notimeout", 0 );
if ( maps/mp/gametypes/_tweakables::gettweakablevalue( "killstreak", "allowrcbomb" ) )
{
maps/mp/killstreaks/_killstreaks::registerkillstreak( "rcbomb_mp", "rcbomb_mp", "killstreak_rcbomb", "rcbomb_used", ::usekillstreakrcbomb );
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "rcbomb_mp", &"KILLSTREAK_EARNED_RCBOMB", &"KILLSTREAK_RCBOMB_NOT_AVAILABLE", &"KILLSTREAK_RCBOMB_INBOUND" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "rcbomb_mp", "mpl_killstreak_rcbomb", "kls_rcbomb_used", "", "kls_rcbomb_enemy", "", "kls_rcbomb_ready" );
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "rcbomb_mp", "scr_givercbomb" );
maps/mp/killstreaks/_killstreaks::allowkillstreakassists( "rcbomb_mp", 1 );
}
}
register()
{
registerclientfield( "vehicle", "rcbomb_death", 1, 1, "int" );
registerclientfield( "vehicle", "rcbomb_countdown", 1, 2, "int" );
}
loadtreadfx( type )
{
loadfx( "vehicle/treadfx/fx_treadfx_rcbomb_" + type );
loadfx( "vehicle/treadfx/fx_treadfx_rcbomb_" + type + "_drift" );
loadfx( "vehicle/treadfx/fx_treadfx_rcbomb_" + type + "_peel" );
loadfx( "vehicle/treadfx/fx_treadfx_rcbomb_" + type + "_first_person" );
loadfx( "vehicle/treadfx/fx_treadfx_rcbomb_" + type + "_reverse" );
loadfx( "vehicle/treadfx/fx_treadfx_rcbomb_" + type + "_trail" );
loadfx( "vehicle/treadfx/fx_treadfx_rcbomb_" + type + "_slow" );
}
usekillstreakrcbomb( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
if ( !self isonground() || self isusingremote() )
{
self iprintlnbold( &"KILLSTREAK_RCBOMB_NOT_PLACEABLE" );
return 0;
}
placement = self.rcbombplacement;
if ( !isDefined( placement ) )
{
placement = getrcbombplacement();
}
if ( !isDefined( placement ) )
{
self iprintlnbold( &"KILLSTREAK_RCBOMB_NOT_PLACEABLE" );
return 0;
}
if ( maps/mp/killstreaks/_killstreaks::isinteractingwithobject() )
{
self iprintlnbold( &"KILLSTREAK_RCBOMB_NOT_PLACEABLE" );
return 0;
}
self setusingremote( "rcbomb" );
self freezecontrolswrapper( 1 );
result = self maps/mp/killstreaks/_killstreaks::initridekillstreak( "rcbomb" );
if ( result != "success" )
{
if ( result != "disconnect" )
{
self clearusingremote();
}
return 0;
}
if ( level.gameended )
{
return 0;
}
ret = self usercbomb( placement );
if ( !isDefined( ret ) && level.gameended )
{
ret = 1;
}
else
{
if ( !isDefined( ret ) )
{
ret = 0;
}
}
if ( isDefined( self ) )
{
self clearusingremote();
}
return ret;
}
spawnrcbomb( placement, team )
{
car_size = getDvar( "scr_rcbomb_car_size" );
model = "veh_t6_drone_rcxd";
enemymodel = "veh_t6_drone_rcxd_alt";
death_model = "veh_t6_drone_rcxd";
car = "rc_car_medium_mp";
vehicle = spawnvehicle( model, "rcbomb", car, placement.origin, placement.angles );
vehicle makevehicleunusable();
vehicle.death_model = death_model;
vehicle.allowfriendlyfiredamageoverride = ::rccarallowfriendlyfiredamage;
vehicle setenemymodel( enemymodel );
vehicle enableaimassist();
vehicle setowner( self );
vehicle setvehicleteam( team );
vehicle.team = team;
vehicle setdrawinfrared( 1 );
maps/mp/_treadfx::loadtreadfx( vehicle );
vehicle maps/mp/gametypes/_spawning::create_rcbomb_influencers( team );
return vehicle;
}
getrcbombplacement()
{
return calculatespawnorigin( self.origin, self.angles );
}
giveplayercontrolofrcbomb()
{
self endon( "disconnect" );
level endon( "game_ended" );
self thread maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "rcbomb_mp", self.team );
level.globalkillstreakscalled++;
self addweaponstat( "rcbomb_mp", "used", 1 );
xpamount = maps/mp/killstreaks/_killstreaks::getxpamountforkillstreak( "rcbomb_mp" );
if ( maps/mp/_scoreevents::shouldaddrankxp( self ) )
{
self addrankxpvalue( "killstreakCalledIn", xpamount );
}
self freeze_player_controls( 0 );
self.rcbomb usevehicle( self, 0 );
self thread playerdisconnectwaiter( self.rcbomb );
self thread cardetonatewaiter( self.rcbomb );
self thread exitcarwaiter( self.rcbomb );
self thread gameendwatcher( self.rcbomb );
self thread changeteamwaiter( self.rcbomb );
self.rcbomb thread maps/mp/_flashgrenades::monitorrcbombflash();
self thread cartimer( self.rcbomb );
self waittill( "rcbomb_done" );
}
usercbomb( placement )
{
self endon( "disconnect" );
level endon( "game_ended" );
hardpointtype = "rcbomb_mp";
maps/mp/gametypes/_globallogic_utils::waittillslowprocessallowed();
if ( isDefined( self ) && isalive( self ) || self isremotecontrolling() && self maps/mp/killstreaks/_killstreaks::isinteractingwithobject() )
{
self iprintlnbold( &"KILLSTREAK_RCBOMB_NOT_PLACEABLE" );
return 0;
}
if ( !isDefined( self.rcbomb ) )
{
self.rcbomb = self spawnrcbomb( placement, self.team );
self.rcbomb thread carcleanupwaiter( self.rcbomb );
self.rcbomb thread trigger_hurt_monitor();
self.rcbomb.team = self.team;
if ( !isDefined( self.rcbomb ) )
{
return 0;
}
self maps/mp/gametypes/_weaponobjects::addweaponobjecttowatcher( "rcbomb", self.rcbomb );
}
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team, undefined, 0 );
if ( killstreak_id == -1 )
{
if ( isDefined( self.rcbomb ) )
{
self.rcbomb delete();
}
return 0;
}
self.rcbomb.killstreak_id = killstreak_id;
self.enteringvehicle = 1;
self thread updatekillstreakondisconnect();
self thread updatekillstreakondeletion( self.team );
self freeze_player_controls( 1 );
if ( isDefined( self ) || !isalive( self ) && !isDefined( self.rcbomb ) )
{
if ( isDefined( self ) )
{
self.enteringvehicle = 0;
self notify( "weapon_object_destroyed" );
}
return 0;
}
self thread giveplayercontrolofrcbomb();
self.rcbomb thread watchforscramblers();
self.killstreak_waitamount = 30000;
self.enteringvehicle = 0;
self stopshellshock();
if ( isDefined( level.killstreaks[ hardpointtype ] ) && isDefined( level.killstreaks[ hardpointtype ].inboundtext ) )
{
level thread maps/mp/_popups::displaykillstreakteammessagetoall( hardpointtype, self );
}
if ( isDefined( level.rcbomb_vision ) )
{
self thread setvisionsetwaiter();
}
self updaterulesonend();
return 1;
}
watchforscramblers()
{
self endon( "death" );
while ( 1 )
{
scrambled = self getclientflag( 9 );
shouldscramble = 0;
players = level.players;
i = 0;
while ( i < players.size )
{
if ( !isDefined( players[ i ] ) || !isDefined( players[ i ].scrambler ) )
{
i++;
continue;
}
else
{
player = players[ i ];
scrambler = player.scrambler;
if ( level.teambased && self.team == player.team )
{
i++;
continue;
}
else
{
if ( !level.teambased && self.owner == player )
{
i++;
continue;
}
else
{
if ( distancesquared( scrambler.origin, self.origin ) < level.scramblerinnerradiussq )
{
shouldscramble = 1;
break;
}
}
}
}
else
{
i++;
}
}
if ( shouldscramble == 1 && scrambled == 0 )
{
self setclientflag( 9 );
}
else
{
if ( shouldscramble == 0 && scrambled == 1 )
{
self clearclientflag( 9 );
}
}
wait_delay = randomfloatrange( 0,25, 0,5 );
wait wait_delay;
}
}
updaterulesonend()
{
team = self.rcbomb.team;
killstreak_id = self.rcbomb.killstreak_id;
self endon( "disconnect" );
self waittill( "rcbomb_done" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( "rcbomb_mp", team, killstreak_id );
}
updatekillstreakondisconnect()
{
team = self.rcbomb.team;
killstreak_id = self.rcbomb.killstreak_id;
self endon( "rcbomb_done" );
self waittill( "disconnect" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( "rcbomb_mp", team, killstreak_id );
}
updatekillstreakondeletion( team )
{
killstreak_id = self.rcbomb.killstreak_id;
self endon( "disconnect" );
self endon( "rcbomb_done" );
self waittill( "weapon_object_destroyed" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( "rcbomb_mp", team, killstreak_id );
if ( isDefined( self.rcbomb ) )
{
self.rcbomb delete();
}
}
cardetonatewaiter( vehicle )
{
self endon( "disconnect" );
vehicle endon( "death" );
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcher( "rcbomb" );
while ( !self attackbuttonpressed() )
{
wait 0,05;
}
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( vehicle, 0 );
self thread maps/mp/gametypes/_hud::fadetoblackforxsec( getDvarFloat( #"CDE26736" ), getDvarFloat( #"AFCAD5CD" ), getDvarFloat( #"88490433" ), getDvarFloat( #"A925AA4E" ) );
}
jumpwaiter( vehicle )
{
self endon( "disconnect" );
vehicle endon( "death" );
self.jump_hud = newclienthudelem( self );
self.jump_hud.alignx = "left";
self.jump_hud.aligny = "bottom";
self.jump_hud.horzalign = "user_left";
self.jump_hud.vertalign = "user_bottom";
self.jump_hud.font = "small";
self.jump_hud.hidewheninmenu = 1;
self.jump_hud.x = 5;
self.jump_hud.y = -60;
self.jump_hud.fontscale = 1,25;
while ( 1 )
{
self.jump_hud settext( "[{+gostand}]" + "Jump" );
if ( self jumpbuttonpressed() )
{
vehicle launchvehicle( ( 0, 0, 1 ) * -10, vehicle.origin, 0 );
self.jump_hud settext( "" );
wait 5;
}
wait 0,05;
}
}
playerdisconnectwaiter( vehicle )
{
vehicle endon( "death" );
self endon( "rcbomb_done" );
self waittill( "disconnect" );
vehicle delete();
}
gameendwatcher( vehicle )
{
vehicle endon( "death" );
self endon( "rcbomb_done" );
level waittill( "game_ended" );
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcher( "rcbomb" );
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( vehicle, 0 );
self thread maps/mp/gametypes/_hud::fadetoblackforxsec( getDvarFloat( #"CDE26736" ), getDvarFloat( #"AFCAD5CD" ), getDvarFloat( #"88490433" ), getDvarFloat( #"A925AA4E" ) );
}
exitcarwaiter( vehicle )
{
self endon( "disconnect" );
self waittill( "unlink" );
self notify( "rcbomb_done" );
}
changeteamwaiter( vehicle )
{
self endon( "disconnect" );
self endon( "rcbomb_done" );
vehicle endon( "death" );
self waittill_either( "joined_team", "joined_spectators" );
vehicle.owner unlink();
self.killstreak_waitamount = undefined;
vehicle delete();
}
cardeathwaiter( vehicle )
{
self endon( "disconnect" );
self endon( "rcbomb_done" );
self waittill( "death" );
maps/mp/killstreaks/_killstreaks::removeusedkillstreak( "rcbomb_mp" );
self notify( "rcbomb_done" );
}
carcleanupwaiter( vehicle )
{
self endon( "disconnect" );
self waittill( "death" );
self.rcbomb = undefined;
}
setvisionsetwaiter()
{
self endon( "disconnect" );
self useservervisionset( 1 );
self setvisionsetforplayer( level.rcbomb_vision, 1 );
self waittill( "rcbomb_done" );
self useservervisionset( 0 );
}
cartimer( vehicle )
{
self endon( "disconnect" );
vehicle endon( "death" );
if ( !level.vehiclestimed )
{
return;
}
/#
if ( getDvarInt( "scr_rcbomb_notimeout" ) != 0 )
{
return;
#/
}
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpause( 20 );
vehicle setclientfield( "rcbomb_countdown", 1 );
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpause( 6 );
vehicle setclientfield( "rcbomb_countdown", 2 );
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpause( 4 );
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcher( "rcbomb" );
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( vehicle, 0 );
}
detonateiftouchingsphere( origin, radius )
{
if ( distancesquared( self.origin, origin ) < ( radius * radius ) )
{
self rcbomb_force_explode();
}
}
detonatealliftouchingsphere( origin, radius )
{
rcbombs = getentarray( "rcbomb", "targetname" );
index = 0;
while ( index < rcbombs.size )
{
rcbombs[ index ] detonateiftouchingsphere( origin, radius );
index++;
}
}
blowup( attacker, weaponname )
{
self.owner endon( "disconnect" );
self endon( "death" );
explosionorigin = self.origin;
explosionangles = self.angles;
if ( !isDefined( attacker ) )
{
attacker = self.owner;
}
from_emp = maps/mp/killstreaks/_emp::isempweapon( weaponname );
origin = self.origin + vectorScale( ( 0, 0, 1 ), 10 );
radius = 256;
min_damage = 25;
max_damage = 350;
if ( !from_emp )
{
self radiusdamage( origin, radius, max_damage, min_damage, attacker, "MOD_EXPLOSIVE", "rcbomb_mp" );
physicsexplosionsphere( origin, radius, radius, 1, max_damage, min_damage );
maps/mp/gametypes/_shellshock::rcbomb_earthquake( origin );
playsoundatposition( "mpl_rc_exp", self.origin );
playfx( level._effect[ "rcbombexplosion" ], explosionorigin, ( 0, 0, 1 ) );
}
self setmodel( self.death_model );
self hide();
self setclientfield( "rcbomb_death", 1 );
if ( attacker != self.owner && isplayer( attacker ) )
{
attacker maps/mp/_challenges::destroyrcbomb( weaponname );
if ( self.owner isenemyplayer( attacker ) )
{
maps/mp/_scoreevents::processscoreevent( "destroyed_rcbomb", attacker, self.owner, weaponname );
if ( isDefined( weaponname ) )
{
weaponstatname = "destroyed";
attacker addweaponstat( weaponname, weaponstatname, 1 );
level.globalkillstreaksdestroyed++;
attacker addweaponstat( "rcbomb_mp", "destroyed", 1 );
attacker addweaponstat( weaponname, "destroyed_controlled_killstreak", 1 );
}
}
}
wait 1;
if ( isDefined( self.neverdelete ) && self.neverdelete )
{
return;
}
if ( isDefined( self.owner.jump_hud ) )
{
self.owner.jump_hud destroy();
}
self.owner unlink();
if ( isDefined( level.gameended ) && level.gameended )
{
self.owner freezecontrolswrapper( 1 );
}
self.owner.killstreak_waitamount = undefined;
self delete();
}
rccarallowfriendlyfiredamage( einflictor, eattacker, smeansofdeath, sweapon )
{
if ( isDefined( eattacker ) && eattacker == self.owner )
{
return 1;
}
if ( isDefined( einflictor ) && einflictor islinkedto( self ) )
{
return 1;
}
return 0;
}
getplacementstartheight()
{
startheight = 50;
switch( self getstance() )
{
case "crouch":
startheight = 30;
break;
case "prone":
startheight = 15;
break;
}
return startheight;
}
calculatespawnorigin( origin, angles )
{
distance_from_player = 70;
startheight = getplacementstartheight();
mins = vectorScale( ( 0, 0, 1 ), 5 );
maxs = ( 5, 5, 10 );
startpoints = [];
startangles = [];
wheelcounts = [];
testcheck = [];
largestcount = 0;
largestcountindex = 0;
testangles = [];
testangles[ 0 ] = ( 0, 0, 1 );
testangles[ 1 ] = vectorScale( ( 0, 0, 1 ), 20 );
testangles[ 2 ] = vectorScale( ( 0, 0, 1 ), 20 );
testangles[ 3 ] = vectorScale( ( 0, 0, 1 ), 45 );
testangles[ 4 ] = vectorScale( ( 0, 0, 1 ), 45 );
heightoffset = 5;
i = 0;
while ( i < testangles.size )
{
testcheck[ i ] = 0;
startangles[ i ] = ( 0, angles[ 1 ], 0 );
startpoint = origin + vectorScale( anglesToForward( startangles[ i ] + testangles[ i ] ), distance_from_player );
endpoint = startpoint - vectorScale( ( 0, 0, 1 ), 100 );
startpoint += ( 0, 0, startheight );
mask = level.physicstracemaskphysics | level.physicstracemaskvehicle;
trace = physicstrace( startpoint, endpoint, mins, maxs, self, mask );
if ( isDefined( trace[ "entity" ] ) && isplayer( trace[ "entity" ] ) )
{
wheelcounts[ i ] = 0;
i++;
continue;
}
else
{
startpoints[ i ] = trace[ "position" ] + ( 0, 0, heightoffset );
wheelcounts[ i ] = testwheellocations( startpoints[ i ], startangles[ i ], heightoffset );
if ( positionwouldtelefrag( startpoints[ i ] ) )
{
i++;
continue;
}
else
{
if ( largestcount < wheelcounts[ i ] )
{
largestcount = wheelcounts[ i ];
largestcountindex = i;
}
if ( wheelcounts[ i ] >= 3 )
{
testcheck[ i ] = 1;
if ( testspawnorigin( startpoints[ i ], startangles[ i ] ) )
{
placement = spawnstruct();
placement.origin = startpoints[ i ];
placement.angles = startangles[ i ];
return placement;
}
}
}
}
i++;
}
i = 0;
while ( i < testangles.size )
{
if ( !testcheck[ i ] )
{
if ( wheelcounts[ i ] >= 2 )
{
if ( testspawnorigin( startpoints[ i ], startangles[ i ] ) )
{
placement = spawnstruct();
placement.origin = startpoints[ i ];
placement.angles = startangles[ i ];
return placement;
}
}
}
i++;
}
return undefined;
}
testwheellocations( origin, angles, heightoffset )
{
forward = 13;
side = 10;
wheels = [];
wheels[ 0 ] = ( forward, side, 0 );
wheels[ 1 ] = ( forward, -1 * side, 0 );
wheels[ 2 ] = ( -1 * forward, -1 * side, 0 );
wheels[ 3 ] = ( -1 * forward, side, 0 );
height = 5;
touchcount = 0;
yawangles = ( 0, angles[ 1 ], 0 );
i = 0;
while ( i < 4 )
{
wheel = rotatepoint( wheels[ i ], yawangles );
startpoint = origin + wheel;
endpoint = startpoint + ( 0, 0, ( -1 * height ) - heightoffset );
startpoint += ( 0, 0, height - heightoffset );
trace = bullettrace( startpoint, endpoint, 0, self );
if ( trace[ "fraction" ] < 1 )
{
touchcount++;
rcbomb_debug_line( startpoint, endpoint, ( 0, 0, 1 ) );
i++;
continue;
}
else
{
rcbomb_debug_line( startpoint, endpoint, ( 0, 0, 1 ) );
}
i++;
}
return touchcount;
}
testspawnorigin( origin, angles )
{
liftedorigin = origin + vectorScale( ( 0, 0, 1 ), 5 );
size = 12;
height = 15;
mins = ( -1 * size, -1 * size, 0 );
maxs = ( size, size, height );
absmins = liftedorigin + mins;
absmaxs = liftedorigin + maxs;
if ( boundswouldtelefrag( absmins, absmaxs ) )
{
rcbomb_debug_box( liftedorigin, mins, maxs, ( 0, 0, 1 ) );
return 0;
}
else
{
rcbomb_debug_box( liftedorigin, mins, maxs, ( 0, 0, 1 ) );
}
startheight = getplacementstartheight();
mask = level.physicstracemaskphysics | level.physicstracemaskvehicle | level.physicstracemaskwater;
trace = physicstrace( liftedorigin, origin + ( 0, 0, 1 ), mins, maxs, self, mask );
if ( trace[ "fraction" ] < 1 )
{
rcbomb_debug_box( trace[ "position" ], mins, maxs, ( 0, 0, 1 ) );
return 0;
}
else
{
rcbomb_debug_box( origin + ( 0, 0, 1 ), mins, maxs, ( 0, 0, 1 ) );
}
size = 2,5;
height = size * 2;
mins = ( -1 * size, -1 * size, 0 );
maxs = ( size, size, height );
sweeptrace = physicstrace( self.origin + ( 0, 0, startheight ), liftedorigin, mins, maxs, self, mask );
if ( sweeptrace[ "fraction" ] < 1 )
{
rcbomb_debug_box( sweeptrace[ "position" ], mins, maxs, ( 0, 0, 1 ) );
return 0;
}
return 1;
}
trigger_hurt_monitor()
{
self endon( "death" );
for ( ;; )
{
self waittill( "touch", ent );
if ( ent.classname == "trigger_hurt" )
{
if ( level.script == "mp_castaway" )
{
if ( ent.spawnflags & 16 )
{
if ( self depthinwater() < 23 )
{
break;
}
}
}
else
{
self rcbomb_force_explode();
return;
}
}
}
}
rcbomb_force_explode()
{
self endon( "death" );
/#
assert( self.targetname == "rcbomb" );
#/
while ( !isDefined( self getseatoccupant( 0 ) ) )
{
wait 0,1;
}
self dodamage( 10, self.origin + vectorScale( ( 0, 0, 1 ), 10 ), self.owner, self.owner, "none", "MOD_EXPLOSIVE" );
}
rcbomb_debug_box( origin, mins, maxs, color )
{
/#
debug_rcbomb = getDvar( #"8EAE5CA0" );
if ( debug_rcbomb == "1" )
{
box( origin, mins, maxs, 0, color, 1, 1, 300 );
#/
}
}
rcbomb_debug_line( start, end, color )
{
/#
debug_rcbomb = getDvar( #"8EAE5CA0" );
if ( debug_rcbomb == "1" )
{
line( start, end, color, 1, 1, 300 );
#/
}
}

View File

@ -0,0 +1,496 @@
#include maps/mp/gametypes/_hud;
#include maps/mp/killstreaks/_killstreaks;
#include maps/mp/killstreaks/_ai_tank;
#include maps/mp/killstreaks/_turret_killstreak;
#include maps/mp/gametypes/_hud_util;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
level.remoteweapons = [];
level.remoteweapons[ "killstreak_remote_turret_mp" ] = spawnstruct();
level.remoteweapons[ "killstreak_remote_turret_mp" ].hintstring = &"MP_REMOTE_USE_TURRET";
level.remoteweapons[ "killstreak_remote_turret_mp" ].usecallback = ::maps/mp/killstreaks/_turret_killstreak::startturretremotecontrol;
level.remoteweapons[ "killstreak_remote_turret_mp" ].endusecallback = ::maps/mp/killstreaks/_turret_killstreak::endremoteturret;
level.remoteweapons[ "killstreak_ai_tank_mp" ] = spawnstruct();
level.remoteweapons[ "killstreak_ai_tank_mp" ].hintstring = &"MP_REMOTE_USE_TANK";
level.remoteweapons[ "killstreak_ai_tank_mp" ].usecallback = ::maps/mp/killstreaks/_ai_tank::starttankremotecontrol;
level.remoteweapons[ "killstreak_ai_tank_mp" ].endusecallback = ::maps/mp/killstreaks/_ai_tank::endtankremotecontrol;
level.remoteexithint = &"MP_REMOTE_EXIT";
level thread onplayerconnect();
}
onplayerconnect()
{
for ( ;; )
{
level waittill( "connected", player );
player thread onplayerspawned();
}
}
onplayerspawned()
{
self endon( "disconnect" );
for ( ;; )
{
self waittill( "spawned_player" );
if ( isDefined( self.remotecontroltrigger ) )
{
self.remotecontroltrigger.origin = self.origin;
self.remotecontroltrigger linkto( self );
}
}
}
initremoteweapon( weapon, weaponname )
{
weapon.inittime = getTime();
weapon.remotename = weaponname;
weapon thread watchfindremoteweapon( self );
if ( isDefined( self.remoteweapon ) )
{
if ( !isusingremote() )
{
self notify( "remove_remote_weapon" );
}
}
else
{
self thread setactiveremotecontrolledweapon( weapon );
}
}
setactiveremotecontrolledweapon( weapon )
{
/#
assert( !isDefined( self.remoteweapon ), "Trying to activate remote weapon without cleaning up the current one" );
#/
if ( isDefined( self.remoteweapon ) )
{
return;
}
while ( !isalive( self ) )
{
wait 0,05;
}
self notify( "set_active_remote_weapon" );
self.remoteweapon = weapon;
self thread watchremoveremotecontrolledweapon( weapon.remotename );
self thread watchremotecontrolledweapondeath();
self thread watchremoteweaponpings();
self createremoteweapontrigger( weapon.remotename );
}
watchfindremoteweapon( player )
{
self endon( "removed_on_death" );
self endon( "death" );
while ( 1 )
{
player waittill( "find_remote_weapon" );
player notify( "remote_weapon_ping" );
}
}
watchremoteweaponpings()
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
self endon( "set_active_remote_weapon" );
self.remoteweaponqueue = [];
self thread collectweaponpings();
while ( 1 )
{
self waittill( "remote_weapon_ping", weapon );
if ( isDefined( weapon ) )
{
self.remoteweaponqueue[ self.remoteweaponqueue.size ] = weapon;
}
}
}
collectweaponpings()
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
self waittill( "remote_weapon_ping" );
wait 0,1;
while ( !isalive( self ) )
{
wait 0,05;
}
if ( isDefined( self ) )
{
/#
assert( isDefined( self.remoteweaponqueue ) );
#/
best_weapon = undefined;
_a186 = self.remoteweaponqueue;
_k186 = getFirstArrayKey( _a186 );
while ( isDefined( _k186 ) )
{
weapon = _a186[ _k186 ];
if ( isDefined( weapon ) && isalive( weapon ) )
{
if ( !isDefined( best_weapon ) || best_weapon.inittime < weapon.inittime )
{
best_weapon = weapon;
}
}
_k186 = getNextArrayKey( _a186, _k186 );
}
if ( isDefined( best_weapon ) )
{
self thread setactiveremotecontrolledweapon( best_weapon );
}
}
}
watchremotecontrolledweapondeath()
{
self endon( "remove_remote_weapon" );
/#
assert( isDefined( self.remoteweapon ) );
#/
self.remoteweapon waittill( "death" );
if ( isDefined( self ) )
{
self notify( "remove_remote_weapon" );
}
}
watchremoveremotecontrolledweapon( weaponname )
{
self endon( "disconnect" );
self waittill( "remove_remote_weapon", trytoreplace );
self removeremotecontrolledweapon( weaponname );
while ( isDefined( self.remoteweapon ) )
{
wait 0,05;
}
if ( trytoreplace == 1 )
{
self notify( "find_remote_weapon" );
}
}
removeremotecontrolledweapon( weaponname )
{
if ( self isusingremote() )
{
remoteweaponname = self getremotename();
if ( remoteweaponname == weaponname )
{
self baseendremotecontrolweaponuse( weaponname, 1 );
}
}
self destroyremotecontrolactionprompthud();
self.remoteweapon = undefined;
self.remotecontroltrigger delete();
}
createremoteweapontrigger( weaponname )
{
trigger = spawn( "trigger_radius_use", self.origin, 32, 32 );
trigger enablelinkto();
trigger linkto( self );
trigger sethintlowpriority( 1 );
trigger setcursorhint( "HINT_NOICON" );
trigger sethintstring( level.remoteweapons[ weaponname ].hintstring );
if ( level.teambased )
{
trigger setteamfortrigger( self.team );
trigger.triggerteam = self.team;
}
self clientclaimtrigger( trigger );
trigger.claimedby = self;
self.remotecontroltrigger = trigger;
self thread watchremotetriggeruse( weaponname );
self thread removeremotetriggerondisconnect( trigger );
}
removeremotetriggerondisconnect( trigger )
{
self endon( "remove_remote_weapon" );
trigger endon( "death" );
self waittill( "disconnect" );
trigger delete();
}
watchremotetriggeruse( weaponname )
{
self endon( "remove_remote_weapon" );
self endon( "disconnect" );
if ( self is_bot() )
{
return;
}
while ( 1 )
{
self.remotecontroltrigger waittill( "trigger", player );
while ( self isusingoffhand() )
{
continue;
}
while ( isDefined( self.remoteweapon ) && isDefined( self.remoteweapon.hackertrigger ) && isDefined( self.remoteweapon.hackertrigger.progressbar ) )
{
if ( weaponname == "killstreak_remote_turret_mp" )
{
self iprintlnbold( &"KILLSTREAK_AUTO_TURRET_NOT_AVAILABLE" );
}
}
if ( self usebuttonpressed() && !self.throwinggrenade && !self meleebuttonpressed() && !self isusingremote() )
{
self useremotecontrolweapon( weaponname );
}
}
}
useremotecontrolweapon( weaponname, allowexit )
{
self disableoffhandweapons();
self giveweapon( weaponname );
self switchtoweapon( weaponname );
if ( !isDefined( allowexit ) )
{
allowexit = 1;
}
self thread maps/mp/killstreaks/_killstreaks::watchforemoveremoteweapon();
self waittill( "weapon_change", newweapon );
self notify( "endWatchFoRemoveRemoteWeapon" );
self setusingremote( weaponname );
if ( !self isonground() )
{
self clearusingremote();
return;
}
result = self maps/mp/killstreaks/_killstreaks::initridekillstreak( weaponname );
if ( allowexit && result != "success" )
{
if ( result != "disconnect" )
{
self clearusingremote();
}
}
else
{
if ( allowexit && !self isonground() )
{
self clearusingremote();
return;
return;
}
else
{
self.remoteweapon.controlled = 1;
self.remoteweapon.killcament = self;
self.remoteweapon notify( "remote_start" );
if ( !isDefined( allowexit ) || allowexit )
{
self thread watchremotecontroldeactivate( weaponname );
}
self thread [[ level.remoteweapons[ weaponname ].usecallback ]]( self.remoteweapon );
}
}
}
createremotecontrolactionprompthud()
{
if ( !isDefined( self.hud_prompt_exit ) )
{
self.hud_prompt_exit = newclienthudelem( self );
}
self.hud_prompt_exit.alignx = "left";
self.hud_prompt_exit.aligny = "bottom";
self.hud_prompt_exit.horzalign = "user_left";
self.hud_prompt_exit.vertalign = "user_bottom";
self.hud_prompt_exit.font = "small";
self.hud_prompt_exit.fontscale = 1,25;
self.hud_prompt_exit.hidewheninmenu = 1;
self.hud_prompt_exit.archived = 0;
self.hud_prompt_exit.x = 25;
self.hud_prompt_exit.y = -10;
self.hud_prompt_exit settext( level.remoteexithint );
}
destroyremotecontrolactionprompthud()
{
if ( isDefined( self ) && isDefined( self.hud_prompt_exit ) )
{
self.hud_prompt_exit destroy();
}
}
watchremotecontroldeactivate( weaponname )
{
self endon( "remove_remote_weapon" );
self endon( "disconnect" );
self.remoteweapon endon( "remote_start" );
wait 1;
while ( 1 )
{
timeused = 0;
while ( self usebuttonpressed() )
{
timeused += 0,05;
if ( timeused > 0,25 )
{
self thread baseendremotecontrolweaponuse( weaponname, 0 );
return;
}
wait 0,05;
}
wait 0,05;
}
}
endremotecontrolweaponuse( weaponname )
{
if ( isDefined( self.hud_prompt_exit ) )
{
self.hud_prompt_exit settext( "" );
}
self [[ level.remoteweapons[ weaponname ].endusecallback ]]( self.remoteweapon );
}
fadeouttoblack( isdead )
{
self endon( "disconnect" );
self endon( "early_death" );
if ( isdead )
{
self sendkillstreakdamageevent( 600 );
wait 0,75;
self thread maps/mp/gametypes/_hud::fadetoblackforxsec( 0, 0,25, 0,1, 0,25 );
}
else
{
self thread maps/mp/gametypes/_hud::fadetoblackforxsec( 0, 0,2, 0, 0,3 );
}
}
baseendremotecontrolweaponuse( weaponname, isdead )
{
if ( isDefined( self ) )
{
if ( isdead && isDefined( self.remoteweapon ) && !isDefined( self.remoteweapon.skipfutz ) )
{
self thread fadeouttoblack( 1 );
wait 1;
}
else
{
self thread fadeouttoblack( 0 );
}
self clearusingremote();
self takeweapon( weaponname );
}
if ( isDefined( self.remoteweapon ) )
{
if ( isdead )
{
self.remoteweapon.wascontrollednowdead = self.remoteweapon.controlled;
}
self.remoteweapon.controlled = 0;
self [[ level.remoteweapons[ weaponname ].endusecallback ]]( self.remoteweapon, isdead );
self.remoteweapon.killcament = self.remoteweapon;
self unlink();
self.killstreak_waitamount = undefined;
self destroyremotehud();
self clientnotify( "nofutz" );
if ( isDefined( level.gameended ) && level.gameended )
{
self freezecontrolswrapper( 1 );
}
}
if ( isDefined( self.hud_prompt_exit ) )
{
self.hud_prompt_exit settext( "" );
}
self notify( "remove_remote_weapon" );
}
destroyremotehud()
{
self useservervisionset( 0 );
self setinfraredvision( 0 );
if ( isDefined( self.fullscreen_static ) )
{
self.fullscreen_static destroy();
}
if ( isDefined( self.remote_hud_reticle ) )
{
self.remote_hud_reticle destroy();
}
if ( isDefined( self.remote_hud_bracket_right ) )
{
self.remote_hud_bracket_right destroy();
}
if ( isDefined( self.remote_hud_bracket_left ) )
{
self.remote_hud_bracket_left destroy();
}
if ( isDefined( self.remote_hud_arrow_right ) )
{
self.remote_hud_arrow_right destroy();
}
if ( isDefined( self.remote_hud_arrow_left ) )
{
self.remote_hud_arrow_left destroy();
}
if ( isDefined( self.tank_rocket_1 ) )
{
self.tank_rocket_1 destroy();
}
if ( isDefined( self.tank_rocket_2 ) )
{
self.tank_rocket_2 destroy();
}
if ( isDefined( self.tank_rocket_3 ) )
{
self.tank_rocket_3 destroy();
}
if ( isDefined( self.tank_rocket_hint ) )
{
self.tank_rocket_hint destroy();
}
if ( isDefined( self.tank_mg_bar ) )
{
self.tank_mg_bar destroy();
}
if ( isDefined( self.tank_mg_arrow ) )
{
self.tank_mg_arrow destroy();
}
if ( isDefined( self.tank_mg_hint ) )
{
self.tank_mg_hint destroy();
}
if ( isDefined( self.tank_fullscreen_effect ) )
{
self.tank_fullscreen_effect destroy();
}
if ( isDefined( self.hud_prompt_exit ) )
{
self.hud_prompt_exit destroy();
}
}
stunstaticfx( duration )
{
self endon( "remove_remote_weapon" );
self.fullscreen_static.alpha = 0,65;
wait ( duration - 0,5 );
time = duration - 0,5;
while ( time < duration )
{
wait 0,05;
time += 0,05;
self.fullscreen_static.alpha -= 0,05;
}
self.fullscreen_static.alpha = 0,15;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,815 @@
#include maps/mp/killstreaks/_spyplane;
#include maps/mp/_popups;
#include maps/mp/_challenges;
#include maps/mp/_scoreevents;
#include maps/mp/gametypes/_weapon_utils;
#include maps/mp/gametypes/_damagefeedback;
#include maps/mp/gametypes/_weaponobjects;
#include maps/mp/gametypes/_hostmigration;
#include maps/mp/gametypes/_spawning;
#include maps/mp/gametypes/_hud;
#include maps/mp/gametypes/_gameobjects;
#include maps/mp/_heatseekingmissile;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/gametypes/_spawnlogic;
#include maps/mp/killstreaks/_helicopter;
#include maps/mp/killstreaks/_airsupport;
#include maps/mp/killstreaks/_killstreaks;
#include common_scripts/utility;
#include maps/mp/gametypes/_hud_util;
#include maps/mp/_utility;
init()
{
precachemodel( "veh_t6_drone_pegasus_mp" );
precacheshader( "compass_lodestar" );
precacheitem( "remote_mortar_missile_mp" );
precachestring( &"remotemortar" );
level.remote_mortar_fx[ "laserTarget" ] = loadfx( "weapon/remote_mortar/fx_rmt_mortar_laser_loop" );
level.remote_mortar_fx[ "missileExplode" ] = loadfx( "weapon/remote_mortar/fx_rmt_mortar_explosion" );
registerkillstreak( "remote_mortar_mp", "remote_mortar_mp", "killstreak_remote_mortar", "remote_mortar_used", ::remote_mortar_killstreak, 1 );
registerkillstreakaltweapon( "remote_mortar_mp", "remote_mortar_missile_mp" );
registerkillstreakstrings( "remote_mortar_mp", &"KILLSTREAK_EARNED_REMOTE_MORTAR", &"KILLSTREAK_REMOTE_MORTAR_NOT_AVAILABLE", &"KILLSTREAK_REMOTE_MORTAR_INBOUND" );
registerkillstreakdialog( "remote_mortar_mp", "mpl_killstreak_planemortar", "kls_reaper_used", "", "kls_reaper_enemy", "", "kls_reaper_ready" );
registerkillstreakdevdvar( "remote_mortar_mp", "scr_givemortarremote" );
setkillstreakteamkillpenaltyscale( "remote_mortar_mp", level.teamkillreducedpenalty );
overrideentitycameraindemo( "remote_mortar_mp", 1 );
set_dvar_float_if_unset( "scr_remote_mortar_lifetime", 45 );
level.remore_mortar_infrared_vision = "remote_mortar_infrared";
level.remore_mortar_enhanced_vision = "remote_mortar_enhanced";
minimaporigins = getentarray( "minimap_corner", "targetname" );
if ( minimaporigins.size )
{
uavorigin = maps/mp/gametypes/_spawnlogic::findboxcenter( minimaporigins[ 0 ].origin, minimaporigins[ 1 ].origin );
}
else
{
uavorigin = ( 0, 0, 1 );
}
if ( level.script == "mp_la" )
{
uavorigin += vectorScale( ( 0, 0, 1 ), 1200 );
}
if ( level.script == "mp_hydro" )
{
uavorigin += vectorScale( ( 0, 0, 1 ), 2000 );
}
if ( level.script == "mp_concert" )
{
uavorigin += vectorScale( ( 0, 0, 1 ), 750 );
}
if ( level.script == "mp_vertigo" )
{
uavorigin += vectorScale( ( 0, 0, 1 ), 500 );
}
level.remotemortarrig = spawn( "script_model", uavorigin );
level.remotemortarrig setmodel( "tag_origin" );
level.remotemortarrig.angles = vectorScale( ( 0, 0, 1 ), 115 );
level.remotemortarrig hide();
level.remotemortarrig thread rotaterig( 1 );
level.remote_zoffset = 8000;
level.remote_radiusoffset = 9000;
remote_mortar_height = getstruct( "remote_mortar_height", "targetname" );
if ( isDefined( remote_mortar_height ) )
{
level.remote_radiusoffset = ( remote_mortar_height.origin[ 2 ] / level.remote_zoffset ) * level.remote_radiusoffset;
level.remote_zoffset = remote_mortar_height.origin[ 2 ];
}
}
remote_mortar_killstreak( hardpointtype )
{
/#
assert( hardpointtype == "remote_mortar_mp" );
#/
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
if ( !self isonground() || self isusingremote() )
{
self iprintlnbold( &"KILLSTREAK_REMOTE_MORTAR_NOT_USABLE" );
return 0;
}
self setusingremote( hardpointtype );
self freezecontrolswrapper( 1 );
self disableweaponcycling();
result = self maps/mp/killstreaks/_killstreaks::initridekillstreak( "qrdrone" );
if ( result != "success" )
{
if ( result != "disconnect" )
{
self notify( "remote_mortar_unlock" );
self clearusingremote();
self enableweaponcycling();
}
return 0;
}
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, self.team, 0, 1 );
if ( killstreak_id == -1 )
{
self clearusingremote();
self enableweaponcycling();
self notify( "remote_mortar_unlock" );
return 0;
}
self.killstreak_waitamount = getDvarFloat( #"F9AB897A" ) * 1000;
remote = self remote_mortar_spawn();
remote setdrawinfrared( 1 );
remote thread remote_killstreak_abort();
remote thread remote_killstreak_game_end();
remote thread remote_owner_exit();
remote thread remote_owner_teamkillkicked();
remote thread remote_damage_think();
remote thread play_lockon_sounds( self );
remote thread maps/mp/_heatseekingmissile::missiletarget_lockonmonitor( self, "remote_end" );
remote thread maps/mp/_heatseekingmissile::missiletarget_proximitydetonateincomingmissile( "crashing" );
remote.killstreak_id = killstreak_id;
remote thread play_remote_fx();
remote playloopsound( "mpl_ks_reaper_exterior_loop", 1 );
self.pilottalking = 0;
remote.copilotvoicenumber = self.bcvoicenumber;
remote.pilotvoicenumber = self.bcvoicenumber + 1;
if ( remote.pilotvoicenumber > 3 )
{
remote.pilotvoicenumber = 0;
}
self clientnotify( "krms" );
self player_linkto_remote( remote );
self freezecontrolswrapper( 0 );
self thread player_aim_think( remote );
self thread player_fire_think( remote );
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "remote_mortar_mp", self.pers[ "team" ] );
remote thread remote_killstreak_copilot( remote.copilotvoicenumber );
level.globalkillstreakscalled++;
self addweaponstat( "remote_mortar_mp", "used", 1 );
self thread visionswitch();
level waittill( "remote_unlinked" );
if ( isDefined( remote ) )
{
remote stoploopsound( 4 );
}
if ( !isDefined( self ) )
{
return 1;
}
self clientnotify( "krme" );
self clearclientflag( 1 );
self clientnotify( "nofutz" );
self clearusingremote();
return 1;
}
remote_killstreak_copilot( voice )
{
level endon( "remote_end" );
wait 2,5;
while ( 1 )
{
self thread playpilotdialog( "reaper_used", 0, voice );
wait randomfloatrange( 4,5, 15 );
}
}
remote_killstreak_abort()
{
level endon( "remote_end" );
/#
assert( isDefined( self.owner ) );
#/
/#
assert( isplayer( self.owner ) );
#/
self.owner waittill_any( "disconnect", "joined_team", "joined_spectators" );
self thread remote_killstreak_end( 0, 1 );
}
remote_owner_teamkillkicked( hardpointtype )
{
level endon( "remote_end" );
self.owner waittill( "teamKillKicked" );
self thread remote_killstreak_end();
}
remote_owner_exit()
{
level endon( "remote_end" );
wait 1;
while ( 1 )
{
timeused = 0;
while ( self.owner usebuttonpressed() )
{
timeused += 0,05;
if ( timeused > 0,25 )
{
self thread remote_killstreak_end();
return;
}
wait 0,05;
}
wait 0,05;
}
}
remote_killstreak_game_end()
{
level endon( "remote_end" );
/#
assert( isDefined( self.owner ) );
#/
/#
assert( isplayer( self.owner ) );
#/
level waittill( "game_ended" );
self thread remote_killstreak_end();
}
remote_mortar_spawn()
{
self setclientflag( 1 );
self clientnotify( "reapfutz" );
remote = spawnplane( self, "script_model", level.remotemortarrig gettagorigin( "tag_origin" ) );
/#
assert( isDefined( remote ) );
#/
remote setmodel( "veh_t6_drone_pegasus_mp" );
remote.targetname = "remote_mortar";
remote setowner( self );
remote setteam( self.team );
remote.team = self.team;
remote.owner = self;
remote.numflares = 2;
remote.flareoffset = vectorScale( ( 0, 0, 1 ), 256 );
remote.attackers = [];
remote.attackerdata = [];
remote.attackerdamage = [];
remote.flareattackerdamage = [];
remote.pilotvoicenumber = self.bcvoicenumber + 1;
if ( remote.pilotvoicenumber > 3 )
{
remote.pilotvoicenumber = 0;
}
angle = randomint( 360 );
xoffset = cos( angle ) * level.remote_radiusoffset;
yoffset = sin( angle ) * level.remote_radiusoffset;
anglevector = vectornormalize( ( xoffset, yoffset, level.remote_zoffset ) );
anglevector *= 6100;
remote linkto( level.remotemortarrig, "tag_origin", anglevector, ( 0, angle - 90, 0 ) );
remoteobjidfriendly = maps/mp/gametypes/_gameobjects::getnextobjid();
objective_add( remoteobjidfriendly, "invisible", remote.origin, &"remotemortar", self );
objective_state( remoteobjidfriendly, "active" );
objective_onentity( remoteobjidfriendly, remote );
objective_team( remoteobjidfriendly, self.team );
self.remoteobjidfriendly = remoteobjidfriendly;
remote.fx = spawn( "script_model", ( 0, 0, 1 ) );
remote.fx setmodel( "tag_origin" );
remote.fx setinvisibletoplayer( remote.owner, 1 );
remote remote_mortar_visibility();
target_setturretaquire( remote, 1 );
return remote;
}
rotaterig( clockwise )
{
turn = 360;
if ( clockwise )
{
turn = -360;
}
for ( ;; )
{
if ( !clockwise )
{
self rotateyaw( turn, 30 );
wait 30;
continue;
}
else
{
self rotateyaw( turn, 45 );
wait 45;
}
}
}
remote_mortar_visibility()
{
players = get_players();
_a315 = players;
_k315 = getFirstArrayKey( _a315 );
while ( isDefined( _k315 ) )
{
player = _a315[ _k315 ];
if ( player == self.owner )
{
self setinvisibletoplayer( player );
}
else
{
self setvisibletoplayer( player );
}
_k315 = getNextArrayKey( _a315, _k315 );
}
}
play_lockon_sounds( player )
{
player endon( "disconnect" );
self endon( "death" );
self endon( "remote_end" );
self.locksounds = spawn( "script_model", self.origin );
wait 0,1;
self.locksounds linkto( self, "tag_player" );
while ( 1 )
{
self waittill( "locking on" );
while ( 1 )
{
if ( enemy_locking() )
{
self playsoundtoplayer( "uin_alert_lockon", player );
wait 0,125;
}
if ( enemy_locked() )
{
self playsoundtoplayer( "uin_alert_lockon", player );
wait 0,125;
}
if ( !enemy_locking() && !enemy_locked() )
{
break;
}
else
{
}
}
}
}
enemy_locking()
{
if ( isDefined( self.locking_on ) && self.locking_on )
{
return 1;
}
return 0;
}
enemy_locked()
{
if ( isDefined( self.locked_on ) && self.locked_on )
{
return 1;
}
return 0;
}
create_remote_mortar_hud( remote )
{
self.missile_hud = newclienthudelem( self );
self.missile_hud.alignx = "left";
self.missile_hud.aligny = "bottom";
self.missile_hud.horzalign = "user_left";
self.missile_hud.vertalign = "user_bottom";
self.missile_hud.font = "small";
self.missile_hud settext( "[{+attack}]" + "Fire Missile" );
self.missile_hud.hidewheninmenu = 1;
self.missile_hud.hidewhenindemo = 1;
self.missile_hud.x = 5;
self.missile_hud.y = -40;
self.missile_hud.fontscale = 1,25;
self.zoom_hud = newclienthudelem( self );
self.zoom_hud.alignx = "left";
self.zoom_hud.aligny = "bottom";
self.zoom_hud.horzalign = "user_left";
self.zoom_hud.vertalign = "user_bottom";
self.zoom_hud.font = "small";
self.zoom_hud settext( &"KILLSTREAK_INCREASE_ZOOM" );
self.zoom_hud.hidewheninmenu = 1;
self.zoom_hud.hidewhenindemo = 1;
self.zoom_hud.x = 5;
self.zoom_hud.y = -25;
self.zoom_hud.fontscale = 1,25;
self.hud_prompt_exit = newclienthudelem( self );
self.hud_prompt_exit.alignx = "left";
self.hud_prompt_exit.aligny = "bottom";
self.hud_prompt_exit.horzalign = "user_left";
self.hud_prompt_exit.vertalign = "user_bottom";
self.hud_prompt_exit.font = "small";
self.hud_prompt_exit.fontscale = 1,25;
self.hud_prompt_exit.hidewheninmenu = 1;
self.hud_prompt_exit.hidewhenindemo = 1;
self.hud_prompt_exit.archived = 0;
self.hud_prompt_exit.x = 5;
self.hud_prompt_exit.y = -10;
self.hud_prompt_exit settext( level.remoteexithint );
self thread fade_out_hint_hud( remote );
}
fade_out_hint_hud( remote )
{
self endon( "disconnect" );
remote endon( "death" );
wait 8;
time = 0;
while ( time < 2 )
{
if ( !isDefined( self.missile_hud ) )
{
return;
}
self.missile_hud.alpha -= 0,025;
self.zoom_hud.alpha -= 0,025;
time += 0,05;
wait 0,05;
}
self.missile_hud.alpha = 0;
self.zoom_hud.alpha = 0;
}
remove_hud()
{
if ( isDefined( self.missile_hud ) )
{
self.missile_hud destroy();
}
if ( isDefined( self.zoom_hud ) )
{
self.zoom_hud destroy();
}
if ( isDefined( self.hud_prompt_exit ) )
{
self.hud_prompt_exit destroy();
}
}
remote_killstreak_end( explode, disconnected )
{
level notify( "remote_end" );
if ( !isDefined( explode ) )
{
explode = 0;
}
if ( !isDefined( disconnected ) )
{
disconnected = 0;
}
if ( isDefined( self.owner ) )
{
if ( disconnected == 0 )
{
if ( explode )
{
self.owner sendkillstreakdamageevent( 600 );
self.owner thread maps/mp/gametypes/_hud::fadetoblackforxsec( 0,5, 0,5, 0,1, 0,25 );
wait 1;
}
else
{
self.owner sendkillstreakdamageevent( 600 );
self.owner thread maps/mp/gametypes/_hud::fadetoblackforxsec( 0, 0,25, 0,1, 0,25 );
wait 0,25;
}
}
self.owner unlink();
self.owner.killstreak_waitamount = undefined;
self.owner enableweaponcycling();
self.owner remove_hud();
if ( isDefined( level.gameended ) && level.gameended )
{
self.owner freezecontrolswrapper( 1 );
}
}
self maps/mp/gametypes/_spawning::remove_tvmissile_influencers();
objective_delete( self.owner.remoteobjidfriendly );
releaseobjid( self.owner.remoteobjidfriendly );
target_setturretaquire( self, 0 );
level notify( "remote_unlinked" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( "remote_mortar_mp", self.team, self.killstreak_id );
if ( isDefined( self.owner ) )
{
self.owner setinfraredvision( 0 );
self.owner useservervisionset( 0 );
}
if ( isDefined( self.fx ) )
{
self.fx delete();
}
if ( explode )
{
self remote_explode();
}
else
{
self remote_leave();
}
}
player_linkto_remote( remote )
{
leftarc = 40;
rightarc = 40;
uparc = 25;
downarc = 65;
if ( isDefined( level.remotemotarviewleft ) )
{
leftarc = level.remotemotarviewleft;
}
if ( isDefined( level.remotemotarviewright ) )
{
rightarc = level.remotemotarviewright;
}
if ( isDefined( level.remotemotarviewup ) )
{
uparc = level.remotemotarviewup;
}
if ( isDefined( level.remotemotarviewdown ) )
{
downarc = level.remotemotarviewdown;
}
/#
leftarc = getdvarintdefault( "scr_remotemortar_right", leftarc );
rightarc = getdvarintdefault( "scr_remotemortar_left", rightarc );
uparc = getdvarintdefault( "scr_remotemortar_up", uparc );
downarc = getdvarintdefault( "scr_remotemortar_down", downarc );
#/
self playerlinkweaponviewtodelta( remote, "tag_player", 1, leftarc, rightarc, uparc, downarc );
self player_center_view();
}
player_center_view( org )
{
wait 0,05;
lookvec = vectorToAngle( level.uavrig.origin - self geteye() );
self setplayerangles( lookvec );
}
player_aim_think( remote )
{
level endon( "remote_end" );
wait 0,25;
playfxontag( level.remote_mortar_fx[ "laserTarget" ], remote.fx, "tag_origin" );
remote.fx playloopsound( "mpl_ks_reaper_laser" );
while ( 1 )
{
origin = self geteye();
forward = anglesToForward( self getplayerangles() );
endpoint = origin + ( forward * 15000 );
trace = bullettrace( origin, endpoint, 0, remote );
remote.fx.origin = trace[ "position" ];
remote.fx.angles = vectorToAngle( trace[ "normal" ] );
if ( isDefined( self.pegasus_influencer ) )
{
removeinfluencer( self.pegasus_influencer );
self.pegasus_influencer = undefined;
}
if ( isDefined( self.active_pegasus ) )
{
self.pegasus_influencer = maps/mp/gametypes/_spawning::create_pegasus_influencer( trace[ "position" ], self.team );
}
wait 0,05;
}
}
player_fire_think( remote )
{
level endon( "remote_end" );
end_time = getTime() + self.killstreak_waitamount;
shot = 0;
while ( getTime() < end_time )
{
self.active_pegasus = undefined;
while ( !self attackbuttonpressed() )
{
wait 0,05;
}
self playlocalsound( "mpl_ks_reaper_fire" );
self playrumbleonentity( "sniper_fire" );
if ( ( shot % 3 ) == 1 )
{
if ( isDefined( remote.owner ) && isDefined( remote.owner.pilottalking ) && remote.owner.pilottalking )
{
shot = 0;
}
remote thread playpilotdialog( "reaper_fire", 0,25, undefined, 0 );
}
shot = ( shot + 1 ) % 3;
origin = self geteye();
earthquake( 0,3, 0,5, origin, 256 );
angles = self getplayerangles();
forward = anglesToForward( angles );
right = anglesToRight( angles );
up = anglesToUp( angles );
offset = ( ( origin + ( forward * 100 ) ) + ( right * -40 ) ) + ( up * -100 );
missile = magicbullet( "remote_mortar_missile_mp", offset, ( origin + ( forward * 1000 ) ) + ( up * -100 ), self, remote.fx );
self.active_pegasus = missile;
missile thread remote_missile_life( remote );
missile waittill( "death" );
self playlocalsound( "mpl_ks_reaper_explosion" );
}
if ( isDefined( self.pegasus_influencer ) )
{
removeinfluencer( self.pegasus_influencer );
self.pegasus_influencer = undefined;
}
remote thread remote_killstreak_end();
}
remote_missile_life( remote )
{
self endon( "death" );
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpause( 6 );
playfx( level.remote_mortar_fx[ "missileExplode" ], self.origin );
self delete();
}
remote_damage_think()
{
level endon( "remote_end" );
self.health = 999999;
maxhealth = level.heli_amored_maxhealth;
damagetaken = 0;
self.lowhealth = 0;
self setcandamage( 1 );
target_set( self, vectorScale( ( 0, 0, 1 ), 30 ) );
while ( 1 )
{
self waittill( "damage", damage, attacker, direction_vec, point, meansofdeath, tagname, modelname, partname, weapon );
self.health = 999999;
heli_friendlyfire = maps/mp/gametypes/_weaponobjects::friendlyfirecheck( self.owner, attacker );
while ( !heli_friendlyfire )
{
continue;
}
if ( isplayer( attacker ) )
{
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback( meansofdeath );
if ( attacker hasperk( "specialty_armorpiercing" ) )
{
if ( meansofdeath == "MOD_RIFLE_BULLET" || meansofdeath == "MOD_PISTOL_BULLET" )
{
damage += int( damage * level.cac_armorpiercing_data );
}
}
}
if ( meansofdeath == "MOD_RIFLE_BULLET" || meansofdeath == "MOD_PISTOL_BULLET" )
{
damage *= level.heli_armor_bulletdamage;
}
if ( isDefined( weapon ) )
{
if ( maps/mp/gametypes/_weapon_utils::islauncherweapon( weapon ) || weapon == "remote_missile_missile_mp" )
{
damage = maxhealth + 1;
}
}
while ( damage <= 0 )
{
continue;
}
self.owner playlocalsound( "reaper_damaged" );
self.owner sendkillstreakdamageevent( int( damage ) );
damagetaken += damage;
if ( damagetaken >= maxhealth )
{
if ( self.owner isenemyplayer( attacker ) )
{
maps/mp/_scoreevents::processscoreevent( "destroyed_remote_mortar", attacker, self.owner, weapon );
attacker maps/mp/_challenges::addflyswatterstat( weapon, self );
attacker addweaponstat( weapon, "destroyed_controlled_killstreak", 1 );
attacker destroyedplayercontrolledaircraft();
break;
}
level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_DESTROYED_REMOTE_MORTAR", attacker );
self thread remote_killstreak_end( 1 );
return;
continue;
}
else
{
if ( !self.lowhealth && damagetaken >= ( maxhealth / 2 ) )
{
playfxontag( level.fx_u2_damage_trail, self, "tag_origin" );
self.lowhealth = 1;
}
}
}
}
remote_leave()
{
level endon( "game_ended" );
self endon( "death" );
self unlink();
tries = 10;
yaw = 0;
while ( tries > 0 )
{
exitvector = anglesToForward( self.angles + ( 0, yaw, 0 ) ) * 20000;
exitpoint = ( self.origin[ 0 ] + exitvector[ 0 ], self.origin[ 1 ] + exitvector[ 1 ], self.origin[ 2 ] - 2500 );
exitpoint = self.origin + exitvector;
nfz = crossesnoflyzone( self.origin, exitpoint );
if ( isDefined( nfz ) )
{
if ( ( tries % 2 ) == 1 && tries != 1 )
{
yaw *= -1;
tries--;
continue;
}
else
{
if ( tries != 1 )
{
yaw += 10;
yaw *= -1;
}
}
tries--;
continue;
}
else
{
tries = 0;
}
}
self thread maps/mp/killstreaks/_spyplane::flattenyaw( self.angles[ 1 ] + yaw );
self moveto( exitpoint, 8, 4 );
if ( self.lowhealth )
{
playfxontag( level.chopper_fx[ "damage" ][ "heavy_smoke" ], self, "tag_origin" );
}
self thread play_afterburner_fx();
maps/mp/gametypes/_hostmigration::waitlongdurationwithhostmigrationpause( 8 );
self delete();
}
play_remote_fx()
{
self.exhaustfx = spawn( "script_model", self.origin );
self.exhaustfx setmodel( "tag_origin" );
self.exhaustfx linkto( self, "tag_turret", vectorScale( ( 0, 0, 1 ), 25 ) );
wait 0,1;
playfxontag( level.fx_cuav_burner, self.exhaustfx, "tag_origin" );
}
play_afterburner_fx()
{
if ( !isDefined( self.exhaustfx ) )
{
self.exhaustfx = spawn( "script_model", self.origin );
self.exhaustfx setmodel( "tag_origin" );
self.exhaustfx linkto( self, "tag_turret", vectorScale( ( 0, 0, 1 ), 25 ) );
}
self endon( "death" );
wait 0,1;
playfxontag( level.fx_cuav_afterburner, self.exhaustfx, "tag_origin" );
}
remote_explode()
{
self notify( "death" );
self hide();
forward = anglesToForward( self.angles ) * 200;
playfx( level.fx_u2_explode, self.origin, forward );
self playsound( "evt_helicopter_midair_exp" );
wait 0,2;
self notify( "delete" );
self delete();
}
visionswitch()
{
self endon( "disconnect" );
level endon( "remote_end" );
inverted = 1;
self setinfraredvision( 1 );
self useservervisionset( 1 );
self setvisionsetforplayer( level.remore_mortar_infrared_vision, 1 );
for ( ;; )
{
while ( self changeseatbuttonpressed() )
{
if ( !inverted )
{
self setinfraredvision( 1 );
self setvisionsetforplayer( level.remore_mortar_infrared_vision, 0,5 );
self playlocalsound( "mpl_ks_reaper_view_select" );
}
else
{
self setinfraredvision( 0 );
self setvisionsetforplayer( level.remore_mortar_enhanced_vision, 0,5 );
self playlocalsound( "mpl_ks_reaper_view_select" );
}
inverted = !inverted;
while ( self changeseatbuttonpressed() )
{
wait 0,05;
}
}
wait 0,05;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
#include maps/mp/_utility;
#include common_scripts/utility;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff