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

init()
{
    level.killstreakfuncs["ball_drone_radar"] = ::tryuseballdrone;
    level.killstreakfuncs["ball_drone_backup"] = ::tryuseballdrone;
    level.balldronesettings = [];
    level.balldronesettings["ball_drone_radar"] = spawnstruct();
    level.balldronesettings["ball_drone_radar"].timeout = 60.0;
    level.balldronesettings["ball_drone_radar"].health = 999999;
    level.balldronesettings["ball_drone_radar"].maxhealth = 500;
    level.balldronesettings["ball_drone_radar"].streakname = "ball_drone_radar";
    level.balldronesettings["ball_drone_radar"].vehicleinfo = "ball_drone_mp";
    level.balldronesettings["ball_drone_radar"].modelbase = "vehicle_ball_drone_iw6";
    level.balldronesettings["ball_drone_radar"].teamsplash = "used_ball_drone_radar";
    level.balldronesettings["ball_drone_radar"].fxid_sparks = loadfx( "vfx/gameplay/mp/killstreaks/vfx_ims_sparks" );
    level.balldronesettings["ball_drone_radar"].fxid_explode = loadfx( "vfx/gameplay/explosions/vehicle/ball/vfx_exp_ball_drone" );
    level.balldronesettings["ball_drone_radar"].sound_explode = "ball_drone_explode";
    level.balldronesettings["ball_drone_radar"].vodestroyed = "nowl_destroyed";
    level.balldronesettings["ball_drone_radar"].votimedout = "nowl_gone";
    level.balldronesettings["ball_drone_radar"].xppopup = "destroyed_ball_drone_radar";
    level.balldronesettings["ball_drone_radar"].playfxcallback = ::radarbuddyplayfx;
    level.balldronesettings["ball_drone_radar"].fxid_light1 = [];
    level.balldronesettings["ball_drone_radar"].fxid_light2 = [];
    level.balldronesettings["ball_drone_radar"].fxid_light3 = [];
    level.balldronesettings["ball_drone_radar"].fxid_light4 = [];
    level.balldronesettings["ball_drone_radar"].fxid_light1["enemy"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_light_detonator_blink" );
    level.balldronesettings["ball_drone_radar"].fxid_light2["enemy"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_light_detonator_blink" );
    level.balldronesettings["ball_drone_radar"].fxid_light3["enemy"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_light_detonator_blink" );
    level.balldronesettings["ball_drone_radar"].fxid_light4["enemy"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_light_detonator_blink" );
    level.balldronesettings["ball_drone_radar"].fxid_light1["friendly"] = loadfx( "fx/misc/light_mine_blink_friendly" );
    level.balldronesettings["ball_drone_radar"].fxid_light2["friendly"] = loadfx( "fx/misc/light_mine_blink_friendly" );
    level.balldronesettings["ball_drone_radar"].fxid_light3["friendly"] = loadfx( "fx/misc/light_mine_blink_friendly" );
    level.balldronesettings["ball_drone_radar"].fxid_light4["friendly"] = loadfx( "fx/misc/light_mine_blink_friendly" );
    level.balldronesettings["ball_drone_backup"] = spawnstruct();
    level.balldronesettings["ball_drone_backup"].timeout = 90.0;
    level.balldronesettings["ball_drone_backup"].health = 999999;
    level.balldronesettings["ball_drone_backup"].maxhealth = 500;
    level.balldronesettings["ball_drone_backup"].streakname = "ball_drone_backup";
    level.balldronesettings["ball_drone_backup"].vehicleinfo = "backup_drone_mp";
    level.balldronesettings["ball_drone_backup"].modelbase = "vehicle_drone_backup_buddy";
    level.balldronesettings["ball_drone_backup"].teamsplash = "used_ball_drone_radar";
    level.balldronesettings["ball_drone_backup"].fxid_sparks = loadfx( "vfx/gameplay/mp/killstreaks/vfx_ims_sparks" );
    level.balldronesettings["ball_drone_backup"].fxid_explode = loadfx( "fx/explosions/bouncing_betty_explosion" );
    level.balldronesettings["ball_drone_backup"].sound_explode = "ball_drone_explode";
    level.balldronesettings["ball_drone_backup"].vodestroyed = "vulture_destroyed";
    level.balldronesettings["ball_drone_backup"].votimedout = "vulture_gone";
    level.balldronesettings["ball_drone_backup"].xppopup = "destroyed_ball_drone";
    level.balldronesettings["ball_drone_backup"].weaponinfo = "ball_drone_gun_mp";
    level.balldronesettings["ball_drone_backup"].weaponmodel = "vehicle_drone_backup_buddy_gun";
    level.balldronesettings["ball_drone_backup"].weapontag = "tag_turret_attach";
    level.balldronesettings["ball_drone_backup"].sound_weapon = "weap_p99_fire_npc";
    level.balldronesettings["ball_drone_backup"].sound_targeting = "ball_drone_targeting";
    level.balldronesettings["ball_drone_backup"].sound_lockon = "ball_drone_lockon";
    level.balldronesettings["ball_drone_backup"].sentrymode = "sentry";
    level.balldronesettings["ball_drone_backup"].visual_range_sq = 1440000;
    level.balldronesettings["ball_drone_backup"].burstmin = 10;
    level.balldronesettings["ball_drone_backup"].burstmax = 20;
    level.balldronesettings["ball_drone_backup"].pausemin = 0.15;
    level.balldronesettings["ball_drone_backup"].pausemax = 0.35;
    level.balldronesettings["ball_drone_backup"].lockontime = 0.25;
    level.balldronesettings["ball_drone_backup"].playfxcallback = ::backupbuddyplayfx;
    level.balldronesettings["ball_drone_backup"].fxid_light1 = [];
    level.balldronesettings["ball_drone_backup"].fxid_light1["enemy"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_light_detonator_blink" );
    level.balldronesettings["ball_drone_backup"].fxid_light1["friendly"] = loadfx( "fx/misc/light_mine_blink_friendly" );
    level.balldrones = [];
}

tryuseballdrone( var_0, var_1 )
{
    return useballdrone( var_1 );
}

useballdrone( var_0 )
{
    var_1 = 1;

    if ( maps\mp\_utility::isusingremote() )
        return 0;
    else if ( exceededmaxballdrones() )
    {
        self iprintlnbold( &"KILLSTREAKS_AIR_SPACE_TOO_CROWDED" );
        return 0;
    }
    else if ( maps\mp\_utility::currentactivevehiclecount() >= maps\mp\_utility::maxvehiclesallowed() || level.fauxvehiclecount + var_1 >= maps\mp\_utility::maxvehiclesallowed() )
    {
        self iprintlnbold( &"KILLSTREAKS_TOO_MANY_VEHICLES" );
        return 0;
    }
    else if ( isdefined( self.balldrone ) )
    {
        self iprintlnbold( &"KILLSTREAKS_COMPANION_ALREADY_EXISTS" );
        return 0;
    }
    else if ( isdefined( self.drones_disabled ) )
    {
        self iprintlnbold( &"KILLSTREAKS_UNAVAILABLE" );
        return 0;
    }

    maps\mp\_utility::incrementfauxvehiclecount();
    var_2 = createballdrone( var_0 );

    if ( !isdefined( var_2 ) )
    {
        if ( maps\mp\_utility::is_aliens() )
            self.drone_failed = 1;
        else
            self iprintlnbold( &"KILLSTREAKS_UNAVAILABLE" );

        maps\mp\_utility::decrementfauxvehiclecount();
        return 0;
    }

    self.balldrone = var_2;
    thread startballdrone( var_2 );

    if ( var_0 == "ball_drone_backup" && maps\mp\agents\_agent_utility::getnumownedactiveagentsbytype( self, "dog" ) > 0 )
        maps\mp\gametypes\_missions::processchallenge( "ch_twiceasdeadly" );

    return 1;
}

createballdrone( var_0 )
{
    var_1 = self.angles;
    var_2 = anglestoforward( self.angles );
    var_3 = self.origin + var_2 * 100 + ( 0, 0, 90 );
    var_4 = self.origin + ( 0, 0, 90 );
    var_5 = bullettrace( var_4, var_3, 0 );
    var_6 = 3;

    while ( var_5["surfacetype"] != "none" && var_6 > 0 )
    {
        var_3 = self.origin + vectornormalize( var_4 - var_5["position"] ) * 5;
        var_5 = bullettrace( var_4, var_3, 0 );
        var_6--;
        wait 0.05;
    }

    if ( var_6 <= 0 )
        return;

    var_7 = anglestoright( self.angles );
    var_8 = self.origin + var_7 * 20 + ( 0, 0, 90 );
    var_5 = bullettrace( var_3, var_8, 0 );
    var_6 = 3;

    while ( var_5["surfacetype"] != "none" && var_6 > 0 )
    {
        var_8 = var_3 + vectornormalize( var_3 - var_5["position"] ) * 5;
        var_5 = bullettrace( var_3, var_8, 0 );
        var_6--;
        wait 0.05;
    }

    if ( var_6 <= 0 )
        return;

    var_9 = spawnhelicopter( self, var_3, var_1, level.balldronesettings[var_0].vehicleinfo, level.balldronesettings[var_0].modelbase );

    if ( !isdefined( var_9 ) )
        return;

    var_9 enableaimassist();
    var_9 makevehiclenotcollidewithplayers( 1 );
    var_9 addtoballdronelist();
    var_9 thread removefromballdronelistondeath();
    var_9.health = level.balldronesettings[var_0].health;
    var_9.maxhealth = level.balldronesettings[var_0].maxhealth;
    var_9.damagetaken = 0;
    var_9.speed = 140;
    var_9.followspeed = 140;
    var_9.owner = self;
    var_9.team = self.team;
    var_9 vehicle_setspeed( var_9.speed, 16, 16 );
    var_9 setyawspeed( 120, 90 );
    var_9 setneargoalnotifydist( 16 );
    var_9.balldronetype = var_0;
    var_9 sethoverparams( 30, 10, 5 );
    var_9 setotherent( self );
    var_9 common_scripts\utility::make_entity_sentient_mp( self.team, var_0 != "ball_drone_backup" );

    if ( issentient( var_9 ) )
        var_9 setthreatbiasgroup( "DogsDontAttack" );

    if ( !maps\mp\_utility::is_aliens() )
    {
        if ( level.teambased )
            var_9 maps\mp\_entityheadicons::setteamheadicon( var_9.team, ( 0, 0, 25 ) );
        else
            var_9 maps\mp\_entityheadicons::setplayerheadicon( var_9.owner, ( 0, 0, 25 ) );
    }

    var_10 = 45;
    var_11 = 45;

    switch ( var_0 )
    {
        case "ball_drone_radar":
            var_10 = 90;
            var_11 = 90;
            var_12 = spawn( "script_model", self.origin );
            var_12.team = self.team;
            var_12 makeportableradar( self );
            var_9.radar = var_12;
            var_9 thread radarmover();
            var_9.ammo = 99999;
            var_9.cameraoffset = distance( var_9.origin, var_9 gettagorigin( "camera_jnt" ) );
            var_9 thread maps\mp\gametypes\_trophy_system::trophyactive( self );
            var_9 thread balldrone_handledamage();
            break;
        case "alien_ball_drone_4":
        case "alien_ball_drone_3":
        case "alien_ball_drone_2":
        case "alien_ball_drone_1":
        case "alien_ball_drone":
        case "ball_drone_backup":
            var_13 = spawnturret( "misc_turret", var_9 gettagorigin( level.balldronesettings[var_0].weapontag ), level.balldronesettings[var_0].weaponinfo );
            var_13 linkto( var_9, level.balldronesettings[var_0].weapontag );
            var_13 setmodel( level.balldronesettings[var_0].weaponmodel );
            var_13.angles = var_9.angles;
            var_13.owner = var_9.owner;
            var_13.team = self.team;
            var_13 maketurretinoperable();
            var_13 makeunusable();
            var_13.vehicle = var_9;
            var_13.health = level.balldronesettings[var_0].health;
            var_13.maxhealth = level.balldronesettings[var_0].maxhealth;
            var_13.damagetaken = 0;
            var_14 = self.origin + var_2 * -100 + ( 0, 0, 40 );
            var_13.idletarget = spawn( "script_origin", var_14 );
            var_13.idletarget.targetname = "test";
            thread idletargetmover( var_13.idletarget );

            if ( level.teambased )
                var_13 setturretteam( self.team );

            var_13 setmode( level.balldronesettings[var_0].sentrymode );
            var_13 setsentryowner( self );
            var_13 setleftarc( 180 );
            var_13 setrightarc( 180 );
            var_13 setbottomarc( 50 );
            var_13 thread balldrone_attacktargets();
            var_13 setturretminimapvisible( 1, "buddy_turret" );
            var_15 = var_9.origin + ( anglestoforward( var_9.angles ) * -10 + anglestoright( var_9.angles ) * -10 ) + ( 0, 0, 10 );
            var_13.killcament = spawn( "script_model", var_15 );
            var_13.killcament setscriptmoverkillcam( "explosive" );
            var_13.killcament linkto( var_9 );
            var_9.turret = var_13;
            var_13.parent = var_9;
            var_9 thread balldrone_backup_handledamage();
            var_9.turret thread balldrone_backup_turret_handledamage();
            break;
        default:
            break;
    }

    var_9 setmaxpitchroll( var_10, var_11 );
    var_9.targetpos = var_8;
    var_9.attract_strength = 10000;
    var_9.attract_range = 150;

    if ( !( maps\mp\_utility::is_aliens() && isdefined( level.script ) && level.script == "mp_alien_last" ) )
        var_9.attractor = missile_createattractorent( var_9, var_9.attract_strength, var_9.attract_range );

    var_9.hasdodged = 0;
    var_9.stunned = 0;
    var_9.inactive = 0;
    var_9 thread watchempdamage();
    var_9 thread balldrone_watchdeath();
    var_9 thread balldrone_watchtimeout();
    var_9 thread balldrone_watchownerloss();
    var_9 thread balldrone_watchownerdeath();
    var_9 thread balldrone_watchroundend();
    var_9 thread balldrone_enemy_lightfx();
    var_9 thread balldrone_friendly_lightfx();
    var_16 = spawnstruct();
    var_16.validateaccuratetouching = 1;
    var_16.deathoverridecallback = ::balldrone_moving_platform_death;
    var_9 thread maps\mp\_movers::handle_moving_platforms( var_16 );
    var_9.owner maps\mp\_matchdata::logkillstreakevent( level.balldronesettings[var_9.balldronetype].streakname, var_9.targetpos );
    return var_9;
}

balldrone_moving_platform_death( var_0 )
{
    if ( !isdefined( var_0.lasttouchedplatform.destroydroneoncollision ) || var_0.lasttouchedplatform.destroydroneoncollision )
        self notify( "death" );
}

idletargetmover( var_0 )
{
    self endon( "disconnect" );
    level endon( "game_ended" );
    var_0 endon( "death" );
    var_1 = anglestoforward( self.angles );

    for (;;)
    {
        if ( maps\mp\_utility::isreallyalive( self ) && !maps\mp\_utility::isusingremote() && anglestoforward( self.angles ) != var_1 )
        {
            var_1 = anglestoforward( self.angles );
            var_2 = self.origin + var_1 * -100 + ( 0, 0, 40 );
            var_0 moveto( var_2, 0.5 );
        }

        wait 0.5;
    }
}

balldrone_enemy_lightfx()
{
    self endon( "death" );
    var_0 = level.balldronesettings[self.balldronetype];

    for (;;)
    {
        foreach ( var_2 in level.players )
        {
            if ( isdefined( var_2 ) )
            {
                if ( level.teambased )
                {
                    if ( var_2.team != self.team )
                        self [[ var_0.playfxcallback ]]( "enemy", var_2 );

                    continue;
                }

                if ( var_2 != self.owner )
                    self [[ var_0.playfxcallback ]]( "enemy", var_2 );
            }
        }

        wait 1.0;
    }
}

balldrone_friendly_lightfx()
{
    self endon( "death" );
    var_0 = level.balldronesettings[self.balldronetype];

    foreach ( var_2 in level.players )
    {
        if ( isdefined( var_2 ) )
        {
            if ( level.teambased )
            {
                if ( var_2.team == self.team )
                    self [[ var_0.playfxcallback ]]( "friendly", var_2 );

                continue;
            }

            if ( var_2 == self.owner )
                self [[ var_0.playfxcallback ]]( "friendly", var_2 );
        }
    }

    thread watchconnectedplayfx();
    thread watchjoinedteamplayfx();
}

backupbuddyplayfx( var_0, var_1 )
{
    var_2 = level.balldronesettings[self.balldronetype];
    playfxontagforclients( var_2.fxid_light1[var_0], self.turret, "tag_fx", var_1 );
    playfxontagforclients( var_2.fxid_light1[var_0], self, "tag_fx", var_1 );
}

radarbuddyplayfx( var_0, var_1 )
{
    var_2 = level.balldronesettings[self.balldronetype];
    playfxontagforclients( var_2.fxid_light1[var_0], self, "tag_fx", var_1 );
    playfxontagforclients( var_2.fxid_light2[var_0], self, "tag_fx1", var_1 );
    playfxontagforclients( var_2.fxid_light3[var_0], self, "tag_fx2", var_1 );
    playfxontagforclients( var_2.fxid_light4[var_0], self, "tag_fx3", var_1 );
}

watchconnectedplayfx()
{
    self endon( "death" );

    for (;;)
    {
        level waittill( "connected", var_0 );
        var_0 waittill( "spawned_player" );
        var_1 = level.balldronesettings[self.balldronetype];

        if ( isdefined( var_0 ) )
        {
            if ( level.teambased )
            {
                if ( var_0.team == self.team )
                    self [[ var_1.playfxcallback ]]( "friendly", var_0 );
                else
                    self [[ var_1.playfxcallback ]]( "enemy", var_0 );

                continue;
            }

            if ( var_0 == self.owner )
            {
                self [[ var_1.playfxcallback ]]( "friendly", var_0 );
                continue;
            }

            self [[ var_1.playfxcallback ]]( "enemy", var_0 );
        }
    }
}

watchjoinedteamplayfx()
{
    self endon( "death" );

    for (;;)
    {
        level waittill( "joined_team", var_0 );
        var_0 waittill( "spawned_player" );
        var_1 = level.balldronesettings[self.balldronetype];

        if ( isdefined( var_0 ) )
        {
            if ( level.teambased )
            {
                if ( var_0.team == self.team )
                    self [[ var_1.playfxcallback ]]( "friendly", var_0 );
                else
                    self [[ var_1.playfxcallback ]]( "enemy", var_0 );

                continue;
            }

            if ( var_0 == self.owner )
            {
                self [[ var_1.playfxcallback ]]( "friendly", var_0 );
                continue;
            }

            self [[ var_1.playfxcallback ]]( "enemy", var_0 );
        }
    }
}

startballdrone( var_0 )
{
    level endon( "game_ended" );
    var_0 endon( "death" );

    switch ( var_0.balldronetype )
    {
        case "alien_ball_drone_4":
        case "alien_ball_drone_3":
        case "alien_ball_drone_2":
        case "alien_ball_drone_1":
        case "alien_ball_drone":
        case "ball_drone_backup":
            if ( isdefined( var_0.turret ) && isdefined( var_0.turret.idletarget ) )
                var_0 setlookatent( var_0.turret.idletarget );
            else
                var_0 setlookatent( self );

            break;
        default:
            var_0 setlookatent( self );
            break;
    }

    var_1 = ( 0, 0, 118 );
    var_0 setdronegoalpos( self, var_1 );
    var_0 waittill( "near_goal" );
    var_0 vehicle_setspeed( var_0.speed, 10, 10 );
    var_0 waittill( "goal" );
    var_0 thread balldrone_followplayer();
}

balldrone_followplayer()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "leaving" );

    if ( !isdefined( self.owner ) )
    {
        thread balldrone_leave();
        return;
    }

    self.owner endon( "disconnect" );
    self endon( "owner_gone" );
    self vehicle_setspeed( self.followspeed, 10, 10 );
    var_0 = ( 0, 0, 0 );
    var_1 = 4096;
    thread low_entries_watcher();

    for (;;)
    {
        if ( isdefined( self.owner ) && isalive( self.owner ) )
        {
            if ( self.owner.origin != var_0 && distancesquared( self.owner.origin, var_0 ) > var_1 )
            {
                if ( self.balldronetype == "ball_drone_backup" || self.balldronetype == "alien_ball_drone" || self.balldronetype == "alien_ball_drone_1" || self.balldronetype == "alien_ball_drone_2" || self.balldronetype == "alien_ball_drone_3" || self.balldronetype == "alien_ball_drone_4" )
                {
                    if ( !isdefined( self.turret getturrettarget( 0 ) ) )
                    {
                        var_0 = self.owner.origin;
                        balldrone_movetoplayer();
                        continue;
                    }
                }
                else
                {
                    var_0 = self.owner.origin;
                    balldrone_movetoplayer();
                    continue;
                }
            }
        }

        wait 1;
    }
}

balldrone_movetoplayer()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "leaving" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "owner_gone" );
    self notify( "ballDrone_moveToPlayer" );
    self endon( "ballDrone_moveToPlayer" );
    var_0 = 40;
    var_1 = 40;
    var_2 = 118;

    switch ( self.owner getstance() )
    {
        case "stand":
            var_2 = 118;
            break;
        case "crouch":
            var_2 = 70;
            break;
        case "prone":
            var_2 = 36;
            break;
    }

    if ( isdefined( self.low_entry ) )
        var_2 = var_2 * self.low_entry;

    var_3 = ( var_1, var_0, var_2 );
    self setdronegoalpos( self.owner, var_3 );
    self.intransit = 1;
    thread balldrone_watchforgoal();
}

balldrone_watchforgoal()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "leaving" );
    self.owner endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "owner_gone" );
    self notify( "ballDrone_watchForGoal" );
    self endon( "ballDrone_watchForGoal" );
    var_0 = common_scripts\utility::waittill_any_return( "goal", "near_goal", "hit_goal" );
    self.intransit = 0;
    self.inactive = 0;
    self notify( "hit_goal" );
}

