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

init_drill()
{
    common_scripts\utility::flag_init( "drill_detonated" );
    common_scripts\utility::flag_init( "drill_destroyed" );
    common_scripts\utility::flag_init( "drill_drilling" );
    level.drill_use_trig = getent( "drill_pickup_trig", "targetname" );

    if ( isdefined( level.drill_use_trig ) )
        level.drill_use_trig.original_origin = level.drill_use_trig.origin;

    level.drill_id = 0;
    level.drill_marker_id = 1;
    level.drill = undefined;
    level.drill_carrier = undefined;
    init_fx();
    init_drill_drop_loc();
    thread drill_think();
    level thread drill_out_of_playable();
}

drill_out_of_playable()
{
    level endon( "game_ended" );
    var_0 = getentarray( "trigger_hurt", "classname" );

    for (;;)
    {
        if ( !isdefined( level.drill ) )
        {
            wait 0.5;
            continue;
        }

        foreach ( var_2 in var_0 )
        {
            if ( !isdefined( var_2.script_noteworthy ) || var_2.script_noteworthy != "out_of_playable" )
                continue;

            if ( level.drill istouching( var_2 ) )
            {
                level.drill delete();

                assertex( isdefined( level.last_drill_pickup_origin ) && isdefined( level.last_drill_pickup_angles ), "Last drill pickup spot was not defined" );
                playfx( level._effect["alien_teleport"], level.last_drill_pickup_origin );
                playfx( level._effect["alien_teleport_dist"], level.last_drill_pickup_origin );
                drop_drill( level.last_drill_pickup_origin, level.last_drill_pickup_angles );

                foreach ( var_4 in level.players )
                    var_4 maps\mp\_utility::setlowermessage( "drill_overboard", &"ALIEN_COLLECTIBLES_DRILL_OUTOFPLAY", 4 );
            }
        }

        wait 0.1;
    }
}

init_drill_drop_loc()
{
    level.drill_locs = [];
    level.drill_locs = common_scripts\utility::getstructarray( "bomb_drop_loc", "targetname" );
}

init_fx()
{
    level._effect["drill_laser_contact"] = loadfx( "vfx/gameplay/alien/vfx_alien_drill_laser_contact" );
    level._effect["drill_laser"] = loadfx( "vfx/gameplay/alien/vfx_alien_drill_laser" );
    level._effect["stronghold_explode_med"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_sentry_gun_explosion" );
    level._effect["stronghold_explode_large"] = loadfx( "fx/explosions/aerial_explosion" );
    level._effect["alien_hive_explode"] = loadfx( "fx/explosions/alien_hive_explosion" );
    level.spawnglowmodel["friendly"] = "mil_emergency_flare_mp";
    level.spawnglow["friendly"] = loadfx( "fx/misc/flare_ambient_green" );
}

drill_think()
{
    level endon( "game_ended" );

    while ( !isdefined( level.players ) || level.players.size < 1 )
        wait 0.05;

    level.drill_health_hardcore = 1250;

    if ( maps\mp\alien\_utility::isplayingsolo() )
        level.drill_health_hardcore = 2000;

    level thread drill_threat_think();
    var_0 = ( 2822.27, -196, 524.068 );
    var_1 = common_scripts\utility::getstruct( "drill_loc", "targetname" );

    if ( isdefined( var_1 ) )
        var_0 = var_1.origin;

    var_2 = ( 1.287, 0.995, -103.877 );

    if ( isdefined( var_1 ) && isdefined( var_1.angles ) )
        var_2 = var_1.angles;

    level waittill( "spawn_intro_drill", var_3, var_4 );
    var_5 = 1;

    if ( isdefined( level.initial_drill_origin ) && isdefined( level.initial_drill_angles ) )
    {
        var_0 = level.initial_drill_origin;
        var_2 = level.initial_drill_angles;
        var_5 = 0;
    }

    if ( isdefined( var_3 ) && isdefined( var_4 ) )
    {
        var_0 = var_3;
        var_2 = var_4;
        var_5 = 0;
    }

    var_6 = undefined;

    for (;;)
    {
        spawn_drill_raw( "mp_laser_drill", var_0, var_2, var_6, var_5 );
        var_5 = 1;
        level waittill( "new_drill", var_0, var_2, var_6 );
        assertex( isdefined( drop_loc ), "Drill dropped at invalid position" );

        wait 0.05;
    }
}

drop_drill( var_0, var_1, var_2 )
{
    level notify( "new_drill", var_0, var_1, var_2 );
}

spawn_drill_raw( var_0, var_1, var_2, var_3, var_4 )
{
    if ( !isdefined( var_4 ) )
        var_4 = 1;

    level.drill_carrier = undefined;

    if ( isdefined( level.drill ) )
    {
        level.drill delete();
        level.drill = undefined;
    }

    level.drill = spawn( "script_model", var_1 );
    level.drill setmodel( var_0 );
    level.drill set_drill_icon();
    level.drill.state = "idle";

    if ( var_4 )
        level.drill thread angles_to_ground( var_1, var_2, ( 0, 0, -4 ) );
    else
        level.drill.angles = var_2;

    if ( common_scripts\utility::flag_exist( "intro_sequence_complete" ) && !common_scripts\utility::flag( "intro_sequence_complete" ) )
        common_scripts\utility::flag_wait( "intro_sequence_complete" );

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::add_to_drill_preplant_watch_list( level.drill );

    if ( !maps\mp\alien\_utility::is_true( level.automatic_drill ) )
        level.drill thread drill_pickup_listener( var_3 );

    level notify( "drill_spawned" );
}

enable_alt_drill_pickup( var_0 )
{
    assert( isdefined( level.drill_use_trig ) );
    level.drill_use_trig.origin = var_0.origin + ( 0, 0, 24 );
}

disable_alt_drill_pickup()
{
    assert( isdefined( level.drill_use_trig ) );
    level.drill_use_trig.origin = level.drill_use_trig.original_origin;
}

drill_pickup_listener( var_0 )
{
    self endon( "death" );
    level endon( "game_ended" );
    level endon( "new_drill" );

    if ( isdefined( level.drill_use_trig ) )
        var_1 = level.drill_use_trig;
    else
        var_1 = self;

    if ( !maps\mp\alien\_utility::is_true( level.prevent_drill_pickup ) )
    {
        if ( isdefined( level.drill_use_trig ) )
            level.drill_use_trig enable_alt_drill_pickup( self );
        else
            var_1 makeusable();
    }

    var_1 setcursorhint( "HINT_ACTIVATE" );
    var_1 sethintstring( &"ALIEN_COLLECTIBLES_PICKUP_BOMB" );

    for (;;)
    {
        var_1 waittill( "trigger", var_2 );

        if ( var_2 maps\mp\alien\_utility::is_holding_deployable() )
        {
            var_2 maps\mp\_utility::setlowermessage( "cant_buy", &"ALIEN_COLLECTIBLES_PLAYER_HOLDING", 3 );
            continue;
        }

        if ( var_2 getstance() == "prone" || var_2 getstance() == "crouch" )
        {
            var_2 maps\mp\_utility::setlowermessage( "change_stance", &"ALIENS_PATCH_CHANGE_STANCE", 3 );
            continue;
        }

        if ( maps\mp\alien\_utility::is_true( var_2.picking_up_item ) )
            continue;

        if ( maps\mp\alien\_utility::is_true( var_2.iscarrying ) )
            continue;

        var_2.has_special_weapon = 1;
        var_2 common_scripts\utility::_disableusability();
        var_2 thread delayed_enable_usability();

        if ( isplayer( var_2 ) )
            break;
    }

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::remove_from_drill_preplant_watch_list( level.drill );

    if ( isdefined( level.drill_use_trig ) )
        level.drill_use_trig disable_alt_drill_pickup();

    level notify( "drill_pickedup", var_2 );
    self playsound( "extinction_item_pickup" );
    level.drill_carrier = var_2;
    level.last_drill_pickup_origin = common_scripts\utility::drop_to_ground( self.origin, 16, -32 );
    level.last_drill_pickup_angles = self.angles;
    level.drill_carrier set_drill_icon( 1 );
    self.state = "carried";
    var_2 thread drop_drill_on_death();
    var_2 thread drop_drill_on_disconnect();
    var_2.lastweapon = var_2 getcurrentweapon();
    var_2 maps\mp\_utility::_giveweapon( "alienbomb_mp" );
    var_2 switchtoweapon( "alienbomb_mp" );
    var_2 disableweaponswitch();
    var_2 common_scripts\utility::_disableoffhandweapons();

    if ( isdefined( var_0 ) )
        var_0 delete();

    var_2 notify( "kill_spendhint" );
    var_2 notify( "dpad_cancel" );
    self delete();
}

delayed_enable_usability()
{
    self endon( "death" );
    self endon( "disconnect" );
    wait 1;
    common_scripts\utility::_enableusability();
}

drop_drill_on_death()
{
    level endon( "game_ended" );
    level endon( "new_drill" );
    level endon( "drill_planted" );
    level endon( "drill_dropping" );
    self notify( "watching_drop_drill_on_death" );
    self endon( "watching_drop_drill_on_death" );
    common_scripts\utility::waittill_either( "death", "last_stand" );
    self takeweapon( "alienbomb_mp" );
    self enableweaponswitch();
    self switchtoweapon( self.lastweapon );
    common_scripts\utility::_enableoffhandweapons();
    level.drill_carrier = undefined;
    var_0 = getgroundposition( self.last_death_pos + ( 0, 0, 4 ), 8 );
    var_1 = self.angles;

    if ( maps\mp\alien\_utility::is_true( self.kill_trigger_event_processed ) )
    {
        var_2 = common_scripts\utility::getclosest( self.origin, level.killtriggerspawnlocs );
        var_0 = getgroundposition( var_2.origin + ( 0, 0, 4 ), 8 );

        if ( !isdefined( var_2.angles ) )
            var_2.angles = ( 0, 0, 0 );

        var_1 = var_2.angles;
    }

    drop_drill( var_0, var_1 );
}

drop_drill_on_disconnect()
{
    level endon( "drill_dropping" );
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "last_stand" );
    self waittill( "disconnect" );
    playfx( level._effect["alien_teleport"], level.last_drill_pickup_origin );
    playfx( level._effect["alien_teleport_dist"], level.last_drill_pickup_origin );
    drop_drill( level.last_drill_pickup_origin, level.last_drill_pickup_angles );

    foreach ( var_1 in level.players )
    {
        if ( !isalive( var_1 ) )
            continue;

        if ( var_1 == self )
            continue;

        var_1 maps\mp\_utility::setlowermessage( "drill_overboard", &"ALIEN_COLLECTIBLES_DRILL_OUTOFPLAY", 4 );
    }
}

