// IW6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool

init()
{
    maps\mp\killstreaks\_helicopter_guard::lbsupport_setairstartnodes();
    maps\mp\killstreaks\_helicopter_guard::lbsupport_setairnodemesh();
    level.sniper_explode = loadfx( "fx/explosions/sniper_incendiary" );
    level.killstreakfuncs["heli_sniper"] = ::tryusehelisniper;
    var_0 = spawnstruct();
    var_0.xppopup = "destroyed_helo_scout";
    var_0.callout = "callout_destroyed_helo_scout";
    var_0.samdamagescale = 0.09;
    var_0.enginevfxtag = "tag_engine_right";
    level.heliconfigs["heli_sniper"] = var_0;
}

tryusehelisniper( var_0, var_1 )
{
    var_2 = getcloseststartnode( self.origin );
    var_3 = getclosestnode( self.origin );
    var_4 = vectortoangles( var_3.origin - var_2.origin );

    if ( isdefined( self.underwater ) && self.underwater )
        return 0;

    if ( isdefined( self.isjuggernautlevelcustom ) && self.isjuggernautlevelcustom == 1 )
        return 0;
    else if ( !isdefined( level.air_node_mesh ) || !isdefined( var_2 ) || !isdefined( var_3 ) )
    {
        self iprintlnbold( &"KILLSTREAKS_UNAVAILABLE_IN_LEVEL" );
        return 0;
    }

    var_5 = 1;

    if ( exceededmaxhelisnipers() )
    {
        self iprintlnbold( &"KILLSTREAKS_AIR_SPACE_TOO_CROWDED" );
        return 0;
    }

    if ( maps\mp\_utility::currentactivevehiclecount() >= maps\mp\_utility::maxvehiclesallowed() || level.fauxvehiclecount + var_5 >= maps\mp\_utility::maxvehiclesallowed() )
    {
        self iprintlnbold( &"KILLSTREAKS_TOO_MANY_VEHICLES" );
        return 0;
    }

    if ( isdefined( self.iscapturingcrate ) && self.iscapturingcrate )
        return 0;

    if ( isdefined( self.isreviving ) && self.isreviving )
        return 0;

    var_6 = createheli( self, var_2, var_3, var_4, var_1, var_0 );

    if ( !isdefined( var_6 ) )
        return 0;

    var_7 = helipickup( var_6, var_1 );

    if ( isdefined( var_7 ) && var_7 == "fail" )
        return 0;

    return 1;
}

exceededmaxhelisnipers()
{
    return isdefined( level.lbsniper );
}

getcloseststartnode( var_0 )
{
    var_1 = undefined;
    var_2 = 999999;

    foreach ( var_4 in level.air_start_nodes )
    {
        var_5 = distance( var_4.origin, var_0 );

        if ( var_5 < var_2 )
        {
            var_1 = var_4;
            var_2 = var_5;
        }
    }

    return var_1;
}

