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

attachmentgroup( var_0 )
{
    if ( maps\mp\_utility::is_aliens() )
        return tablelookup( "mp/alien/alien_attachmentTable.csv", 4, var_0, 2 );
    else
        return tablelookup( "mp/attachmentTable.csv", 4, var_0, 2 );
}

init()
{
    level.scavenger_altmode = 1;
    level.scavenger_secondary = 1;
    level.maxperplayerexplosives = max( maps\mp\_utility::getintproperty( "scr_maxPerPlayerExplosives", 2 ), 1 );
    level.riotshieldxpbullets = maps\mp\_utility::getintproperty( "scr_riotShieldXPBullets", 15 );
    createthreatbiasgroup( "DogsDontAttack" );
    createthreatbiasgroup( "Dogs" );
    setignoremegroup( "DogsDontAttack", "Dogs" );

    switch ( maps\mp\_utility::getintproperty( "perk_scavengerMode", 0 ) )
    {
        case 1:
            level.scavenger_altmode = 0;
            break;
        case 2:
            level.scavenger_secondary = 0;
            break;
        case 3:
            level.scavenger_altmode = 0;
            level.scavenger_secondary = 0;
            break;
    }

    var_0 = getdvar( "g_gametype" );
    var_1 = maps\mp\_utility::getattachmentlistbasenames();
    var_1 = common_scripts\utility::alphabetize( var_1 );
    var_2 = 149;
    level.weaponlist = [];
    level.weaponattachments = [];
    var_3 = "mp/statstable.csv";

    if ( maps\mp\_utility::is_aliens() )
        var_3 = "mp/alien/mode_string_tables/alien_statstable.csv";

    for ( var_4 = 0; var_4 <= var_2; var_4++ )
    {
        var_5 = tablelookup( var_3, 0, var_4, 4 );

        if ( var_5 == "" )
            continue;

        if ( !issubstr( tablelookup( var_3, 0, var_4, 2 ), "weapon_" ) )
            continue;

        if ( issubstr( var_5, "iw5" ) || issubstr( var_5, "iw6" ) )
        {
            var_6 = strtok( var_5, "_" );
            var_5 = var_6[0] + "_" + var_6[1] + "_mp";
            level.weaponlist[level.weaponlist.size] = var_5;
            continue;
        }
        else
            level.weaponlist[level.weaponlist.size] = var_5 + "_mp";

        var_7 = [];

        for ( var_8 = 0; var_8 < 10; var_8++ )
        {
            if ( var_0 == "aliens" )
                var_9 = tablelookup( "mp/alien/mode_string_tables/alien_statstable.csv", 0, var_4, var_8 + 11 );
            else
                var_9 = maps\mp\_utility::getweaponattachmentfromstats( var_5, var_8 );

            if ( var_9 == "" )
                break;

            var_7[var_9] = 1;
        }

        var_10 = [];

        foreach ( var_9 in var_1 )
        {
            if ( !isdefined( var_7[var_9] ) )
                continue;

            level.weaponlist[level.weaponlist.size] = var_5 + "_" + var_9 + "_mp";
            var_10[var_10.size] = var_9;
        }

        var_13 = [];

        for ( var_14 = 0; var_14 < var_10.size - 1; var_14++ )
        {
            var_15 = tablelookuprownum( "mp/attachmentCombos.csv", 0, var_10[var_14] );

            for ( var_16 = var_14 + 1; var_16 < var_10.size; var_16++ )
            {
                if ( tablelookup( "mp/attachmentCombos.csv", 0, var_10[var_16], var_15 ) == "no" )
                    continue;

                var_13[var_13.size] = var_10[var_14] + "_" + var_10[var_16];
            }
        }

        foreach ( var_18 in var_13 )
            level.weaponlist[level.weaponlist.size] = var_5 + "_" + var_18 + "_mp";
    }

    foreach ( var_21 in level.weaponlist )
        precacheitem( var_21 );

    thread maps\mp\_flashgrenades::main();
    thread maps\mp\_entityheadicons::init();
    thread maps\mp\_empgrenade::init();
    initbombsquaddata();
    maps\mp\_utility::buildattachmentmaps();
    maps\mp\_utility::buildweaponperkmap();
    level._effect["weap_blink_friend"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_detonator_blink_cyan" );
    level._effect["weap_blink_enemy"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_detonator_blink_orange" );
    level._effect["emp_stun"] = loadfx( "vfx/gameplay/mp/equipment/vfx_emp_grenade" );
    level._effect["equipment_explode_big"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_ims_explosion" );
    level._effect["equipment_smoke"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_sg_damage_blacksmoke" );
    level._effect["equipment_sparks"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_sentry_gun_explosion" );
    level.weaponconfigs = [];

    if ( !isdefined( level.weapondropfunction ) )
        level.weapondropfunction = ::dropweaponfordeath;

    var_24 = 70;
    level.claymoredetectiondot = cos( var_24 );
    level.claymoredetectionmindist = 20;
    level.claymoredetectiongraceperiod = 0.75;
    level.claymoredetonateradius = 192;
    level.minedetectiongraceperiod = 0.3;
    level.minedetectionradius = 100;
    level.minedetectionheight = 20;
    level.minedamageradius = 256;
    level.minedamagemin = 70;
    level.minedamagemax = 210;
    level.minedamagehalfheight = 46;
    level.mineselfdestructtime = 120;
    level.mine_launch = loadfx( "fx/impacts/bouncing_betty_launch_dirt" );
    level.mine_explode = loadfx( "fx/explosions/bouncing_betty_explosion" );
    var_25 = spawnstruct();
    var_25.model = "projectile_bouncing_betty_grenade";
    var_25.bombsquadmodel = "projectile_bouncing_betty_grenade_bombsquad";
    var_25.mine_beacon["enemy"] = loadfx( "fx/misc/light_c4_blink" );
    var_25.mine_beacon["friendly"] = loadfx( "fx/misc/light_mine_blink_friendly" );
    var_25.mine_spin = loadfx( "fx/dust/bouncing_betty_swirl" );
    var_25.armtime = 2;
    var_25.ontriggeredsfx = "mine_betty_click";
    var_25.onlaunchsfx = "mine_betty_spin";
    var_25.onexplodesfx = "grenade_explode_metal";
    var_25.launchheight = 64;
    var_25.launchtime = 0.65;
    var_25.ontriggeredfunc = ::minebounce;
    var_25.headiconoffset = 20;
    level.weaponconfigs["bouncingbetty_mp"] = var_25;
    level.weaponconfigs["alienbetty_mp"] = var_25;
    var_25 = spawnstruct();
    var_25.model = "weapon_motion_sensor";
    var_25.bombsquadmodel = "weapon_motion_sensor_bombsquad";
    var_25.mine_beacon["enemy"] = common_scripts\utility::getfx( "weap_blink_enemy" );
    var_25.mine_beacon["friendly"] = common_scripts\utility::getfx( "weap_blink_friend" );
    var_25.mine_spin = loadfx( "fx/dust/bouncing_betty_swirl" );
    var_25.armtime = 2;
    var_25.ontriggeredsfx = "motion_click";
    var_25.ontriggeredfunc = ::minesensorbounce;
    var_25.onlaunchsfx = "motion_spin";
    var_25.launchvfx = level.mine_launch;
    var_25.launchheight = 64;
    var_25.launchtime = 0.65;
    var_25.onexplodesfx = "motion_explode_default";
    var_25.onexplodevfx = loadfx( "vfx/gameplay/mp/equipment/vfx_motionsensor_exp" );
    var_25.headiconoffset = 25;
    var_25.markedduration = 4.0;
    level.weaponconfigs["motion_sensor_mp"] = var_25;
    var_25 = spawnstruct();
    var_25.armingdelay = 1.5;
    var_25.detectionradius = 232;
    var_25.detectionheight = 512;
    var_25.detectiongraceperiod = 1;
    var_25.headiconoffset = 20;
    var_25.killcamoffset = 12;
    level.weaponconfigs["proximity_explosive_mp"] = var_25;
    var_25 = spawnstruct();
    var_26 = 800;
    var_27 = 200;
    var_25.radius_max_sq = var_26 * var_26;
    var_25.radius_min_sq = var_27 * var_27;
    var_25.onexplodevfx = loadfx( "vfx/gameplay/mp/equipment/vfx_flashbang" );
    var_25.onexplodesfx = "flashbang_explode_default";
    var_25.vfxradius = 72;
    level.weaponconfigs["flash_grenade_mp"] = var_25;
    level.delayminetime = 3.0;
    level.sentry_fire = loadfx( "fx/muzzleflashes/shotgunflash" );
    level.stingerfxid = loadfx( "fx/explosions/aerial_explosion_large" );
    level.primary_weapon_array = [];
    level.side_arm_array = [];
    level.grenade_array = [];
    level.missile_array = [];
    level.inventory_array = [];
    level.mines = [];
    level._effect["equipment_explode"] = loadfx( "fx/explosions/sparks_a" );
    level._effect["sniperDustLarge"] = loadfx( "fx/dust/sniper_dust_kickup" );
    level._effect["sniperDustSmall"] = loadfx( "fx/dust/sniper_dust_kickup_minimal" );
    level._effect["sniperDustLargeSuppress"] = loadfx( "fx/dust/sniper_dust_kickup_accum_suppress" );
    level._effect["sniperDustSmallSuppress"] = loadfx( "fx/dust/sniper_dust_kickup_accum_supress_minimal" );
    level thread onplayerconnect();
    level.c4explodethisframe = 0;
    common_scripts\utility::array_thread( getentarray( "misc_turret", "classname" ), ::turret_monitoruse );
}

dumpit()
{
    wait 5.0;
}

initbombsquaddata()
{
    level.bomb_squad = [];
    level.bomb_squad["c4_mp"] = spawnstruct();
    level.bomb_squad["c4_mp"].model = "weapon_c4_iw6_bombsquad";
    level.bomb_squad["c4_mp"].tag = "tag_origin";
    level.bomb_squad["claymore_mp"] = spawnstruct();
    level.bomb_squad["claymore_mp"].model = "weapon_claymore_bombsquad";
    level.bomb_squad["claymore_mp"].tag = "tag_origin";
    level.bomb_squad["frag_grenade_mp"] = spawnstruct();
    level.bomb_squad["frag_grenade_mp"].model = "projectile_m67fraggrenade_bombsquad";
    level.bomb_squad["frag_grenade_mp"].tag = "tag_weapon";
    level.bomb_squad["frag_grenade_short_mp"] = spawnstruct();
    level.bomb_squad["frag_grenade_short_mp"].model = "projectile_m67fraggrenade_bombsquad";
    level.bomb_squad["frag_grenade_short_mp"].tag = "tag_weapon";
    level.bomb_squad["semtex_mp"] = spawnstruct();
    level.bomb_squad["semtex_mp"].model = "weapon_semtex_grenade_iw6_bombsquad";
    level.bomb_squad["semtex_mp"].tag = "tag_origin";
    level.bomb_squad["mortar_shell_mp"] = spawnstruct();
    level.bomb_squad["mortar_shell_mp"].model = "weapon_canister_bomb_bombsquad";
    level.bomb_squad["mortar_shell_mp"].tag = "tag_weapon";
    level.bomb_squad["thermobaric_grenade_mp"] = spawnstruct();
    level.bomb_squad["thermobaric_grenade_mp"].model = "weapon_thermobaric_grenade_bombsquad";
    level.bomb_squad["thermobaric_grenade_mp"].tag = "tag_weapon";
    level.bomb_squad["proximity_explosive_mp"] = spawnstruct();
    level.bomb_squad["proximity_explosive_mp"].model = "mp_proximity_explosive_bombsquad";
    level.bomb_squad["proximity_explosive_mp"].tag = "tag_origin";
}

bombsquadwaiter_missilefire()
{
    self endon( "disconnect" );

    for (;;)
    {
        var_0 = maps\mp\_utility::waittill_missile_fire();

        if ( var_0.weapon_name == "iw6_mk32_mp" )
            var_0 thread createbombsquadmodel( "projectile_semtex_grenade_bombsquad", "tag_weapon", self );
    }
}

createbombsquadmodel( var_0, var_1, var_2 )
{
    var_3 = spawn( "script_model", ( 0, 0, 0 ) );
    var_3 hide();
    wait 0.05;

    if ( !isdefined( self ) )
        return;

    self.bombsquadmodel = var_3;
    var_3 thread bombsquadvisibilityupdater( var_2 );
    var_3 setmodel( var_0 );
    var_3 linkto( self, var_1, ( 0, 0, 0 ), ( 0, 0, 0 ) );
    var_3 setcontents( 0 );
    common_scripts\utility::waittill_any( "death", "trap_death" );

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

    var_3 delete();
}

disablevisibilitycullingforclient( var_0 )
{
    self hudoutlineenableforclient( var_0, 6, 1 );
}

enablevisibilitycullingforclient( var_0 )
{
    self hudoutlinedisableforclient( var_0 );
}

bombsquadvisibilityupdater( var_0 )
{
    self endon( "death" );
    self endon( "trap_death" );

    if ( !isdefined( var_0 ) )
        return;

    var_1 = var_0.team;

    for (;;)
    {
        self hide();

        foreach ( var_3 in level.players )
        {
            enablevisibilitycullingforclient( var_3 );

            if ( !var_3 maps\mp\_utility::_hasperk( "specialty_detectexplosive" ) )
                continue;

            if ( level.teambased )
            {
                if ( var_3.team == "spectator" || var_3.team == var_1 )
                    continue;
            }
            else if ( isdefined( var_0 ) && var_3 == var_0 )
                continue;

            self showtoplayer( var_3 );
            disablevisibilitycullingforclient( var_3 );
        }

        level common_scripts\utility::waittill_any( "joined_team", "player_spawned", "changed_kit", "update_bombsquad" );
    }
}

onplayerconnect()
{
    for (;;)
    {
        level waittill( "connected", var_0 );
        var_0.hits = 0;
        maps\mp\gametypes\_gamelogic::sethasdonecombat( var_0, 0 );
        var_0 thread onplayerspawned();
        var_0 thread bombsquadwaiter_missilefire();
        var_0 thread watchmissileusage();
        var_0 thread sniperdustwatcher();
    }
}

onplayerspawned()
{
    self endon( "disconnect" );

    for (;;)
    {
        self waittill( "spawned_player" );
        self.currentweaponatspawn = self getcurrentweapon();
        self.empendtime = 0;
        self.concussionendtime = 0;
        self.hits = 0;
        maps\mp\gametypes\_gamelogic::sethasdonecombat( self, 0 );

        if ( !isdefined( self.trackingweaponname ) )
        {
            self.trackingweaponname = "";
            self.trackingweaponname = "none";
            self.trackingweaponshots = 0;
            self.trackingweaponkills = 0;
            self.trackingweaponhits = 0;
            self.trackingweaponheadshots = 0;
            self.trackingweapondeaths = 0;
        }

        if ( !maps\mp\_utility::is_aliens() )
        {
            thread watchweaponusage();
            thread watchweaponchange();
            thread watchweaponperkupdates();
            thread watchsniperboltactionkills();
        }

        thread watchgrenadeusage();
        thread watchsentryusage();

        if ( !maps\mp\_utility::is_aliens() )
            thread maps\mp\gametypes\_class::trackriotshield();

        thread stancerecoiladjuster();
        self.lasthittime = [];
        self.droppeddeathweapon = undefined;
        self.tookweaponfrom = [];
        thread updatesavedlastweapon();
        thread monitormk32semtexlauncher();
        self.currentweaponatspawn = undefined;
        self.trophyremainingammo = undefined;
    }
}

recordtogglescopestates()
{
    self.pers["toggleScopeStates"] = [];
    var_0 = self getweaponslistprimaries();

    foreach ( var_2 in var_0 )
    {
        if ( var_2 == self.primaryweapon || var_2 == self.secondaryweapon )
        {
            var_3 = getweaponattachments( var_2 );

            foreach ( var_5 in var_3 )
            {
                if ( istogglescope( var_5 ) )
                {
                    self.pers["toggleScopeStates"][var_2] = self gethybridscopestate( var_2 );
                    break;
                }
            }
        }
    }
}

updatetogglescopestate( var_0 )
{
    if ( isdefined( self.pers["toggleScopeStates"] ) && isdefined( self.pers["toggleScopeStates"][var_0] ) )
        self sethybridscopestate( var_0, self.pers["toggleScopeStates"][var_0] );
}

istogglescope( var_0 )
{
    var_1 = undefined;

    if ( var_0 == "thermalsniper" )
        var_1 = 0;
    else if ( var_0 == "dlcweap02scope" )
        var_1 = 1;
    else
    {
        var_2 = maps\mp\_utility::attachmentmap_tobase( var_0 );

        switch ( var_2 )
        {
            case "tracker":
            case "thermal":
            case "hybrid":
                var_1 = 1;
                break;
            default:
                var_1 = 0;
                break;
        }
    }

    return var_1;
}

sniperdustwatcher()
{
    self endon( "death" );
    self endon( "disconnect" );
    level endon( "game_ended" );
    var_0 = undefined;

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

        if ( self getstance() != "prone" )
            continue;

        if ( maps\mp\_utility::getweaponclass( self getcurrentweapon() ) != "weapon_sniper" )
            continue;

        var_1 = anglestoforward( self.angles );

        if ( !isdefined( var_0 ) || gettime() - var_0 > 2000 )
        {
            playfx( level._effect["sniperDustLarge"], self.origin + ( 0, 0, 10 ) + var_1 * 50, var_1 );
            var_0 = gettime();
            continue;
        }

        playfx( level._effect["sniperDustLargeSuppress"], self.origin + ( 0, 0, 10 ) + var_1 * 50, var_1 );
    }
}

watchstingerusage()
{
    maps\mp\_stinger::stingerusageloop();
}

watchjavelinusage()
{
    maps\mp\_javelin::javelinusageloop();
}

weaponperkudpate( var_0, var_1, var_2 )
{
    var_3 = undefined;

    if ( isdefined( var_0 ) && var_0 != "none" )
    {
        var_0 = maps\mp\_utility::getbaseweaponname( var_0 );
        var_3 = maps\mp\_utility::weaponperkmap( var_0 );

        if ( isdefined( var_3 ) && !maps\mp\_utility::_hasperk( var_3 ) )
            maps\mp\_utility::giveperk( var_3, 0 );
    }

    if ( isdefined( var_1 ) && var_1 != "none" )
    {
        var_1 = maps\mp\_utility::getbaseweaponname( var_1 );
        var_4 = maps\mp\_utility::weaponperkmap( var_1 );

        if ( isdefined( var_4 ) && ( !isdefined( var_3 ) || var_4 != var_3 ) && maps\mp\_utility::_hasperk( var_4 ) && ( !isdefined( var_2 ) || !common_scripts\utility::array_contains( var_2, var_4 ) ) )
            maps\mp\_utility::_unsetperk( var_4 );
    }
}

weaponattachmentperkupdate( var_0, var_1 )
{
    var_2 = undefined;
    var_3 = undefined;
    var_4 = undefined;

    if ( isdefined( var_0 ) && var_0 != "none" )
    {
        var_2 = getweaponattachments( var_0 );

        if ( isdefined( var_2 ) && var_2.size > 0 )
        {
            var_4 = [];

            foreach ( var_6 in var_2 )
            {
                var_7 = maps\mp\_utility::attachmentperkmap( var_6 );

                if ( !isdefined( var_7 ) )
                    continue;

                var_4[var_4.size] = var_7;

                if ( !maps\mp\_utility::_hasperk( var_7 ) )
                    maps\mp\_utility::giveperk( var_7, 0 );
            }
        }
    }

    if ( isdefined( var_1 ) && var_1 != "none" )
    {
        var_3 = getweaponattachments( var_1 );

        if ( isdefined( var_3 ) && var_3.size > 0 )
        {
            foreach ( var_10 in var_3 )
            {
                var_7 = maps\mp\_utility::attachmentperkmap( var_10 );

                if ( !isdefined( var_7 ) )
                    continue;

                if ( ( !isdefined( var_4 ) || !common_scripts\utility::array_contains( var_4, var_7 ) ) && maps\mp\_utility::_hasperk( var_7 ) )
                    maps\mp\_utility::_unsetperk( var_7 );
            }
        }
    }

    return var_4;
}

watchweaponperkupdates()
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );
    var_0 = undefined;
    var_1 = self getcurrentweapon();
    var_2 = weaponattachmentperkupdate( var_1, var_0 );
    weaponperkudpate( var_1, var_0, var_2 );

    for (;;)
    {
        var_0 = var_1;
        common_scripts\utility::waittill_any( "weapon_change", "giveLoadout" );
        var_1 = self getcurrentweapon();
        var_2 = weaponattachmentperkupdate( var_1, var_0 );
        weaponperkudpate( var_1, var_0, var_2 );
    }
}

lethalstowed_clear()
{
    self.loadoutperkequipmentstowedammo = undefined;
    self.loadoutperkequipmentstowed = undefined;
}

hasunderbarrelweapon()
{
    var_0 = 0;
    var_1 = self getweaponslistprimaries();

    foreach ( var_3 in var_1 )
    {
        if ( weaponaltweaponname( var_3 ) != "none" )
        {
            var_0 = 1;
            break;
        }
    }

    return var_0;
}

lethalstowed_updatelethalsonweaponchange()
{
    if ( self.loadoutperkequipment != "specialty_null" )
    {
        if ( hasunderbarrelweapon() )
        {
            self.loadoutperkequipmentstowedammo = self getweaponammoclip( self.loadoutperkequipment );
            self.loadoutperkequipmentstowed = self.loadoutperkequipment;
            self takeweapon( self.loadoutperkequipment );
            self.loadoutperkequipment = "specialty_null";
            maps\mp\_utility::giveperkequipment( "specialty_null", 0 );
        }
    }
    else if ( isdefined( self.loadoutperkequipmentstowed ) && !hasunderbarrelweapon() )
    {
        maps\mp\_utility::giveperkequipment( self.loadoutperkequipmentstowed, 1 );
        self setweaponammoclip( self.loadoutperkequipmentstowed, self.loadoutperkequipmentstowedammo );
        self.loadoutperkequipment = self.loadoutperkequipmentstowed;
        lethalstowed_clear();
    }
}

watchweaponchange()
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );
    childthread watchstartweaponchange();
    self.lastdroppableweapon = self.currentweaponatspawn;
    self.hitsthismag = [];
    var_0 = self getcurrentweapon();

    if ( maps\mp\_utility::iscacprimaryweapon( var_0 ) && !isdefined( self.hitsthismag[var_0] ) )
        self.hitsthismag[var_0] = weaponclipsize( var_0 );

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

        if ( var_0 == "none" )
            continue;

        if ( var_0 == "briefcase_bomb_mp" || var_0 == "briefcase_bomb_defuse_mp" )
            continue;

        lethalstowed_updatelethalsonweaponchange();

        if ( maps\mp\_utility::iskillstreakweapon( var_0 ) )
        {
            if ( ( maps\mp\_utility::isjuggernaut() || maps\mp\killstreaks\_killstreaks::isminigun( var_0 ) || self getcurrentweapon() == "venomxgun_mp" ) && !maps\mp\killstreaks\_killstreaks::isairdropmarker( var_0 ) )
            {
                if ( isdefined( self.changingweapon ) )
                {
                    waittillframeend;
                    self.changingweapon = undefined;
                }
            }

            continue;
        }

        var_1 = strtok( var_0, "_" );

        if ( var_1[0] == "alt" )
        {
            var_2 = getsubstr( var_0, 4 );
            var_0 = var_2;
            var_1 = strtok( var_0, "_" );
        }
        else if ( var_1[0] != "iw5" && var_1[0] != "iw6" )
            var_0 = var_1[0];

        if ( var_0 != "none" && var_1[0] != "iw5" && var_1[0] != "iw6" )
        {
            if ( maps\mp\_utility::iscacprimaryweapon( var_0 ) && !isdefined( self.hitsthismag[var_0 + "_mp"] ) )
                self.hitsthismag[var_0 + "_mp"] = weaponclipsize( var_0 + "_mp" );
        }
        else if ( var_0 != "none" && ( var_1[0] == "iw5" || var_1[0] == "iw6" ) )
        {
            if ( maps\mp\_utility::iscacprimaryweapon( var_0 ) && !isdefined( self.hitsthismag[var_0] ) )
                self.hitsthismag[var_0] = weaponclipsize( var_0 );
        }

        self.changingweapon = undefined;

        if ( var_1[0] == "iw5" || var_1[0] == "iw6" )
        {
            self.lastdroppableweapon = var_0;
            continue;
        }

        if ( var_0 != "none" && maydropweapon( var_0 + "_mp" ) )
            self.lastdroppableweapon = var_0 + "_mp";
    }
}