teleport_drill( var_0 )
{
    wait 5;

    if ( isdefined( level.drill ) && !isdefined( level.drill_carrier ) && distance( var_0, level.drill.origin ) > 1250 )
    {
        var_0 = common_scripts\utility::drop_to_ground( var_0, 16, -64 );
        level.drill angles_to_ground( var_0, level.drill.angles, ( 0, 0, -4 ) );
        level.drill set_drill_icon();
        enable_alt_drill_pickup( level.drill );
    }
}

drilling( var_0, var_1 )
{
    if ( isdefined( level.set_drill_state_drilling_override ) )
        self thread [[ level.set_drill_state_drilling_override ]]( var_0, var_1 );
    else
    {
        self endon( "stop_listening" );
        self endon( "drill_complete" );
        thread set_drill_state_plant( var_0, var_1 );
        level.drill endon( "death" );
        level.drill.owner = var_1;
        level.encounter_name = self.target;
        level.drill.start_time = gettime();
        common_scripts\utility::flag_set( "drill_drilling" );
        level.drill common_scripts\utility::waittill_any_timeout( 5, "drill_finished_plant_anim" );
        init_drilling_parameters();
        level.drill.start_time = gettime();
        thread set_drill_state_run( var_1 );
        maps\mp\alien\_hive::hive_play_drill_planted_animations();
        level.drill waittill( "offline", var_2, var_3 );
        thread set_drill_state_offline();
        common_scripts\utility::flag_set( "drill_destroyed" );
        wait 2;
        maps\mp\gametypes\aliens::alienendgame( "axis", maps\mp\alien\_hud::get_end_game_string_index( "drill_destroyed" ) );
    }
}

set_drill_attack_setup()
{
    var_0 = [];
    var_0["brute"][0] = maps\mp\alien\_utility::set_attack_sync_direction( ( 0, 1, 0 ), "alien_drill_attack_drill_F_enter", "alien_drill_attack_drill_F_loop", "alien_drill_attack_drill_F_exit", "attack_drill_front", "attack_drill" );
    var_0["brute"][1] = maps\mp\alien\_utility::set_attack_sync_direction( ( -1, 0, 0 ), "alien_drill_attack_drill_R_enter", "alien_drill_attack_drill_R_loop", "alien_drill_attack_drill_R_exit", "attack_drill_right", "attack_drill" );
    var_0["brute"][2] = maps\mp\alien\_utility::set_attack_sync_direction( ( 1, 0, 0 ), "alien_drill_attack_drill_L_enter", "alien_drill_attack_drill_L_loop", "alien_drill_attack_drill_L_exit", "attack_drill_left", "attack_drill" );
    var_0["goon"][0] = maps\mp\alien\_utility::set_attack_sync_direction( ( 0, 1, 0 ), "alien_goon_drill_attack_drill_F_enter", "alien_goon_drill_attack_drill_F_loop", "alien_goon_drill_attack_drill_F_exit", "attack_drill_front", "attack_drill" );
    var_0["goon"][1] = maps\mp\alien\_utility::set_attack_sync_direction( ( -1, 0, 0 ), "alien_goon_drill_attack_drill_R_enter", "alien_goon_drill_attack_drill_R_loop", "alien_goon_drill_attack_drill_R_exit", "attack_drill_right", "attack_drill" );
    var_0["goon"][2] = maps\mp\alien\_utility::set_attack_sync_direction( ( 1, 0, 0 ), "alien_goon_drill_attack_drill_L_enter", "alien_goon_drill_attack_drill_L_loop", "alien_goon_drill_attack_drill_L_exit", "attack_drill_left", "attack_drill" );
    var_1[0] = "offline";
    var_1[1] = "death";
    var_1[2] = "drill_complete";
    var_1[3] = "destroyed";
    maps\mp\alien\_utility::set_synch_attack_setup( var_0, 1, var_1, undefined, ::drill_synch_attack_play_anim, ::drill_synch_attack_play_anim, ::drill_synch_attack_exit, "drill" );
}

