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

traps_init()
{
    level.outline_switch["traps_fire"] = 1;
    level thread fire_trap_init();
    level.outline_switch["traps_puddle"] = 1;
    level thread electric_puddle_init();
    level.outline_switch["traps_fence"] = 1;
    level thread electric_fence_init();
    level.spawnglow["enemy"] = loadfx( "fx/misc/flare_ambient" );
}

can_activate_trap( var_0 )
{
    return maps\mp\alien\_persistence::player_has_enough_currency( int( var_0.cost ) );
}

fire_trap_init()
{
    var_0 = getentarray( "fire_trap_barrel", "targetname" );

    if ( !isdefined( var_0 ) || var_0.size == 0 )
        return;

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

    level.fire_traps = [];

    foreach ( var_2 in var_0 )
    {
        var_2.damagefeedback = 0;
        var_3 = fire_trap_setup( var_2 );
        level.fire_traps[level.fire_traps.size] = var_3;
        var_3 thread fire_trap_think();
    }
}

fire_trap_setup( var_0 )
{
    var_1 = spawnstruct();
    var_1.trap_type = "traps_fire";
    var_1.barrel = var_0;
    var_1.burn_trig = getent( var_1.barrel.target, "targetname" );
    var_1.burn_trig.script_noteworthy = "fire_trap";
    var_2 = [];

    for ( var_3 = var_1.burn_trig; isdefined( var_3 ) && isdefined( var_3.target ); var_3 = var_4 )
    {
        var_4 = common_scripts\utility::getstruct( var_3.target, "targetname" );

        if ( !isdefined( var_4 ) )
            break;

        if ( isdefined( var_2[0] ) && var_4 == var_2[0] )
            break;

        var_2[var_2.size] = var_4;
    }

    var_5 = 45;
    var_6 = 15;
    var_7 = [];

    for ( var_8 = 0; var_8 < var_2.size - 1; var_8++ )
    {
        var_9 = distance( var_2[var_8].origin, var_2[var_8 + 1].origin );

        for ( var_10 = 0; var_10 < int( var_9 / var_5 ); var_10++ )
        {
            var_11 = vectorlerp( var_2[var_8].origin, var_2[var_8 + 1].origin, var_10 / int( var_9 / var_5 ) );
            var_7[var_7.size] = var_11;

            if ( var_7.size > var_6 )
                break;
        }

        if ( var_7.size > var_6 )
            break;
    }

    var_1.fire_fx_locs = var_7;
    var_1.fire_link_structs = var_2;
    var_1.fire_fx = loadfx( "vfx/gameplay/alien/vfx_alien_trap_fire" );
    var_1.burning = 0;
    var_1.duration = 50;
    var_1.base_duration = 50;
    var_1.dot = 600;
    var_1.damage_time = 6;
    var_1.dot_player = 33;
    var_1.damage_time_player = 3;
    var_1 fire_trap_setup_sizes();
    var_1.barrel setcursorhint( "HINT_NOICON" );
    var_1.barrel sethintstring( var_1.hintstring );
    var_1.barrel makeusable();

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::add_to_outline_watch_list( var_0, var_1.cost );

    return var_1;
}

fire_trap_setup_sizes()
{
    var_0 = [ "small", "medium", "large" ];
    var_1 = [];
    var_1["small"] = 50;
    var_1["medium"] = 80;
    var_1["large"] = 110;
    var_2 = 1;

    if ( isdefined( self.barrel.script_noteworthy ) )
    {
        if ( self.barrel.script_noteworthy == "small" )
            var_2 = 0;

        if ( self.barrel.script_noteworthy == "large" )
            var_2 = 2;

        if ( issubstr( self.barrel.script_noteworthy, "custom" ) )
        {
            var_3 = strtok( self.barrel.script_noteworthy, " " );

            switch ( var_3[1] )
            {
                case "small":
                    var_2 = 0;
                    break;
                case "medium":
                    var_2 = 1;
                    break;
                case "large":
                    var_2 = 2;
                    break;
                default:
                    break;
            }

            self.custom = var_3[2];
        }
    }

    if ( maps\mp\alien\_utility::isplayingsolo() )
        var_2 = int( max( 0, var_2 - 1 ) );

    if ( var_0[var_2] == "small" )
    {
        self.dot = 400;
        self.cost = 300;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_FIRE_TRAP_SMALL";
    }

    if ( var_0[var_2] == "medium" )
    {
        self.dot = 600;
        self.cost = 750;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_FIRE_TRAP_MED";
    }

    if ( var_0[var_2] == "large" )
    {
        self.dot = 800;
        self.cost = 1000;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_FIRE_TRAP_LARGE";
    }

    if ( isdefined( self.custom ) )
        self.base_duration = var_1[self.custom];
}

trap_bbprint( var_0, var_1, var_2 )
{
    level.alienbbdata["traps_used"]++;
    var_1 maps\mp\alien\_persistence::eog_player_update_stat( "traps", 1 );
    var_3 = var_2[0];
    var_4 = var_2[1];
    var_5 = var_2[2];
    var_6 = var_0;
    var_7 = "";

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

    bbprint( "alientrap", "traptype %s trapx %f trapy %f trapz %f ownername %s ", var_6, var_3, var_4, var_5, var_7 );
}

fire_trap_think()
{
    self endon( "disable_fire_trap" );
    level endon( "game_ended" );

    while ( isdefined( self ) )
    {
        while ( !self.burning )
        {
            self.barrel waittill( "trigger", var_0 );

            if ( var_0 can_activate_trap( self ) )
            {
                thread trap_bbprint( "fire", var_0, self.barrel.origin );
                level thread maps\mp\alien\_music_and_dialog::playvofortrapactivation( var_0, self.trap_type );
                self.owner = var_0;
                self.barrel sethintstring( "" );
                self.barrel makeunusable();
                var_1 = int( self.cost * var_0 maps\mp\alien\_perk_utility::perk_gettrapcostscalar() );
                var_2 = self.cost - var_1;
                var_0 maps\mp\alien\_persistence::take_player_currency( var_1, 0, "trap" );
                self.duration = int( self.base_duration * var_0 maps\mp\alien\_perk_utility::perk_gettrapdurationscalar() );
                thread sounds_fire_trap( self.barrel.origin );
                thread fire_trap_burn( self.barrel.origin );
                var_0 thread stop_firetrap_on_disconnect( self );
                break;
            }
            else
            {
                wait 0.05;
                var_0 maps\mp\_utility::setlowermessage( "no_money", &"ALIEN_COLLECTIBLES_NO_MONEY", 3 );
                continue;
            }
        }

        if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
            maps\mp\alien\_outline_proto::remove_from_outline_watch_list( self.barrel );

        self waittill( "fire_trap_exhausted" );
        wait 0.5;
        markdangerousnodesintrigger( self.burn_trig, 0 );
        self.burning = 0;
        self.barrel sethintstring( self.hintstring );
        self.barrel makeusable();

        if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
            maps\mp\alien\_outline_proto::add_to_outline_watch_list( self.barrel, self.cost );
    }
}