watchsniperboltactionkills()
{
    self endon( "death" );
    self endon( "disconnect" );
    thread watchsniperboltactionkills_ondeath();

    if ( !isdefined( self.pers["recoilReduceKills"] ) )
        self.pers["recoilReduceKills"] = 0;

    self setclientomnvar( "weap_sniper_display_state", self.pers["recoilReduceKills"] );

    for (;;)
    {
        self waittill( "got_a_kill", var_0, var_1, var_2 );

        if ( isrecoilreducingweapon( var_1 ) )
        {
            var_3 = self.pers["recoilReduceKills"] + 1;
            self.pers["recoilReduceKills"] = int( min( var_3, 4 ) );
            self setclientomnvar( "weap_sniper_display_state", self.pers["recoilReduceKills"] );

            if ( var_3 <= 4 )
                stancerecoilupdate( self getstance() );
        }
    }
}

watchsniperboltactionkills_ondeath()
{
    self notify( "watchSniperBoltActionKills_onDeath" );
    self endon( "watchSniperBoltActionKills_onDeath" );
    self endon( "disconnect" );
    self waittill( "death" );
    self.pers["recoilReduceKills"] = 0;
}

isrecoilreducingweapon( var_0 )
{
    if ( !isdefined( var_0 ) || var_0 == "none" )
        return 0;

    var_1 = 0;

    if ( issubstr( var_0, "l115a3scope" ) || issubstr( var_0, "l115a3vzscope" ) || issubstr( var_0, "usrscope" ) || issubstr( var_0, "usrvzscope" ) )
        var_1 = 1;

    return var_1;
}

getrecoilreductionvalue()
{
    if ( !isdefined( self.pers["recoilReduceKills"] ) )
        self.pers["recoilReduceKills"] = 0;

    return self.pers["recoilReduceKills"] * 3;
}

watchstartweaponchange()
{
    self endon( "death" );
    self endon( "disconnect" );
    self.changingweapon = undefined;

    for (;;)
    {
        self waittill( "weapon_switch_started", var_0 );
        thread makesureweaponchanges( self getcurrentweapon() );
        self.changingweapon = var_0;

        if ( var_0 == "none" && isdefined( self.iscapturingcrate ) && self.iscapturingcrate )
        {
            while ( self.iscapturingcrate )
                wait 0.05;

            self.changingweapon = undefined;
        }
    }
}

makesureweaponchanges( var_0 )
{
    self endon( "weapon_switch_started" );
    self endon( "weapon_change" );
    self endon( "disconnect" );
    self endon( "death" );
    level endon( "game_ended" );

    if ( maps\mp\_utility::iskillstreakweapon( var_0 ) )
        return;

    wait 1.0;
    self.changingweapon = undefined;
}

ishackweapon( var_0 )
{
    if ( var_0 == "radar_mp" || var_0 == "airstrike_mp" || var_0 == "helicopter_mp" )
        return 1;

    if ( var_0 == "briefcase_bomb_mp" )
        return 1;

    return 0;
}

maydropweapon( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    if ( issubstr( var_0, "ac130" ) )
        return 0;

    if ( issubstr( var_0, "uav" ) )
        return 0;

    if ( issubstr( var_0, "killstreak" ) )
        return 0;

    var_1 = weaponinventorytype( var_0 );

    if ( var_1 != "primary" )
        return 0;

    return 1;
}

dropweaponfordeath( var_0, var_1 )
{
    if ( isdefined( level.blockweapondrops ) )
        return;

    if ( isdefined( self.droppeddeathweapon ) )
        return;

    if ( level.ingraceperiod )
        return;

    var_2 = self.lastdroppableweapon;

    if ( !isdefined( var_2 ) )
        return;

    if ( var_2 == "none" )
        return;

    if ( !self hasweapon( var_2 ) )
        return;

    if ( maps\mp\_utility::isjuggernaut() )
        return;

    if ( isdefined( level.gamemodemaydropweapon ) && !self [[ level.gamemodemaydropweapon ]]( var_2 ) )
        return;

    var_3 = strtok( var_2, "_" );

    if ( var_3[0] == "alt" )
    {
        for ( var_4 = 1; var_4 < var_3.size; var_4++ )
        {
            if ( var_4 > 1 )
                var_2 = var_2 + "_";

            var_2 = var_2 + var_3[var_4];
        }
    }

    if ( var_2 != "iw6_riotshield_mp" )
    {
        if ( !self anyammoforweaponmodes( var_2 ) )
            return;

        var_5 = self getweaponammoclip( var_2, "right" );
        var_6 = self getweaponammoclip( var_2, "left" );

        if ( !var_5 && !var_6 )
            return;

        var_7 = self getweaponammostock( var_2 );
        var_8 = weaponmaxammo( var_2 );

        if ( var_7 > var_8 )
            var_7 = var_8;

        var_9 = self dropitem( var_2 );

        if ( !isdefined( var_9 ) )
            return;

        var_9 itemweaponsetammo( var_5, var_7, var_6 );
    }
    else
    {
        var_9 = self dropitem( var_2 );

        if ( !isdefined( var_9 ) )
            return;

        var_9 itemweaponsetammo( 1, 1, 0 );
    }

    self.droppeddeathweapon = 1;
    var_9.owner = self;
    var_9.ownersattacker = var_0;
    var_9.targetname = "dropped_weapon";
    var_9 thread watchpickup();
    var_9 thread deletepickupafterawhile();
}

detachifattached( var_0, var_1 )
{
    var_2 = self getattachsize();

    for ( var_3 = 0; var_3 < var_2; var_3++ )
    {
        var_4 = self getattachmodelname( var_3 );

        if ( var_4 != var_0 )
            continue;

        var_5 = self getattachtagname( var_3 );
        self detach( var_0, var_5 );

        if ( var_5 != var_1 )
        {
            var_2 = self getattachsize();

            for ( var_3 = 0; var_3 < var_2; var_3++ )
            {
                var_5 = self getattachtagname( var_3 );

                if ( var_5 != var_1 )
                    continue;

                var_0 = self getattachmodelname( var_3 );
                self detach( var_0, var_5 );
                break;
            }
        }

        return 1;
    }

    return 0;
}

deletepickupafterawhile()
{
    self endon( "death" );
    wait 60;

    if ( !isdefined( self ) )
        return;

    self delete();
}

getitemweaponname()
{
    var_0 = self.classname;
    var_1 = getsubstr( var_0, 7 );
    return var_1;
}

watchpickup()
{
    self endon( "death" );
    var_0 = getitemweaponname();

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

        if ( isdefined( var_2 ) )
            break;
    }

    var_3 = var_2 getitemweaponname();

    if ( isdefined( var_1.primaryweapon ) && var_1.primaryweapon == var_3 )
        var_1.primaryweapon = var_0;

    if ( isdefined( var_1.secondaryweapon ) && var_1.secondaryweapon == var_3 )
        var_1.secondaryweapon = var_0;

    if ( isdefined( var_1.tookweaponfrom[var_3] ) )
    {
        var_2.owner = var_1.tookweaponfrom[var_3];
        var_2.ownersattacker = var_1;
        var_1.tookweaponfrom[var_3] = undefined;
    }

    var_2.targetname = "dropped_weapon";
    var_2 thread watchpickup();

    if ( isdefined( self.ownersattacker ) && self.ownersattacker == var_1 )
        var_1.tookweaponfrom[var_0] = self.owner;
    else
        var_1.tookweaponfrom[var_0] = undefined;
}

