Files
Recompilable-gscs-for-BO2-z…/patch_mp/maps/mp/killstreaks/_airsupport.gsc

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;
}
}