radarmover()
{
    level endon( "game_ended" );
    self endon( "death" );

    for (;;)
    {
        if ( isdefined( self.stunned ) && self.stunned )
        {
            wait 0.5;
            continue;
        }

        if ( isdefined( self.inactive ) && self.inactive )
        {
            wait 0.5;
            continue;
        }

        if ( isdefined( self.radar ) )
            self.radar moveto( self.origin, 0.5 );

        wait 0.5;
    }
}

low_entries_watcher()
{
    level endon( "game_ended" );
    self endon( "gone" );
    self endon( "death" );
    var_0 = getentarray( "low_entry", "targetname" );

    while ( var_0.size > 0 )
    {
        foreach ( var_2 in var_0 )
        {
            while ( self istouching( var_2 ) || self.owner istouching( var_2 ) )
            {
                if ( isdefined( var_2.script_parameters ) )
                    self.low_entry = float( var_2.script_parameters );
                else
                    self.low_entry = 0.5;

                wait 0.1;
            }

            self.low_entry = undefined;
        }

        wait 0.1;
    }
}

balldrone_watchdeath()
{
    level endon( "game_ended" );
    self endon( "gone" );
    self waittill( "death" );
    thread balldronedestroyed();
}

balldrone_watchtimeout()
{
    level endon( "game_ended" );
    self endon( "death" );
    self.owner endon( "disconnect" );
    self endon( "owner_gone" );
    var_0 = level.balldronesettings[self.balldronetype];
    var_1 = var_0.timeout;

    if ( maps\mp\_utility::is_aliens() && isdefined( level.ball_drone_alien_timeout_func ) && isdefined( self.owner ) )
        var_1 = self [[ level.ball_drone_alien_timeout_func ]]( var_1, self.owner );

    if ( !maps\mp\_utility::is_aliens() )
    {

    }

    maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_1 );

    if ( isdefined( self.owner ) && !maps\mp\_utility::is_aliens() )
        self.owner maps\mp\_utility::leaderdialogonplayer( var_0.votimedout );

    thread balldrone_leave();
}