itemremoveammofromaltmodes()
{
    var_0 = getitemweaponname();
    var_1 = weaponaltweaponname( var_0 );

    for ( var_2 = 1; var_1 != "none" && var_1 != var_0; var_2++ )
    {
        self itemweaponsetammo( 0, 0, 0, var_2 );
        var_1 = weaponaltweaponname( var_1 );
    }
}

handlescavengerbagpickup( var_0 )
{
    self endon( "death" );
    level endon( "game_ended" );
    self waittill( "scavenger", var_1 );
    var_1 notify( "scavenger_pickup" );
    scavengergiveammo( var_1 );
    var_1 maps\mp\gametypes\_damagefeedback::hudicontype( "scavenger" );
}

scavengergiveammo( var_0 )
{
    var_1 = var_0 getweaponslistoffhands();

    foreach ( var_3 in var_1 )
    {
        if ( !isthrowingknife( var_3 ) )
            continue;

        var_4 = common_scripts\utility::ter_op( var_0 maps\mp\_utility::_hasperk( "specialty_extra_deadly" ), 2, 1 );
        var_5 = var_0 getweaponammoclip( var_3 );

        if ( var_5 + 1 <= var_4 )
            var_0 setweaponammoclip( var_3, var_5 + 1 );
    }

    var_7 = var_0 getweaponslistprimaries();

    foreach ( var_9 in var_7 )
    {
        if ( !maps\mp\_utility::iscacprimaryweapon( var_9 ) && !level.scavenger_secondary )
            continue;

        if ( issubstr( var_9, "alt_" ) && issubstr( var_9, "_gl" ) )
            continue;

        if ( maps\mp\_utility::getweaponclass( var_9 ) == "weapon_projectile" )
            continue;

        if ( var_9 == "venomxgun_mp" )
            continue;

        var_10 = var_0 getweaponammostock( var_9 );
        var_11 = weaponclipsize( var_9 );
        var_0 setweaponammostock( var_9, var_10 + var_11 );
    }
}

dropscavengerfordeath( var_0 )
{
    if ( level.ingraceperiod )
        return;

    if ( !isdefined( var_0 ) )
        return;

    if ( var_0 == self )
        return;

    var_1 = self dropscavengerbag( "scavenger_bag_mp" );
    var_1 thread handlescavengerbagpickup( self );

    if ( isdefined( level.bot_funcs["bots_add_scavenger_bag"] ) )
        [[ level.bot_funcs["bots_add_scavenger_bag"] ]]( var_1 );
}

setweaponstat( var_0, var_1, var_2 )
{
    maps\mp\gametypes\_gamelogic::setweaponstat( var_0, var_1, var_2 );
}

watchweaponusage( var_0 )
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );
    level endon( "game_ended" );

    if ( isai( self ) )
        return;

    for (;;)
    {
        self waittill( "weapon_fired", var_1 );
        var_1 = self getcurrentweapon();
        maps\mp\gametypes\_gamelogic::sethasdonecombat( self, 1 );
        self.lastshotfiredtime = gettime();

        if ( !maps\mp\_utility::iscacprimaryweapon( var_1 ) && !maps\mp\_utility::iscacsecondaryweapon( var_1 ) )
            continue;

        if ( isdefined( self.hitsthismag[var_1] ) )
            thread updatemagshots( var_1 );

        var_2 = maps\mp\gametypes\_persistence::statgetbuffered( "totalShots" ) + 1;
        var_3 = maps\mp\gametypes\_persistence::statgetbuffered( "hits" );
        var_4 = clamp( float( var_3 ) / float( var_2 ), 0.0, 1.0 ) * 10000.0;

        if ( !issquadsmode() )
        {
            maps\mp\gametypes\_persistence::statsetbuffered( "totalShots", var_2 );
            maps\mp\gametypes\_persistence::statsetbuffered( "accuracy", int( var_4 ) );
            maps\mp\gametypes\_persistence::statsetbuffered( "misses", int( var_2 - var_3 ) );
        }

        if ( isdefined( self.laststandparams ) && self.laststandparams.laststandstarttime == gettime() )
        {
            self.hits = 0;
            return;
        }

        var_5 = 1;
        setweaponstat( var_1, var_5, "shots" );
        setweaponstat( var_1, self.hits, "hits" );
        self.hits = 0;
    }
}

updatemagshots( var_0 )
{
    if ( !maps\mp\_utility::is_aliens() )
        updatemagshots_regularmp( var_0 );
}

updatemagshots_regularmp( var_0 )
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "updateMagShots_" + var_0 );
    self.hitsthismag[var_0]--;
    wait 0.05;
    self.hitsthismag[var_0] = weaponclipsize( var_0 );
}

checkhitsthismag( var_0 )
{
    if ( !maps\mp\_utility::is_aliens() )
        checkhitsthismag_regularmp( var_0 );
}

checkhitsthismag_regularmp( var_0 )
{
    self endon( "death" );
    self endon( "disconnect" );
    self notify( "updateMagShots_" + var_0 );
    waittillframeend;

    if ( isdefined( self.hitsthismag[var_0] ) && self.hitsthismag[var_0] == 0 )
    {
        var_1 = maps\mp\_utility::getweaponclass( var_0 );
        maps\mp\gametypes\_missions::genericchallenge( var_1 );
        self.hitsthismag[var_0] = weaponclipsize( var_0 );
    }
}

checkhit( var_0, var_1 )
{
    self endon( "disconnect" );

    if ( maps\mp\_utility::isstrstart( var_0, "alt_" ) )
    {
        var_2 = maps\mp\_utility::getweaponattachmentsbasenames( var_0 );

        if ( common_scripts\utility::array_contains( var_2, "shotgun" ) || common_scripts\utility::array_contains( var_2, "gl" ) )
            self.hits = 1;
        else
            var_0 = getsubstr( var_0, 4 );
    }

    if ( !isprimaryweapon( var_0 ) && !issidearm( var_0 ) )
        return;

    if ( self meleebuttonpressed() && var_0 != "iw6_knifeonly_mp" && var_0 != "iw6_knifeonlyfast_mp" )
        return;

    switch ( weaponclass( var_0 ) )
    {
        case "smg":
        case "mg":
        case "pistol":
        case "rifle":
        case "sniper":
            self.hits++;
            break;
        case "spread":
            self.hits = 1;
            break;
        default:
            break;
    }

    if ( isriotshield( var_0 ) || var_0 == "iw6_knifeonly_mp" || var_0 == "iw6_knifeonlyfast_mp" )
    {
        thread maps\mp\gametypes\_gamelogic::threadedsetweaponstatbyname( var_0, self.hits, "hits" );
        self.hits = 0;
    }

    waittillframeend;

    if ( isdefined( self.hitsthismag[var_0] ) )
        thread checkhitsthismag( var_0 );

    if ( !isdefined( self.lasthittime[var_0] ) )
        self.lasthittime[var_0] = 0;

    if ( self.lasthittime[var_0] == gettime() )
        return;

    self.lasthittime[var_0] = gettime();

    if ( !issquadsmode() )
    {
        var_3 = maps\mp\gametypes\_persistence::statgetbuffered( "totalShots" );
        var_4 = maps\mp\gametypes\_persistence::statgetbuffered( "hits" ) + 1;

        if ( var_4 <= var_3 )
        {
            maps\mp\gametypes\_persistence::statsetbuffered( "hits", var_4 );
            maps\mp\gametypes\_persistence::statsetbuffered( "misses", int( var_3 - var_4 ) );
            var_5 = clamp( float( var_4 ) / float( var_3 ), 0.0, 1.0 ) * 10000.0;
            maps\mp\gametypes\_persistence::statsetbuffered( "accuracy", int( var_5 ) );
        }
    }
}

attackercandamageitem( var_0, var_1 )
{
    return friendlyfirecheck( var_1, var_0 );
}

friendlyfirecheck( var_0, var_1, var_2 )
{
    if ( !isdefined( var_0 ) )
        return 1;

    if ( !level.teambased )
        return 1;

    var_3 = var_1.team;
    var_4 = level.friendlyfire;

    if ( isdefined( var_2 ) )
        var_4 = var_2;

    if ( var_4 != 0 )
        return 1;

    if ( var_1 == var_0 )
        return !maps\mp\_utility::is_aliens();

    if ( !isdefined( var_3 ) )
        return 1;

    if ( var_3 != var_0.team )
        return 1;

    return 0;
}

watchgrenadeusage()
{
    self notify( "watchGrenadeUsage" );
    self endon( "watchGrenadeUsage" );
    self endon( "spawned_player" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );
    self.throwinggrenade = undefined;
    self.gotpullbacknotify = 0;

    if ( maps\mp\_utility::getintproperty( "scr_deleteexplosivesonspawn", 1 ) == 1 )
    {
        if ( isdefined( self.dont_delete_grenades_on_next_spawn ) )
            self.dont_delete_grenades_on_next_spawn = undefined;
        else
            delete_all_grenades();
    }
    else if ( !isdefined( self.plantedlethalequip ) )
    {
        self.plantedlethalequip = [];
        self.plantedtacticalequip = [];
    }

    thread watchforthrowbacks();

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

        if ( !maps\mp\_utility::is_aliens() )
            setweaponstat( var_0, 1, "shots" );

        maps\mp\gametypes\_gamelogic::sethasdonecombat( self, 1 );
        thread watchoffhandcancel();
        self.throwinggrenade = var_0;
        self.gotpullbacknotify = 1;

        if ( var_0 == "c4_mp" )
            thread beginc4tracking();

        begingrenadetracking();
        self.throwinggrenade = undefined;
    }
}

begingrenadetracking()
{
    self endon( "offhand_end" );
    self endon( "weapon_change" );
    var_0 = gettime();
    var_1 = maps\mp\_utility::waittill_grenade_fire();

    if ( !isdefined( var_1 ) )
        return;

    if ( !isdefined( var_1.weapon_name ) )
        return;

    self.changingweapon = undefined;

    if ( isdefined( level.bomb_squad[var_1.weapon_name] ) )
        var_1 thread createbombsquadmodel( level.bomb_squad[var_1.weapon_name].model, level.bomb_squad[var_1.weapon_name].tag, self );

    switch ( var_1.weapon_name )
    {
        case "thermobaric_grenade_mp":
        case "frag_grenade_mp":
            if ( gettime() - var_0 > 1000 )
                var_1.iscooked = 1;

            var_1 thread maps\mp\gametypes\_shellshock::grenade_earthquake();
            var_1.originalowner = self;
            break;
        case "iw6_aliendlc43_mp":
        case "iw6_aliendlc22_mp":
        case "mortar_shell_mp":
            var_1 thread maps\mp\gametypes\_shellshock::grenade_earthquake();
            var_1.originalowner = self;
            break;
        case "aliensemtex_mp":
        case "semtex_mp":
            thread semtexused( var_1 );
            break;
        case "c4_mp":
            thread c4used( var_1 );
            break;
        case "proximity_explosive_mp":
            thread proximityexplosiveused( var_1 );
            break;
        case "flash_grenade_mp":
            var_2 = gettime() - var_0;
            var_1.ninebangticks = 1;

            if ( var_2 > 1000 )
            {
                var_1.iscooked = 1;
                var_1.ninebangticks = var_1.ninebangticks + min( int( var_2 / 875 ), 5 );
            }

            var_1 thread ninebangexplodewaiter();
            break;
        case "smoke_grenadejugg_mp":
        case "smoke_grenade_mp":
            var_1 thread watchsmokeexplode();
            break;
        case "alientrophy_mp":
        case "trophy_mp":
            thread maps\mp\gametypes\_trophy_system::trophyused( var_1 );
            break;
        case "alienclaymore_mp":
        case "claymore_mp":
            thread claymoreused( var_1 );
            break;
        case "alienbetty_mp":
        case "bouncingbetty_mp":
            thread mineused( var_1, ::spawnmine );
            break;
        case "motion_sensor_mp":
            thread mineused( var_1, ::spawnmotionsensor );
            break;
        case "throwingknifejugg_mp":
        case "throwingknife_mp":
            level thread throwingknifeused( self, var_1, var_1.weapon_name );
            break;
    }
}

throwingknifeused( var_0, var_1, var_2 )
{
    level endon( "game_ended" );
    var_1 waittill( "missile_stuck", var_3 );
    var_1 endon( "death" );
    var_1 makeunusable();
    var_4 = spawn( "trigger_radius", var_1.origin, 0, 64, 64 );
    var_4 enablelinkto();
    var_4 linkto( var_1 );
    var_4.targetname = "dropped_knife";
    var_1.knife_trigger = var_4;
    var_1 thread watchgrenadedeath();

    for (;;)
    {
        common_scripts\utility::waitframe();

        if ( !isdefined( var_4 ) )
            return;

        var_4 waittill( "trigger", var_5 );

        if ( !isplayer( var_5 ) || !maps\mp\_utility::isreallyalive( var_5 ) )
            continue;

        if ( !var_5 hasweapon( var_2 ) )
            continue;

        var_6 = var_5 getweaponammoclip( var_2 );
        var_7 = var_5 maps\mp\_utility::_hasperk( "specialty_extra_deadly" );

        if ( var_7 && var_6 == 2 )
            continue;

        if ( !var_7 && var_6 == 1 )
            continue;

        var_5 setweaponammoclip( var_2, var_6 + 1 );
        var_5 thread maps\mp\gametypes\_damagefeedback::hudicontype( "throwingknife" );
        var_1 delete();
        break;
    }
}

watchgrenadedeath()
{
    self waittill( "death" );

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

watchoffhandcancel()
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );
    self endon( "grenade_fire" );
    self waittill( "offhand_end" );

    if ( isdefined( self.changingweapon ) && self.changingweapon != self getcurrentweapon() )
        self.changingweapon = undefined;
}

watchsmokeexplode()
{
    level endon( "smokeTimesUp" );
    var_0 = self.owner;
    var_0 endon( "disconnect" );
    self waittill( "explode", var_1 );
    var_2 = 128;
    var_3 = 8;
    level thread waitsmoketime( var_3, var_2, var_1 );

    for (;;)
    {
        if ( !isdefined( var_0 ) )
            break;

        foreach ( var_5 in level.players )
        {
            if ( !isdefined( var_5 ) )
                continue;

            if ( level.teambased && var_5.team == var_0.team )
                continue;

            if ( distancesquared( var_5.origin, var_1 ) < var_2 * var_2 )
            {
                var_5.inplayersmokescreen = var_0;
                continue;
            }

            var_5.inplayersmokescreen = undefined;
        }

        wait 0.05;
    }
}

waitsmoketime( var_0, var_1, var_2 )
{
    maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_0 );
    level notify( "smokeTimesUp" );
    waittillframeend;

    foreach ( var_4 in level.players )
    {
        if ( isdefined( var_4 ) )
            var_4.inplayersmokescreen = undefined;
    }
}