drill_synch_attack_play_anim( var_0 )
{
    level.drill scriptmodelclearanim();
    level.drill scriptmodelplayanim( var_0 );
}

drill_synch_attack_exit( var_0, var_1 )
{
    if ( isdefined( var_0 ) )
    {
        level.drill scriptmodelclearanim();
        level.drill scriptmodelplayanim( var_0 );
        wait( var_1 );
    }

    if ( isalive( level.drill ) && !common_scripts\utility::flag( "drill_detonated" ) )
    {
        level.drill scriptmodelclearanim();
        level.drill scriptmodelplayanim( "alien_drill_loop" );
    }
}

use_alternate_drill()
{
    return 1;
}

watch_to_repair( var_0 )
{
    self endon( "drill_complete" );
    self endon( "death" );
    var_0 endon( "hive_dying" );
    wait 5.0;
    self makeunusable();
    var_1 = 100;
    var_2 = 1000;
    var_3 = 4000;
    var_4 = 2000;

    for (;;)
    {
        self makeunusable();

        for (;;)
        {
            var_5 = ( self.health - 20000 ) / level.drill_health_hardcore;

            if ( var_5 < 0.75 )
                break;

            wait 1;
        }

        self makeusable();

        if ( isdefined( level.drill_repair ) )
            self sethintstring( level.drill_repair );
        else
            self sethintstring( &"ALIEN_COLLECTIBLES_DRILL_REPAIR" );

        self waittill( "trigger", var_6 );

        if ( maps\mp\alien\_utility::is_true( var_6.iscarrying ) )
            continue;

        self sethintstring( "" );
        var_7 = level.players.size;
        var_6.isrepairing = 1;
        level notify( "dlc_vo_notify", "drill_repair", var_6 );
        var_8 = int( var_3 * var_6 maps\mp\alien\_perk_utility::perk_getdrilltimescalar() * var_6.drillspeedmodifier );

        if ( var_7 > 1 )
            var_8 = int( ( var_3 + ( var_7 - 1 ) * var_4 ) * var_6 maps\mp\alien\_perk_utility::perk_getdrilltimescalar() * var_6.drillspeedmodifier );

        var_9 = useholdthink( var_6, var_8 );

        if ( !var_9 )
        {
            var_6.isrepairing = 0;
            continue;
        }

        if ( isdefined( level.drill_sfx_lp ) )
        {
            if ( isdefined( level.drill_overheat_lp_02 ) )
                level.drill_overheat_lp_02 stoploopsound();

            if ( !var_0 maps\mp\alien\_utility::is_door() && !var_0 maps\mp\alien\_utility::is_door_hive() && level.script != "mp_alien_dlc3" )
            {
                if ( level.script == "mp_alien_last" )
                    level.drill_sfx_lp playloopsound( "alien_conduit_on_lp" );
                else
                    level.drill_sfx_lp playloopsound( "alien_laser_drill_lp" );
            }
        }

        level notify( "dlc_vo_notify", "drill_repaired", var_6 );
        level notify( "drill_repaired" );
        var_6.isrepairing = 0;
        var_0 thread drill_reset_bbprint( var_6 );
        var_6 maps\mp\alien\_persistence::give_player_currency( var_1 );
        self.health = level.drill_health_hardcore + 20000;
        level.drill_last_health = level.drill_health_hardcore + 20000;
        update_drill_health_hud();
        var_6.isrepairing = 0;
        var_6 maps\mp\alien\_persistence::eog_player_update_stat( "drillrestarts", 1 );
        wait 1.0;
    }
}

set_drill_state_plant( var_0, var_1 )
{
    if ( isdefined( level.drill ) )
    {
        level.drill delete();
        level.drill = undefined;
    }

    level.drill = spawn( "script_model", var_0 );
    level.drill setmodel( "mp_laser_drill" );
    level.drill.state = "planted";
    level.drill.angles = self.angles;

    if ( !maps\mp\alien\_utility::is_door() )
        level.drill set_drill_attack_setup();

    if ( isdefined( level.drill_attack_setup_override ) )
        level.drill [[ level.drill_attack_setup_override ]]();

    var_2 = 150;

    if ( use_alternate_drill() )
    {
        var_2 = level.drill_health_hardcore;
        level.drill thread watch_to_repair( self );
    }

    level.drill.maxhealth = 20000 + var_2;
    level.drill.health = int( 20000 + var_2 * var_1 maps\mp\alien\_perk_utility::perk_getdrillhealthscalar() );
    level.drill thread watch_drill_health_for_challenge();

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::add_to_outline_drill_watch_list( level.drill, 0 );

    thread sfx_drill_plant();
    self.depth_marker = gettime();
    level thread maps\mp\alien\_music_and_dialog::playvoforbombplant( var_1 );
    destroy_drill_icon();

    if ( !maps\mp\alien\_utility::is_door() && !maps\mp\alien\_utility::is_door_hive() )
    {
        level.drill scriptmodelplayanim( "alien_drill_enter" );
        wait 4;
    }
    else
        wait 0.5;

    level.drill notify( "drill_finished_plant_anim" );
}

watch_drill_health_for_challenge()
{
    self endon( "drill_complete" );
    self endon( "death" );

    for (;;)
    {
        var_0 = ( level.drill.health - 20000 ) / level.drill_health_hardcore;

        if ( var_0 < 0.5 )
        {
            maps\mp\alien\_challenge::update_challenge( "no_stuck_drill", 0 );
            break;
        }

        wait 1;
    }
}

drill_threat_think()
{
    level endon( "game_ended" );
    var_0 = 1;

    for (;;)
    {
        if ( !isdefined( level.drill ) || !issentient( level.drill ) || !isalive( level.drill ) )
        {
            wait( var_0 );
            continue;
        }

        if ( use_alternate_drill() )
        {
            self.drill.threatbias = -1000;
            wait( var_0 );
            continue;
        }

        var_1 = 0;
        var_2 = 0;

        foreach ( var_4 in level.players )
        {
            if ( isdefined( var_4 ) && isalive( var_4 ) )
            {
                var_2++;
                var_1 = var_1 + distance2d( var_4.origin, level.drill.origin );
            }
        }

        if ( var_2 == 0 )
        {
            level.drill.threatbias = int( -3000 );
            wait( var_0 );
            continue;
        }

        var_6 = var_1 / max( 1, var_2 );

        if ( var_6 < 1000 )
            level.drill.threatbias = int( -3000 );
        else if ( var_6 > 2500 )
            level.drill.threatbias = int( -1000 );
        else
        {
            var_7 = 1500;
            var_8 = 2000;
            var_9 = ( var_6 - 1000 ) / var_7;
            var_10 = var_9 * var_8;
            level.drill.threatbias = int( -3000 + var_10 );
        }

        wait( var_0 );
    }
}