balldrone_watchownerloss()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "leaving" );
    self.owner waittill( "killstreak_disowned" );
    self notify( "owner_gone" );
    thread balldrone_leave();
}

balldrone_watchownerdeath()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "leaving" );

    for (;;)
    {
        self.owner waittill( "death" );

        if ( maps\mp\_utility::getgametypenumlives() && self.owner.pers["deaths"] == maps\mp\_utility::getgametypenumlives() )
            thread balldrone_leave();
    }
}

balldrone_watchroundend()
{
    self endon( "death" );
    self endon( "leaving" );
    self.owner endon( "disconnect" );
    self endon( "owner_gone" );
    level common_scripts\utility::waittill_any( "round_end_finished", "game_ended" );
    thread balldrone_leave();
}

balldrone_leave()
{
    self endon( "death" );
    self notify( "leaving" );
    balldroneexplode();
}

balldrone_handledamage()
{
    maps\mp\gametypes\_damage::monitordamage( self.maxhealth, "ball_drone", ::handledeathdamage, ::modifydamage, 1 );
}

balldrone_backup_handledamage()
{
    self endon( "death" );
    level endon( "game_ended" );
    self setcandamage( 1 );

    for (;;)
    {
        self waittill( "damage", var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 );
        maps\mp\gametypes\_damage::monitordamageoneshot( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, "ball_drone", ::handledeathdamage, ::modifydamage, 1 );
    }
}