lockonlaunchers_gettargetarray()
{
    var_0 = [];

    if ( level.teambased )
    {
        if ( isdefined( level.chopper ) && ( level.chopper.team != self.team || isdefined( level.chopper.owner ) && level.chopper.owner == self ) )
            var_0[var_0.size] = level.chopper;

        if ( isdefined( level.littlebirds ) )
        {
            foreach ( var_2 in level.littlebirds )
            {
                if ( isdefined( var_2 ) && ( var_2.team != self.team || isdefined( var_2.owner ) && var_2.owner == self ) )
                    var_0[var_0.size] = var_2;
            }
        }

        if ( isdefined( level.balldrones ) )
        {
            foreach ( var_5 in level.balldrones )
            {
                if ( isdefined( var_5 ) && ( var_5.team != self.team || isdefined( var_5.owner ) && var_5.owner == self ) )
                    var_0[var_0.size] = var_5;
            }
        }

        if ( isdefined( level.harriers ) )
        {
            foreach ( var_8 in level.harriers )
            {
                if ( isdefined( var_8 ) && ( var_8.team != self.team || isdefined( var_8.owner ) && var_8.owner == self ) )
                    var_0[var_0.size] = var_8;
            }
        }
    }
    else
    {
        if ( isdefined( level.chopper ) )
            var_0[var_0.size] = level.chopper;

        if ( isdefined( level.littlebirds ) )
        {
            foreach ( var_2 in level.littlebirds )
            {
                if ( !isdefined( var_2 ) )
                    continue;

                var_0[var_0.size] = var_2;
            }
        }

        if ( isdefined( level.balldrones ) )
        {
            foreach ( var_5 in level.balldrones )
            {
                if ( !isdefined( var_5 ) )
                    continue;

                var_0[var_0.size] = var_5;
            }
        }

        if ( isdefined( level.harriers ) )
        {
            foreach ( var_8 in level.harriers )
            {
                if ( !isdefined( var_8 ) )
                    continue;

                var_0[var_0.size] = var_8;
            }
        }
    }

    return var_0;
}

watchmissileusage()
{
    self endon( "disconnect" );

    for (;;)
    {
        var_0 = maps\mp\_utility::waittill_missile_fire();

        if ( issubstr( var_0.weapon_name, "gl_" ) )
        {
            var_0.primaryweapon = self getcurrentprimaryweapon();
            var_0 thread maps\mp\gametypes\_shellshock::grenade_earthquake();
        }

        switch ( var_0.weapon_name )
        {
            case "stinger_mp":
            case "iw5_smaw_mp":
            case "at4_mp":
                level notify( "stinger_fired", self, var_0, self.stingertarget );
                break;
            case "javelin_mp":
            case "lasedStrike_missile_mp":
            case "remote_mortar_missile_mp":
                level notify( "stinger_fired", self, var_0, self.javelintarget );
                break;
            default:
                break;
        }

        switch ( var_0.weapon_name )
        {
            case "remotemissile_projectile_mp":
            case "ac130_40mm_mp":
            case "ac130_105mm_mp":
            case "lasedStrike_missile_mp":
            case "remote_mortar_missile_mp":
            case "iw6_panzerfaust3_mp":
            case "iw6_maaws_mp":
                var_0 thread maps\mp\gametypes\_shellshock::grenade_earthquake();
            default:
                break;
        }
    }
}

watchhitbymissile()
{
    self endon( "disconnect" );

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

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

        if ( level.teambased && self.team == var_0.team )
        {
            self cancelrocketcorpse( var_1, var_3, var_4, var_5, var_6, var_7 );
            continue;
        }

        if ( var_2 != "rpg_mp" )
        {
            self cancelrocketcorpse( var_1, var_3, var_4, var_5, var_6, var_7 );
            continue;
        }

        if ( randomintrange( 0, 100 ) < 99 )
        {
            self cancelrocketcorpse( var_1, var_3, var_4, var_5, var_6, var_7 );
            continue;
        }

        var_8 = getdvarfloat( "rocket_corpse_max_air_time", 0.5 );
        var_9 = getdvarfloat( "rocket_corpse_view_offset_up", 100 );
        var_10 = getdvarfloat( "rocket_corpse_view_offset_forward", 35 );
        self.isrocketcorpse = 1;
        self setcontents( 0 );
        var_11 = self setrocketcorpse( 1 );
        var_12 = var_11 / 1000.0;
        self.killcament = spawn( "script_model", var_1.origin );
        self.killcament.angles = var_1.angles;
        self.killcament linkto( var_1 );
        self.killcament setscriptmoverkillcam( "rocket_corpse" );
        self.killcament setcontents( 0 );
        self dodamage( 1000, self.origin, var_0, var_1 );
        self.body = self cloneplayer( var_11 );
        self.body.origin = var_1.origin;
        self.body.angles = var_1.angles;
        self.body.targetname = "player_corpse";
        self.body setcorpsefalling( 0 );
        self.body enablelinkto();
        self.body linkto( var_1 );
        self.body setcontents( 0 );

        if ( !isdefined( self.switching_teams ) )
            thread maps\mp\gametypes\_deathicons::adddeathicon( self.body, self, self.team, 5.0 );

        self playerhide();
        var_13 = vectornormalize( anglestoup( var_1.angles ) );
        var_14 = vectornormalize( anglestoforward( var_1.angles ) );
        var_15 = var_14 * var_9 + var_13 * var_10;
        var_16 = var_1.origin + var_15;
        var_17 = spawn( "script_model", var_16 );
        var_17 setmodel( "tag_origin" );
        var_17.angles = vectortoangles( var_1.origin - var_17.origin );
        var_17 linkto( var_1 );
        var_17 setcontents( 0 );
        self cameralinkto( var_17, "tag_origin" );

        if ( var_8 > var_12 )
            var_8 = var_12;

        var_18 = var_1 common_scripts\utility::waittill_notify_or_timeout_return( "death", var_8 );

        if ( isdefined( var_18 ) && var_18 == "timeout" && isdefined( var_1 ) )
            var_1 detonate();

        self notify( "final_rocket_corpse_death" );
        self.body unlink();
        self.body setcorpsefalling( 1 );
        self.body startragdoll();
        var_17 linkto( self.body );
        self.isrocketcorpse = undefined;
        self waittill( "death_delay_finished" );
        self cameraunlink();
        self.killcament delete();
        var_17 delete();
    }
}

watchsentryusage()
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );

    for (;;)
    {
        self waittill( "sentry_placement_finished", var_0 );
        thread maps\mp\_utility::setaltsceneobj( var_0, "tag_flash", 65 );
    }
}

ninebangexplodewaiter()
{
    thread maps\mp\gametypes\_shellshock::endondeath();
    self endon( "end_explode" );
    self waittill( "explode", var_0 );
    thread doninebang( var_0, self.owner, self.ninebangticks );
    ninebangdoempdamage( var_0, self.owner, self.ninebangticks );
}

ninebangdoempdamage( var_0, var_1, var_2 )
{
    if ( var_2 >= 5 || pitchercheck( var_1, var_2 ) )
    {
        playsoundatpos( var_0, "weap_emp_explode" );
        var_3 = getempdamageents( var_0, 512, 0 );

        foreach ( var_5 in var_3 )
        {
            if ( isdefined( var_5.owner ) && !friendlyfirecheck( var_1, var_5.owner ) )
                continue;

            var_5 notify( "emp_damage", self.owner, 8.0 );
        }
    }
}

pitchercheck( var_0, var_1 )
{
    if ( var_0 maps\mp\_utility::_hasperk( "specialty_pitcher" ) )
    {
        if ( var_1 >= 4 )
            return 1;
    }

    return 0;
}

doninebang( var_0, var_1, var_2 )
{
    level endon( "game_ended" );
    var_3 = level.weaponconfigs[self.weapon_name];
    wait( randomfloatrange( 0.25, 0.5 ) );

    for ( var_4 = 1; var_4 < var_2; var_4++ )
    {
        var_5 = getninebangsubexplosionpos( var_0, var_3.vfxradius );
        playsoundatpos( var_5, var_3.onexplodesfx );
        playfx( var_3.onexplodevfx, var_5 );

        foreach ( var_7 in level.players )
        {
            if ( !maps\mp\_utility::isreallyalive( var_7 ) || var_7.sessionstate != "playing" )
                continue;

            var_8 = var_7 geteye();
            var_9 = distancesquared( var_0, var_8 );

            if ( var_9 > var_3.radius_max_sq )
                continue;

            if ( !bullettracepassed( var_0, var_8, 0, var_7 ) )
                continue;

            if ( var_9 <= var_3.radius_min_sq )
                var_10 = 1.0;
            else
                var_10 = 1.0 - ( var_9 - var_3.radius_min_sq ) / ( var_3.radius_max_sq - var_3.radius_min_sq );

            var_11 = anglestoforward( var_7 getplayerangles() );
            var_12 = var_0 - var_8;
            var_12 = vectornormalize( var_12 );
            var_13 = 0.5 * ( 1.0 + vectordot( var_11, var_12 ) );
            var_14 = 1;
            var_7 notify( "flashbang", var_0, var_10, var_13, var_1, var_14 );
        }

        wait( randomfloatrange( 0.25, 0.5 ) );
    }
}

getninebangsubexplosionpos( var_0, var_1 )
{
    var_2 = ( randomfloatrange( -1.0 * var_1, var_1 ), randomfloatrange( -1.0 * var_1, var_1 ), 0 );
    var_3 = var_0 + var_2;
    var_4 = bullettrace( var_0, var_3, 0, self, 0, 0, 0, 0, 0 );

    if ( var_4["fraction"] < 1 )
        var_3 = var_0 + var_4["fraction"] * var_2;

    return var_3;
}

beginc4tracking()
{
    self notify( "beginC4Tracking" );
    self endon( "beginC4Tracking" );
    self endon( "death" );
    self endon( "disconnect" );
    common_scripts\utility::waittill_any( "grenade_fire", "weapon_change", "offhand_end" );
    self.changingweapon = undefined;
}

watchforthrowbacks()
{
    self endon( "death" );
    self endon( "disconnect" );

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

        if ( self.gotpullbacknotify )
        {
            self.gotpullbacknotify = 0;
            continue;
        }

        if ( !issubstr( var_1, "frag_" ) && !issubstr( var_1, "mortar_shell" ) )
            continue;

        var_0.threwback = 1;
        thread maps\mp\_utility::incplayerstat( "throwbacks", 1 );
        var_0 thread maps\mp\gametypes\_shellshock::grenade_earthquake();
        var_0.originalowner = self;
    }
}

c4used( var_0 )
{
    if ( !maps\mp\_utility::isreallyalive( self ) )
    {
        var_0 delete();
        return;
    }

    var_0 thread ondetonateexplosive();
    thread watchc4detonation();
    thread watchc4altdetonation();

    if ( !self.plantedlethalequip.size )
        thread watchc4altdetonate();

    var_0 setotherent( self );
    var_0.activated = 0;
    onlethalequipmentplanted( var_0 );
    var_0 thread maps\mp\gametypes\_shellshock::c4_earthquake();
    var_0 thread c4activate();
    var_0 thread c4damage();
    var_0 thread c4empdamage();
    var_0 thread watchc4stuck();
    level thread monitordisownedequipment( self, var_0 );
}

movingplatformdetonate( var_0 )
{
    if ( !isdefined( var_0.lasttouchedplatform ) || !isdefined( var_0.lasttouchedplatform.destroyexplosiveoncollision ) || var_0.lasttouchedplatform.destroyexplosiveoncollision )
        self notify( "detonateExplosive" );
}

watchc4stuck()
{
    self endon( "death" );
    self waittill( "missile_stuck", var_0 );
    makeexplosiveusable();
    makeexplosivetargetablebyai();
    explosivehandlemovers( var_0 );
}

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

    for (;;)
    {
        self waittill( "emp_damage", var_0, var_1 );
        equipmentempstunvfx();
        self.disabled = 1;
        self notify( "disabled" );
        wait( var_1 );
        self.disabled = undefined;
        self notify( "enabled" );
    }
}

proximityexplosiveused( var_0 )
{
    if ( !maps\mp\_utility::isreallyalive( self ) )
    {
        var_0 delete();
        return;
    }

    var_0 waittill( "missile_stuck", var_1 );

    if ( !maps\mp\_utility::isreallyalive( self ) )
    {
        var_0 delete();
        return;
    }

    if ( !isdefined( var_0.owner.team ) )
    {
        var_0 delete();
        return;
    }

    var_2 = anglestoup( var_0.angles );
    var_0.origin = var_0.origin - var_2;
    var_3 = level.weaponconfigs[var_0.weapon_name];
    var_4 = spawn( "script_model", var_0.origin + var_3.killcamoffset * var_2 );
    var_4 setscriptmoverkillcam( "explosive" );
    var_4 linkto( var_0 );
    var_0.killcament = var_4;
    var_0 explosivehandlemovers( var_1 );
    var_0 makeexplosiveusable();
    var_0 makeexplosivetargetablebyai();
    onlethalequipmentplanted( var_0 );
    var_0 thread ondetonateexplosive();
    var_0 thread c4damage();
    var_0 thread proximityexplosiveempstun();
    var_0 thread proximityexplosivetrigger( var_1 );

    if ( !maps\mp\_utility::is_aliens() )
        var_0 thread setclaymoreteamheadicon( self.team, 20 );

    level thread monitordisownedequipment( self, var_0 );
}

proximityexplosivetrigger( var_0 )
{
    self endon( "death" );
    self endon( "disabled" );
    var_1 = level.weaponconfigs[self.weapon_name];
    wait( var_1.armingdelay );
    self playloopsound( "ied_explo_beeps" );
    thread doblinkinglight( "tag_fx" );
    var_2 = self.origin * ( 1, 1, 0 );
    var_3 = var_1.detectionheight / 2;
    var_4 = self.origin[2] - var_3;
    var_2 = var_2 + ( 0, 0, var_4 );
    var_5 = spawn( "trigger_radius", var_2, 0, var_1.detectionradius, var_1.detectionheight );
    var_5.owner = self;

    if ( isdefined( var_0 ) )
    {
        var_5 enablelinkto();
        var_5 linkto( self );
    }

    self.damagearea = var_5;
    thread deleteondeath( var_5 );
    var_6 = undefined;

    for (;;)
    {
        var_5 waittill( "trigger", var_6 );

        if ( !isdefined( var_6 ) )
            continue;

        if ( getdvarint( "scr_minesKillOwner" ) != 1 )
        {
            if ( isdefined( self.owner ) )
            {
                if ( var_6 == self.owner )
                    continue;

                if ( isdefined( var_6.owner ) && var_6.owner == self.owner )
                    continue;
            }

            if ( !friendlyfirecheck( self.owner, var_6, 0 ) )
                continue;
        }

        if ( lengthsquared( var_6 getentityvelocity() ) < 10 )
            continue;

        if ( var_6 damageconetrace( self.origin, self ) > 0 )
            break;
    }

    self stoploopsound( "ied_explo_beeps" );
    self playsound( "ied_warning" );
    explosivetrigger( var_6, var_1.detectiongraceperiod, "proxExplosive" );
    self notify( "detonateExplosive" );
}

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

    for (;;)
    {
        self waittill( "emp_damage", var_0, var_1 );
        equipmentempstunvfx();
        self.disabled = 1;
        self notify( "disabled" );
        proximityexplosivecleanup();
        wait( var_1 );

        if ( isdefined( self ) )
        {
            self.disabled = undefined;
            self notify( "enabled" );
            var_2 = self getlinkedparent();
            thread proximityexplosivetrigger( var_2 );
        }
    }
}