createheli( var_0, var_1, var_2, var_3, var_4, var_5 )
{
    var_6 = getent( "airstrikeheight", "targetname" );
    var_7 = var_2.origin;
    var_8 = anglestoforward( var_3 );
    var_9 = var_1.origin;
    var_10 = spawnhelicopter( var_0, var_9, var_8, "attack_littlebird_mp", level.littlebird_model );

    if ( !isdefined( var_10 ) )
        return;

    var_11 = maps\mp\_utility::gethelipilottraceoffset();
    var_12 = var_7 + ( maps\mp\_utility::gethelipilotmeshoffset() + var_11 );
    var_13 = var_7 + ( maps\mp\_utility::gethelipilotmeshoffset() - var_11 );
    var_14 = bullettrace( var_12, var_13, 0, 0, 0, 0, 1 );

    if ( isdefined( var_14["entity"] ) && var_14["normal"][2] > 0.1 )
        var_7 = var_14["position"] - maps\mp\_utility::gethelipilotmeshoffset() + ( 0, 0, 384 );

    var_10 maps\mp\killstreaks\_helicopter::addtolittlebirdlist( "lbSniper" );
    var_10 thread maps\mp\killstreaks\_helicopter::removefromlittlebirdlistondeath();
    var_10 thread waitfordeath();
    var_10.lifeid = var_5;
    var_10.forward = var_8;
    var_10.pathstart = var_9;
    var_10.pathgoal = var_7;
    var_10.pathend = var_1.origin;
    var_10.flyheight = var_7[2];
    var_10.maxheight = var_6.origin;
    var_10.ongroundpos = var_1.origin;
    var_10.pickuppos = var_10.ongroundpos + ( 0, 0, 300 );
    var_10.hoverpos = var_10.ongroundpos + ( 0, 0, 600 );
    var_10.forwardyaw = var_8[1];
    var_10.backwardyaw = var_8[1] + 180;

    if ( var_10.backwardyaw > 360 )
        var_10.backwardyaw = var_10.backwardyaw - 360;

    var_10.helitype = "littlebird";
    var_10.heli_type = "littlebird";
    var_10.locindex = var_1.orgin;
    var_10.allowsafeeject = 1;
    var_10.attractor = missile_createattractorent( var_10, level.heli_attract_strength, level.heli_attract_range );
    var_10.isdestroyed = 0;
    var_10.maxhealth = level.heli_maxhealth;
    var_10 thread maps\mp\killstreaks\_flares::flares_monitor( 1 );
    var_10 thread maps\mp\killstreaks\_helicopter::heli_damage_monitor( "heli_sniper", 1 );
    var_10 thread helideathcleanup( var_4 );
    var_10.owner = var_0;
    var_10.team = var_0.team;
    var_10 thread leaveonownerdisconnect();
    var_10.speed = 100;
    var_10.ammo = 100;
    var_10.followspeed = 40;
    var_10 setcandamage( 1 );
    var_10 setmaxpitchroll( 45, 45 );
    var_10 vehicle_setspeed( var_10.speed, 100, 40 );
    var_10 setyawspeed( 120, 60 );
    var_10 sethoverparams( 10, 10, 60 );
    var_10 setneargoalnotifydist( 512 );
    var_10.killcount = 0;
    var_10.streakname = "heli_sniper";
    var_10.allowboard = 0;
    var_10.ownerboarded = 0;
    var_10 hidepart( "tag_wings" );
    return var_10;
}

getbestheight( var_0 )
{
    self endon( "death" );
    self endon( "crashing" );
    self endon( "helicopter_removed" );
    self endon( "heightReturned" );
    var_1 = getent( "airstrikeheight", "targetname" );

    if ( isdefined( var_1 ) )
        var_2 = var_1.origin[2];
    else if ( isdefined( level.airstrikeheightscale ) )
        var_2 = 850 * level.airstrikeheightscale;
    else
        var_2 = 850;

    var_3 = bullettrace( var_0, var_0 - ( 0, 0, 10000 ), 0, self, 0, 0, 0, 0 );
    var_4 = var_3["position"][2];
    var_5 = 0;
    var_6 = 0;

    for ( var_7 = 0; var_7 < 30; var_7++ )
    {
        wait 0.05;
        var_8 = var_7 % 8;
        var_9 = var_7 * 7;

        switch ( var_8 )
        {
            case 0:
                var_5 = var_9;
                var_6 = var_9;
                break;
            case 1:
                var_5 = var_9 * -1;
                var_6 = var_9 * -1;
                break;
            case 2:
                var_5 = var_9 * -1;
                var_6 = var_9;
                break;
            case 3:
                var_5 = var_9;
                var_6 = var_9 * -1;
                break;
            case 4:
                var_5 = 0;
                var_6 = var_9 * -1;
                break;
            case 5:
                var_5 = var_9 * -1;
                var_6 = 0;
                break;
            case 6:
                var_5 = var_9;
                var_6 = 0;
                break;
            case 7:
                var_5 = 0;
                var_6 = var_9;
                break;
            default:
                break;
        }

        var_10 = bullettrace( var_0 + ( var_5, var_6, 1000 ), var_0 - ( var_5, var_6, 10000 ), 0, self, 0, 0, 0, 0, 0 );

        if ( isdefined( var_10["entity"] ) )
            continue;

        if ( var_10["position"][2] + 145 > var_4 )
            var_4 = var_10["position"][2] + 145;
    }

    return var_4;
}