balldrone_backup_turret_handledamage()
{
    self endon( "death" );
    level endon( "game_ended" );
    self maketurretsolid();
    self setcandamage( 1 );

    for (;;)
    {
        self waittill( "damage", var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 );

        if ( isdefined( self.parent ) )
            self.parent maps\mp\gametypes\_damage::monitordamageoneshot( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, "ball_drone", ::handledeathdamage, ::modifydamage, 1 );
    }
}

modifydamage( var_0, var_1, var_2, var_3 )
{
    var_4 = var_3;
    var_4 = maps\mp\gametypes\_damage::handlemissiledamage( var_1, var_2, var_4 );
    var_4 = maps\mp\gametypes\_damage::handlegrenadedamage( var_1, var_2, var_4 );
    var_4 = maps\mp\gametypes\_damage::handleapdamage( var_1, var_2, var_4, var_0 );
    return var_4;
}

handledeathdamage( var_0, var_1, var_2, var_3 )
{
    var_4 = level.balldronesettings[self.balldronetype];
    maps\mp\gametypes\_damage::onkillstreakkilled( var_0, var_1, var_2, var_3, var_4.xppopup, var_4.vodestroyed );

    if ( self.balldronetype == "ball_drone_backup" )
        var_0 maps\mp\gametypes\_missions::processchallenge( "ch_vulturekiller" );
}

