mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-06-11 11:17:56 -05:00
949 lines
22 KiB
Plaintext
949 lines
22 KiB
Plaintext
#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;
|
|
}
|
|
}
|