helipickup( var_0, var_1 )
{
    level endon( "game_ended" );
    var_0 endon( "death" );
    var_0 endon( "crashing" );
    var_0 endon( "owner_disconnected" );
    var_0 endon( "killstreakExit" );
    var_2 = getcloseststartnode( self.origin );
    level thread maps\mp\_utility::teamplayercardsplash( "used_heli_sniper", self, self.team );

    if ( isdefined( var_2.angles ) )
        var_3 = var_2.angles;
    else
        var_3 = ( 0, 0, 0 );

    common_scripts\utility::_disableusability();
    var_4 = var_0.flyheight;

    if ( isdefined( var_2.neighbors[0] ) )
        var_5 = var_2.neighbors[0];
    else
        var_5 = getclosestnode( self.origin );

    var_6 = anglestoforward( self.angles );
    var_7 = var_5.origin * ( 1, 1, 0 ) + ( 0, 0, 1 ) * var_4 + var_6 * -100;
    var_0.targetpos = var_7;
    var_0.currentnode = var_5;
    var_8 = moveplayertochopper( var_0 );

    if ( isdefined( var_8 ) && var_8 == "fail" )
    {
        var_0 thread helileave();
        return var_8;
    }
    else
    {
        thread onheli( var_0 );
        return var_8;
    }
}

onheli( var_0 )
{
    level endon( "game_ended" );
    var_0 endon( "death" );
    var_0 endon( "crashing" );
    var_0 endon( "owner_disconnected" );
    var_0 endon( "killstreakExit" );

    if ( isdefined( self.imslist ) )
        destroycarriedims();

    var_0 thread givecoolassgun();
    var_0 setyawspeed( 1, 1, 1, 0.1 );
    var_0 notify( "picked_up_passenger" );
    common_scripts\utility::_enableusability();
    var_0 vehicle_setspeed( var_0.speed, 100, 40 );
    self.onhelisniper = 1;
    self.helisniper = var_0;
    var_0 endon( "owner_death" );
    var_0 thread pushcorpseonownerdeath();
    var_0 thread leaveonownerdeath();
    var_0 setvehgoalpos( var_0.targetpos, 1 );
    var_0 thread helicreatelookatent();
    var_0 waittill( "near_goal" );
    var_0 thread helimovementcontrol();
    thread watchearlyexit( var_0 );
    wait 45;
    self notify( "heli_sniper_timeout" );
    dodropff( var_0 );
}

dodropff( var_0 )
{
    var_0 notify( "dropping" );
    var_0 thread helireturntodropsite();
    var_0 waittill( "at_dropoff" );
    var_0 vehicle_setspeed( 60 );
    var_0 setyawspeed( 180, 180, 180, 0.3 );
    wait 1;

    if ( !maps\mp\_utility::isreallyalive( self ) )
        return;

    thread settempnofalldamage();
    self stopridingvehicle();
    self allowjump( 1 );
    self setstance( "stand" );
    self.onhelisniper = 0;
    self.helisniper = undefined;
    var_0.ownerboarded = 0;
    self takeweapon( "iw6_gm6helisnipe_mp_gm6scope" );
    self enableweaponswitch();
    maps\mp\_utility::setrecoilscale();
    var_1 = common_scripts\utility::getlastweapon();

    if ( !self hasweapon( var_1 ) )
        var_1 = maps\mp\killstreaks\_killstreaks::getfirstprimaryweapon();

    maps\mp\_utility::switch_to_last_weapon( var_1 );
    wait 1;

    if ( isdefined( var_0 ) )
        var_0 thread helileave();
}