watchempdamage()
{
    self endon( "death" );
    level endon( "game_ended" );

    for (;;)
    {
        self waittill( "emp_damage", var_0, var_1 );
        balldrone_stunned( var_1 );
    }
}

balldrone_stunned( var_0 )
{
    self notify( "ballDrone_stunned" );
    self endon( "ballDrone_stunned" );
    self endon( "death" );
    self.owner endon( "disconnect" );
    level endon( "game_ended" );
    self.stunned = 1;

    if ( isdefined( level.balldronesettings[self.balldronetype].fxid_sparks ) )
        playfxontag( level.balldronesettings[self.balldronetype].fxid_sparks, self, "tag_origin" );

    if ( self.balldronetype == "ball_drone_radar" )
    {
        if ( isdefined( self.radar ) )
            self.radar delete();
    }

    if ( isdefined( self.turret ) )
        self.turret notify( "turretstatechange" );

    wait( var_0 );
    self.stunned = 0;

    if ( self.balldronetype == "ball_drone_radar" )
    {
        var_1 = spawn( "script_model", self.origin );
        var_1.team = self.team;
        var_1 makeportableradar( self.owner );
        self.radar = var_1;
    }

    if ( isdefined( self.turret ) )
        self.turret notify( "turretstatechange" );
}

balldronedestroyed()
{
    if ( !isdefined( self ) )
        return;

    balldroneexplode();
}