sounds_fire_trap( var_0 )
{
    var_1 = spawn( "script_origin", var_0 );
    var_1 playsound( "alien_incendiary_impact" );
    self.sound_flames = spawn( "script_origin", var_0 );
    self.sound_flames playloopsound( "fire_trap_fire_lp" );
}

fire_trap_wait_for_impact()
{
    level endon( "game_ended" );
    self endon( "fire_trap_exhausted" );

    for (;;)
    {
        self.activation_trig waittill( "damage", var_0, var_1, var_2, var_3, var_4 );

        if ( !isplayer( var_1 ) )
        {
            if ( isdefined( var_1.owner ) && isplayer( var_1.owner ) )
                var_1 = var_1.owner;
            else
            {
                wait 0.05;
                continue;
            }
        }

        if ( !isdefined( var_4 ) )
        {
            wait 0.05;
            continue;
        }

        var_5 = tolower( var_4 );

        switch ( var_5 )
        {
            case "mod_impact":
            case "mod_crush":
            case "mod_melee":
            case "unknown":
            case "melee":
                wait 0.05;
                continue;
            default:
                return var_3;
        }

        return var_3;
    }

    return undefined;
}

fire_trap_burn( var_0 )
{
    level endon( "game_ended" );
    self endon( "fire_trap_exhausted" );
    thread monitor_fire_trap_exhausted( var_0 );
    markdangerousnodesintrigger( self.burn_trig, 1 );
    wait 2;

    for (;;)
    {
        self.burn_trig waittill( "trigger", var_1 );

        if ( !isdefined( var_1 ) || !maps\mp\_utility::isreallyalive( var_1 ) || !isplayer( var_1 ) && !isagent( var_1 ) || isdefined( var_1.burning ) && var_1.burning )
            continue;

        thread do_damage_over_time( var_1 );
    }
}

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

    if ( !isdefined( self.owner ) )
        return;

    var_0 notify( "fire_trap_burning" );
    var_0 endon( "fire_trap_burning" );
    var_0.burning = 1;

    if ( isplayer( var_0 ) )
    {
        var_1 = self.damage_time_player;
        var_2 = self.dot_player;
    }
    else
    {
        var_1 = self.damage_time * self.owner maps\mp\alien\_perk_utility::perk_gettrapdamagescalar();
        var_2 = self.dot * level.alien_health_per_player_scalar[level.players.size] * self.owner maps\mp\alien\_perk_utility::perk_gettrapdamagescalar();
    }

    var_3 = var_0 maps\mp\alien\_utility::is_alien_agent();

    if ( var_3 )
        var_0 maps\mp\alien\_alien_fx::alien_fire_on();

    var_4 = 1;
    var_5 = var_2 / ( var_1 / var_4 );
    var_0 do_damage_until_timeout( var_5, var_1, var_4, self );

    if ( var_3 )
        var_0 maps\mp\alien\_alien_fx::alien_fire_off();

    var_0.burning = undefined;
}

do_damage_until_timeout( var_0, var_1, var_2, var_3 )
{
    self endon( "death" );
    var_3.owner endon( "disconnect" );
    var_4 = 0;

    while ( var_4 < var_1 && isdefined( var_3.owner ) )
    {
        var_3.owner.burning_victim = 1;

        if ( isplayer( self ) )
            self dodamage( var_0, self.origin, undefined, var_3.burn_trig );
        else if ( isdefined( var_3 ) && isdefined( var_3.owner ) )
            self dodamage( var_0, self.origin, var_3.owner, var_3.burn_trig );

        var_4 = var_4 + 1.0;
        wait( var_2 );
    }
}

monitor_fire_trap_exhausted( var_0 )
{
    level endon( "game_ended" );
    self endon( "owner_disconnected" );
    var_1 = sort_vectors_by_distance( self.fire_fx_locs, var_0 );
    var_2 = 0.25;
    self.fire_fx_array = play_fire( var_1, var_2 );
    wait( self.duration );
    self notify( "fire_trap_exhausted" );

    if ( isdefined( self.fire_fx_array ) )
        kill_fire( self.fire_fx_array );
}

sort_vectors_by_distance( var_0, var_1 )
{
    for ( var_2 = []; var_0.size; var_0 = common_scripts\utility::array_remove( var_0, var_0[var_3] ) )
    {
        var_3 = get_closest_vec_index( var_0, var_1 );
        var_2[var_2.size] = var_0[var_3];
    }

    return var_2;
}

get_closest_vec_index( var_0, var_1 )
{
    var_2 = 0;
    var_3 = var_0[0];

    foreach ( var_6, var_5 in var_0 )
    {
        if ( distance( var_5, var_1 ) <= distance( var_3, var_1 ) )
        {
            var_2 = var_6;
            var_3 = var_5;
        }
    }

    return var_2;
}

play_fire( var_0, var_1 )
{
    var_2 = [];

    for ( var_3 = 0; var_3 < var_0.size; var_3++ )
    {
        var_4 = spawnfx( self.fire_fx, var_0[var_3] );
        triggerfx( var_4 );
        var_2[var_2.size] = var_4;
        wait( var_1 );
    }

    return var_2;
}

kill_fire( var_0 )
{
    if ( isdefined( self.sound_flames ) )
        thread sounds_kill_flames();

    if ( isdefined( var_0 ) )
    {
        foreach ( var_2 in var_0 )
        {
            if ( isdefined( var_2 ) )
                var_2 delete();
        }
    }
}

sounds_kill_flames()
{
    self.sound_flames endon( "death" );
    var_0 = spawn( "script_origin", self.sound_flames.origin );
    var_0 playsound( "fire_trap_fire_end_lp" );
    wait 0.5;
    self.sound_flames stopsounds();
    wait 0.1;
    self.sound_flames delete();
}

run_generator()
{
    self notify( "electric_trap_turned_on" );
    eletric_trap_asserts();
    self.running = 1;
    self.capacity = self.max_capacity;
    self.generator sethintstring( "" );
    self.generator makeunusable();
}