watchearlyexit( var_0 )
{
    self endon( "heli_sniper_timeout" );
    var_0 thread maps\mp\killstreaks\_killstreaks::allowridekillstreakplayerexit( "dropping" );
    var_0 waittill( "killstreakExit" );
    dodropff( var_0 );
}

moveplayertochopper( var_0 )
{
    self endon( "disconnect" );
    self visionsetnakedforplayer( "black_bw", 0.5 );
    maps\mp\_utility::set_visionset_for_watching_players( "black_bw", 0.5, 1.0 );
    var_1 = common_scripts\utility::waittill_any_timeout( 0.5, "death" );
    maps\mp\gametypes\_hostmigration::waittillhostmigrationdone();

    if ( var_1 == "death" )
    {
        thread maps\mp\killstreaks\_killstreaks::clearrideintro( 1.0 );
        return "fail";
    }

    self cancelmantle();

    if ( var_1 != "disconnect" )
    {
        thread maps\mp\killstreaks\_killstreaks::clearrideintro( 1.0, 0.75 );

        if ( self.team == "spectator" )
            return "fail";
    }

    var_0 attachplayertochopper();

    if ( !isalive( self ) )
        return "fail";

    level.helisnipereyeson = var_0;
    level notify( "update_uplink" );
}

destroycarriedims()
{
    foreach ( var_1 in self.imslist )
    {
        if ( isdefined( var_1.carriedby ) && var_1.carriedby == self )
        {
            self forceusehintoff();
            self.iscarrying = undefined;
            self.carrieditem = undefined;

            if ( isdefined( var_1.bombsquadmodel ) )
                var_1.bombsquadmodel delete();

            var_1 delete();
            self enableweapons();
        }
    }
}

helicreatelookatent()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self endon( "leaving" );
    self.owner endon( "death" );
    var_0 = self.origin + anglestoright( self.owner.angles ) * 1000;
    self.lookatent = spawn( "script_origin", var_0 );
    self setlookatent( self.lookatent );
    self setyawspeed( 360, 120 );

    for (;;)
    {
        wait 0.25;
        var_0 = self.origin + anglestoright( self.owner.angles ) * 1000;
        self.lookatent.origin = var_0;
    }
}

attachplayertochopper()
{
    self.owner notify( "force_cancel_sentry" );
    self.owner notify( "force_cancel_ims" );
    self.owner notify( "force_cancel_placement" );
    self.owner notify( "cancel_carryRemoteUAV" );
    self.owner setplayerangles( self gettagangles( "TAG_RIDER" ) );
    self.owner ridevehicle( self, 40, 70, 10, 70, 1 );
    self.owner setstance( "crouch" );
    self.owner allowjump( 0 );
    thread reequiplightarmor();
    self.ownerboarded = 1;
    self notify( "boarded" );
    self.owner.chopper = self;
}