balldroneexplode()
{
    if ( isdefined( level.balldronesettings[self.balldronetype].fxid_explode ) )
        playfx( level.balldronesettings[self.balldronetype].fxid_explode, self.origin );

    if ( isdefined( level.balldronesettings[self.balldronetype].sound_explode ) )
        self playsound( level.balldronesettings[self.balldronetype].sound_explode );

    self notify( "explode" );
    removeballdrone();
}

removeballdrone()
{
    maps\mp\_utility::decrementfauxvehiclecount();

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

    if ( isdefined( self.turret ) )
    {
        self.turret setturretminimapvisible( 0 );

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

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

        self.turret delete();
    }

    if ( isdefined( self.owner ) && isdefined( self.owner.balldrone ) )
        self.owner.balldrone = undefined;

    self delete();
}

addtoballdronelist()
{
    level.balldrones[self getentitynumber()] = self;
}

removefromballdronelistondeath()
{
    var_0 = self getentitynumber();
    self waittill( "death" );
    level.balldrones[var_0] = undefined;
}

exceededmaxballdrones()
{
    if ( level.balldrones.size >= maps\mp\_utility::maxvehiclesallowed() )
        return 1;
    else
        return 0;
}

balldrone_attacktargets()
{
    self.vehicle endon( "death" );
    level endon( "game_ended" );

    for (;;)
    {
        self waittill( "turretstatechange" );

        if ( self isfiringturret() && ( isdefined( self.vehicle.stunned ) && !self.vehicle.stunned ) && ( isdefined( self.vehicle.inactive ) && !self.vehicle.inactive ) )
        {
            self laseron();
            dolockon( level.balldronesettings[self.vehicle.balldronetype].lockontime );
            thread balldrone_burstfirestart();
            continue;
        }

        self laseroff();
        thread balldrone_burstfirestop();
    }
}