trap_shock( var_0, var_1, var_2 )
{
    self endon( "electric_trap_turned_off" );
    var_0 endon( "death" );

    if ( !isdefined( self.owner ) )
        return;

    eletric_trap_asserts();
    var_3 = self.shock_damage * level.alien_health_per_player_scalar[level.players.size] * self.owner maps\mp\alien\_perk_utility::perk_gettrapdamagescalar();

    if ( isdefined( var_1 ) )
        var_3 = var_1;

    var_0.shocked = 1;

    if ( !isalive( var_0 ) )
        return;

    playfx( self.shock_fx["shock"], var_0.origin + ( 0, 0, 32 ) );
    playfx( self.shock_fx["sparks"], var_0.origin + ( 0, 0, 32 ) );
    debug_electric_trap_print( var_0.origin, "hp:" + var_0.health, ( 0.5, 0.5, 1 ), 0.75, 2, 1 );
    var_0.pain_registered = 1;
    wait 0.05;
    var_4 = self.owner;

    if ( isplayer( var_0 ) )
        var_4 = self.generator;

    if ( isdefined( var_2 ) && var_2 )
        self.capacity--;

    var_0 dodamage( var_3, var_0.origin, var_4, self.generator, "MOD_EXPLOSIVE" );
    playsoundatpos( var_0.origin, "alien_fence_shock" );

    if ( !isalive( var_0 ) && isagent( var_0 ) )
    {
        var_5 = var_0 wait_for_ragdoll_pos();

        if ( isdefined( var_5 ) )
        {
            wait 0.1;
            physicsexplosionsphere( var_5, 300, 150, 5 );
            playfx( self.shock_fx["shock"], var_5 );
            playfx( self.shock_fx["sparks"], var_5 );
        }
    }

    var_6 = randomfloatrange( self.shock_interval / 2, self.shock_interval * 1.5 );
    var_0 thread time_out_shocked_state( var_6 );
}

time_out_shocked_state( var_0 )
{
    self endon( "death" );
    self endon( "disconnect" );
    wait( var_0 );
    self.shocked = 0;
}

wait_for_ragdoll_pos()
{
    self endon( "ragdoll_timed_out" );
    thread ragdoll_timeout( 1 );
    self waittill( "in_ragdoll", var_0 );
    return var_0;
}

ragdoll_timeout( var_0 )
{
    wait( var_0 );

    if ( isdefined( self ) )
        self notify( "ragdoll_timed_out" );
}

debug_electric_trap_print( var_0, var_1, var_2, var_3, var_4, var_5 )
{

}

debug_electric_trap_print_raw( var_0, var_1, var_2, var_3, var_4, var_5 )
{
    level endon( "game_ended" );

    while ( var_5 > 0 )
    {
        var_5 = var_5 - 0.05;
        wait 0.05;
    }
}

run_electric_trap( var_0, var_1, var_2 )
{
    self endon( "death" );
    level endon( "game_ended" );
    eletric_trap_asserts();

    if ( isdefined( var_2 ) )
        self thread [[ var_2 ]]();

    while ( isdefined( self ) )
    {
        while ( !self.running )
        {
            self.generator waittill( "trigger", var_3 );

            if ( var_3 can_activate_trap( self ) )
            {
                thread trap_bbprint( "electric", var_3, self.generator.origin );
                level thread maps\mp\alien\_music_and_dialog::playvofortrapactivation( var_3, self.trap_type );
                self.owner = var_3;
                var_3 thread stop_electric_trap_on_disconnect( self );

                if ( isdefined( var_0 ) )
                    self thread [[ var_0 ]]();

                self.shock_trig playloopsound( "alien_fence_hum_lp" );
                self.generator playloopsound( "alien_fence_gen_lp" );
                var_4 = int( self.cost * var_3 maps\mp\alien\_perk_utility::perk_gettrapcostscalar() );
                var_5 = self.cost - var_4;
                var_3 maps\mp\alien\_persistence::take_player_currency( var_4, 0, "trap" );
                self.capacity = int( 20 * var_3 maps\mp\alien\_perk_utility::perk_gettrapdurationscalar() );
                break;
            }
            else
            {
                wait 0.05;
                var_3 maps\mp\_utility::setlowermessage( "no_money", &"ALIEN_COLLECTIBLES_NO_MONEY", 3 );
                continue;
            }
        }

        if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
            maps\mp\alien\_outline_proto::remove_from_outline_watch_list( self.generator );

        thread run_generator();
        var_6 = gettime();

        while ( self.running && self.capacity > 0 && isdefined( self.owner ) && issentient( self.owner ) )
        {
            var_7 = max( 0, ( gettime() - var_6 ) / 1000 );
            var_8 = max( 5, self.life_span - var_7 );
            var_9 = wait_for_trigger_timeout( var_8 * self.owner maps\mp\alien\_perk_utility::perk_gettrapdurationscalar() );

            if ( !isdefined( var_9 ) && ( isdefined( self.trap_timed_out ) && self.trap_timed_out ) )
                break;

            if ( self.capacity <= 0 || !isdefined( self.owner ) )
                break;

            if ( isagent( var_9 ) && isalive( var_9 ) && !( isdefined( var_9.shocked ) && var_9.shocked ) )
                thread trap_shock( var_9, undefined, 1 );

            if ( isdefined( self.player_damage ) && isplayer( var_9 ) && isalive( var_9 ) && !( isdefined( var_9.shocked ) && var_9.shocked ) )
                thread trap_shock( var_9, self.player_damage, 0 );
        }

        if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
            maps\mp\alien\_outline_proto::add_to_outline_watch_list( self.generator, self.cost );

        self notify( "electric_trap_turned_off" );

        if ( isdefined( self.owner ) && isalive( self.owner ) )
        {
            if ( self.trap_type == "traps_fence" )
                self.owner maps\mp\_utility::setlowermessage( "electric_fence_offline", &"ALIEN_COLLECTIBLES_ELECTRIC_FENCE_OFFLINE", 3 );
            else
                self.owner maps\mp\_utility::setlowermessage( "electric_fence_offline", &"ALIENS_PATCH_ELECTRIC_TRAP_OFFLINE", 3 );
        }

        wait 0.5;

        if ( isdefined( var_1 ) )
            self thread [[ var_1 ]]();

        self.owner = undefined;
        self.running = 0;
        self.generator sethintstring( self.hintstring );
        self.generator makeusable();
        self.generator stoploopsound( "alien_fence_gen_lp" );
        self.generator playsound( "alien_fence_gen_off" );
        self.shock_trig stoploopsound( "alien_fence_hum_lp" );
    }
}