proximityexplosivecleanup()
{
    stopblinkinglight();

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

setclaymoreteamheadicon( var_0, var_1 )
{
    self endon( "death" );
    wait 0.05;

    if ( level.teambased )
        maps\mp\_entityheadicons::setteamheadicon( var_0, ( 0, 0, var_1 ) );
    else if ( isdefined( self.owner ) )
        maps\mp\_entityheadicons::setplayerheadicon( self.owner, ( 0, 0, var_1 ) );
}

claymoreused( var_0 )
{
    if ( !isalive( self ) )
    {
        var_0 delete();
        return;
    }

    var_0 hide();
    var_0 common_scripts\utility::waittill_any_timeout( 0.05, "missile_stuck" );

    if ( !isdefined( self ) || !isalive( self ) )
    {
        var_0 delete();
        return;
    }

    var_1 = 60;
    var_2 = ( 0, 0, 4 );
    var_3 = distancesquared( self.origin, var_0.origin );
    var_4 = distancesquared( self geteye(), var_0.origin );
    var_3 = var_3 + 600;
    var_5 = var_0 getlinkedparent();

    if ( isdefined( var_5 ) )
        var_0 unlink();

    if ( var_3 < var_4 )
    {
        if ( var_1 * var_1 < distancesquared( var_0.origin, self.origin ) )
        {
            var_6 = bullettrace( self.origin, self.origin - ( 0, 0, var_1 ), 0, self );

            if ( var_6["fraction"] == 1 )
            {
                var_0 delete();
                self setweaponammostock( var_0.weapon_name, self getweaponammostock( var_0.weapon_name ) + 1 );
                return;
            }
            else
            {
                var_0.origin = var_6["position"];
                var_5 = var_6["entity"];
            }
        }
        else
        {

        }
    }
    else if ( var_1 * var_1 < distancesquared( var_0.origin, self geteye() ) )
    {
        var_6 = bullettrace( self.origin, self.origin - ( 0, 0, var_1 ), 0, self );

        if ( var_6["fraction"] == 1 )
        {
            var_0 delete();
            self setweaponammostock( var_0.weapon_name, self getweaponammostock( var_0.weapon_name ) + 1 );
            return;
        }
        else
        {
            var_0.origin = var_6["position"];
            var_5 = var_6["entity"];
        }
    }
    else
    {
        var_2 = ( 0, 0, -5 );
        var_0.angles = var_0.angles + ( 0, 180, 0 );
    }

    var_0.angles = var_0.angles * ( 0, 1, 1 );
    var_0.origin = var_0.origin + var_2;
    var_0 explosivehandlemovers( var_5 );
    var_0 show();
    var_0 makeexplosiveusable();
    var_0 makeexplosivetargetablebyai();
    onlethalequipmentplanted( var_0 );
    var_0 thread ondetonateexplosive();
    var_0 thread c4damage();
    var_0 thread c4empdamage();
    var_0 thread claymoredetonation( var_5 );

    if ( !maps\mp\_utility::is_aliens() )
        var_0 thread setclaymoreteamheadicon( self.pers["team"], 20 );

    self.changingweapon = undefined;
    level thread monitordisownedequipment( self, var_0 );
}

equipmentwatchuse( var_0, var_1 )
{
    if ( !maps\mp\_utility::is_aliens() )
    {
        self notify( "equipmentWatchUse" );
        self endon( "spawned_player" );
        self endon( "disconnect" );
        self endon( "equipmentWatchUse" );
        self.trigger setcursorhint( "HINT_NOICON" );

        switch ( self.weapon_name )
        {
            case "c4_mp":
                self.trigger sethintstring( &"MP_PICKUP_C4" );
                break;
            case "claymore_mp":
                self.trigger sethintstring( &"MP_PICKUP_CLAYMORE" );
                break;
            case "bouncingbetty_mp":
                self.trigger sethintstring( &"MP_PICKUP_BOUNCING_BETTY" );
                break;
            case "motion_sensor_mp":
                self.trigger sethintstring( &"MP_PICKUP_MOTION_SENSOR" );
                break;
            case "proximity_explosive_mp":
                self.trigger sethintstring( &"MP_PICKUP_PROXIMITY_EXPLOSIVE" );
                break;
        }

        self.trigger maps\mp\_utility::setselfusable( var_0 );
        self.trigger thread maps\mp\_utility::notusableforjoiningplayers( var_0 );

        if ( isdefined( var_1 ) && var_1 )
            thread updatetriggerposition();

        for (;;)
        {
            self.trigger waittill( "trigger", var_0 );
            var_0 playlocalsound( "scavenger_pack_pickup" );

            if ( isdefined( var_0.loadoutperkequipmentstowed ) && var_0.loadoutperkequipmentstowed == self.weapon_name )
                var_0.loadoutperkequipmentstowedammo++;
            else
                var_0 setweaponammostock( self.weapon_name, var_0 getweaponammostock( self.weapon_name ) + 1 );

            deleteexplosive();
            self notify( "death" );
        }
    }
}

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

    for (;;)
    {
        if ( isdefined( self ) && isdefined( self.trigger ) )
        {
            self.trigger.origin = self.origin + getexplosiveusableoffset();

            if ( isdefined( self.bombsquadmodel ) )
                self.bombsquadmodel.origin = self.origin;
        }
        else
            return;

        wait 0.05;
    }
}

claymoredetonation( var_0 )
{
    self endon( "death" );
    var_1 = spawn( "trigger_radius", self.origin + ( 0, 0, 0 - level.claymoredetonateradius ), 0, level.claymoredetonateradius, level.claymoredetonateradius * 2 );

    if ( isdefined( var_0 ) )
    {
        var_1 enablelinkto();
        var_1 linkto( var_0 );
    }

    thread deleteondeath( var_1 );

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

        if ( getdvarint( "scr_claymoredebug" ) != 1 )
        {
            if ( isdefined( self.owner ) )
            {
                if ( var_2 == self.owner )
                    continue;

                if ( isdefined( var_2.owner ) && var_2.owner == self.owner )
                    continue;
            }

            if ( !friendlyfirecheck( self.owner, var_2, 0 ) )
                continue;
        }

        if ( lengthsquared( var_2 getentityvelocity() ) < 10 )
            continue;

        var_3 = abs( var_2.origin[2] - self.origin[2] );

        if ( var_3 > 128 )
            continue;

        if ( !var_2 shouldaffectclaymore( self ) )
            continue;

        if ( var_2 damageconetrace( self.origin, self ) > 0 )
            break;
    }

    self playsound( "claymore_activated" );
    explosivetrigger( var_2, level.claymoredetectiongraceperiod, "claymore" );

    if ( isdefined( self.owner ) && isdefined( level.leaderdialogonplayer_func ) )
        self.owner thread [[ level.leaderdialogonplayer_func ]]( "claymore_destroyed", undefined, undefined, self.origin );

    self notify( "detonateExplosive" );
}

shouldaffectclaymore( var_0 )
{
    if ( isdefined( var_0.disabled ) )
        return 0;

    var_1 = self.origin + ( 0, 0, 32 );
    var_2 = var_1 - var_0.origin;
    var_3 = anglestoforward( var_0.angles );
    var_4 = vectordot( var_2, var_3 );

    if ( var_4 < level.claymoredetectionmindist )
        return 0;

    var_2 = vectornormalize( var_2 );
    var_5 = vectordot( var_2, var_3 );
    return var_5 > level.claymoredetectiondot;
}

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

    if ( isdefined( var_0 ) )
    {
        if ( isdefined( var_0.trigger ) )
            var_0.trigger delete();

        var_0 delete();
    }
}

c4activate()
{
    self endon( "death" );
    self waittill( "missile_stuck", var_0 );
    wait 0.05;
    self notify( "activated" );
    self.activated = 1;
}

watchc4altdetonate()
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "detonated" );
    level endon( "game_ended" );
    var_0 = 0;

    for (;;)
    {
        if ( self usebuttonpressed() )
        {
            var_0 = 0;

            while ( self usebuttonpressed() )
            {
                var_0 = var_0 + 0.05;
                wait 0.05;
            }

            if ( var_0 >= 0.5 )
                continue;

            var_0 = 0;

            while ( !self usebuttonpressed() && var_0 < 0.5 )
            {
                var_0 = var_0 + 0.05;
                wait 0.05;
            }

            if ( var_0 >= 0.5 )
                continue;

            if ( !self.plantedlethalequip.size )
                return;

            self notify( "alt_detonate" );
        }

        wait 0.05;
    }
}

watchc4detonation()
{
    self endon( "death" );
    self endon( "disconnect" );

    for (;;)
    {
        self waittillmatch( "detonate", "c4_mp" );
        c4detonateallcharges();
    }
}

watchc4altdetonation()
{
    self endon( "death" );
    self endon( "disconnect" );

    for (;;)
    {
        self waittill( "alt_detonate" );
        var_0 = self getcurrentweapon();

        if ( var_0 != "c4_mp" )
            c4detonateallcharges();
    }
}

c4detonateallcharges()
{
    foreach ( var_1 in self.plantedlethalequip )
    {
        if ( isdefined( var_1 ) )
            var_1 thread waitanddetonate( 0.1 );
    }

    self.plantedlethalequip = [];
    self notify( "detonated" );
}

waitanddetonate( var_0 )
{
    self endon( "death" );
    wait( var_0 );
    waittillenabled();
    self notify( "detonateExplosive" );
}

c4damage()
{
    self endon( "death" );
    self setcandamage( 1 );
    self.maxhealth = 100000;
    self.health = self.maxhealth;
    var_0 = undefined;

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

        if ( !isplayer( var_0 ) && !isagent( var_0 ) )
            continue;

        if ( !friendlyfirecheck( self.owner, var_0 ) )
            continue;

        if ( isdefined( var_9 ) )
        {
            switch ( var_9 )
            {
                case "concussion_grenade_mp":
                case "smoke_grenade_mp":
                case "flash_grenade_mp":
                    continue;
            }
        }

        break;
    }

    if ( level.c4explodethisframe )
        wait( 0.1 + randomfloat( 0.4 ) );
    else
        wait 0.05;

    if ( !isdefined( self ) )
        return;

    level.c4explodethisframe = 1;
    thread resetc4explodethisframe();

    if ( isdefined( var_4 ) && ( issubstr( var_4, "MOD_GRENADE" ) || issubstr( var_4, "MOD_EXPLOSIVE" ) ) )
        self.waschained = 1;

    if ( isdefined( var_8 ) && var_8 & level.idflags_penetration )
        self.wasdamagedfrombulletpenetration = 1;

    self.wasdamaged = 1;

    if ( isdefined( var_0 ) )
        self.damagedby = var_0;

    if ( isplayer( var_0 ) )
        var_0 maps\mp\gametypes\_damagefeedback::updatedamagefeedback( "c4" );

    if ( level.teambased )
    {
        if ( isdefined( var_0 ) && isdefined( self.owner ) )
        {
            var_10 = var_0.pers["team"];
            var_11 = self.owner.pers["team"];

            if ( isdefined( var_10 ) && isdefined( var_11 ) && var_10 != var_11 )
                var_0 notify( "destroyed_equipment" );
        }
    }
    else if ( isdefined( self.owner ) && isdefined( var_0 ) && var_0 != self.owner )
        var_0 notify( "destroyed_equipment" );

    self notify( "detonateExplosive", var_0 );
}

resetc4explodethisframe()
{
    wait 0.05;
    level.c4explodethisframe = 0;
}

saydamaged( var_0, var_1 )
{
    for ( var_2 = 0; var_2 < 60; var_2++ )
        wait 0.05;
}

waittillenabled()
{
    if ( !isdefined( self.disabled ) )
        return;

    self waittill( "enabled" );
}

c4detectiontrigger( var_0 )
{
    self waittill( "activated" );
    var_1 = spawn( "trigger_radius", self.origin - ( 0, 0, 128 ), 0, 512, 256 );
    var_1.detectid = "trigger" + gettime() + randomint( 1000000 );
    var_1.owner = self;
    var_1 thread detecticonwaiter( level.otherteam[var_0] );
    self waittill( "death" );
    var_1 notify( "end_detection" );

    if ( isdefined( var_1.bombsquadicon ) )
        var_1.bombsquadicon destroy();

    var_1 delete();
}

claymoredetectiontrigger( var_0 )
{
    var_1 = spawn( "trigger_radius", self.origin - ( 0, 0, 128 ), 0, 512, 256 );
    var_1.detectid = "trigger" + gettime() + randomint( 1000000 );
    var_1.owner = self;
    var_1 thread detecticonwaiter( level.otherteam[var_0] );
    self waittill( "death" );
    var_1 notify( "end_detection" );

    if ( isdefined( var_1.bombsquadicon ) )
        var_1.bombsquadicon destroy();

    var_1 delete();
}

detecticonwaiter( var_0 )
{
    self endon( "end_detection" );
    level endon( "game_ended" );

    while ( !level.gameended )
    {
        self waittill( "trigger", var_1 );

        if ( !var_1.detectexplosives )
            continue;

        if ( level.teambased && var_1.team != var_0 )
            continue;
        else if ( !level.teambased && var_1 == self.owner.owner )
            continue;

        if ( isdefined( var_1.bombsquadids[self.detectid] ) )
            continue;

        var_1 thread showheadicon( self );
    }
}

monitordisownedequipment( var_0, var_1 )
{
    level endon( "game_ended" );
    var_1 endon( "death" );
    var_0 common_scripts\utility::waittill_any( "joined_team", "joined_spectators", "disconnect" );
    var_1 deleteexplosive();
}

onlethalequipmentplanted( var_0 )
{
    if ( self.plantedlethalequip.size )
    {
        self.plantedlethalequip = common_scripts\utility::array_removeundefined( self.plantedlethalequip );

        if ( self.plantedlethalequip.size >= level.maxperplayerexplosives )
            self.plantedlethalequip[0] notify( "detonateExplosive" );
    }

    self.plantedlethalequip[self.plantedlethalequip.size] = var_0;
    var_1 = var_0 getentitynumber();
    level.mines[var_1] = var_0;
    level notify( "mine_planted" );
}

ontacticalequipmentplanted( var_0 )
{
    if ( self.plantedtacticalequip.size )
    {
        self.plantedtacticalequip = common_scripts\utility::array_removeundefined( self.plantedtacticalequip );

        if ( self.plantedtacticalequip.size >= level.maxperplayerexplosives )
            self.plantedtacticalequip[0] notify( "detonateExplosive" );
    }

    self.plantedtacticalequip[self.plantedtacticalequip.size] = var_0;
    var_1 = var_0 getentitynumber();
    level.mines[var_1] = var_0;
    level notify( "mine_planted" );
}

disableplantedequipmentuse()
{
    if ( isdefined( self.plantedlethalequip ) && self.plantedlethalequip.size > 0 )
    {
        foreach ( var_1 in self.plantedlethalequip )
        {
            if ( isdefined( var_1.trigger ) && isdefined( var_1.owner ) )
                var_1.trigger disableplayeruse( var_1.owner );
        }
    }

    if ( isdefined( self.plantedtacticalequip ) && self.plantedtacticalequip.size > 0 )
    {
        foreach ( var_1 in self.plantedtacticalequip )
        {
            if ( isdefined( var_1.trigger ) && isdefined( var_1.owner ) )
                var_1.trigger disableplayeruse( var_1.owner );
        }
    }
}

cleanupequipment( var_0, var_1, var_2, var_3 )
{
    if ( isdefined( var_0 ) )
        level.mines[var_0] = undefined;

    if ( isdefined( var_1 ) )
        var_1 delete();

    if ( isdefined( var_2 ) )
        var_2 delete();

    if ( isdefined( var_3 ) )
        var_3 delete();
}

deleteexplosive()
{
    if ( isdefined( self ) )
    {
        var_0 = self getentitynumber();
        var_1 = self.killcament;
        var_2 = self.trigger;
        var_3 = self.sensor;
        cleanupequipment( var_0, var_1, var_2, var_3 );
        self notify( "deleted_equipment" );
        self delete();
    }
}

ondetonateexplosive()
{
    self endon( "death" );
    level endon( "game_ended" );
    thread cleanupexplosivesondeath();
    self waittill( "detonateExplosive" );
    self detonate( self.owner );
}

cleanupexplosivesondeath()
{
    self endon( "deleted_equipment" );
    level endon( "game_ended" );
    var_0 = self getentitynumber();
    var_1 = self.killcament;
    var_2 = self.trigger;
    var_3 = self.sensor;
    self waittill( "death" );
    cleanupequipment( var_0, var_1, var_2, var_3 );
}

getexplosiveusableoffset()
{
    var_0 = anglestoup( self.angles );
    return 10 * var_0;
}

makeexplosiveusable()
{
    if ( maps\mp\_utility::isreallyalive( self.owner ) )
    {
        self setotherent( self.owner );
        self.trigger = spawn( "script_origin", self.origin + getexplosiveusableoffset() );
        self.trigger.owner = self;
        thread equipmentwatchuse( self.owner, 1 );
    }
}