helireturntodropsite()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self endon( "owner_disconnected" );
    self endon( "owner_death" );
    var_0 = undefined;
    var_1 = undefined;
    var_2 = undefined;
    var_3 = 0;

    foreach ( var_5 in level.air_node_mesh )
    {
        if ( !isdefined( var_5.script_parameters ) || !issubstr( var_5.script_parameters, "pickupNode" ) )
            continue;

        var_6 = distancesquared( var_5.origin, self.origin );

        if ( !isdefined( var_2 ) || var_6 < var_2 )
        {
            var_1 = var_5;
            var_2 = var_6;

            if ( var_5.script_parameters == "pickupNodehigh" )
            {
                var_3 = 1;
                continue;
            }

            var_3 = 0;
        }
    }

    if ( maps\mp\_utility::getmapname() == "mp_chasm" )
    {
        if ( var_1.origin == ( -224, -1056, 2376 ) )
            var_1.origin = ( -304, -896, 2376 );
    }

    if ( var_3 && !bullettracepassed( self.origin, var_1.origin, 0, self ) )
    {
        self setvehgoalpos( self.origin + ( 0, 0, 2300 ), 1 );
        waittill_msg_or_timeout( "near_goal", "goal", 5 );
        var_8 = var_1.origin;
        var_8 = var_8 + ( 0, 0, 1500 );
    }
    else if ( var_1.origin[2] > self.origin[2] )
        var_8 = var_1.origin;
    else
    {
        var_8 = var_1.origin * ( 1, 1, 0 );
        var_8 = var_8 + ( 0, 0, self.origin[2] );
    }

    self setvehgoalpos( var_8, 1 );
    var_9 = getbestheight( var_8 );
    var_10 = var_8 * ( 1, 1, 0 );
    var_11 = var_10 + ( 0, 0, var_9 );
    waittill_msg_or_timeout( "near_goal", "goal", 5 );
    self.movedlow = 0;
    self setvehgoalpos( var_11 + ( 0, 0, 200 ), 1 );
    self.droppingoff = 1;
    waittill_msg_or_timeout( "near_goal", "goal", 5 );
    self.movedlow = 1;
    self notify( "at_dropoff" );
}

waittill_msg_or_timeout( var_0, var_1, var_2 )
{
    level endon( "game_ended" );
    self endon( var_0 );
    self endon( var_1 );
    wait( var_2 );
}

helimovementcontrol()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "dropping" );
    self vehicle_setspeed( 60, 45, 20 );
    self setneargoalnotifydist( 8 );

    for (;;)
    {
        var_0 = self.owner getnormalizedmovement();

        if ( var_0[0] >= 0.15 || var_0[1] >= 0.15 || var_0[0] <= -0.15 || var_0[1] <= -0.15 )
            thread manualmove( var_0 );

        wait 0.05;
    }
}

helifreemovementcontrol()
{
    self vehicle_setspeed( 80, 60, 20 );
    self setneargoalnotifydist( 8 );

    for (;;)
    {
        var_0 = self.owner getnormalizedmovement();

        if ( var_0[0] >= 0.15 || var_0[1] >= 0.15 || var_0[0] <= -0.15 || var_0[1] <= -0.15 )
            thread manualmovefree( var_0 );

        wait 0.05;
    }
}

manualmovefree( var_0 )
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "dropping" );
    self notify( "manualMove" );
    self endon( "manualMove" );
    var_1 = anglestoforward( self.owner.angles ) * ( 350 * var_0[0] );
    var_2 = anglestoright( self.owner.angles ) * ( 250 * var_0[1] );
    var_3 = var_1 + var_2;
    var_4 = self.origin + var_3;
    var_4 = var_4 * ( 1, 1, 0 );
    var_4 = var_4 + ( 0, 0, self.maxheight[2] );

    if ( distance2dsquared( ( 0, 0, 0 ), var_4 ) > 8000000 )
        return;

    self setvehgoalpos( var_4, 1 );
    self waittill( "goal" );
}

manualmove( var_0 )
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "dropping" );
    self notify( "manualMove" );
    self endon( "manualMove" );
    var_1 = anglestoforward( self.owner.angles ) * ( 250 * var_0[0] );
    var_2 = anglestoright( self.owner.angles ) * ( 250 * var_0[1] );
    var_3 = var_1 + var_2;
    var_4 = 256;
    var_5 = self.origin + var_3;
    var_6 = maps\mp\_utility::gethelipilottraceoffset();
    var_7 = var_5 + ( maps\mp\_utility::gethelipilotmeshoffset() + var_6 );
    var_8 = var_5 + ( maps\mp\_utility::gethelipilotmeshoffset() - var_6 );
    var_9 = bullettrace( var_7, var_8, 0, 0, 0, 0, 1 );

    if ( isdefined( var_9["entity"] ) && var_9["normal"][2] > 0.1 )
    {
        var_5 = var_9["position"] - maps\mp\_utility::gethelipilotmeshoffset() + ( 0, 0, var_4 );
        var_10 = var_5[2] - self.origin[2];

        if ( var_10 > 1000 )
            return;

        self setvehgoalpos( var_5, 1 );
        self waittill( "goal" );
    }
}