stop_electric_trap_on_disconnect( var_0 )
{
    var_0 endon( "electric_trap_turned_off" );
    var_0 endon( "timed_out" );
    self waittill( "disconnect" );
    var_0 notify( "electric_trap_turned_off" );
}

stop_firetrap_on_disconnect( var_0 )
{
    var_0 endon( "timed_out" );
    var_0 endon( "fire_trap_exhausted" );
    self waittill( "disconnect" );
    var_0 thread kill_fire( var_0.fire_fx_array );
    var_0 notify( "owner_disconnected" );
    var_0 notify( "fire_trap_exhausted" );
}

wait_for_trigger_timeout( var_0 )
{
    self endon( "electric_trap_turned_off" );
    thread timeout_watch( var_0 );
    self endon( "timed_out" );
    self.shock_trig waittill( "trigger", var_1 );
    return var_1;
}

timeout_watch( var_0 )
{
    self endon( "electric_trap_turned_off" );
    self.trap_timed_out = 0;
    wait( var_0 );
    self notify( "timed_out" );
    self.trap_timed_out = 1;
}

eletric_trap_asserts()
{
    var_0 = " is not defined in eletric trap setup function.";
}

electric_puddle_init()
{
    var_0 = getentarray( "puddle_generator", "targetname" );

    if ( !isdefined( var_0 ) || var_0.size == 0 )
        return;

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

    level.electric_puddles = [];

    foreach ( var_2 in var_0 )
    {
        var_2.damagefeedback = 0;
        var_3 = setup_electric_puddle( var_2 );
        level.electric_puddles[level.electric_puddles.size] = var_3;
        var_3 thread run_electric_trap( ::play_puddle_on_fx, ::play_puddle_off_fx, ::ambient_puddle_shocks );
    }
}

setup_electric_puddle( var_0 )
{
    var_1 = spawnstruct();
    var_1.trap_type = "traps_puddle";
    var_1.generator = var_0;
    var_1.shock_trig = getent( var_0.target, "targetname" );
    var_1.contact_points = [];
    var_2 = common_scripts\utility::getstruct( var_1.shock_trig.target, "targetname" );

    for ( var_1.contact_points[0] = var_2; isdefined( var_2.target ); var_2 = var_3 )
    {
        var_3 = common_scripts\utility::getstruct( var_2.target, "targetname" );
        var_1.contact_points[var_1.contact_points.size] = var_3;
    }

    var_1.shock_fx["shock"] = loadfx( "vfx/moments/alien/fence_lightning_shock" );
    var_1.shock_fx["ambient_flash"] = loadfx( "vfx/moments/alien/fence_lightning_turn_on" );
    var_1.shock_fx["sparks"] = loadfx( "fx/explosions/transformer_sparks_f_sound" );
    var_1.shock_fx["sparks_sm"] = loadfx( "fx/explosions/transformer_sparks_b_sound" );
    var_1.running = 0;
    var_1.capacity = 20;
    var_1.max_capacity = 20;
    var_1.player_damage = 3;
    var_1 puddle_trap_setup_sizes();
    var_1.generator setcursorhint( "HINT_NOICON" );
    var_1.generator sethintstring( var_1.hintstring );
    var_1.generator makeusable();

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::add_to_outline_watch_list( var_0, var_1.cost );

    return var_1;
}

puddle_trap_setup_sizes()
{
    var_0 = [ "small", "medium", "large" ];
    var_1 = [];
    var_1["small"] = 90;
    var_1["medium"] = 120;
    var_1["large"] = 150;
    var_2 = 1;

    if ( isdefined( self.generator.script_noteworthy ) )
    {
        if ( self.generator.script_noteworthy == "small" )
            var_2 = 0;

        if ( self.generator.script_noteworthy == "large" )
            var_2 = 2;

        if ( issubstr( self.generator.script_noteworthy, "custom" ) )
        {
            var_3 = strtok( self.generator.script_noteworthy, " " );

            switch ( var_3[1] )
            {
                case "small":
                    var_2 = 0;
                    break;
                case "medium":
                    var_2 = 1;
                    break;
                case "large":
                    var_2 = 2;
                    break;
                default:
                    break;
            }

            self.custom = var_3[2];
        }
    }

    if ( maps\mp\alien\_utility::isplayingsolo() )
        var_2 = int( max( 0, var_2 - 1 ) );

    self.shock_damage = 200;
    self.shock_interval = 0.35;

    if ( var_0[var_2] == "small" )
    {
        self.cost = 300;
        self.life_span = 90;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_PUDDLE_SMALL";
    }

    if ( var_0[var_2] == "medium" )
    {
        self.cost = 500;
        self.life_span = 120;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_PUDDLE_MED";
    }

    if ( var_0[var_2] == "large" )
    {
        self.cost = 750;
        self.life_span = 150;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_PUDDLE_LARGE";
    }

    if ( isdefined( self.custom ) )
        self.life_span = var_1[self.custom];
}

play_puddle_off_fx()
{
    playfx( self.shock_fx["sparks"], self.contact_points[0].origin );
    var_0 = 3;

    while ( var_0 > 0 )
    {
        playfx( self.shock_fx["sparks"], self.generator.origin );
        var_0--;
        wait 0.2;
    }
}

play_puddle_on_fx()
{
    playfx( self.shock_fx["sparks"], self.contact_points[0].origin );
}

ambient_puddle_shocks()
{
    self endon( "death" );
    level endon( "game_ended" );
    var_0 = spawnfx( self.shock_fx["sparks"], self.contact_points[0].origin );
    var_1 = [];

    foreach ( var_3 in self.contact_points )
        var_1[var_1.size] = spawnfx( self.shock_fx["sparks"], var_3.origin );

    var_5 = 0;

    for (;;)
    {
        while ( !self.running )
        {
            var_5 = 0;
            self waittill( "electric_trap_turned_on" );
        }

        if ( !var_5 )
            var_5 = 1;

        triggerfx( var_0 );
        wait 0.25;
        triggerfx( var_0 );

        foreach ( var_8, var_7 in var_1 )
        {
            if ( var_8 == 0 )
            {
                triggerfx( var_7 );
                continue;
            }

            if ( common_scripts\utility::cointoss() )
                triggerfx( var_7 );
        }

        if ( !maps\mp\alien\_utility::is_true( level.skip_radius_damage_on_puddles ) )
            radiusdamage( self.contact_points[0].origin, 80, 20, 5 );

        common_scripts\utility::waittill_any_timeout( randomintrange( 3, 5 ), "electric_trap_turned_off" );
    }
}