set_drill_state_run( var_0 )
{
    if ( isdefined( level.set_drill_state_run_override ) )
    {
        self thread [[ level.set_drill_state_run_override ]]( var_0 );
        return;
    }

    self endon( "death" );
    self endon( "stop_listening" );
    level.drill.state = "online";
    level.drill notify( "online" );
    level.drill setcandamage( 1 );
    level.drill makeunusable();
    level.drill sethintstring( "" );
    var_1 = 150;

    if ( use_alternate_drill() )
        var_1 = level.drill_health_hardcore;

    level.drill.maxhealth = 20000 + var_1;
    level.drill.health = int( 20000 + var_1 * level.drill.owner maps\mp\alien\_perk_utility::perk_getdrillhealthscalar() );
    level.drill.threatbias = -3000;
    level.drill makeentitysentient( "allies" );
    level.drill setthreatbiasgroup( "drill" );
    update_drill_health_hud();

    foreach ( var_3 in level.agentarray )
    {
        if ( isdefined( var_3.wave_spawned ) && var_3.wave_spawned )
            var_3 getenemyinfo( level.drill );
    }

    var_5 = level.drill gettagangles( "tag_laser" );
    var_6 = anglestoforward( var_5 );
    var_7 = anglestoup( var_5 );
    var_8 = vectorcross( var_6, ( 0, 0, 1 ) );
    var_9 = level.drill gettagorigin( "tag_laser_end" ) - ( 0, 0, 16 ) + var_8 * 4 * -1 + var_6 * 1.0 * -1;
    var_10 = level.drill gettagorigin( "tag_laser" ) - ( 0, 0, 8 );
    level.drill.fxent = spawnfx( level._effect["drill_laser_contact"], var_9 );
    level.drill.fxlaserent = spawnfx( level._effect["drill_laser"], var_10, var_6, var_7 );
    var_11 = maps\mp\alien\_utility::is_door() || maps\mp\alien\_utility::is_door_hive();
    thread sfx_drill_on( var_11 );

    if ( maps\mp\alien\_utility::is_door() )
    {
        level notify( "drill_start_door_fx" );
        level.drill scriptmodelplayanim( "alien_drill_open_door" );
    }
    else if ( isdefined( level.custom_hive_logic ) )
        level [[ level.custom_hive_logic ]]();
    else
    {
        triggerfx( level.drill.fxent );
        triggerfx( level.drill.fxlaserent );
        level.drill scriptmodelplayanim( "alien_drill_loop" );
    }

    thread handle_bomb_damage();
    self.depth_marker = gettime();
    thread monitor_drill_complete( self.depth );
    thread maps\mp\alien\_hive::hive_pain_monitor();
    thread maps\mp\alien\_hive::set_hive_icon( "waypoint_alien_defend" );
    destroy_drill_icon();
    maps\mp\alien\_hud::turn_on_drill_meter_hud( self.depth );
    level thread watch_drill_depth_for_vo( self.depth );
}

watch_drill_depth_for_vo( var_0 )
{
    level endon( "drill_detonated" );
    level endon( "game_ended" );
    wait( var_0 / 2 );
    level thread maps\mp\alien\_music_and_dialog::playvofordrillhalfway();
}

monitor_drill_complete( var_0 )
{
    self endon( "death" );
    self endon( "stop_listening" );
    level.drill endon( "offline" );

    while ( self.layers.size > 0 )
    {
        var_1 = self.layers[self.layers.size - 1];
        var_2 = self.layers.size == 1;
        var_3 = var_0 - var_1;

        if ( var_2 )
            childthread maps\mp\alien\_music_and_dialog::playmusicbeforereachlayer( var_3 );

        var_4 = "remaining_depth_to_layer is negative, ";
        var_4 = var_4 + "[depth=" + var_0 + "][layer_depth=" + var_1 + "][layer index=" + ( self.layers.size - 1 ) + "]";
        var_4 = var_4 + "[hive.origin=" + self.origin + "]";
        common_scripts\utility::waittill_any_timeout( var_3, "force_drill_complete" );
        self.layer_completed++;
        setomnvar( "ui_alien_drill_layer_completed", self.layer_completed );
        self.layers = common_scripts\utility::array_remove( self.layers, var_1 );
        var_0 = var_1;
        reach_layer_earthquake();

        if ( !maps\mp\alien\_utility::is_door() )
            reach_layer_spawn_event( var_2 );
    }

    self notify( "drill_complete" );
    level.drill notify( "drill_complete" );
    level.encounter_name = undefined;
    common_scripts\utility::flag_clear( "drill_drilling" );
    common_scripts\utility::flag_set( "drill_detonated" );

    foreach ( var_6 in level.players )
    {
        if ( !isalive( var_6 ) || maps\mp\alien\_utility::is_true( var_6.isreviving ) || maps\mp\alien\_utility::is_true( var_6.being_revived ) )
            continue;

        var_6 setclientomnvar( "ui_securing_progress", 0 );
        var_6 setclientomnvar( "ui_securing", 0 );
    }

    setomnvar( "ui_alien_drill_state", 0 );
}

reach_layer_earthquake()
{
    var_0 = 0.4;
    var_1 = 1.75;

    if ( maps\mp\alien\_utility::is_door() )
        var_0 = 0.15;

    thread maps\mp\alien\_hive::warn_all_players( var_1, var_0 );
}

reach_layer_spawn_event( var_0 )
{
    if ( var_0 )
        return;

    var_1 = "reached_layer_" + self.layer_completed;
    maps\mp\alien\_spawn_director::activate_spawn_event( var_1 );
}

init_drilling_parameters()
{
    if ( maps\mp\alien\_utility::is_door() )
    {
        self.depth = 30;
        self.total_depth = self.depth;
        self.layer_completed = 0;
        self.layers[0] = 0;
        setomnvar( "ui_alien_drill_layers_table_line", 599 + level.current_cycle_num + 1 );
        setomnvar( "ui_alien_drill_layer_completed", self.layer_completed );
    }
    else
    {
        var_0 = level.cycle_data.cycle_drill_layers[level.current_cycle_num + 1];
        self.depth = var_0[var_0.size - 1];
        self.total_depth = self.depth;
        self.layer_completed = 0;
        self.layers[0] = 0;

        for ( var_1 = 0; var_1 <= var_0.size - 2; var_1++ )
            self.layers[self.layers.size] = var_0[var_1];

        setomnvar( "ui_alien_drill_layers_table_line", 599 + level.current_cycle_num + 1 );
        setomnvar( "ui_alien_drill_layer_completed", self.layer_completed );
    }
}

set_drill_state_offline()
{
    self endon( "death" );
    self endon( "stop_listening" );
    level.drill.state = "offline";

    if ( isdefined( level.drill.fxent ) )
        level.drill.fxent delete();

    if ( isdefined( level.drill.fxlaserent ) )
        level.drill.fxlaserent delete();

    if ( maps\mp\alien\_utility::is_door() )
        level notify( "drill_stop_door_fx" );

    thread sfx_drill_offline();
    var_0 = ( gettime() - self.depth_marker ) / 1000;
    self.depth = max( 0, self.depth - var_0 );
    level.drill scriptmodelplayanim( "alien_drill_operate_end" );
    wait 1.4;
    level.drill scriptmodelplayanim( "alien_drill_nonoperate" );
    level.drill makeusable();
    level.drill setcursorhint( "HINT_ACTIVATE" );
    level.drill sethintstring( &"ALIEN_COLLECTIBLES_PLANT_BOMB" );
    level.drill setcandamage( 0 );
    level.drill freeentitysentient();
    maps\mp\alien\_hive::destroy_hive_icon();
    level.drill set_drill_icon();
    setomnvar( "ui_alien_drill_state", 2 );
}