makeexplosivetargetablebyai( var_0 )
{
    common_scripts\utility::make_entity_sentient_mp( self.owner.team );

    if ( !isdefined( var_0 ) || !var_0 )
        self makeentitynomeleetarget();

    if ( issentient( self ) )
        self setthreatbiasgroup( "DogsDontAttack" );
}

explosivehandlemovers( var_0, var_1 )
{
    var_2 = spawnstruct();
    var_2.linkparent = var_0;
    var_2.deathoverridecallback = ::movingplatformdetonate;
    var_2.endonstring = "death";

    if ( !isdefined( var_1 ) || !var_1 )
        var_2.invalidparentoverridecallback = maps\mp\_movers::moving_platform_empty_func;

    thread maps\mp\_movers::handle_moving_platforms( var_2 );
}

explosivetrigger( var_0, var_1, var_2 )
{
    if ( isplayer( var_0 ) && var_0 maps\mp\_utility::_hasperk( "specialty_delaymine" ) )
    {
        var_0 notify( "triggeredExpl", var_2 );
        var_1 = level.delayminetime;
    }

    wait( var_1 );
}

setupbombsquad()
{
    self.bombsquadids = [];

    if ( self.detectexplosives && !self.bombsquadicons.size )
    {
        for ( var_0 = 0; var_0 < 4; var_0++ )
        {
            self.bombsquadicons[var_0] = newclienthudelem( self );
            self.bombsquadicons[var_0].x = 0;
            self.bombsquadicons[var_0].y = 0;
            self.bombsquadicons[var_0].z = 0;
            self.bombsquadicons[var_0].alpha = 0;
            self.bombsquadicons[var_0].archived = 1;
            self.bombsquadicons[var_0] setshader( "waypoint_bombsquad", 14, 14 );
            self.bombsquadicons[var_0] setwaypoint( 0, 0 );
            self.bombsquadicons[var_0].detectid = "";
        }
    }
    else if ( !self.detectexplosives )
    {
        for ( var_0 = 0; var_0 < self.bombsquadicons.size; var_0++ )
            self.bombsquadicons[var_0] destroy();

        self.bombsquadicons = [];
    }
}

showheadicon( var_0 )
{
    var_1 = var_0.detectid;
    var_2 = -1;

    for ( var_3 = 0; var_3 < 4; var_3++ )
    {
        var_4 = self.bombsquadicons[var_3].detectid;

        if ( var_4 == var_1 )
            return;

        if ( var_4 == "" )
            var_2 = var_3;
    }

    if ( var_2 < 0 )
        return;

    self.bombsquadids[var_1] = 1;
    self.bombsquadicons[var_2].x = var_0.origin[0];
    self.bombsquadicons[var_2].y = var_0.origin[1];
    self.bombsquadicons[var_2].z = var_0.origin[2] + 24 + 128;
    self.bombsquadicons[var_2] fadeovertime( 0.25 );
    self.bombsquadicons[var_2].alpha = 1;
    self.bombsquadicons[var_2].detectid = var_0.detectid;

    while ( isalive( self ) && isdefined( var_0 ) && self istouching( var_0 ) )
        wait 0.05;

    if ( !isdefined( self ) )
        return;

    self.bombsquadicons[var_2].detectid = "";
    self.bombsquadicons[var_2] fadeovertime( 0.25 );
    self.bombsquadicons[var_2].alpha = 0;
    self.bombsquadids[var_1] = undefined;
}

getdamageableents( var_0, var_1, var_2, var_3 )
{
    var_4 = [];

    if ( !isdefined( var_2 ) )
        var_2 = 0;

    if ( !isdefined( var_3 ) )
        var_3 = 0;

    var_5 = var_1 * var_1;
    var_6 = level.players;

    for ( var_7 = 0; var_7 < var_6.size; var_7++ )
    {
        if ( !isalive( var_6[var_7] ) || var_6[var_7].sessionstate != "playing" )
            continue;

        var_8 = maps\mp\_utility::get_damageable_player_pos( var_6[var_7] );
        var_9 = distancesquared( var_0, var_8 );

        if ( var_9 < var_5 && ( !var_2 || weapondamagetracepassed( var_0, var_8, var_3, var_6[var_7] ) ) )
            var_4[var_4.size] = maps\mp\_utility::get_damageable_player( var_6[var_7], var_8 );
    }

    var_10 = getentarray( "grenade", "classname" );

    for ( var_7 = 0; var_7 < var_10.size; var_7++ )
    {
        var_11 = maps\mp\_utility::get_damageable_grenade_pos( var_10[var_7] );
        var_9 = distancesquared( var_0, var_11 );

        if ( var_9 < var_5 && ( !var_2 || weapondamagetracepassed( var_0, var_11, var_3, var_10[var_7] ) ) )
            var_4[var_4.size] = maps\mp\_utility::get_damageable_grenade( var_10[var_7], var_11 );
    }

    var_12 = getentarray( "destructible", "targetname" );

    for ( var_7 = 0; var_7 < var_12.size; var_7++ )
    {
        var_11 = var_12[var_7].origin;
        var_9 = distancesquared( var_0, var_11 );

        if ( var_9 < var_5 && ( !var_2 || weapondamagetracepassed( var_0, var_11, var_3, var_12[var_7] ) ) )
        {
            var_13 = spawnstruct();
            var_13.isplayer = 0;
            var_13.isadestructable = 0;
            var_13.entity = var_12[var_7];
            var_13.damagecenter = var_11;
            var_4[var_4.size] = var_13;
        }
    }

    var_14 = getentarray( "destructable", "targetname" );

    for ( var_7 = 0; var_7 < var_14.size; var_7++ )
    {
        var_11 = var_14[var_7].origin;
        var_9 = distancesquared( var_0, var_11 );

        if ( var_9 < var_5 && ( !var_2 || weapondamagetracepassed( var_0, var_11, var_3, var_14[var_7] ) ) )
        {
            var_13 = spawnstruct();
            var_13.isplayer = 0;
            var_13.isadestructable = 1;
            var_13.entity = var_14[var_7];
            var_13.damagecenter = var_11;
            var_4[var_4.size] = var_13;
        }
    }

    var_15 = getentarray( "misc_turret", "classname" );

    foreach ( var_17 in var_15 )
    {
        var_11 = var_17.origin + ( 0, 0, 32 );
        var_9 = distancesquared( var_0, var_11 );

        if ( var_9 < var_5 && ( !var_2 || weapondamagetracepassed( var_0, var_11, var_3, var_17 ) ) )
        {
            switch ( var_17.model )
            {
                case "vehicle_ugv_talon_gun_mp":
                case "mp_remote_turret":
                case "mp_scramble_turret":
                case "mp_sam_turret":
                case "sentry_minigun_weak":
                    var_4[var_4.size] = maps\mp\_utility::get_damageable_sentry( var_17, var_11 );
                    break;
            }
        }
    }

    var_19 = getentarray( "script_model", "classname" );

    foreach ( var_21 in var_19 )
    {
        if ( var_21.model != "projectile_bouncing_betty_grenade" && var_21.model != "ims_scorpion_body" )
            continue;

        var_11 = var_21.origin + ( 0, 0, 32 );
        var_9 = distancesquared( var_0, var_11 );

        if ( var_9 < var_5 && ( !var_2 || weapondamagetracepassed( var_0, var_11, var_3, var_21 ) ) )
            var_4[var_4.size] = maps\mp\_utility::get_damageable_mine( var_21, var_11 );
    }

    return var_4;
}

getempdamageents( var_0, var_1, var_2, var_3 )
{
    var_4 = [];

    if ( !isdefined( var_2 ) )
        var_2 = 0;

    if ( !isdefined( var_3 ) )
        var_3 = 0;

    var_5 = var_1 * var_1;
    level.mines = common_scripts\utility::array_removeundefined( level.mines );

    foreach ( var_7 in level.mines )
    {
        if ( empcandamage( var_7, var_0, var_5, var_2, var_3 ) )
            var_4[var_4.size] = var_7;
    }

    var_9 = getentarray( "misc_turret", "classname" );

    foreach ( var_7 in var_9 )
    {
        if ( empcandamage( var_7, var_0, var_5, var_2, var_3 ) )
            var_4[var_4.size] = var_7;
    }

    foreach ( var_7 in level.uplinks )
    {
        if ( empcandamage( var_7, var_0, var_5, var_2, var_3 ) )
            var_4[var_4.size] = var_7;
    }

    foreach ( var_7 in level.remote_uav )
    {
        if ( empcandamage( var_7, var_0, var_5, var_2, var_3 ) )
            var_4[var_4.size] = var_7;
    }

    foreach ( var_7 in level.balldrones )
    {
        if ( empcandamage( var_7, var_0, var_5, var_2, var_3 ) )
            var_4[var_4.size] = var_7;
    }

    foreach ( var_7 in level.placedims )
    {
        if ( empcandamage( var_7, var_0, var_5, var_2, var_3 ) )
            var_4[var_4.size] = var_7;
    }

    foreach ( var_7 in level.players )
    {
        if ( empcandamage( var_7, var_0, var_5, var_2, var_3 ) )
            var_4[var_4.size] = var_7;
    }

    return var_4;
}

empcandamage( var_0, var_1, var_2, var_3, var_4 )
{
    var_5 = var_0.origin;
    var_6 = distancesquared( var_1, var_5 );
    return var_6 < var_2 && ( !var_3 || weapondamagetracepassed( var_1, var_5, var_4, var_0 ) );
}

weapondamagetracepassed( var_0, var_1, var_2, var_3 )
{
    var_4 = undefined;
    var_5 = var_1 - var_0;

    if ( lengthsquared( var_5 ) < var_2 * var_2 )
        return 1;

    var_6 = vectornormalize( var_5 );
    var_4 = var_0 + ( var_6[0] * var_2, var_6[1] * var_2, var_6[2] * var_2 );
    var_7 = bullettrace( var_4, var_1, 0, var_3 );

    if ( getdvarint( "scr_damage_debug" ) != 0 || getdvarint( "scr_debugMines" ) != 0 )
    {
        thread debugprint( var_0, ".dmg" );

        if ( isdefined( var_3 ) )
            thread debugprint( var_1, "." + var_3.classname );
        else
            thread debugprint( var_1, ".undefined" );

        if ( var_7["fraction"] == 1 )
            thread debugline( var_4, var_1, ( 1, 1, 1 ) );
        else
        {
            thread debugline( var_4, var_7["position"], ( 1, 0.9, 0.8 ) );
            thread debugline( var_7["position"], var_1, ( 1, 0.4, 0.3 ) );
        }
    }

    return var_7["fraction"] == 1;
}

damageent( var_0, var_1, var_2, var_3, var_4, var_5, var_6 )
{
    if ( self.isplayer )
    {
        self.damageorigin = var_5;
        self.entity thread [[ level.callbackplayerdamage ]]( var_0, var_1, var_2, 0, var_3, var_4, var_5, var_6, "none", 0 );
    }
    else
    {
        if ( self.isadestructable && ( var_4 == "artillery_mp" || var_4 == "claymore_mp" || var_4 == "stealth_bomb_mp" || var_4 == "alienclaymore_mp" ) )
            return;

        self.entity notify( "damage", var_2, var_1, ( 0, 0, 0 ), ( 0, 0, 0 ), "MOD_EXPLOSIVE", "", "", "", undefined, var_4 );
    }
}

debugline( var_0, var_1, var_2 )
{
    for ( var_3 = 0; var_3 < 600; var_3++ )
        wait 0.05;
}

debugcircle( var_0, var_1, var_2, var_3 )
{
    if ( !isdefined( var_3 ) )
        var_3 = 16;

    var_4 = 360 / var_3;
    var_5 = [];

    for ( var_6 = 0; var_6 < var_3; var_6++ )
    {
        var_7 = var_4 * var_6;
        var_8 = cos( var_7 ) * var_1;
        var_9 = sin( var_7 ) * var_1;
        var_10 = var_0[0] + var_8;
        var_11 = var_0[1] + var_9;
        var_12 = var_0[2];
        var_5[var_5.size] = ( var_10, var_11, var_12 );
    }

    for ( var_6 = 0; var_6 < var_5.size; var_6++ )
    {
        var_13 = var_5[var_6];

        if ( var_6 + 1 >= var_5.size )
            var_14 = var_5[0];
        else
            var_14 = var_5[var_6 + 1];

        thread debugline( var_13, var_14, var_2 );
    }
}

debugprint( var_0, var_1 )
{
    for ( var_2 = 0; var_2 < 600; var_2++ )
        wait 0.05;
}

onweapondamage( var_0, var_1, var_2, var_3, var_4 )
{
    self endon( "death" );
    self endon( "disconnect" );

    switch ( var_1 )
    {
        case "concussion_grenade_mp":
            if ( !isdefined( var_0 ) )
                return;
            else if ( var_2 == "MOD_IMPACT" )
                return;

            var_5 = 1;

            if ( isdefined( var_0.owner ) && var_0.owner == var_4 )
                var_5 = 0;

            var_6 = 512;
            var_7 = 1 - distance( self.origin, var_0.origin ) / var_6;

            if ( var_7 < 0 )
                var_7 = 0;

            var_8 = 2 + 4 * var_7;
            var_8 = maps\mp\perks\_perkfunctions::applystunresistence( var_8 );
            wait 0.05;
            var_4 notify( "stun_hit" );
            self notify( "concussed", var_4 );

            if ( var_4 != self )
                var_4 maps\mp\gametypes\_missions::processchallenge( "ch_alittleconcussed" );

            self shellshock( "concussion_grenade_mp", var_8 );
            self.concussionendtime = gettime() + var_8 * 1000;

            if ( var_5 )
                var_4 thread maps\mp\gametypes\_damagefeedback::updatedamagefeedback( "stun" );

            break;
        case "weapon_cobra_mk19_mp":
            break;
        default:
            maps\mp\gametypes\_shellshock::shellshockondamage( var_2, var_3 );
            break;
    }
}

isprimaryweapon( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    if ( weaponinventorytype( var_0 ) != "primary" )
        return 0;

    switch ( weaponclass( var_0 ) )
    {
        case "smg":
        case "mg":
        case "pistol":
        case "rifle":
        case "sniper":
        case "rocketlauncher":
        case "spread":
            return 1;
        default:
            return 0;
    }
}

isbulletweapon( var_0 )
{
    if ( var_0 == "none" || isriotshield( var_0 ) || isknifeonly( var_0 ) )
        return 0;

    switch ( weaponclass( var_0 ) )
    {
        case "smg":
        case "mg":
        case "pistol":
        case "rifle":
        case "sniper":
        case "spread":
            return 1;
        default:
            return 0;
    }
}

isknifeonly( var_0 )
{
    return issubstr( var_0, "knifeonly" );
}

isaltmodeweapon( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    return weaponinventorytype( var_0 ) == "altmode";
}

isinventoryweapon( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    return weaponinventorytype( var_0 ) == "item";
}

isriotshield( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    return weapontype( var_0 ) == "riotshield";
}

isoffhandweapon( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    return weaponinventorytype( var_0 ) == "offhand";
}

issidearm( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    if ( weaponinventorytype( var_0 ) != "primary" )
        return 0;

    return weaponclass( var_0 ) == "pistol";
}

isgrenade( var_0 )
{
    var_1 = weaponclass( var_0 );
    var_2 = weaponinventorytype( var_0 );

    if ( var_1 != "grenade" )
        return 0;

    if ( var_2 != "offhand" )
        return 0;

    return 1;
}

isthrowingknife( var_0 )
{
    if ( var_0 == "none" )
        return 0;

    return issubstr( var_0, "throwingknife" );
}

isrocketlauncher( var_0 )
{
    return var_0 == "iw6_panzerfaust3_mp" || var_0 == "iw6_maaws_mp";
}