electric_fence_init()
{
    var_0 = getentarray( "fence_generator", "targetname" );

    if ( !isdefined( var_0 ) || var_0.size == 0 )
        return;

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

    level.electric_fences = [];

    foreach ( var_2 in var_0 )
    {
        var_2.damagefeedback = 0;
        var_3 = setup_electric_fence( var_2 );
        level.electric_fences[level.electric_fences.size] = var_3;
        var_3 thread run_electric_trap( ::play_fence_on_fx, ::play_fence_off_fx, ::ambient_fence_shocks );
    }
}

setup_electric_fence( var_0 )
{
    var_1 = spawnstruct();
    var_1.trap_type = "traps_fence";
    var_1.generator = var_0;
    var_2 = common_scripts\utility::getstructarray( var_0.target, "targetname" );
    var_3 = [];
    var_4 = var_2[0];

    foreach ( var_6 in var_2 )
    {
        if ( isdefined( var_6.script_noteworthy ) && var_6.script_noteworthy == "fence_sparks" )
            var_3[var_3.size] = var_6;

        if ( isdefined( var_6.script_noteworthy ) && var_6.script_noteworthy == "fence_area" )
            var_4 = var_6;
    }

    var_8 = common_scripts\utility::getstruct( var_4.target, "targetname" );
    var_9 = common_scripts\utility::getstruct( var_8.target, "targetname" );
    var_10 = common_scripts\utility::getstruct( var_9.target, "targetname" );
    var_1.fence_top_left_angles = var_4.angles;
    var_1.fence_top_left = var_4.origin;
    var_1.fence_top_right = var_10.origin;
    var_1.fence_bottom_left = var_8.origin;
    var_1.fence_bottom_right = var_9.origin;
    var_1.fence_height = var_1.fence_top_left[2] - var_1.fence_bottom_left[2];
    var_1.fence_center = get_center( var_4.origin, var_10.origin, var_8.origin, var_9.origin );
    var_1.fence_sparks = var_3;
    var_1.shock_trig = getent( var_10.target, "targetname" );
    var_1.optimal_height = 100;
    var_1.shock_fx["ambient"] = loadfx( "vfx/moments/alien/fence_lightning_ambient" );
    var_1.shock_fx["shock"] = loadfx( "vfx/moments/alien/fence_lightning_shock" );
    var_1.shock_fx["turn_on"] = loadfx( "vfx/moments/alien/fence_lightning_turn_on" );
    var_1.shock_fx["sparks"] = loadfx( "fx/explosions/transformer_sparks_b_sound" );
    var_1.shock_fx["sparks_sm"] = loadfx( "fx/explosions/transformer_sparks_f_sound" );
    var_1.shock_bar_fx_ent = spawn( "script_origin", var_1.fence_center );
    var_1.shock_bar_fx_ent setmodel( "tag_origin" );
    var_1.running = 0;
    var_1.capacity = 20;
    var_1.max_capacity = 20;
    var_1.player_damage = 2;
    var_1 fence_trap_setup_sizes();
    var_1.generator setcursorhint( "HINT_NOICON" );
    var_1.generator sethintstring( var_1.hintstring );
    var_1.generator makeusable();

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::add_to_outline_watch_list( var_0, var_1.cost );

    return var_1;
}

fence_trap_setup_sizes()
{
    var_0 = [ "small", "medium", "large" ];
    var_1 = [];
    var_1["small"] = 90;
    var_1["medium"] = 120;
    var_1["large"] = 150;
    var_2 = 1;

    if ( isdefined( self.generator.script_noteworthy ) )
    {
        if ( self.generator.script_noteworthy == "small" )
            var_2 = 0;

        if ( self.generator.script_noteworthy == "large" )
            var_2 = 2;

        if ( issubstr( self.generator.script_noteworthy, "custom" ) )
        {
            var_3 = strtok( self.generator.script_noteworthy, " " );

            switch ( var_3[1] )
            {
                case "small":
                    var_2 = 0;
                    break;
                case "medium":
                    var_2 = 1;
                    break;
                case "large":
                    var_2 = 2;
                    break;
                default:
                    break;
            }

            self.custom = var_3[2];
        }
    }

    if ( maps\mp\alien\_utility::isplayingsolo() )
        var_2 = int( max( 0, var_2 - 1 ) );

    self.shock_damage = int( min( 800, 200 * max( 1, self.optimal_height / self.fence_height ) ) );
    self.shock_interval = 0.35;

    if ( var_0[var_2] == "small" )
    {
        self.cost = 300;
        self.life_span = 90;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_FENCE_SMALL";

        if ( isdefined( level.generic_electric_trap_check ) && self [[ level.generic_electric_trap_check ]]() )
            self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_PUDDLE_SMALL";
    }

    if ( var_0[var_2] == "medium" )
    {
        self.cost = 500;
        self.life_span = 120;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_FENCE_MED";

        if ( isdefined( level.generic_electric_trap_check ) && self [[ level.generic_electric_trap_check ]]() )
            self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_PUDDLE_MED";
    }

    if ( var_0[var_2] == "large" )
    {
        self.cost = 750;
        self.life_span = 150;
        self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_FENCE_LARGE";

        if ( isdefined( level.generic_electric_trap_check ) && self [[ level.generic_electric_trap_check ]]() )
            self.hintstring = &"ALIEN_COLLECTIBLES_ACTIVATE_PUDDLE_LARGE";
    }

    if ( isdefined( self.custom ) )
        self.life_span = var_1[self.custom];
}

get_center( var_0, var_1, var_2, var_3 )
{
    var_4 = ( var_0[0] + var_1[0] + var_2[0] + var_3[0] ) / 4;
    var_5 = ( var_0[1] + var_1[1] + var_2[1] + var_3[1] ) / 4;
    var_6 = ( var_0[2] + var_1[2] + var_2[2] + var_3[2] ) / 4;
    return ( var_4, var_5, var_6 );
}