handle_bomb_damage()
{
    self endon( "death" );
    self endon( "stop_listening" );
    level endon( "hives_cleared" );
    level.drill endon( "death" );
    level.drill endon( "offline" );
    var_0 = 0;
    var_1 = gettime();
    level.drill_last_health = level.drill.health;
    var_2 = 0;
    var_3 = 0;
    var_4 = 0;

    for (;;)
    {
        level.drill waittill( "damage", var_5, var_6, var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14 );

        if ( isdefined( var_6 ) && isai( var_6 ) )
            level.drill_last_health = level.drill_last_health - var_5;
        else if ( isdefined( var_14 ) && var_14 == "alien_minion_explosion" )
            level.drill_last_health = level.drill_last_health - var_5;
        else
        {
            level.drill.health = level.drill_last_health;
            continue;
        }

        if ( isdefined( level.level_drill_damage_adjust_function ) )
            [[ level.level_drill_damage_adjust_function ]]( var_5, var_6, var_14 );

        level.drill.health = level.drill_last_health;
        maps\mp\alien\_gamescore::update_team_encounter_performance( maps\mp\alien\_gamescore::get_drill_score_component_name(), "drill_damage_taken", var_5 );
        maps\mp\alien\_alien_matchdata::inc_drill_heli_damages( var_5 );

        if ( level.script == "mp_alien_last" )
        {
            if ( isdefined( var_6 ) && ( !isdefined( var_6.team ) || var_6.team == "axis" ) )
                self playsound( "scn_dscnt_alien_pod_hit" );
        }

        if ( level.drill.health < 20000 )
        {
            maps\mp\alien\_hud::update_drill_health( 0 );
            level.drill notify( "offline", var_6, var_5 );
            continue;
        }

        if ( !isdefined( self.icon ) )
            continue;

        var_16 = ( level.drill.health - 20000 ) / 150;
        var_16 = max( 0, min( 1, var_16 ) );
        var_17 = var_16 * var_16;
        var_18 = var_17;
        var_19 = var_18;
        self.icon.color = ( 1, var_18, var_19 );

        if ( use_alternate_drill() )
        {
            var_20 = ( level.drill.health - 20000 ) / level.drill_health_hardcore;
            update_drill_health_hud();

            if ( var_20 <= 0.75 && !var_2 )
            {
                if ( isdefined( level.drill_repair_hint ) )
                    iprintlnbold( level.drill_repair_hint );
                else
                    iprintlnbold( &"ALIEN_COLLECTIBLES_DRILL_REPAIR_HINT" );

                var_2 = 1;
            }
            else if ( var_20 <= 0.5 && !var_3 )
            {
                if ( isdefined( level.drill_repair_hint ) )
                    iprintlnbold( level.drill_repair_hint );
                else
                    iprintlnbold( &"ALIEN_COLLECTIBLES_DRILL_REPAIR_HINT" );

                var_3 = 1;
            }
            else if ( var_20 <= 0.25 && !var_4 )
            {
                if ( isdefined( level.drill_repair_hint_urgent ) )
                    iprintlnbold( level.drill_repair_hint_urgent );
                else
                    iprintlnbold( &"ALIEN_COLLECTIBLES_REACT_DRILL" );

                var_4 = 1;
            }

            if ( var_20 <= 0.25 )
                thread sfx_overheat();

            if ( var_20 < 0.5 && gettime() - var_1 > var_0 )
                level thread maps\mp\alien\_music_and_dialog::playvofordrillhot();
            else if ( gettime() - var_1 > var_0 )
                level thread maps\mp\alien\_music_and_dialog::playvofordrilldamaged();

            var_1 = gettime();
        }
    }
}

sfx_overheat()
{
    if ( !maps\mp\alien\_utility::is_door() && !maps\mp\alien\_utility::is_door_hive() && level.script != "mp_alien_dlc3" )
        level.drill_sfx_lp stoploopsound( "alien_laser_drill_lp" );

    if ( !isdefined( level.drill_overheat_lp_02 ) )
    {
        level.drill_overheat_lp_02 = spawn( "script_origin", level.drill.origin );
        level.drill_overheat_lp_02 linkto( level.drill );

        if ( level.script == "mp_alien_last" )
        {
            level.drill_sfx_lp stoploopsound( "alien_conduit_on_lp" );
            level.drill_overheat_lp_02 playloopsound( "alien_conduit_damaged_lp" );
            return;
        }
    }

    if ( level.script == "mp_alien_dlc3" )
        level.drill_overheat_lp_02 playloopsound( "alien_drill_scanner_overheat_lp" );
    else
        level.drill_overheat_lp_02 playloopsound( "alien_laser_drill_overheat_lp" );
}

drill_detonate()
{
    if ( isdefined( level.drill_detonate_override ) )
    {
        self thread [[ level.drill_detonate_override ]]();
        return;
    }

    maps\mp\alien\_hive::destroy_hive_icon();
    self makeunusable();
    self sethintstring( "" );

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::remove_from_outline_drill_watch_list( level.drill );

    if ( !maps\mp\alien\_utility::is_door() && !maps\mp\alien\_utility::is_door_hive() )
    {
        thread sfx_drill_off( 0 );
        thread kill_sequence();
    }

    if ( isdefined( level.drill.fxent ) )
        level.drill.fxent delete();

    if ( isdefined( level.drill.fxlaserent ) )
        level.drill.fxlaserent delete();

    if ( maps\mp\alien\_utility::is_door() )
        level notify( "drill_stop_door_fx" );

    level.drill scriptmodelclearanim();

    if ( !maps\mp\alien\_utility::is_door() )
    {
        level.drill scriptmodelplayanim( "alien_drill_end" );
        wait 3.8;
    }

    if ( !isdefined( self.last_hive ) || !self.last_hive )
    {
        var_0 = level.drill.origin + ( 0, 0, 8 );
        drop_drill( var_0, self.angles - ( 0, 90, 0 ) );
    }

    if ( maps\mp\alien\_utility::is_door() || maps\mp\alien\_utility::is_door_hive() )
        maps\mp\_utility::delaythread( 3, ::open_door );
    else
        thread maps\mp\alien\_hive::delete_removables();

    thread remove_spawner();
    thread fx_ents_playfx();
    maps\mp\alien\_hive::show_dead_hive_model();
    thread do_radius_damage();

    if ( isdefined( self.last_hive ) && self.last_hive )
    {
        common_scripts\utility::flag_set( "hives_cleared" );
        level thread detonate_drill_when_nuke_goes_off( self );
    }

    common_scripts\utility::flag_clear( "drill_detonated" );
    wait 8;
    level thread maps\mp\alien\_music_and_dialog::playvoforbombdetonate( self );
}

do_radius_damage()
{
    var_0 = 300;

    foreach ( var_2 in self.scriptables )
    {
        radiusdamage( var_2.origin, var_0, 0, 0, var_2 );
        common_scripts\utility::waitframe();
    }
}