balldrone_burstfirestart()
{
    self.vehicle endon( "death" );
    self endon( "stop_shooting" );
    level endon( "game_ended" );
    var_0 = self.vehicle;
    var_1 = weaponfiretime( level.balldronesettings[var_0.balldronetype].weaponinfo );
    var_2 = level.balldronesettings[var_0.balldronetype].burstmin;
    var_3 = level.balldronesettings[var_0.balldronetype].burstmax;
    var_4 = level.balldronesettings[var_0.balldronetype].pausemin;
    var_5 = level.balldronesettings[var_0.balldronetype].pausemax;

    if ( maps\mp\_utility::is_aliens() && level.balldronesettings[var_0.balldronetype].weaponinfo == "alien_ball_drone_gun4_mp" )
        childthread fire_rocket();

    for (;;)
    {
        var_6 = randomintrange( var_2, var_3 + 1 );

        for ( var_7 = 0; var_7 < var_6; var_7++ )
        {
            if ( isdefined( var_0.inactive ) && var_0.inactive )
                break;

            var_8 = self getturrettarget( 0 );

            if ( isdefined( var_8 ) && canbetargeted( var_8 ) )
            {
                var_0 setlookatent( var_8 );
                self shootturret();
            }

            wait( var_1 );
        }

        wait( randomfloatrange( var_4, var_5 ) );
    }
}