ambient_fence_shocks()
{
    self endon( "death" );
    level endon( "game_ended" );
    var_0 = 0;

    for (;;)
    {
        while ( !self.running )
        {
            var_0 = 0;
            stopfxontag( self.shock_fx["ambient"], self.shock_bar_fx_ent, "tag_origin" );
            self waittill( "electric_trap_turned_on" );
        }

        if ( !var_0 )
        {
            playfxontag( self.shock_fx["ambient"], self.shock_bar_fx_ent, "tag_origin" );
            var_0 = 1;
        }

        var_1 = self.capacity / self.max_capacity;
        var_2 = self.fence_height * var_1;
        var_3 = self.fence_bottom_left + ( 0, 0, var_2 );
        var_4 = self.fence_bottom_right + ( 0, 0, var_2 );
        var_5 = ( self.fence_center[0], self.fence_center[1], var_4[2] );
        playfx( self.shock_fx["sparks_sm"], var_3 );
        wait 0.3;
        playfx( self.shock_fx["sparks_sm"], var_5 );
        wait 0.3;
        playfx( self.shock_fx["sparks_sm"], var_4 );

        if ( isdefined( self.fence_sparks ) )
        {
            foreach ( var_7 in self.fence_sparks )
            {
                playfx( self.shock_fx["sparks_sm"], var_7.origin );
                wait 0.3;
            }
        }

        debug_electric_trap_print( self.generator.origin, "Power: " + var_1, ( 0.5, 0.5, 1 ), 0.75, 3, 3 );
        common_scripts\utility::waittill_any_timeout( randomintrange( 2, 3 ), "electric_trap_turned_off" );
    }
}

play_fence_off_fx()
{
    playfx( self.shock_fx["shock"], self.fence_top_left );
    playfx( self.shock_fx["sparks"], self.fence_top_left );
    playfx( self.shock_fx["shock"], self.fence_top_right );
    playfx( self.shock_fx["sparks"], self.fence_top_right );
    var_0 = 3;

    while ( var_0 > 0 )
    {
        playfx( self.shock_fx["shock"], self.generator.origin );
        playfx( self.shock_fx["sparks"], self.generator.origin );
        var_0--;
        wait 0.2;
    }
}

play_fence_on_fx()
{
    playfx( self.shock_fx["shock"], self.fence_top_left );
    playfx( self.shock_fx["sparks"], self.fence_top_left );
    playfx( self.shock_fx["shock"], self.fence_top_right );
    playfx( self.shock_fx["sparks"], self.fence_top_right );
}

turret_monitoruse()
{
    level endon( "game_ended" );
    self setcursorhint( "HINT_NOICON" );
    self makeusable();
    wait 0.05;

    if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) )
        maps\mp\alien\_outline_proto::add_to_outline_watch_list( self, 750 );

    disable_turret();

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

        if ( !isplayer( var_0 ) )
            continue;

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

        var_1 = int( 750 * var_0 maps\mp\alien\_perk_utility::perk_gettrapcostscalar() );

        if ( !is_turret_enabled() )
        {
            if ( var_0 can_activate_turret() )
            {
                var_0 maps\mp\alien\_persistence::take_player_currency( var_1, 0, "trap" );
                enable_turret();
                level thread maps\mp\alien\_music_and_dialog::playvoforsentry( var_0, "minigun" );
                thread monitor_player_use();
            }
            else
                var_0 maps\mp\_utility::setlowermessage( "no_money", &"ALIEN_COLLECTIBLES_NO_MONEY", 3 );

            continue;
        }

        self.owner = var_0;
        wait_for_disable_turret();
        disable_turret();
    }
}

wait_for_disable_turret()
{
    thread watch_bullet_fired();
    self waittill( "disable_turret" );
}

watch_bullet_fired()
{
    self endon( "disable_turret" );
    self notify( "stop_fire_monitor" );
    self endon( "stop_fire_monitor" );
    var_0 = 0;
    var_1 = int( 300 * self.owner maps\mp\alien\_perk_utility::perk_gettrapdurationscalar() );
    self.turret_ammo = var_1;
    var_2 = weaponfiretime( self.weaponinfo );

    for (;;)
    {
        self waittill( "turret_fire" );
        self getturretowner() notify( "turret_fire" );
        self.heatlevel = self.heatlevel + var_2;
        var_0++;
        self.cooldownwaittime = var_2;
        self.turret_ammo = var_1 - var_0;

        if ( var_0 > var_1 )
        {
            self.turret_ammo = 0;
            break;
        }

        self.owner maps\mp\alien\_utility::set_turret_ammocount( self.turret_ammo );
    }

    if ( isdefined( self.owner ) && isalive( self.owner ) )
        self.owner thread maps\mp\alien\_utility::wait_for_player_to_dismount_turret();

    self notify( "disable_turret" );
}

is_turret_enabled()
{
    return self.enabled;
}

disable_turret()
{
    self.enabled = 0;
    self sethintstring( &"ALIEN_COLLECTIBLES_ACTIVATE_TURRET" );
    self turretfiredisable();
    self maketurretinoperable();
}

enable_turret()
{
    self.enabled = 1;
    self sethintstring( "" );
    self turretfireenable();
    self maketurretoperable();
}

can_activate_turret()
{
    return maps\mp\alien\_persistence::player_has_enough_currency( 750 );
}

monitor_player_use()
{
    self endon( "turret_disabled" );

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

        if ( !isdefined( var_0 ) || !isalive( var_0 ) )
            continue;

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

        if ( var_0 isusingturret() )
        {
            self.owner = var_0;

            while ( !isdefined( self.turret_ammo ) )
                wait 0.05;

            if ( !maps\mp\alien\_utility::is_chaos_mode() )
                var_0 maps\mp\alien\_utility::disable_special_ammo();

            var_0 maps\mp\alien\_utility::show_turret_icon( 2 );
            var_0 maps\mp\alien\_utility::set_turret_ammocount( self.turret_ammo );
            var_0 setclientomnvar( "ui_alien_turret_overheat", 0 );
            thread turret_overheat_monitor( var_0 );
            thread turret_cooldown_monitor();
            thread clear_turret_ammo_counter_on_dismount( var_0 );
            thread clear_turret_ammo_counter_on_death( var_0 );
            var_0 maps\mp\_utility::setlowermessage( "disengage_turret", &"ALIEN_COLLECTIBLES_DISENGAGE_TURRET", 4 );
            continue;
        }

        var_0 maps\mp\alien\_utility::hide_turret_icon();

        if ( !maps\mp\alien\_utility::is_chaos_mode() )
            var_0 maps\mp\alien\_utility::enable_special_ammo();

        self.owner = undefined;
        var_0 setclientomnvar( "ui_alien_turret_overheat", -1 );
        var_0 maps\mp\_utility::clearlowermessage( "disengage_turret" );
    }
}