detonate_drill_when_nuke_goes_off( var_0 )
{
    if ( isdefined( level.drill ) )
    {
        level.drill setcandamage( 0 );
        level.drill freeentitysentient();
        level.drill makeunusable();
    }

    level waittill( "nuke_went_off" );
    wait 1.5;
    var_1 = level._effect["stronghold_explode_med"];
    var_2 = var_0.origin;

    if ( isdefined( level.drill ) )
        var_2 = level.drill.origin;

    playfx( var_1, var_2 );

    if ( isdefined( level.drill ) )
    {
        level.drill_carrier = undefined;
        level.drill delete();
    }
}

kill_sequence()
{
    playfx( level._effect["stronghold_explode_large"], self.origin );

    if ( !maps\mp\alien\_utility::is_door() )
        thread maps\mp\alien\_hive::sfx_destroy_hive();

    if ( isalive( level.drill ) )
    {
        foreach ( var_1 in self.scriptables )
        {
            var_1 thread maps\mp\alien\_hive::hive_explode( 1 );
            common_scripts\utility::waitframe();
        }
    }
}

createuseent()
{
    var_0 = spawn( "script_origin", self.origin );
    var_0.curprogress = 0;
    var_0.usetime = 0;
    var_0.userate = 1;
    var_0.inuse = 0;
    var_0 thread deleteuseent( self );
    return var_0;
}

deleteuseent( var_0 )
{
    self endon( "death" );
    var_0 waittill( "death" );
    self delete();
}

cancel_repair_on_hive_death( var_0 )
{
    var_0 endon( "disconnect" );
    self notify( "cancel_repair_on_hive_death" );
    self endon( "cancel_repair_on_hive_death" );
    level endon( "drill_repaired" );
    self waittill( "drill_complete" );

    if ( isalive( var_0 ) )
    {
        var_0 notify( "drill_repair_weapon_management" );

        if ( var_0.disabledweapon > 0 )
            var_0 common_scripts\utility::_enableweapon();

        if ( maps\mp\alien\_utility::is_true( var_0.hasprogressbar ) )
            var_0.hasprogressbar = 0;

        var_0.isrepairing = 0;
    }
}

useholdthink( var_0, var_1 )
{
    thread cancel_repair_on_hive_death( var_0 );
    self.curprogress = 0;
    self.inuse = 1;
    self.userate = 1;

    if ( isdefined( var_1 ) )
        self.usetime = var_1;
    else
        self.usetime = 3000;

    if ( !var_0 maps\mp\alien\_perk_utility::has_perk( "perk_rigger", [ 0, 1, 2, 3, 4 ] ) )
        var_0 maps\mp\alien\_utility::disable_weapon_timeout( var_1 + 0.05, "drill_repair_weapon_management" );

    var_0 thread personalusebar( self );
    var_0.hasprogressbar = 1;
    var_2 = useholdthinkloop( var_0, self, 18496 );

    if ( isalive( var_0 ) )
    {
        var_0.hasprogressbar = 0;

        if ( !var_0 maps\mp\alien\_perk_utility::has_perk( "perk_rigger", [ 0, 1, 2, 3, 4 ] ) )
            var_0 maps\mp\alien\_utility::enable_weapon_wrapper( "drill_repair_weapon_management" );
    }

    if ( !isdefined( self ) )
        return 0;

    self.inuse = 0;
    self.curprogress = 0;
    return var_2;
}

personalusebar( var_0 )
{
    var_1 = 2;

    if ( level.script == "mp_alien_last" )
        var_1 = 7;

    self endon( "disconnect" );
    self setclientomnvar( "ui_securing", var_1 );
    var_2 = -1;

    while ( maps\mp\_utility::isreallyalive( self ) && isdefined( var_0 ) && var_0.inuse && !level.gameended )
    {
        if ( var_2 != var_0.userate )
        {
            if ( var_0.curprogress > var_0.usetime )
                var_0.curprogress = var_0.usetime;
        }

        var_2 = var_0.userate;
        self setclientomnvar( "ui_securing_progress", var_0.curprogress / var_0.usetime );
        wait 0.05;
    }

    self setclientomnvar( "ui_securing_progress", 0 );
    self setclientomnvar( "ui_securing", 0 );
}

useholdthinkloop( var_0, var_1, var_2 )
{
    while ( !level.gameended && isdefined( self ) && maps\mp\_utility::isreallyalive( var_0 ) && var_0 usebuttonpressed() && ( !isdefined( var_0.laststand ) || !var_0.laststand ) && self.curprogress < self.usetime )
    {
        var_3 = ( self.health - 20000 ) / level.drill_health_hardcore;

        if ( var_3 <= 0 )
            return 0;

        if ( isdefined( var_1 ) && isdefined( var_2 ) )
        {
            if ( distancesquared( var_0.origin, var_1.origin ) > var_2 )
                return 0;
        }

        self.curprogress = self.curprogress + 50 * self.userate;
        self.userate = 1;

        if ( self.curprogress >= self.usetime )
            return maps\mp\_utility::isreallyalive( var_0 );

        wait 0.05;
    }

    return 0;
}

draw_line( var_0, var_1, var_2, var_3 )
{
    if ( isdefined( var_3 ) )
    {
        for ( var_4 = 0; var_4 < var_3; var_4++ )
            wait 0.05;
    }
    else
    {
        for (;;)
            wait 0.05;
    }
}

angles_to_ground( var_0, var_1, var_2 )
{
    var_3 = var_0 + ( 0, 0, 16 );
    var_4 = var_0 - ( 0, 0, 64 );
    var_5 = bullettrace( var_3, var_4, 0, self );
    var_6 = var_5["normal"] * -1;
    var_7 = vectortoangles( var_6 );
    var_8 = vectortoangles( anglestoup( var_7 ) )[1] - vectortoangles( anglestoforward( var_1 ) )[1];
    var_9 = vectornormalize( var_6 );
    var_10 = vectornormalize( anglestoup( vectortoangles( var_6 ) ) );
    var_11 = vectornormalize( anglestoright( vectortoangles( var_6 ) ) );
    var_10 = rotatepointaroundvector( var_9, var_10, var_8 - 90 );
    var_11 = rotatepointaroundvector( var_9, var_11, var_8 - 90 );
    self.angles = axistoangles( var_10, var_11, var_9 );

    if ( abs( self.angles[2] ) > 45 )
        self.angles = ( self.angles[0], self.angles[1], 0 );

    if ( abs( self.angles[0] ) > 45 )
        self.angles = ( 0, self.angles[1], self.angles[2] );

    self.origin = var_0 + var_2;
}

watchbomb()
{
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "disconnect" );

    if ( self hasweapon( "alienbomb_mp" ) )
    {
        self takeweapon( "alienbomb_mp" );
        self enableweaponswitch();
    }

    for (;;)
    {
        self waittill( "grenade_fire", var_0, var_1 );

        if ( var_1 == "alienbomb" || var_1 == "alienbomb_mp" )
        {
            var_0.owner = self;
            var_0 setotherent( self );
            var_0.team = self.team;
            var_0 thread watchbombstuck( self );
        }
    }
}