updatesavedlastweapon()
{
    self endon( "death" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );
    var_0 = self.currentweaponatspawn;

    if ( isdefined( self.saved_lastweaponhack ) )
        var_0 = self.saved_lastweaponhack;

    self.saved_lastweapon = var_0;

    for (;;)
    {
        self waittill( "weapon_change", var_1 );

        if ( var_1 == "none" )
        {
            self.saved_lastweapon = var_0;
            continue;
        }

        var_2 = weaponinventorytype( var_1 );

        if ( var_2 != "primary" && var_2 != "altmode" )
        {
            self.saved_lastweapon = var_0;
            continue;
        }

        updatemovespeedscale();
        self.saved_lastweapon = var_0;
        var_0 = var_1;
    }
}

empplayer( var_0 )
{
    self endon( "disconnect" );
    self endon( "death" );
    thread clearempondeath();
}

clearempondeath()
{
    self endon( "disconnect" );
    self waittill( "death" );
}

getweaponheaviestvalue()
{
    var_0 = 1000;
    self.weaponlist = self getweaponslistprimaries();

    if ( self.weaponlist.size )
    {
        foreach ( var_2 in self.weaponlist )
        {
            var_3 = getweaponweight( var_2 );

            if ( var_3 == 0 )
                continue;

            if ( var_3 < var_0 )
                var_0 = var_3;
        }
    }
    else
        var_0 = 8;

    var_0 = clampweaponweightvalue( var_0 );
    return var_0;
}

getweaponweight( var_0 )
{
    var_1 = undefined;
    var_2 = maps\mp\_utility::getbaseweaponname( var_0 );

    if ( maps\mp\_utility::is_aliens() )
        var_1 = float( tablelookup( "mp/alien/mode_string_tables/alien_statstable.csv", 4, var_2, 8 ) );
    else
        var_1 = float( tablelookup( "mp/statstable.csv", 4, var_2, 8 ) );

    return var_1;
}

clampweaponweightvalue( var_0 )
{
    return clamp( var_0, 0.0, 11.0 );
}

updatemovespeedscale()
{
    var_0 = undefined;
    self.weaponlist = self getweaponslistprimaries();

    if ( !self.weaponlist.size )
        var_0 = 8;
    else
    {
        var_1 = self getcurrentweapon();
        var_2 = weaponinventorytype( var_1 );

        if ( var_2 != "primary" && var_2 != "altmode" )
        {
            if ( isdefined( self.saved_lastweapon ) )
                var_1 = self.saved_lastweapon;
            else
                var_1 = undefined;
        }

        if ( !isdefined( var_1 ) || !self hasweapon( var_1 ) )
            var_0 = getweaponheaviestvalue();
        else
        {
            var_0 = getweaponweight( var_1 );
            var_0 = clampweaponweightvalue( var_0 );
        }
    }

    var_3 = var_0 / 10;
    self.weaponspeed = var_3;

    if ( !isdefined( self.combatspeedscalar ) )
        self.combatspeedscalar = 1;

    self setmovespeedscale( var_3 * self.movespeedscaler * self.combatspeedscalar );
}

stancerecoiladjuster()
{
    if ( !isplayer( self ) )
        return;

    self endon( "death" );
    self endon( "disconnect" );
    self endon( "faux_spawn" );
    self notifyonplayercommand( "adjustedStance", "+stance" );
    self notifyonplayercommand( "adjustedStance", "+goStand" );

    if ( !level.console && !isai( self ) )
    {
        self notifyonplayercommand( "adjustedStance", "+togglecrouch" );
        self notifyonplayercommand( "adjustedStance", "toggleprone" );
        self notifyonplayercommand( "adjustedStance", "+movedown" );
        self notifyonplayercommand( "adjustedStance", "-movedown" );
        self notifyonplayercommand( "adjustedStance", "+prone" );
        self notifyonplayercommand( "adjustedStance", "-prone" );
    }

    for (;;)
    {
        common_scripts\utility::waittill_any( "adjustedStance", "sprint_begin", "weapon_change" );
        wait 0.5;

        if ( isdefined( self.onhelisniper ) && self.onhelisniper )
            continue;

        var_0 = self getstance();
        stancerecoilupdate( var_0 );
    }
}

stancerecoilupdate( var_0 )
{
    var_1 = self getcurrentprimaryweapon();
    var_2 = 0;

    if ( isrecoilreducingweapon( var_1 ) )
        var_2 = getrecoilreductionvalue();

    if ( var_0 == "prone" )
    {
        var_3 = maps\mp\_utility::getweaponclass( var_1 );

        if ( var_3 == "weapon_lmg" )
        {
            maps\mp\_utility::setrecoilscale( 0, 40 );
            return;
        }

        if ( var_3 == "weapon_sniper" )
        {
            if ( issubstr( var_1, "barrelbored" ) )
            {
                maps\mp\_utility::setrecoilscale( 0, 20 + var_2 );
                return;
            }

            maps\mp\_utility::setrecoilscale( 0, 40 + var_2 );
            return;
            return;
        }

        maps\mp\_utility::setrecoilscale();
        return;
        return;
    }
    else if ( var_0 == "crouch" )
    {
        var_3 = maps\mp\_utility::getweaponclass( var_1 );

        if ( var_3 == "weapon_lmg" )
        {
            maps\mp\_utility::setrecoilscale( 0, 10 );
            return;
        }

        if ( var_3 == "weapon_sniper" )
        {
            if ( issubstr( var_1, "barrelbored" ) )
            {
                maps\mp\_utility::setrecoilscale( 0, 10 + var_2 );
                return;
            }

            maps\mp\_utility::setrecoilscale( 0, 20 + var_2 );
            return;
            return;
        }

        maps\mp\_utility::setrecoilscale();
        return;
        return;
    }
    else if ( var_2 > 0 )
        maps\mp\_utility::setrecoilscale( 0, var_2 );
    else
        maps\mp\_utility::setrecoilscale();
}

buildweapondata( var_0 )
{
    var_1 = maps\mp\_utility::getattachmentlistbasenames();
    var_1 = common_scripts\utility::alphabetize( var_1 );
    var_2 = 149;
    var_3 = [];
    var_4 = "mp/statstable.csv";
    var_5 = getdvar( "g_gametype" );

    if ( var_5 == "aliens" )
        var_4 = "mp/alien/mode_string_tables/alien_statstable.csv";

    for ( var_6 = 0; var_6 <= var_2; var_6++ )
    {
        var_7 = tablelookup( var_4, 0, var_6, 4 );

        if ( var_7 == "" )
            continue;

        var_8 = var_7 + "_mp";

        if ( !issubstr( tablelookup( var_4, 0, var_6, 2 ), "weapon_" ) )
            continue;

        if ( weaponinventorytype( var_8 ) != "primary" )
            continue;

        var_9 = spawnstruct();
        var_9.basename = var_7;
        var_9.assetname = var_8;
        var_9.variants = [];
        var_9.variants[0] = var_8;
        var_10 = [];

        for ( var_11 = 0; var_11 < 6; var_11++ )
        {
            var_12 = tablelookup( var_4, 0, var_6, var_11 + 11 );

            if ( var_0 )
            {
                switch ( var_12 )
                {
                    case "xmags":
                    case "rof":
                    case "fmj":
                        continue;
                }
            }

            if ( var_12 == "" )
                break;

            var_10[var_12] = 1;
        }

        var_13 = [];

        foreach ( var_12 in var_1 )
        {
            if ( !isdefined( var_10[var_12] ) )
                continue;

            var_9.variants[var_9.variants.size] = var_7 + "_" + var_12 + "_mp";
            var_13[var_13.size] = var_12;
        }

        for ( var_16 = 0; var_16 < var_13.size - 1; var_16++ )
        {
            var_17 = tablelookuprownum( "mp/attachmentCombos.csv", 0, var_13[var_16] );

            for ( var_18 = var_16 + 1; var_18 < var_13.size; var_18++ )
            {
                if ( tablelookup( "mp/attachmentCombos.csv", 0, var_13[var_18], var_17 ) == "no" )
                    continue;

                var_9.variants[var_9.variants.size] = var_7 + "_" + var_13[var_16] + "_" + var_13[var_18] + "_mp";
            }
        }

        var_3[var_7] = var_9;
    }

    return var_3;
}

monitormk32semtexlauncher()
{
    self endon( "disconnect" );
    self endon( "death" );
    self endon( "faux_spawn" );

    for (;;)
    {
        var_0 = maps\mp\_utility::waittill_grenade_fire();

        if ( isdefined( var_0.weapon_name ) && var_0.weapon_name == "iw6_mk32_mp" )
            semtexused( var_0 );
    }
}

semtexused( var_0 )
{
    if ( !isdefined( var_0 ) )
        return;

    if ( !isdefined( var_0.weapon_name ) )
        return;

    if ( !issubstr( var_0.weapon_name, "semtex" ) && var_0.weapon_name != "iw6_mk32_mp" )
        return;

    var_0.originalowner = self;
    var_0 waittill( "missile_stuck", var_1 );
    var_0 thread maps\mp\gametypes\_shellshock::grenade_earthquake();

    if ( isplayer( var_1 ) || isagent( var_1 ) )
    {
        if ( !isdefined( self ) )
        {
            var_0.stuckenemyentity = var_1;
            var_1.stuckbygrenade = var_0;
        }
        else if ( level.teambased && isdefined( var_1.team ) && var_1.team == self.team )
            var_0.isstuck = "friendly";
        else
        {
            var_0.isstuck = "enemy";
            var_0.stuckenemyentity = var_1;

            if ( isplayer( var_1 ) )
                var_1 maps\mp\gametypes\_hud_message::playercardsplashnotify( "semtex_stuck", self );

            thread maps\mp\gametypes\_hud_message::splashnotify( "stuck_semtex", 100 );
            var_1.stuckbygrenade = var_0;
        }
    }

    var_0 explosivehandlemovers( undefined );
}

turret_monitoruse()
{
    for (;;)
    {
        self waittill( "trigger", var_0 );
        thread turret_playerthread( var_0 );
    }
}

turret_playerthread( var_0 )
{
    var_0 endon( "death" );
    var_0 endon( "disconnect" );
    var_0 notify( "weapon_change", "none" );
    self waittill( "turret_deactivate" );
    var_0 notify( "weapon_change", var_0 getcurrentweapon() );
}

spawnmine( var_0, var_1, var_2, var_3 )
{
    if ( !isdefined( var_3 ) )
        var_3 = ( 0, randomfloat( 360 ), 0 );

    var_4 = level.weaponconfigs[var_2];
    var_5 = spawn( "script_model", var_0 );
    var_5.angles = var_3;
    var_5 setmodel( var_4.model );
    var_5.owner = var_1;
    var_5 setotherent( var_1 );
    var_5.weapon_name = var_2;
    var_5.config = var_4;
    var_5.killcamoffset = ( 0, 0, 4 );
    var_5.killcament = spawn( "script_model", var_5.origin + var_5.killcamoffset );
    var_5.killcament setscriptmoverkillcam( "explosive" );
    var_1 onlethalequipmentplanted( var_5 );
    var_5 thread createbombsquadmodel( var_4.bombsquadmodel, "tag_origin", var_1 );

    if ( isdefined( var_4.mine_beacon ) )
        var_5 thread doblinkinglight( "tag_fx", var_4.mine_beacon["friendly"], var_4.mine_beacon["enemy"] );

    if ( !maps\mp\_utility::is_aliens() )
        var_5 thread setclaymoreteamheadicon( var_1.pers["team"], var_4.headiconoffset );

    var_6 = undefined;

    if ( self != level )
        var_6 = self getlinkedparent();

    var_5 explosivehandlemovers( var_6 );
    var_5 thread mineproximitytrigger( var_6 );
    var_5 thread maps\mp\gametypes\_shellshock::grenade_earthquake();
    var_5 makeexplosivetargetablebyai( 1 );

    if ( maps\mp\_utility::is_aliens() && issentient( var_5 ) )
    {
        var_5 setthreatbiasgroup( "deployable_ammo" );
        var_5.threatbias = -10000;
    }

    var_5 thread mineexplodeonnotify();
    level thread monitordisownedequipment( var_1, var_5 );
    return var_5;
}

spawnmotionsensor( var_0, var_1, var_2, var_3 )
{
    if ( !isdefined( var_3 ) )
        var_3 = ( 0, randomfloat( 360 ), 0 );

    var_4 = level.weaponconfigs[var_2];
    var_5 = spawn( "script_model", var_0 );
    var_5.angles = var_3;
    var_5 setmodel( var_4.model );
    var_5.owner = var_1;
    var_5 setotherent( var_1 );
    var_5.weapon_name = var_2;
    var_5.config = var_4;
    var_1 ontacticalequipmentplanted( var_5 );
    var_5 thread createbombsquadmodel( var_4.bombsquadmodel, "tag_origin", var_1 );
    var_5 thread setclaymoreteamheadicon( var_1.pers["team"], var_4.headiconoffset );
    var_6 = undefined;

    if ( self != level )
        var_6 = self getlinkedparent();

    var_5 explosivehandlemovers( var_6, 1 );
    var_5 thread mineproximitytrigger( var_6 );
    var_5 thread maps\mp\gametypes\_shellshock::grenade_earthquake();
    var_5 thread motionsensorempdamage();
    var_5 makeexplosivetargetablebyai( 0 );
    var_5 thread minesensoronnotify();
    level thread monitordisownedequipment( var_1, var_5 );
    return var_5;
}

minedamagemonitor()
{
    self endon( "mine_triggered" );
    self endon( "mine_selfdestruct" );
    self endon( "death" );
    self setcandamage( 1 );
    self.maxhealth = 100000;
    self.health = self.maxhealth;
    var_0 = undefined;

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

        if ( maps\mp\_utility::is_aliens() && is_hive_explosion( var_0, var_4 ) )
            break;

        if ( !isplayer( var_0 ) && !isagent( var_0 ) )
            continue;

        if ( isdefined( var_9 ) && isendstr( var_9, "betty_mp" ) )
            continue;

        if ( !friendlyfirecheck( self.owner, var_0 ) )
            continue;

        if ( isdefined( var_9 ) )
        {
            switch ( var_9 )
            {
                case "concussion_grenade_mp":
                case "smoke_grenadejugg_mp":
                case "smoke_grenade_mp":
                case "flash_grenade_mp":
                    continue;
            }
        }

        break;
    }

    self notify( "mine_destroyed" );

    if ( isdefined( var_4 ) && ( issubstr( var_4, "MOD_GRENADE" ) || issubstr( var_4, "MOD_EXPLOSIVE" ) ) )
        self.waschained = 1;

    if ( isdefined( var_8 ) && var_8 & level.idflags_penetration )
        self.wasdamagedfrombulletpenetration = 1;

    self.wasdamaged = 1;

    if ( isdefined( var_0 ) )
        self.damagedby = var_0;

    if ( isplayer( var_0 ) )
        var_0 maps\mp\gametypes\_damagefeedback::updatedamagefeedback( "bouncing_betty" );

    if ( !maps\mp\_utility::is_aliens() )
    {
        if ( level.teambased )
        {
            if ( isdefined( var_0 ) && isdefined( var_0.pers["team"] ) && isdefined( self.owner ) && isdefined( self.owner.pers["team"] ) )
            {
                if ( var_0.pers["team"] != self.owner.pers["team"] )
                    var_0 notify( "destroyed_equipment" );
            }
        }
        else if ( isdefined( self.owner ) && isdefined( var_0 ) && var_0 != self.owner )
            var_0 notify( "destroyed_equipment" );
    }

    self notify( "detonateExplosive", var_0 );
}

is_hive_explosion( var_0, var_1 )
{
    if ( !isdefined( var_0 ) || !isdefined( var_0.classname ) )
        return 0;

    return var_0.classname == "scriptable" && var_1 == "MOD_EXPLOSIVE";
}