turret_cooldown_monitor()
{
    self endon( "death" );
    self notify( "stop_cooldown_monitor" );
    self endon( "stop_cooldown_monitor" );
    self endon( "turret_disabled" );

    for (;;)
    {
        if ( self.heatlevel > 0 )
        {
            if ( self.cooldownwaittime <= 0 )
                self.heatlevel = max( 0, self.heatlevel - 0.05 );
            else
                self.cooldownwaittime = max( 0, self.cooldownwaittime - 0.05 );
        }

        wait 0.05;
    }
}

turret_overheat_monitor( var_0 )
{
    self notify( "overheat_monitor" );
    self endon( "overheat_monitor" );
    self endon( "turret_disabled" );
    self.heatlevel = 0;
    self.cooldownwaittime = 1;
    var_0 endon( "disconnect" );
    var_1 = 0;

    for (;;)
    {
        if ( !maps\mp\_utility::isreallyalive( var_0 ) )
        {
            self.inuseby = undefined;
            var_0 setclientomnvar( "ui_alien_turret_overheat", -1 );
            break;
        }

        if ( !var_0 isusingturret() )
        {
            var_0 setclientomnvar( "ui_alien_turret_overheat", -1 );
            break;
        }

        if ( self.heatlevel >= 2 )
            var_2 = 1;
        else
            var_2 = self.heatlevel / 2;

        var_3 = 5;
        var_4 = int( var_2 * 100 );

        if ( var_1 != var_4 )
        {
            if ( var_4 <= var_3 || abs( abs( var_1 ) - abs( var_4 ) ) > var_3 )
            {
                var_0 setclientomnvar( "ui_alien_turret_overheat", var_4 );
                var_1 = var_4;
            }
        }

        wait 0.05;
    }

    var_0 setclientomnvar( "ui_alien_turret_overheat", -1 );
}

clear_turret_ammo_counter_on_death( var_0 )
{
    self notify( "clearammocounterondeath" );
    self endon( "clearammocounterondeath" );
    var_0 endon( "disconnect" );
    self waittill( "turret_disabled" );
    var_0 maps\mp\alien\_utility::hide_turret_icon();
    var_0 maps\mp\_utility::clearlowermessage( "disengage_turret" );
}

clear_turret_ammo_counter_on_dismount( var_0 )
{
    self notify( "dimountammocounter" );
    self endon( "dismountammocounter" );
    var_0 endon( "disconnect" );

    while ( var_0 isusingturret() )
        wait 0.1;

    var_0 maps\mp\alien\_utility::hide_turret_icon();
    self.owner = undefined;
    var_0 maps\mp\_utility::clearlowermessage( "disengage_turret" );

    if ( var_0 getcurrentweapon() == "none" )
        var_0 thread restore_last_valid_weapon();
}

restore_last_valid_weapon()
{
    var_0 = self getweaponslistprimaries();

    foreach ( var_2 in var_0 )
    {
        if ( isdefined( var_2 ) && var_2 != "none" )
        {
            self switchtoweapon( var_2 );
            break;
        }
    }
}

monitor_flare_use()
{
    self endon( "death" );
    self endon( "disconnect" );
    level endon( "game_ended" );
    self endon( "end_monitor_flare_use" );

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

        if ( var_1 == "iw6_aliendlc21_mp" )
        {
            var_0 thread sticky_flare( self );
            continue;
        }

        if ( var_1 != "alienflare_mp" )
            continue;

        var_0 common_scripts\utility::make_entity_sentient_mp( "allies" );
        var_0.threatbias = 1000;
        var_2 = var_0 common_scripts\utility::waittill_notify_or_timeout_return( "missile_stuck", 7 );

        if ( isdefined( var_2 ) && var_2 == "timeout" )
        {
            if ( isdefined( var_0 ) )
                var_0 delete();

            continue;
        }

        var_3 = spawn( "script_model", var_0.origin );
        var_0 delete();
        var_3 setmodel( "mil_emergency_flare_mp" );
        var_3.angles = self.angles;
        var_3.owner = self;

        if ( maps\mp\alien\_persistence::is_upgrade_enabled( "master_scavenger_upgrade" ) )
            var_3 thread create_flare( level.spawnglow["enemy"], self );
        else
            var_3 thread create_flare( level.spawnglow["friendly"], self );

        self takeweapon( "alienflare_mp" );
    }
}

sticky_flare( var_0 )
{
    self endon( "death" );
    common_scripts\utility::make_entity_sentient_mp( "allies" );
    self.threatbias = 1000;
    self.owner = var_0;
    thread flare_out_of_playable_monitor();
    thread create_flare( level._effect["sticky_flare"], var_0 );
    thread sfx_flare_lp( var_0 );
    self waittill( "missile_stuck", var_1 );

    if ( isdefined( var_1 ) && var_1 maps\mp\alien\_utility::is_alien_agent() )
    {
        var_1 maps\mp\alien\_utility::enable_alien_scripted();
        var_1.stuck_by_flare = 1;
        var_1 setorigin( var_1.origin );
        level thread wait_for_flare_finished( var_1, self );
    }
    else
    {
        var_2 = undefined;
        level thread wait_for_flare_finished( var_2, self );
    }
}

flare_out_of_playable_monitor()
{
    self endon( "death" );
    self endon( "missile_stuck" );
    wait 7;

    if ( isdefined( self ) )
        self delete();
}

wait_for_flare_finished( var_0, var_1 )
{
    var_2 = var_1.owner;
    var_1 waittill( "deleting_flare", var_3 );
    var_4 = level.placeableconfigs["fuse_resin_tnt"];
    playfx( level._effect["sticky_explode"], var_3 );
    playsoundatpos( var_3, "flare_explode_default" );
    radiusdamage( var_3, var_4.item_damage_radius, var_4.item_damage, var_4.item_damage_falloff, var_2, "MOD_EXPLOSIVE", "iw6_aliendlc22_mp" );
    earthquake( 0.35, 0.5, var_3, 512 );

    if ( isdefined( var_0 ) )
    {
        var_0 maps\mp\alien\_utility::disable_alien_scripted();
        var_0.stuck_by_flare = 0;
    }
}