watchbombstuck( var_0 )
{
    level endon( "game_ended" );
    var_0 endon( "death" );
    var_0 endon( "disconnect" );
    self hide();
    common_scripts\utility::waittill_any_timeout( 0.05, "missile_stuck" );
    var_1 = self aiphysicstrace( var_0.origin + ( 0, 0, 8 ), var_0.origin - ( 0, 0, 12 ), undefined, undefined, 1, 1 );

    if ( var_1["fraction"] == 1 )
    {
        var_0 takeweapon( "alienbomb_mp" );
        var_0 giveweapon( "alienbomb_mp" );
        var_0 setweaponammostock( "alienbomb_mp", var_0 getweaponammostock( "alienbomb_mp" ) + 1 );
        var_0 switchtoweapon( "alienbomb_mp" );
        self delete();
        return;
    }
    else
    {
        self.origin = var_1["position"];
        var_2 = var_1["entity"];
    }

    self.angles = self.angles * ( 0, 1, 1 );
    level notify( "drill_dropping" );

    foreach ( var_4 in level.stronghold_hive_locs )
    {
        if ( var_4 maps\mp\alien\_hive::is_blocker_hive() )
            continue;

        if ( !var_4 maps\mp\alien\_hive::dependent_hives_removed() )
            continue;

        if ( distance( var_4.origin, self.origin ) < 80 )
        {
            var_4 notify( "trigger", var_0 );
            earthquake( 0.25, 0.5, self.origin, 128 );
            var_0 takeweapon( "alienbomb_mp" );

            if ( !var_0 maps\mp\alien\_utility::has_special_weapon() )
                var_0 enableweaponswitch();

            var_0 restore_last_weapon();
            var_0 common_scripts\utility::_enableoffhandweapons();
            self delete();
            return;
        }
    }

    if ( isdefined( level.watch_bomb_stuck_override ) )
    {
        if ( [[ level.watch_bomb_stuck_override ]]( var_0 ) )
            return;
    }

    drop_drill( self.origin, self.angles, self );
    earthquake( 0.25, 0.5, self.origin, 128 );
    var_0 takeweapon( "alienbomb_mp" );

    if ( !var_0 maps\mp\alien\_utility::has_special_weapon() )
        var_0 enableweaponswitch();

    var_0 restore_last_weapon();
    var_0 common_scripts\utility::_enableoffhandweapons();
    level thread maps\mp\alien\_outline_proto::update_drill_outline();
    self delete();
}

restore_last_weapon()
{
    if ( self.lastweapon != "aliendeployable_crate_marker_mp" )
        self switchtoweapon( self.lastweapon );
    else
        self switchtoweapon( self getweaponslistprimaries()[0] );
}

player_carry_bomb_init()
{
    if ( !isdefined( self.carryicon ) )
    {
        if ( level.splitscreen )
        {
            self.carryicon = maps\mp\gametypes\_hud_util::createicon( "hud_suitcase_bomb", 33, 33 );
            self.carryicon maps\mp\gametypes\_hud_util::setpoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -50, -78 );
        }
        else
        {
            self.carryicon = maps\mp\gametypes\_hud_util::createicon( "hud_suitcase_bomb", 50, 50 );
            self.carryicon maps\mp\gametypes\_hud_util::setpoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -50, -65 );
        }

        self.carryicon.hidewheninmenu = 1;
        thread hidecarryiconongameend();
    }

    self.carryicon.alpha = 0;
}

hidecarryiconongameend()
{
    self endon( "disconnect" );
    level waittill( "game_ended" );

    if ( isdefined( self.carryicon ) )
        self.carryicon.alpha = 0;
}

set_drill_icon( var_0 )
{
    level notify( "new_bomb_icon" );
    destroy_drill_icon( self );

    if ( !isdefined( var_0 ) || !var_0 )
    {
        level.drill_icon = newhudelem();
        level.drill_icon setshader( "waypoint_alien_drill", 14, 14 );
        level.drill_icon.color = ( 1, 1, 1 );
        level.drill_icon setwaypoint( 1, 1 );
        level.drill_icon.sort = 1;
        level.drill_icon.foreground = 1;
        level.drill_icon.alpha = 0.5;
        level.drill_icon.x = self.origin[0];
        level.drill_icon.y = self.origin[1];
        level.drill_icon.z = self.origin[2] + 72;
    }
    else
        maps\mp\_entityheadicons::setheadicon( self.team, "waypoint_alien_drill", ( 0, 0, 72 ), 4, 4, undefined, undefined, undefined, 1, undefined, 0 );
}

destroy_drill_icon( var_0 )
{
    if ( isdefined( level.drill_icon ) )
        level.drill_icon destroy();

    if ( !isdefined( var_0 ) )
        return;

    remove_headicons_from_players();
}

remove_headicons_from_players()
{
    foreach ( var_1 in level.players )
    {
        if ( isdefined( var_1.entityheadicons ) )
        {
            foreach ( var_4, var_3 in var_1.entityheadicons )
            {
                if ( !isdefined( var_3 ) )
                    continue;

                var_3 destroy();
            }
        }
    }
}

remove_spawner()
{
    if ( isdefined( self.script_linkto ) )
        maps\mp\alien\_spawn_director::remove_spawn_location( self.script_linkto );
}

fx_ents_playfx()
{
    foreach ( var_1 in self.fx_ents )
    {
        playfx( level._effect["stronghold_explode_med"], var_1.origin );
        var_1 delete();
    }
}

sfx_drill_plant()
{
    var_0 = get_drill_entity();
    var_0 playsound( "alien_laser_drill_plant" );
}

sfx_drill_on( var_0 )
{
    wait 0.1;
    var_1 = get_drill_entity();

    if ( !isdefined( level.drill_sfx_lp ) )
    {
        level.drill_sfx_lp = spawn( "script_origin", var_1.origin );
        level.drill_sfx_lp linkto( var_1 );
    }

    if ( !isdefined( level.drill_sfx_dist_lp ) )
    {
        level.drill_sfx_dist_lp = spawn( "script_origin", var_1.origin );
        level.drill_sfx_dist_lp linkto( var_1 );
    }

    wait 0.1;

    if ( var_0 )
    {
        wait 3.76;

        if ( isdefined( level.drill_sfx_lp ) )
            level.drill_sfx_lp playloopsound( "alien_laser_drill_door_lp" );

        if ( isdefined( level.drill_sfx_dist_lp ) )
            level.drill_sfx_dist_lp playloopsound( "alien_laser_drill_door_dist_lp" );
    }
    else
    {
        if ( isdefined( level.drill_sfx_lp ) )
            level.drill_sfx_lp playloopsound( "alien_laser_drill_lp" );

        if ( isdefined( level.drill_sfx_dist_lp ) )
            level.drill_sfx_dist_lp playloopsound( "alien_laser_drill_dist_lp" );
    }
}

sfx_drill_off( var_0 )
{
    var_1 = get_drill_entity();
    var_2 = var_1.origin;

    if ( !var_0 )
        var_1 playsound( "alien_laser_drill_stop" );
    else
        playsoundatpos( var_2, "alien_laser_drill_stop" );

    if ( isdefined( level.drill_sfx_lp ) )
        level.drill_sfx_lp delete();

    if ( isdefined( level.drill_sfx_dist_lp ) )
        level.drill_sfx_dist_lp delete();

    if ( isdefined( level.drill_overheat_lp ) )
        level.drill_overheat_lp delete();

    if ( isdefined( level.drill_overheat_lp_02 ) )
        level.drill_overheat_lp_02 delete();

    if ( var_0 )
    {
        wait 2.7;
        playsoundatpos( var_2, "alien_laser_drill_door_open" );
    }
}

