mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-07-04 22:47:52 -05:00
uploading 119 patch_mp scripts and 23 patch_zm scripts as a baseline
This commit is contained in:
1449
patch_mp/maps/mp/killstreaks/_ai_tank.gsc
Normal file
1449
patch_mp/maps/mp/killstreaks/_ai_tank.gsc
Normal file
File diff suppressed because it is too large
Load Diff
948
patch_mp/maps/mp/killstreaks/_airsupport.gsc
Normal file
948
patch_mp/maps/mp/killstreaks/_airsupport.gsc
Normal 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;
|
||||
}
|
||||
}
|
1017
patch_mp/maps/mp/killstreaks/_dogs.gsc
Normal file
1017
patch_mp/maps/mp/killstreaks/_dogs.gsc
Normal file
File diff suppressed because it is too large
Load Diff
590
patch_mp/maps/mp/killstreaks/_emp.gsc
Normal file
590
patch_mp/maps/mp/killstreaks/_emp.gsc
Normal 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;
|
||||
}
|
2746
patch_mp/maps/mp/killstreaks/_helicopter.gsc
Normal file
2746
patch_mp/maps/mp/killstreaks/_helicopter.gsc
Normal file
File diff suppressed because it is too large
Load Diff
796
patch_mp/maps/mp/killstreaks/_helicopter_guard.gsc
Normal file
796
patch_mp/maps/mp/killstreaks/_helicopter_guard.gsc
Normal 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();
|
||||
}
|
1580
patch_mp/maps/mp/killstreaks/_helicopter_gunner.gsc
Normal file
1580
patch_mp/maps/mp/killstreaks/_helicopter_gunner.gsc
Normal file
File diff suppressed because it is too large
Load Diff
633
patch_mp/maps/mp/killstreaks/_killstreak_weapons.gsc
Normal file
633
patch_mp/maps/mp/killstreaks/_killstreak_weapons.gsc
Normal 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;
|
||||
}
|
415
patch_mp/maps/mp/killstreaks/_killstreakrules.gsc
Normal file
415
patch_mp/maps/mp/killstreaks/_killstreakrules.gsc
Normal 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 );
|
||||
#/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2049
patch_mp/maps/mp/killstreaks/_killstreaks.gsc
Normal file
2049
patch_mp/maps/mp/killstreaks/_killstreaks.gsc
Normal file
File diff suppressed because it is too large
Load Diff
694
patch_mp/maps/mp/killstreaks/_missile_drone.gsc
Normal file
694
patch_mp/maps/mp/killstreaks/_missile_drone.gsc
Normal 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;
|
||||
}
|
760
patch_mp/maps/mp/killstreaks/_missile_swarm.gsc
Normal file
760
patch_mp/maps/mp/killstreaks/_missile_swarm.gsc
Normal 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;
|
||||
}
|
367
patch_mp/maps/mp/killstreaks/_planemortar.gsc
Normal file
367
patch_mp/maps/mp/killstreaks/_planemortar.gsc
Normal 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 );
|
||||
}
|
1432
patch_mp/maps/mp/killstreaks/_qrdrone.gsc
Normal file
1432
patch_mp/maps/mp/killstreaks/_qrdrone.gsc
Normal file
File diff suppressed because it is too large
Load Diff
292
patch_mp/maps/mp/killstreaks/_radar.gsc
Normal file
292
patch_mp/maps/mp/killstreaks/_radar.gsc
Normal 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 );
|
||||
}
|
||||
}
|
792
patch_mp/maps/mp/killstreaks/_rcbomb.gsc
Normal file
792
patch_mp/maps/mp/killstreaks/_rcbomb.gsc
Normal 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 );
|
||||
#/
|
||||
}
|
||||
}
|
496
patch_mp/maps/mp/killstreaks/_remote_weapons.gsc
Normal file
496
patch_mp/maps/mp/killstreaks/_remote_weapons.gsc
Normal 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;
|
||||
}
|
1068
patch_mp/maps/mp/killstreaks/_remotemissile.gsc
Normal file
1068
patch_mp/maps/mp/killstreaks/_remotemissile.gsc
Normal file
File diff suppressed because it is too large
Load Diff
815
patch_mp/maps/mp/killstreaks/_remotemortar.gsc
Normal file
815
patch_mp/maps/mp/killstreaks/_remotemortar.gsc
Normal 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;
|
||||
}
|
||||
}
|
1146
patch_mp/maps/mp/killstreaks/_spyplane.gsc
Normal file
1146
patch_mp/maps/mp/killstreaks/_spyplane.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1018
patch_mp/maps/mp/killstreaks/_straferun.gsc
Normal file
1018
patch_mp/maps/mp/killstreaks/_straferun.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2
patch_mp/maps/mp/killstreaks/_supplycrate.gsc
Normal file
2
patch_mp/maps/mp/killstreaks/_supplycrate.gsc
Normal file
@ -0,0 +1,2 @@
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
2643
patch_mp/maps/mp/killstreaks/_supplydrop.gsc
Normal file
2643
patch_mp/maps/mp/killstreaks/_supplydrop.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2573
patch_mp/maps/mp/killstreaks/_turret_killstreak.gsc
Normal file
2573
patch_mp/maps/mp/killstreaks/_turret_killstreak.gsc
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user