create_flare( var_0, var_1 )
{
    self endon( "death" );
    wait 0.5;
    var_2 = self gettagangles( "tag_fire_fx" );
    playfxontag( var_0, self, "tag_fire_fx" );
    self playloopsound( "emt_road_flare_burn" );
    self.flaretype = 1;

    if ( var_1 maps\mp\alien\_persistence::is_upgrade_enabled( "master_scavenger_upgrade" ) )
    {
        thread flare_attract_aliens( 30, var_1 );
        wait 30;
    }
    else
    {
        thread flare_attract_aliens( 20, var_1 );
        wait 20;
    }

    self notify( "deleting_flare", self.origin );
    self delete();
}

sfx_flare_lp( var_0 )
{
    self endon( "death" );
    var_1 = 0.163;

    if ( var_0 maps\mp\alien\_persistence::is_upgrade_enabled( "master_scavenger_upgrade" ) )
        var_2 = gettime() + 28600.0;
    else
        var_2 = gettime() + 18600.0;

    wait 0.2;

    while ( gettime() < var_2 && isdefined( self ) )
    {
        playsoundatpos( self.origin, "flare_beep" );
        wait( var_1 );
    }

    playsoundatpos( self.origin, "flare_beep_end" );
}

flare_attract_aliens( var_0, var_1 )
{
    var_2 = gettime() + var_0 * 1000;
    var_3 = [];

    while ( gettime() < var_2 && isdefined( self ) )
    {
        var_4 = [];

        foreach ( var_6 in var_3 )
        {
            if ( isdefined( var_6 ) && isalive( var_6 ) )
                var_4[var_4.size] = var_6;
        }

        var_3 = var_4;

        if ( isdefined( var_1 ) )
            var_8 = var_1.origin;
        else
            var_8 = self.origin;

        var_9 = get_possible_flare_victims( var_8 );

        for ( var_10 = 0; var_10 < var_9.size && var_3.size < 6; var_10++ )
        {
            var_6 = var_9[var_10];

            if ( !var_6 should_attract_alien() )
                continue;

            if ( isdefined( var_6.attractor_flare ) )
                continue;

            var_6 maps\mp\agents\alien\_alien_think::handle_attractor_flare( self, 1 );
            var_3[var_3.size] = var_6;
        }

        wait 0.2;
    }

    foreach ( var_6 in var_3 )
        var_6 maps\mp\agents\alien\_alien_think::handle_attractor_flare( self, 0 );
}

get_possible_flare_victims( var_0 )
{
    var_1 = 131072.0;
    var_2 = maps\mp\agents\_agent_utility::getactiveagentsoftype( "alien" );
    var_3 = common_scripts\utility::get_array_of_closest( var_0, var_2, undefined, undefined, 512 );
    var_4 = common_scripts\utility::get_array_of_closest( self.origin, var_2, undefined, undefined, 512 );
    var_5 = [];

    for ( var_6 = 0; var_6 < var_3.size; var_6++ )
    {
        var_7 = var_3[var_6];

        if ( common_scripts\utility::array_contains( var_5, var_7 ) )
            continue;

        var_8 = distancesquared( var_0, var_7.origin );

        if ( var_8 <= var_1 )
        {
            var_5[var_5.size] = var_7;
            continue;
        }

        break;
    }

    var_9 = 0;

    while ( var_6 < var_3.size || var_9 < var_4.size )
    {
        var_10 = undefined;

        for ( var_11 = undefined; var_6 < var_3.size; var_6++ )
        {
            var_11 = var_3[var_6];

            if ( !common_scripts\utility::array_contains( var_5, var_11 ) )
            {
                var_10 = distancesquared( var_0, var_11.origin );
                break;
            }
        }

        while ( var_9 < var_4.size )
        {
            var_12 = var_4[var_9];

            if ( common_scripts\utility::array_contains( var_5, var_12 ) )
            {
                var_9++;
                continue;
            }

            var_13 = distancesquared( self.origin, var_12.origin );

            if ( !isdefined( var_10 ) || var_13 < var_10 )
                var_5[var_5.size] = var_12;
            else
                break;

            var_9++;
        }

        if ( isdefined( var_10 ) )
        {
            var_5[var_5.size] = var_11;
            var_6++;
        }
    }

    return var_5;
}

should_attract_alien()
{
    if ( maps\mp\alien\_utility::is_true( self.stuck_by_flare ) )
        return 0;

    switch ( maps\mp\alien\_utility::get_alien_type() )
    {
        case "mammoth":
        case "gargoyle":
        case "elite":
            return 0;
        default:
            return 1;
    }
}

deleteondeath( var_0 )
{
    self waittill( "death" );

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

easter_egg_lodge_sign()
{
    level endon( "game_ended" );
    level notify( "easter_egg_lodge_sign_reset" );
    level endon( "easter_egg_lodge_sign_reset" );
    var_0 = getent( "easter_egg_letter_l", "targetname" );
    var_1 = getent( "easter_egg_letter_o", "targetname" );
    var_2 = getent( "easter_egg_letter_reset", "targetname" );

    if ( !isdefined( var_0 ) || !isdefined( var_1 ) || !isdefined( var_2 ) )
        return;

    var_2 thread watch_for_letter_reset();

    for (;;)
    {
        var_0 waittill( "damage", var_3, var_4, var_5, var_6, var_7 );
        var_8 = gettime();

        if ( !is_letter_valid_hit( var_4, var_7 ) )
            continue;

        var_1 waittill( "damage", var_3, var_4, var_5, var_6, var_7 );

        if ( !is_letter_valid_hit( var_4, var_7 ) )
            continue;

        var_0 waittill( "damage", var_3, var_4, var_5, var_6, var_7 );

        if ( !is_letter_valid_hit( var_4, var_7 ) || gettime() - var_8 > 5000 )
            continue;

        wait 1;
        iprintlnbold( "^5L^6O^5L" );
        level.easter_egg_lodge_sign_active = 1;
        wait 120;
        level.easter_egg_lodge_sign_active = 0;
    }
}

is_letter_valid_hit( var_0, var_1 )
{
    if ( !isdefined( var_0 ) || !isplayer( var_0 ) )
        return 0;

    var_2 = var_0 getcurrentweapon();

    if ( !isdefined( var_2 ) || var_2 != "iw6_alienvks_mp_alienvksscope" )
        return 0;

    var_1 = tolower( var_1 );

    if ( !isdefined( var_1 ) || var_1 != "mod_rifle_bullet" )
        return 0;

    return 1;
}

watch_for_letter_reset()
{
    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( var_1 ) || !isplayer( var_1 ) )
            continue;

        if ( isdefined( level.easter_egg_lodge_sign_active ) && level.easter_egg_lodge_sign_active )
            continue;

        wait 1;
        return easter_egg_lodge_sign();
    }
}