mineproximitytrigger( var_0 )
{
    self endon( "mine_destroyed" );
    self endon( "mine_selfdestruct" );
    self endon( "death" );
    self endon( "disabled" );
    var_1 = self.config;
    wait( var_1.armtime );

    if ( isdefined( var_1.mine_beacon ) )
        thread doblinkinglight( "tag_fx", var_1.mine_beacon["friendly"], var_1.mine_beacon["enemy"] );

    var_2 = spawn( "trigger_radius", self.origin, 0, level.minedetectionradius, level.minedetectionheight );
    var_2.owner = self;
    thread minedeletetrigger( var_2 );

    if ( isdefined( var_0 ) )
    {
        var_2 enablelinkto();
        var_2 linkto( var_0 );
    }

    self.damagearea = var_2;
    var_3 = undefined;

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

        if ( !isdefined( var_3 ) )
            continue;

        if ( getdvarint( "scr_minesKillOwner" ) != 1 )
        {
            if ( isdefined( self.owner ) )
            {
                if ( var_3 == self.owner )
                    continue;

                if ( isdefined( var_3.owner ) && var_3.owner == self.owner )
                    continue;
            }

            if ( !friendlyfirecheck( self.owner, var_3, 0 ) )
                continue;
        }

        if ( lengthsquared( var_3 getentityvelocity() ) < 10 )
            continue;

        if ( var_3 damageconetrace( self.origin, self ) > 0 )
            break;
    }

    self notify( "mine_triggered" );
    self playsound( self.config.ontriggeredsfx );
    explosivetrigger( var_3, level.minedetectiongraceperiod, "mine" );
    self thread [[ self.config.ontriggeredfunc ]]();
}

minedeletetrigger( var_0 )
{
    common_scripts\utility::waittill_any( "mine_triggered", "mine_destroyed", "mine_selfdestruct", "death" );

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

motionsensorempdamage()
{
    self endon( "mine_triggered" );
    self endon( "death" );

    for (;;)
    {
        self waittill( "emp_damage", var_0, var_1 );
        equipmentempstunvfx();
        stopblinkinglight();

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

        self.disabled = 1;
        self notify( "disabled" );
        wait( var_1 );

        if ( isdefined( self ) )
        {
            self.disabled = undefined;
            self notify( "enabled" );
            var_2 = self getlinkedparent();
            thread mineproximitytrigger( var_2 );
        }
    }
}

mineselfdestruct()
{
    self endon( "mine_triggered" );
    self endon( "mine_destroyed" );
    self endon( "death" );
    wait( level.mineselfdestructtime + randomfloat( 0.4 ) );
    self notify( "mine_selfdestruct" );
    self notify( "detonateExplosive" );
}

minebounce()
{
    self playsound( self.config.onlaunchsfx );
    playfx( level.mine_launch, self.origin );

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

    var_0 = self.origin + ( 0, 0, 64 );
    self moveto( var_0, 0.7, 0, 0.65 );
    self.killcament moveto( var_0 + self.killcamoffset, 0.7, 0, 0.65 );
    self rotatevelocity( ( 0, 750, 32 ), 0.7, 0, 0.65 );
    thread playspinnerfx();
    wait 0.65;
    self notify( "detonateExplosive" );
}

mineexplodeonnotify()
{
    self endon( "death" );
    level endon( "game_ended" );
    self waittill( "detonateExplosive", var_0 );

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

    if ( !isdefined( var_0 ) )
        var_0 = self.owner;

    self playsound( self.config.onexplodesfx );
    var_1 = self gettagorigin( "tag_fx" );
    playfx( level.mine_explode, var_1 );
    self notify( "explode", var_1 );
    wait 0.05;

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

    self hide();
    self radiusdamage( self.origin, level.minedamageradius, level.minedamagemax, level.minedamagemin, var_0, "MOD_EXPLOSIVE", self.weapon_name );

    if ( isdefined( self.owner ) && isdefined( level.leaderdialogonplayer_func ) )
        self.owner thread [[ level.leaderdialogonplayer_func ]]( "mine_destroyed", undefined, undefined, self.origin );

    wait 0.2;
    deleteexplosive();
}

minesensorbounce()
{
    self playsound( self.config.onlaunchsfx );
    playfx( self.config.launchvfx, self.origin );

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

    self hidepart( "tag_sensor" );
    stopblinkinglight();
    var_0 = spawn( "script_model", self.origin );
    var_0.angles = self.angles;
    var_0 setmodel( self.config.model );
    var_0 hidepart( "tag_base" );
    var_0.config = self.config;
    self.sensor = var_0;
    var_1 = self.origin + ( 0, 0, self.config.launchheight );
    var_2 = self.config.launchtime;
    var_3 = self.config.launchtime + 0.1;
    var_0 moveto( var_1, var_3, 0, var_2 );
    var_0 rotatevelocity( ( 0, 1100, 32 ), var_3, 0, var_2 );
    var_0 thread playspinnerfx();
    wait( var_2 );
    self notify( "detonateExplosive" );
}

minesensoronnotify()
{
    self endon( "death" );
    level endon( "game_ended" );
    self waittill( "detonateExplosive", var_0 );

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

    if ( !isdefined( var_0 ) )
        var_0 = self.owner;

    self playsound( self.config.onexplodesfx );
    var_1 = undefined;

    if ( isdefined( self.sensor ) )
        var_1 = self.sensor gettagorigin( "tag_sensor" );
    else
        var_1 = self gettagorigin( "tag_origin" );

    playfx( self.config.onexplodevfx, var_1 );
    common_scripts\utility::waitframe();

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

    if ( isdefined( self.sensor ) )
        self.sensor delete();
    else
        self hidepart( "tag_sensor" );

    self.owner thread maps\mp\gametypes\_damagefeedback::updatedamagefeedback( "hitmotionsensor" );
    var_2 = [];

    foreach ( var_4 in level.characters )
    {
        if ( var_4.team == self.owner.team )
            continue;

        if ( !maps\mp\_utility::isreallyalive( var_4 ) )
            continue;

        if ( var_4 maps\mp\_utility::_hasperk( "specialty_heartbreaker" ) )
            continue;

        if ( distance2d( self.origin, var_4.origin ) < 300 )
            var_2[var_2.size] = var_4;
    }

    foreach ( var_7 in var_2 )
    {
        thread markplayer( var_7, self.owner );
        level thread sensorscreeneffects( var_7, self.owner );
    }

    if ( var_2.size > 0 )
    {
        self.owner maps\mp\gametypes\_missions::processchallenge( "ch_motiondetected", var_2.size );
        self.owner thread maps\mp\gametypes\_gamelogic::threadedsetweaponstatbyname( "motion_sensor", 1, "hits" );
    }

    if ( isdefined( self.owner ) && isdefined( level.leaderdialogonplayer_func ) )
        self.owner thread [[ level.leaderdialogonplayer_func ]]( "mine_destroyed", undefined, undefined, self.origin );

    wait 0.2;
    deleteexplosive();
}

markplayer( var_0, var_1 )
{
    if ( var_0 == var_1 )
        return;

    var_0 endon( "disconnect" );
    var_2 = undefined;

    if ( level.teambased )
        var_2 = maps\mp\_utility::outlineenableforteam( var_0, "orange", var_1.team, 0, "equipment" );
    else
        var_2 = maps\mp\_utility::outlineenableforplayer( var_0, "orange", var_1, 0, "equipment" );

    var_0 thread maps\mp\gametypes\_damagefeedback::updatedamagefeedback( "hitmotionsensor" );
    var_0.motionsensormarkedby = var_1;
    var_0 common_scripts\utility::waittill_any_timeout( self.config.markedduration, "death" );
    var_0.motionsensormarkedby = undefined;
    maps\mp\_utility::outlinedisable( var_2, var_0 );
}

sensorscreeneffects( var_0, var_1 )
{
    if ( var_0 == var_1 )
        return;

    if ( isai( var_0 ) )
        return;

    var_2 = "coup_sunblind";
    var_0 setclientomnvar( "ui_hud_shake", 1 );
    var_0 visionsetnakedforplayer( var_2, 0.05 );
    wait 0.05;
    var_0 visionsetnakedforplayer( var_2, 0 );
    var_0 visionsetnakedforplayer( "", 0.5 );
}

motionsensor_processtaggedassist( var_0 )
{
    if ( isdefined( level.assists_disabled ) )
        return;

    self.taggedassist = 1;

    if ( isdefined( var_0 ) )
        thread maps\mp\gametypes\_gamescore::processassist( var_0 );
    else
    {
        maps\mp\gametypes\_gamescore::giveplayerscore( "assist", self, undefined, 1 );
        thread maps\mp\gametypes\_rank::giverankxp( "assist" );
    }
}

playspinnerfx()
{
    if ( isdefined( self.config.mine_spin ) )
    {
        self endon( "death" );
        var_0 = gettime() + 1000;

        while ( gettime() < var_0 )
        {
            wait 0.05;
            playfxontag( self.config.mine_spin, self, "tag_fx_spin1" );
            playfxontag( self.config.mine_spin, self, "tag_fx_spin3" );
            wait 0.05;
            playfxontag( self.config.mine_spin, self, "tag_fx_spin2" );
            playfxontag( self.config.mine_spin, self, "tag_fx_spin4" );
        }
    }
}

minedamagedebug( var_0, var_1, var_2, var_3, var_4, var_5 )
{
    var_6[0] = ( 1, 0, 0 );
    var_6[1] = ( 0, 1, 0 );

    if ( var_1[2] < var_5 )
        var_7 = 0;
    else
        var_7 = 1;

    var_8 = ( var_0[0], var_0[1], var_5 );
    var_9 = ( var_1[0], var_1[1], var_5 );
    thread debugcircle( var_8, level.minedamageradius, var_6[var_7], 32 );
    var_10 = distancesquared( var_0, var_1 );

    if ( var_10 > var_2 )
        var_7 = 0;
    else
        var_7 = 1;

    thread debugline( var_8, var_9, var_6[var_7] );
}

minedamageheightpassed( var_0, var_1 )
{
    if ( isplayer( var_1 ) && isalive( var_1 ) && var_1.sessionstate == "playing" )
        var_2 = var_1 maps\mp\_utility::getstancecenter();
    else if ( var_1.classname == "misc_turret" )
        var_2 = var_1.origin + ( 0, 0, 32 );
    else
        var_2 = var_1.origin;

    var_3 = 0;
    var_4 = var_0.origin[2] + var_3 + level.minedamagehalfheight;
    var_5 = var_0.origin[2] + var_3 - level.minedamagehalfheight;

    if ( var_2[2] > var_4 || var_2[2] < var_5 )
        return 0;

    return 1;
}

mineused( var_0, var_1 )
{
    if ( !isalive( self ) )
    {
        var_0 delete();
        return;
    }

    maps\mp\gametypes\_gamelogic::sethasdonecombat( self, 1 );
    var_0 thread minethrown( self, var_0.weapon_name, var_1 );
}

minethrown( var_0, var_1, var_2 )
{
    self.owner = var_0;
    self waittill( "missile_stuck", var_3 );

    if ( !isdefined( var_0 ) )
        return;

    var_4 = bullettrace( self.origin + ( 0, 0, 4 ), self.origin - ( 0, 0, 4 ), 0, self );
    var_5 = var_4["position"];

    if ( var_4["fraction"] == 1 )
    {
        var_5 = getgroundposition( self.origin, 12, 0, 32 );
        var_4["normal"] = var_4["normal"] * -1;
    }

    var_6 = vectornormalize( var_4["normal"] );
    var_7 = vectortoangles( var_6 );
    var_7 = var_7 + ( 90, 0, 0 );
    var_8 = [[ var_2 ]]( var_5, var_0, var_1, var_7 );
    var_8 makeexplosiveusable();
    var_8 thread minedamagemonitor();
    self delete();
}

delete_all_grenades()
{
    if ( isdefined( self.plantedlethalequip ) )
    {
        foreach ( var_1 in self.plantedlethalequip )
            var_1 deleteexplosive();
    }

    if ( isdefined( self.plantedtacticalequip ) )
    {
        foreach ( var_1 in self.plantedtacticalequip )
            var_1 deleteexplosive();
    }

    if ( isdefined( self ) )
    {
        self.plantedlethalequip = [];
        self.plantedtacticalequip = [];
    }
}

transfer_grenade_ownership( var_0 )
{
    var_0 delete_all_grenades();

    if ( isdefined( self.plantedlethalequip ) )
        var_0.plantedlethalequip = common_scripts\utility::array_removeundefined( self.plantedlethalequip );

    if ( isdefined( self.plantedtacticalequip ) )
        var_0.plantedtacticalequip = common_scripts\utility::array_removeundefined( self.plantedtacticalequip );

    if ( isdefined( var_0.plantedlethalequip ) )
    {
        foreach ( var_2 in var_0.plantedlethalequip )
        {
            var_2.owner = var_0;
            var_2 thread equipmentwatchuse( var_0 );
        }
    }

    if ( isdefined( var_0.plantedtacticalequip ) )
    {
        foreach ( var_2 in var_0.plantedtacticalequip )
        {
            var_2.owner = var_0;
            var_2 thread equipmentwatchuse( var_0 );
        }
    }

    self.plantedlethalequip = [];
    self.plantedtacticalequip = [];
    self.dont_delete_grenades_on_next_spawn = 1;
    self.dont_delete_mines_on_next_spawn = 1;
}

doblinkinglight( var_0, var_1, var_2 )
{
    if ( !isdefined( var_1 ) )
        var_1 = common_scripts\utility::getfx( "weap_blink_friend" );

    if ( !isdefined( var_2 ) )
        var_2 = common_scripts\utility::getfx( "weap_blink_enemy" );

    self.blinkinglightfx["friendly"] = var_1;
    self.blinkinglightfx["enemy"] = var_2;
    self.blinkinglighttag = var_0;
    thread updateblinkinglight( var_1, var_2, var_0 );
    self waittill( "death" );
    stopblinkinglight();
}

updateblinkinglight( var_0, var_1, var_2 )
{
    self endon( "death" );
    self endon( "carried" );
    self endon( "emp_damage" );
    var_3 = ::checkteam;

    if ( !level.teambased )
        var_3 = ::checkplayer;

    var_4 = randomfloatrange( 0.05, 0.25 );
    wait( var_4 );
    childthread onjointeamblinkinglight( var_0, var_1, var_2, var_3 );

    foreach ( var_6 in level.players )
    {
        if ( isdefined( var_6 ) )
        {
            if ( self.owner [[ var_3 ]]( var_6 ) )
                playfxontagforclients( var_0, self, var_2, var_6 );
            else
                playfxontagforclients( var_1, self, var_2, var_6 );

            wait 0.05;
        }
    }
}

onjointeamblinkinglight( var_0, var_1, var_2, var_3 )
{
    self endon( "death" );
    level endon( "game_ended" );
    self endon( "emp_damage" );

    for (;;)
    {
        level waittill( "joined_team", var_4 );

        if ( self.owner [[ var_3 ]]( var_4 ) )
        {
            playfxontagforclients( var_0, self, var_2, var_4 );
            continue;
        }

        playfxontagforclients( var_1, self, var_2, var_4 );
    }
}

stopblinkinglight()
{
    if ( isalive( self ) && isdefined( self.blinkinglightfx ) )
    {
        stopfxontag( self.blinkinglightfx["friendly"], self, self.blinkinglighttag );
        stopfxontag( self.blinkinglightfx["enemy"], self, self.blinkinglighttag );
        self.blinkinglightfx = undefined;
        self.blinkinglighttag = undefined;
    }
}

checkteam( var_0 )
{
    return self.team == var_0.team;
}

checkplayer( var_0 )
{
    return self == var_0;
}

equipmentdeathvfx()
{
    playfx( common_scripts\utility::getfx( "equipment_sparks" ), self.origin );
    self playsound( "sentry_explode" );
}

equipmentdeletevfx()
{
    playfx( common_scripts\utility::getfx( "equipment_explode_big" ), self.origin );
    playfx( common_scripts\utility::getfx( "equipment_smoke" ), self.origin );
    self playsound( "mp_killstreak_disappear" );
}

equipmentempstunvfx()
{
    playfxontag( common_scripts\utility::getfx( "emp_stun" ), self, "tag_origin" );
}