sfx_drill_offline()
{
    var_0 = get_drill_entity();

    if ( level.script == "mp_alien_dlc3" )
        level.drill playsound( "alien_drill_scanner_shutdown" );
    else
        var_0 playsound( "alien_laser_drill_shutdown" );

    if ( isdefined( level.drill_sfx_lp ) )
        level.drill_sfx_lp delete();

    if ( isdefined( level.drill_sfx_dist_lp ) )
        level.drill_sfx_dist_lp delete();

    if ( isdefined( level.drill_overheat_lp_02 ) )
        level.drill_overheat_lp_02 delete();
}

drill_plant_bbprint( var_0 )
{
    drill_generic_bbprint( "aliendrillplant", var_0 );
}

drill_reset_bbprint( var_0 )
{
    drill_generic_bbprint( "aliendrillreset", var_0 );
}

drill_generic_bbprint( var_0, var_1 )
{
    var_2 = level.current_cycle_num;
    var_3 = "unknown hive";

    if ( isdefined( self.target ) )
        var_3 = self.target;

    var_4 = gettime() - level.starttime;
    var_5 = "unknown player";

    if ( isdefined( var_1.name ) )
        var_5 = var_1.name;

    var_6 = level.players.size;
    var_7 = var_1 maps\mp\alien\_persistence::get_selected_perk_0();
    var_8 = var_1 maps\mp\alien\_persistence::get_perk_0_level();
    var_9 = var_1 maps\mp\alien\_persistence::get_selected_perk_1();
    var_10 = var_1 maps\mp\alien\_persistence::get_perk_1_level();
    var_11 = -1;

    if ( isdefined( level.drill ) && isdefined( level.drill.health ) && isdefined( level.drill_health_hardcore ) )
        var_11 = ( level.drill.health - 20000 ) / level.drill_health_hardcore;

    bbprint( var_0, "cyclenum %i hivename %s playtime %f drillhealth %f repairer %s repairerperk0 %s repairerperk1 %s repairerperk0level %s repairerperk1level %s playernum %i ", var_2, var_3, var_4, var_11, var_5, var_7, var_9, var_8, var_10, var_6 );
}

check_for_player_near_hive_with_drill()
{
    if ( maps\mp\alien\_utility::is_true( level.automatic_drill ) )
        return;

    self endon( "disconnect" );
    var_0 = 6400;

    for (;;)
    {
        while ( !common_scripts\utility::flag( "drill_drilling" ) )
        {
            if ( isdefined( self.inlaststand ) && self.inlaststand || common_scripts\utility::flag( "drill_drilling" ) || isdefined( self.usingremote ) || maps\mp\alien\_utility::is_true( self.iscarrying ) )
            {
                wait 0.05;
                continue;
            }

            foreach ( var_2 in level.stronghold_hive_locs )
            {
                if ( var_2 maps\mp\alien\_hive::is_blocker_hive() )
                    continue;

                if ( !var_2 maps\mp\alien\_hive::dependent_hives_removed() )
                    continue;

                if ( distancesquared( var_2.origin, self.origin ) < var_0 )
                {
                    if ( !isdefined( level.drill_carrier ) || isdefined( level.drill_carrier ) && level.drill_carrier != self )
                    {
                        maps\mp\_utility::setlowermessage( "need_drill", &"ALIEN_COLLECTIBLES_NEED_DRILL", undefined, 10 );

                        while ( player_should_see_drill_hint( var_2, var_0, 1 ) )
                            wait 0.05;

                        maps\mp\_utility::clearlowermessage( "need_drill" );
                        continue;
                    }

                    maps\mp\_utility::setlowermessage( "plant_drill", &"ALIEN_COLLECTIBLES_PLANT_BOMB", undefined, 10 );

                    while ( player_should_see_drill_hint( var_2, var_0, 0 ) )
                        wait 0.05;

                    maps\mp\_utility::clearlowermessage( "plant_drill" );
                }
            }

            wait 0.05;
        }

        common_scripts\utility::flag_waitopen( "drill_drilling" );
    }
}

player_should_see_drill_hint( var_0, var_1, var_2 )
{
    if ( distancesquared( var_0.origin, self.origin ) > var_1 )
        return 0;

    if ( common_scripts\utility::flag( "drill_drilling" ) )
        return 0;

    if ( self.inlaststand )
        return 0;

    if ( isdefined( self.usingremote ) )
        return 0;

    if ( maps\mp\alien\_utility::is_true( var_2 ) )
        return 1;
    else if ( maps\mp\alien\_utility::is_true( self.iscarrying ) )
        return 0;

    return 1;
}

get_drill_entity()
{
    if ( isdefined( level.drill.vehicle ) )
        return level.drill.vehicle;
    else
        return level.drill;
}

open_door()
{
    level notify( "door_opening", self.target );

    foreach ( var_1 in self.removeables )
    {
        if ( isdefined( var_1 ) )
        {
            if ( var_1.classname == "script_model" )
            {
                var_1 thread slide_open();
                continue;
            }

            if ( var_1.classname == "script_brushmodel" )
                var_1 connectpaths();

            var_1 delete();
        }
    }
}

slide_open()
{
    if ( !isdefined( self.script_angles ) )
        self delete();
    else
        self moveto( self.origin + self.script_angles, 1 );
}

wait_for_drill_plant()
{
    self endon( "stop_listening" );

    for (;;)
    {
        self waittill( "trigger", var_0 );

        if ( !maps\mp\alien\_utility::is_true( level.automatic_drill ) && ( !isdefined( level.drill_carrier ) || level.drill_carrier != var_0 ) )
        {
            var_0 maps\mp\_utility::setlowermessage( "no_bomb", &"ALIEN_COLLECTIBLES_NO_BOMB", 5 );
            wait 0.05;
            continue;
        }

        if ( isplayer( var_0 ) )
        {
            if ( !maps\mp\alien\_utility::is_true( level.automatic_drill ) )
            {
                var_0 maps\mp\_utility::clearlowermessage( "go_plant" );
                var_0 takeweapon( "alienbomb_mp" );

                if ( !var_0 maps\mp\alien\_utility::has_special_weapon() )
                    var_0 enableweaponswitch();

                if ( !isdefined( level.non_player_drill_plant_check ) || ![[ level.non_player_drill_plant_check ]]() )
                    var_0 switchtoweapon( var_0.lastweapon );

                self makeunusable();
                self sethintstring( "" );
                remove_headicons_from_players();
            }

            var_1 = 0.4;
            var_2 = 1.75;
            thread maps\mp\alien\_hive::warn_all_players( var_2, var_1 );
            var_0 maps\mp\alien\_persistence::eog_player_update_stat( "drillplants", 1 );
            level notify( "drill_planted", var_0, self );
            return var_0;
        }
    }
}

update_drill_health_hud()
{
    var_0 = int( ( level.drill.health - 20000 ) / level.drill_health_hardcore * 100 );
    maps\mp\alien\_hud::update_drill_health( var_0 );
}