fire_rocket()
{
    for (;;)
    {
        var_0 = self getturrettarget( 0 );

        if ( isdefined( var_0 ) && canbetargeted( var_0 ) )
            magicbullet( "alienvulture_mp", self gettagorigin( "tag_flash" ), var_0.origin, self.owner );

        var_1 = weaponfiretime( "alienvulture_mp" );

        if ( isdefined( level.ball_drone_faster_rocket_func ) && isdefined( self.owner ) )
            var_1 = self [[ level.ball_drone_faster_rocket_func ]]( var_1, self.owner );

        wait( weaponfiretime( "alienvulture_mp" ) );
    }
}

dolockon( var_0 )
{
    while ( var_0 > 0 )
    {
        self playsound( level.balldronesettings[self.vehicle.balldronetype].sound_targeting );
        wait 0.5;
        var_0 = var_0 - 0.5;
    }

    self playsound( level.balldronesettings[self.vehicle.balldronetype].sound_lockon );
}

balldrone_burstfirestop()
{
    self notify( "stop_shooting" );

    if ( isdefined( self.idletarget ) )
        self.vehicle setlookatent( self.idletarget );
}

canbetargeted( var_0 )
{
    var_1 = 1;

    if ( isplayer( var_0 ) )
    {
        if ( !maps\mp\_utility::isreallyalive( var_0 ) || var_0.sessionstate != "playing" )
            return 0;
    }

    if ( level.teambased && isdefined( var_0.team ) && var_0.team == self.team )
        return 0;

    if ( isdefined( var_0.team ) && var_0.team == "spectator" )
        return 0;

    if ( isplayer( var_0 ) && var_0 == self.owner )
        return 0;

    if ( isplayer( var_0 ) && isdefined( var_0.spawntime ) && ( gettime() - var_0.spawntime ) / 1000 <= 5 )
        return 0;

    if ( isplayer( var_0 ) && var_0 maps\mp\_utility::_hasperk( "specialty_blindeye" ) )
        return 0;

    if ( distancesquared( var_0.origin, self.origin ) > level.balldronesettings[self.vehicle.balldronetype].visual_range_sq )
        return 0;

    var_2 = self gettagorigin( "tag_flash" );
    return var_1;
}