helileave()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self notify( "end_disconnect_check" );
    self notify( "end_death_check" );
    self notify( "leaving" );

    if ( isdefined( self.ladder ) )
        self.ladder delete();

    if ( isdefined( self.trigger ) )
        self.trigger delete();

    if ( isdefined( self.turret ) )
        self.turret delete();

    if ( isdefined( self.msg ) )
        self.msg maps\mp\gametypes\_hud_util::destroyelem();

    if ( isdefined( self.switchmsg ) )
        self.switchmsg maps\mp\gametypes\_hud_util::destroyelem();

    if ( isdefined( self.movemsg ) )
        self.movemsg maps\mp\gametypes\_hud_util::destroyelem();

    self clearlookatent();
    level.helisnipereyeson = undefined;
    level notify( "update_uplink" );
    self setyawspeed( 220, 220, 220, 0.3 );
    self vehicle_setspeed( 120, 60 );
    self setvehgoalpos( self.origin + ( 0, 0, 1200 ), 1 );
    self waittill( "goal" );
    var_0 = ( self.pathend - self.pathgoal ) * 5000;
    self setvehgoalpos( var_0, 1 );
    self vehicle_setspeed( 300, 75 );
    self.leaving = 1;
    common_scripts\utility::waittill_any_timeout( 5, "goal" );

    if ( isdefined( level.lbsniper ) && level.lbsniper == self )
        level.lbsniper = undefined;

    self notify( "delete" );
    self delete();
}

helideathcleanup( var_0 )
{
    level endon( "game_ended" );
    self endon( "leaving" );
    self waittill( "death" );
    maps\mp\gametypes\_hostmigration::waittillhostmigrationdone();
    thread maps\mp\killstreaks\_helicopter::lbonkilled();

    if ( isdefined( self.ladder ) )
        self.ladder delete();

    if ( isdefined( self.trigger ) )
        self.trigger delete();

    if ( isdefined( self.turret ) )
        self.turret delete();

    if ( isdefined( self.msg ) )
        self.msg maps\mp\gametypes\_hud_util::destroyelem();

    if ( isdefined( self.switchmsg ) )
        self.switchmsg maps\mp\gametypes\_hud_util::destroyelem();

    if ( isdefined( self.movemsg ) )
        self.movemsg maps\mp\gametypes\_hud_util::destroyelem();

    if ( isdefined( self.owner ) && isalive( self.owner ) && self.ownerboarded == 1 )
    {
        self.owner stopridingvehicle();
        var_1 = undefined;
        var_2 = undefined;

        if ( isdefined( self.attackers ) )
        {
            var_3 = 0;

            foreach ( var_6, var_5 in self.attackers )
            {
                if ( var_5 >= var_3 )
                {
                    var_3 = var_5;
                    var_1 = var_6;
                }
            }
        }

        if ( isdefined( var_1 ) )
        {
            foreach ( var_8 in level.participants )
            {
                if ( var_8 maps\mp\_utility::getuniqueid() == var_1 )
                    var_2 = var_8;
            }
        }

        var_10 = getdvarint( "scr_team_fftype" );

        if ( isdefined( self.killingattacker ) && isdefined( self.killingattacker.isharrier ) )
            self.killingattacker radiusdamage( self.owner.origin, 200, 2600, 2600, self.killingattacker );
        else if ( isdefined( var_2 ) && var_10 != 2 )
            radiusdamage( self.owner.origin, 200, 2600, 2600, var_2 );
        else if ( var_10 == 2 && isdefined( var_2 ) && maps\mp\_utility::attackerishittingteam( var_2, self.owner ) )
        {
            radiusdamage( self.owner.origin, 200, 2600, 2600, var_2 );
            radiusdamage( self.owner.origin, 200, 2600, 2600 );
        }
        else
            radiusdamage( self.owner.origin, 200, 2600, 2600 );

        self.owner.onhelisniper = 0;
        self.owner.helisniper = undefined;
    }
}

settempnofalldamage()
{
    if ( !maps\mp\_utility::_hasperk( "specialty_falldamage" ) )
    {
        level endon( "game_ended" );
        self endon( "death" );
        self endon( "disconnect" );
        maps\mp\_utility::giveperk( "specialty_falldamage", 0 );
        wait 2;
        maps\mp\_utility::_unsetperk( "specialty_falldamage" );
    }
}

reequiplightarmor()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "dropping" );
    var_0 = 0;

    for (;;)
    {
        wait 0.05;

        if ( !isdefined( self.owner.lightarmorhp ) && !self.owner maps\mp\_utility::isjuggernaut() )
        {
            self.owner maps\mp\perks\_perkfunctions::setlightarmor();
            var_0++;

            if ( var_0 >= 2 )
                break;
        }
    }
}

keepcrouched()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "dropping" );

    for (;;)
    {
        if ( self.owner getstance() != "crouch" )
            self.owner setstance( "crouch" );

        wait 0.05;
    }
}

givecoolassgun()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self endon( "dropping" );
    self.owner endon( "disconnect" );

    for (;;)
    {
        if ( !isalive( self.owner ) )
            return "fail";

        if ( self.owner getcurrentprimaryweapon() != "iw6_gm6helisnipe_mp_gm6scope" )
        {
            self.owner giveweapon( "iw6_gm6helisnipe_mp_gm6scope" );
            self.owner switchtoweaponimmediate( "iw6_gm6helisnipe_mp_gm6scope" );
            self.owner disableweaponswitch();
            self.owner maps\mp\_utility::setrecoilscale( 0, 100 );
            self.owner givemaxammo( "iw6_gm6helisnipe_mp_gm6scope" );
        }
        else
            return;

        wait 0.05;
    }
}

restockownerammo()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self.owner endon( "dropping" );

    for (;;)
    {
        self.owner waittill( "weapon_fired" );
        self.owner givemaxammo( "iw6_gm6helisnipe_mp_gm6scope" );
    }
}

pushcorpseonownerdeath()
{
    level endon( "game_ended" );
    self.owner endon( "disconnect" );
    self endon( "death" );
    self endon( "crashing" );
    self.owner waittill( "death" );
    self.owner.onhelisniper = 0;
    self.owner.helisniper = undefined;
    self.ownerboarded = 0;

    if ( isdefined( self.origin ) )
        physicsexplosionsphere( self.origin, 200, 200, 1 );
}

leaveonownerdisconnect()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self endon( "end_disconnect_check" );
    self.owner waittill( "disconnect" );
    self notify( "owner_disconnected" );
    thread helileave();
}

leaveonownerdeath()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "crashing" );
    self endon( "end_death_check" );
    self.owner waittill( "death" );
    self notify( "owner_death" );
    thread helileave();
}

getclosestnode( var_0 )
{
    var_1 = undefined;
    var_2 = 999999;

    foreach ( var_4 in level.air_node_mesh )
    {
        var_5 = distance( var_4.origin, var_0 );

        if ( var_5 < var_2 )
        {
            var_1 = var_4;
            var_2 = var_5;
        }
    }

    return var_1;
}

waitfordeath()
{
    var_0 = self getentitynumber();
    self waittill( "death" );
    level.lbsniper = undefined;

    if ( isdefined( level.helisnipereyeson ) )
    {
        level.helisnipereyeson = undefined;
        level notify( "update_uplink" );
    }
}
