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

main()
{
    maps\mp\gametypes\_globallogic::init();
    maps\mp\gametypes\_callbacksetup::setupcallbacks();
    maps\mp\gametypes\_globallogic::setupcallbacks();

    if ( isusingmatchrulesdata() )
    {
        level.initializematchrules = ::initializematchrules;
        [[ level.initializematchrules ]]();
        level thread maps\mp\_utility::reinitializematchrulesonmigration();
    }
    else
    {
        maps\mp\_utility::registerroundswitchdvar( level.gametype, 0, 0, 9 );
        maps\mp\_utility::registertimelimitdvar( level.gametype, 0 );
        maps\mp\_utility::registerscorelimitdvar( level.gametype, 0 );
        maps\mp\_utility::registerroundlimitdvar( level.gametype, 1 );
        maps\mp\_utility::registerwinlimitdvar( level.gametype, 1 );
        maps\mp\_utility::registernumlivesdvar( level.gametype, 1 );
        maps\mp\_utility::registerhalftimedvar( level.gametype, 0 );
    }

    setdynamicdvar( "r_hudOutlineWidth", 1 );
    setdynamicdvar( "scr_horde_timeLimit", 0 );
    setdynamicdvar( "scr_horde_numLives", 1 );
    maps\mp\_utility::registertimelimitdvar( level.gametype, 0 );
    setspecialloadouts();
    initpickups();
    loadeffects();
    level.enablespecialround = 1;
    level.specialroundtime = 25;
    level.teambased = 1;
    level.ishorde = 1;
    level.disableforfeit = 1;
    level.nobuddyspawns = 1;
    level.alwaysdrawfriendlynames = 1;
    level.scorelimitoverride = 1;
    level.allowlatecomers = 1;
    level.skiplivesxpscalar = 1;
    level.highlightairdrop = 1;
    level.nocratetimeout = 1;
    level.noairdropkills = 1;
    level.allowlaststandai = 1;
    level.enableteamintel = 1;
    level.isteamintelcomplete = 1;
    level.removekillstreakicons = 1;
    level.assists_disabled = 1;
    level.skippointdisplayxp = 1;
    level.forceranking = 1;
    level.allowcamoswap = 0;
    level.allowfauxdeath = 0;
    level.killstreakrewards = 0;
    level.supportintel = 0;
    level.gamehasstarted = 0;
    level.donottrackgamesplayed = 1;
    level.disableweaponstats = 1;
    level.playerteam = "allies";
    level.enemyteam = "axis";
    level.laststandusetime = 2000;
    level.currentteamintelname = "";
    level.timeromnvars = [];
    level.onstartgametype = ::onstartgametype;
    level.getspawnpoint = ::getspawnpoint;
    level.onnormaldeath = ::onnormaldeath;
    level.onspawnplayer = ::onspawnplayer;
    level.modifyplayerdamage = ::modifyplayerdamagehorde;
    level.callbackplayerlaststand = maps\mp\gametypes\_horde_laststand::callback_playerlaststandhorde;
    level.ondeadevent = ::ondeadevent;
    level.customcratefunc = maps\mp\gametypes\_horde_crates::createhordecrates;
    level.onsuicidedeath = ::onnormaldeath;
    level.weapondropfunction = ::dropweaponfordeathhorde;
}

setupdialog()
{
    game["dialog"]["gametype"] = "infct_hint";
    game["dialog"]["offense_obj"] = "null";
    game["dialog"]["defense_obj"] = "null";
    game["dialog"]["mission_success"] = "sgd_end";
    game["dialog"]["mission_failure"] = "sgd_end_fail";
    game["dialog"]["mission_draw"] = "sgd_end_fail";
    game["dialog"]["round_end"] = "sgd_rnd_end";
    game["dialog"]["round_start"] = "sgd_rnd_start";
    game["dialog"]["round_loot"] = "sgd_plr_join";
    game["dialog"]["weapon_level"] = "sgd_prf_inc";
    game["dialog"]["max_ammo"] = "sgd_team_restock";
    game["dialog"]["support_drop"] = "sgd_supply_drop";
    game["dialog"]["ally_down"] = "sgd_ally_down";
    game["dialog"]["ally_dead"] = "sgd_ally_dead";
    game["dialog"]["dc"] = "sgd_plr_quit";
    game["dialog"]["squadmate"] = "sgd_squad";
}

loadeffects()
{
    level._effect["dropLocation"] = loadfx( "smoke/signal_smoke_airdrop" );
    level._effect["spawn_effect"] = loadfx( "fx/maps/mp_siege_dam/mp_siege_spawn" );
    level._effect["crate_teleport"] = loadfx( "vfx/gameplay/mp/core/vfx_teleport_player" );
    level._effect["loot_crtae"] = loadfx( "vfx/gameplay/mp/core/vfx_marker_base_cyan" );
    level._effect["weapon_level"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_3d_world_ping" );
}

initpickups()
{
    level.maxpickupsperround = getmaxpickupsperround();
    level.maxammopickupsperround = 1;
    level.currentpickupcount = 0;
    level.currentammopickupcount = 0;
    level.percentchancetodrop = getpercentchancetodrop();
    level.weaponpickupmodel = "mp_weapon_level_pickup_badge";
    level.weaponpickupfunc = ::weaponpickup;
    level.ammopickupmodel = "prop_mp_max_ammo_pickup";
    level.ammopickupfunc = ::ammopickup;
}

waitthenflashhudtimer( var_0 )
{
    maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_0 );
    settimeromnvar( "ui_cranked_bomb_timer_final_seconds", 1 );
}

sethudtimer( var_0, var_1 )
{
    level thread waitthenflashhudtimer( var_1 - 5 );
    settimeromnvar( "ui_cranked_bomb_timer_text", var_0 );
    settimeromnvar( "ui_cranked_bomb_timer_end_milliseconds", int( gettime() + var_1 * 1000 ) );
}

clearhudtimer()
{
    settimeromnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 );
}

settimeromnvar( var_0, var_1 )
{
    level.timeromnvars[var_0] = var_1;

    foreach ( var_3 in level.players )
        var_3 setclientomnvar( var_0, var_1 );
}

updatetimeromnvars( var_0 )
{
    foreach ( var_3, var_2 in level.timeromnvars )
        var_0 setclientomnvar( var_3, var_2 );
}

getmaxpickupsperround()
{
    var_0 = maps\mp\gametypes\_horde_util::getnumplayers() + 1;
    return clamp( var_0, 3, 5 );
}

getpercentchancetodrop()
{
    var_0 = 0;
    var_1 = maps\mp\gametypes\_horde_util::getnumplayers();

    switch ( var_1 )
    {
        case 0:
            var_0 = 0;
            break;
        case 1:
            var_0 = 14;
            break;
        case 2:
            var_0 = 13;
            break;
        case 3:
            var_0 = 12;
            break;
        case 4:
        default:
            var_0 = 10;
            break;
    }

    return var_0;
}

initializematchrules()
{
    maps\mp\_utility::setcommonrulesfrommatchrulesdata();
    setdynamicdvar( "scr_horde_roundswitch", 0 );
    maps\mp\_utility::registerroundswitchdvar( "horde", 0, 0, 9 );
    setdynamicdvar( "scr_horde_roundlimit", 1 );
    maps\mp\_utility::registerroundlimitdvar( "horde", 1 );
    setdynamicdvar( "scr_horde_winlimit", 1 );
    maps\mp\_utility::registerwinlimitdvar( "horde", 1 );
    setdynamicdvar( "scr_horde_halftime", 0 );
    maps\mp\_utility::registerhalftimedvar( "horde", 0 );
    setdynamicdvar( "scr_horde_promode", 0 );
    setdynamicdvar( "scr_horde_timeLimit", 0 );
    maps\mp\_utility::registertimelimitdvar( level.gametype, 0 );
    setdynamicdvar( "scr_horde_numLives", 1 );
    maps\mp\_utility::registernumlivesdvar( level.gametype, 1 );
    setdynamicdvar( "scr_horde_difficulty", getmatchrulesdata( "hordeData", "difficulty" ) );
    setdynamicdvar( "r_hudOutlineWidth", 1 );
}

onstartgametype()
{
    setclientnamemode( "auto_change" );

    if ( !isdefined( game["switchedsides"] ) )
        game["switchedsides"] = 0;

    maps\mp\_utility::setobjectivetext( "allies", &"HORDE_OBJECTIVE" );
    maps\mp\_utility::setobjectivetext( "axis", &"HORDE_OBJECTIVE" );
    maps\mp\_utility::setobjectivescoretext( "allies", &"HORDE_OBJECTIVE_SCORE" );
    maps\mp\_utility::setobjectivescoretext( "axis", &"HORDE_OBJECTIVE_SCORE" );
    maps\mp\_utility::setobjectivehinttext( "allies", &"HORDE_OBJECTIVE_HINT" );
    maps\mp\_utility::setobjectivehinttext( "axis", &"HORDE_OBJECTIVE_HINT" );
    initspawns();
    setupdialog();
    var_0[0] = level.gametype;
    maps\mp\gametypes\_gameobjects::main( var_0 );
    inithordesettings();
    level thread onplayerconnecthorde();
    level thread runhordemode();
    level thread rundroplocations();
}

inithordesettings()
{
    setdvar( "g_keyboarduseholdtime", 250 );
    level.hordedroplocations = common_scripts\utility::getstructarray( "horde_drop", "targetname" );
    level.blastshieldmod = 0.75;
    level.intelminigun = "iw6_minigunjugg_mp";
    level.hordedifficultylevel = int( clamp( getdvarint( "scr_horde_difficulty", 3 ), 1, 3 ) );
    level.maxrounds = getmaxrounds( level.hordedifficultylevel );
    level.currentroundnumber = 0;
    level.currentpointtotal = 0;
    level.enemyoutlinecolor = 4;
    level.droplocationindex = 0;
    hordedroplocationtrace();
    level.chancetospawndog = 0;
    level.lastdoground = 0;
    level.pointevents = [];
    level.pointevents["damage_body"] = 10;
    level.pointevents["damage_head"] = 30;
    level.pointevents["kill_normal"] = 20;
    level.pointevents["kill_melee"] = 50;
    level.pointevents["kill_head"] = 50;
    level.hudleftspace = 50;
    level.huddownspace = 395;
}

hordedroplocationtrace()
{
    foreach ( var_1 in level.hordedroplocations )
    {
        var_2 = var_1.origin + ( 0, 0, 32 );
        var_3 = var_1.origin - ( 0, 0, 256 );
        var_4 = bullettrace( var_2, var_3, 0 );
        var_1.tracelocation = var_1.origin;

        if ( var_4["fraction"] < 1 )
            var_1.tracelocation = var_4["position"];
    }
}

onplayerconnecthorde()
{
    for (;;)
    {
        level waittill( "connected", var_0 );
        var_0.gamemodefirstspawn = 1;
        var_0.hasusedsquadmate = 0;

        if ( level.currentroundnumber > 10 )
            var_0.hasusedsquadmate = 1;

        level thread createplayervariables( var_0 );
        level thread maps\mp\gametypes\_horde_crates::monitordoubletap( var_0 );
        level thread monitorstuck( var_0 );
        level thread updateoutlines( var_0 );
    }
}

createplayervariables( var_0 )
{
    var_0.weaponstate = [];
    var_0.horde_perks = [];
    var_0.pointnotifylua = [];
    var_0.beingrevived = 0;
    var_0.killz = 0;
    var_0.numrevives = 0;
    var_0.numcrtaescaptured = 0;
    var_0.roundsplayed = 0;
    var_0.maxweaponlevel = 1;
    level.playerstartweaponname = "iw6_mp443_mp_xmags";
    var_1 = getweaponbasename( level.playerstartweaponname );
    createhordeweaponstate( var_0, level.playerstartweaponname, 0 );
    createhordeweaponstate( var_0, level.intelminigun, 0 );
    level thread activateplayerhud( var_0 );
    level thread monitorweaponprogress( var_0 );
    level thread monitorpointnotifylua( var_0 );
}

createhordeweaponstate( var_0, var_1, var_2 )
{
    var_3 = getweaponbasename( var_1 );

    if ( hasweaponstate( var_0, var_3 ) )
        return;

    var_0.weaponstate[var_3]["level"] = 1;
    var_0.weaponstate[var_3]["vaule"] = 0;
    var_0.weaponstate[var_3]["barSize"] = 0;

    if ( var_2 )
        var_0.weaponstate[var_3]["barSize"] = getweaponbarsize( 1, var_3 );
}

hasweaponstate( var_0, var_1 )
{
    return isdefined( var_1 ) && isdefined( var_0.weaponstate[var_1] );
}

onspawnplayer()
{
    if ( self.gamemodefirstspawn )
    {
        self.pers["class"] = "gamemode";
        self.pers["lastClass"] = "";
        self.pers["gamemodeLoadout"] = level.hordeloadouts[level.playerteam];
        self.class = self.pers["class"];
        self.lastclass = self.pers["lastClass"];
    }

    if ( isagent( self ) )
    {
        if ( !maps\mp\gametypes\_horde_util::isonhumanteam( self ) )
        {
            setenemyagenthealth( self );
            setenemydifficultysettings( self );
            var_0 = gethordeenemyloadout();
            self.pers["gamemodeLoadout"] = var_0;
            self.agentname = var_0["name_localized"];
            self.horde_type = var_0["type"];
            thread maps\mp\agents\_agents_gametype_horde::playaispawneffect();
        }
        else
        {
            self.pers["gamemodeLoadout"] = level.hordeloadouts["squadmate"];
            maps\mp\bots\_bots_util::bot_set_personality( "camper" );
            maps\mp\bots\_bots_util::bot_set_difficulty( "regular" );
            self botsetdifficultysetting( "allowGrenades", 1 );
        }

        self.avoidkillstreakonspawntimer = 0;
    }

    thread onspawnfinished();
}

setenemydifficultysettings( var_0 )
{
    var_0 maps\mp\bots\_bots_util::bot_set_personality( "run_and_gun" );

    if ( level.currentroundnumber < 41 )
    {
        var_0 maps\mp\bots\_bots_util::bot_set_difficulty( "recruit" );
        var_0 botsetdifficultysetting( "visionBlinded", 0.05 );
        var_0 botsetdifficultysetting( "hearingDeaf", 0.05 );
        var_0 botsetdifficultysetting( "meleeReactAllowed", 1 );
        var_0 botsetdifficultysetting( "meleeReactionTime", 600 );
        var_0 botsetdifficultysetting( "meleeDist", 85 );
        var_0 botsetdifficultysetting( "meleeChargeDist", 100 );
        var_0 botsetdifficultysetting( "minGraceDelayFireTime", 0 );
        var_0 botsetdifficultysetting( "maxGraceDelayFireTime", 0 );
        var_0 botsetdifficultysetting( "minInaccuracy", 1.25 );
        var_0 botsetdifficultysetting( "maxInaccuracy", 1.75 );
        var_0 botsetdifficultysetting( "strafeChance", 0.25 );

        if ( level.currentroundnumber > 8 )
        {
            var_0 botsetdifficultysetting( "minInaccuracy", 0.75 );
            var_0 botsetdifficultysetting( "maxInaccuracy", 1.5 );
        }

        if ( level.currentroundnumber > 20 )
        {
            var_0 botsetdifficultysetting( "adsAllowed", 1 );
            var_0 botsetdifficultysetting( "diveChance", 0.15 );
        }
    }
    else if ( level.currentroundnumber > 50 )
        var_0 maps\mp\bots\_bots_util::bot_set_difficulty( "veteran" );
    else
        var_0 maps\mp\bots\_bots_util::bot_set_difficulty( "hardened" );

    var_0 botsetdifficultysetting( "allowGrenades", 0 );
    var_0 botsetdifficultysetting( "avoidSkyPercent", 0 );
}

giveenemyperks()
{
    if ( level.currentroundnumber > 15 )
        maps\mp\_utility::giveperk( "specialty_fastreload", 0 );

    if ( level.currentroundnumber > 20 )
        maps\mp\_utility::giveperk( "specialty_fastsprintrecovery", 0 );

    if ( level.currentroundnumber > 30 )
        maps\mp\_utility::giveperk( "specialty_lightweight", 0 );

    if ( level.currentroundnumber > 35 )
        maps\mp\_utility::giveperk( "specialty_quickdraw", 0 );

    if ( level.currentroundnumber > 40 )
        maps\mp\_utility::giveperk( "specialty_stalker", 0 );

    if ( level.currentroundnumber > 45 )
        maps\mp\_utility::giveperk( "specialty_marathon", 0 );

    if ( level.currentroundnumber > 50 )
        maps\mp\_utility::giveperk( "specialty_regenfaster", 0 );
}

setenemyagenthealth( var_0 )
{
    var_0.maxhealth = 60 + 20 * level.currentroundnumber;
    var_0.health = var_0.maxhealth;
}

onspawnfinished()
{
    self endon( "death" );
    self endon( "disconnect" );
    level endon( "game_ended" );
    self waittill( "giveLoadout" );
    maps\mp\killstreaks\_killstreaks::clearkillstreaks();

    if ( maps\mp\gametypes\_horde_util::isonhumanteam( self ) )
    {
        self givemaxammo( level.playerstartweaponname );
        thread playerammoregen( level.playerstartweaponname );

        if ( isplayer( self ) )
        {
            self setweaponammoclip( "proximity_explosive_mp", 1 );
            self setweaponammoclip( "concussion_grenade_mp", 1 );
            maps\mp\_utility::giveperk( "specialty_pistoldeath", 0 );

            if ( !self.hasusedsquadmate )
                thread maps\mp\killstreaks\_killstreaks::givekillstreak( "agent", 0, 0, self );

            childthread updaterespawnsplash( self.gamemodefirstspawn );
            removeperkhud( self );
            updatetimeromnvars( self );
        }

        if ( isagent( self ) )
        {
            self.agentname = &"HORDE_BUDDY";
            self.horde_type = "Buddy";
            childthread ammorefillprimary();
            thread maps\mp\bots\_bots::bot_think_revive();

            if ( isdefined( self.owner ) )
                self.owner.hasusedsquadmate = 1;
        }
    }
    else
    {
        childthread ammorefillprimary();
        childthread ammorefillsecondary();

        switch ( self.horde_type )
        {
            case "Ravager":
                setravagermodel();
                break;
            case "Enforcer":
                setenforcermodel();
                break;
            case "Striker":
                setstrikermodel();
                self botsetflag( "path_traverse_wait", 1 );
                break;
            case "Blaster":
                setblastermodel();
                self botsetdifficultysetting( "maxFireTime", 2800 );
                self botsetdifficultysetting( "minFireTime", 1500 );
                break;
            case "Hammer":
                sethammermodel();
                break;
            default:
        }

        self setviewmodel( "viewhands_juggernaut_ally" );
        self setclothtype( "cloth" );
        giveenemyperks();
    }

    self.gamemodefirstspawn = 0;
}

updaterespawnsplash( var_0 )
{
    self waittill( "spawned_player" );

    if ( !var_0 )
        thread maps\mp\gametypes\_hud_message::splashnotify( "horde_respawn" );
}

monitorstuck( var_0 )
{
    var_0 endon( "disconnect" );

    for (;;)
    {
        var_0 waittill( "unresolved_collision" );
        maps\mp\_movers::unresolved_collision_nearest_node( var_0, 0 );
        wait 0.5;
    }
}

updateoutlines( var_0 )
{
    var_0 endon( "disconnect" );

    if ( level.currentroundnumber == 0 )
        return;

    if ( !isdefined( level.carepackages ) )
        return;

    foreach ( var_2 in level.carepackages )
    {
        if ( isdefined( var_2.outlinecolor ) )
            var_2.friendlymodel hudoutlineenable( var_2.outlinecolor, 0 );
    }

    common_scripts\utility::waitframe();

    if ( !isdefined( level.characters ) )
        return;

    foreach ( var_5 in level.characters )
    {
        if ( isdefined( var_5.outlinecolor ) )
            var_5 hudoutlineenable( var_5.outlinecolor, 0 );
    }
}

setravagermodel()
{
    self setmodel( "mp_body_infected_a" );

    if ( isdefined( self.headmodel ) )
        self detach( self.headmodel, "" );

    self.headmodel = "head_mp_infected";
    self attach( self.headmodel, "", 1 );
}

setenforcermodel()
{
    self setmodel( "mp_body_juggernaut_light_black" );

    if ( isdefined( self.headmodel ) )
        self detach( self.headmodel, "" );

    self.headmodel = "head_juggernaut_light_black";
    self attach( self.headmodel, "", 1 );
}

setstrikermodel()
{
    self setmodel( "mp_body_infected_a" );

    if ( isdefined( self.headmodel ) )
        self detach( self.headmodel, "" );

    self.headmodel = "head_mp_infected";
    self attach( self.headmodel, "", 1 );
}

setblastermodel()
{
    self setmodel( "mp_fullbody_juggernaut_heavy_black" );

    if ( isdefined( self.headmodel ) )
    {
        self detach( self.headmodel, "" );
        self.headmodel = undefined;
    }
}

sethammermodel()
{
    self setmodel( "mp_body_juggernaut_light_black" );

    if ( isdefined( self.headmodel ) )
        self detach( self.headmodel, "" );

    self.headmodel = "head_juggernaut_light_black";
    self attach( self.headmodel, "", 1 );
}

playerammoregen( var_0 )
{
    self endon( "death" );
    self endon( "disconnect" );
    level endon( "game_ended" );
    var_1 = self getweaponslistprimaries();

    foreach ( var_3 in var_1 )
    {
        var_4 = weaponclipsize( var_3 );
        self setweaponammoclip( var_3, var_4 );
    }

    var_6 = 1.5;

    for (;;)
    {
        var_1 = self getweaponslistprimaries();

        foreach ( var_3 in var_1 )
        {
            if ( var_3 == var_0 )
            {
                var_8 = self getweaponammostock( var_3 );
                self setweaponammostock( var_3, var_8 + 1 );
            }
        }

        wait( var_6 );
    }
}

ammorefillprimary()
{
    if ( self.primaryweapon == "none" )
        return;

    for (;;)
    {
        self givemaxammo( self.primaryweapon );
        wait 12;
    }
}

ammorefillsecondary()
{
    if ( self.secondaryweapon == "none" )
        return;

    for (;;)
    {
        self givemaxammo( self.secondaryweapon );
        wait 8;
    }
}

runhordemode()
{
    level endon( "game_ended" );
    waituntilmatchstart();

    foreach ( var_1 in level.players )
    {
        if ( var_1.class == "" )
        {
            var_1 notify( "luinotifyserver", "class_select", 0 );
            var_1 thread closeclassmenu();
        }
    }

    for (;;)
    {
        updatehordesettings();
        shownextroundmessage();
        level notify( "start_round" );
        level.gamehasstarted = 1;
        assignintel();
        level childthread monitorroundend();
        level waittill( "round_ended" );
    }
}

closeclassmenu()
{
    self endon( "death" );
    self endon( "disconnect" );
    level endon( "game_ended" );
    common_scripts\utility::waitframe();
    self setclientomnvar( "ui_options_menu", -1 );
}

assignintel()
{
    if ( !( level.currentroundnumber % 4 ) && level.isteamintelcomplete )
        level notify( "giveTeamIntel", level.playerteam );

    if ( level.currentroundnumber == 21 && maps\mp\gametypes\_horde_util::getnumplayers() == 1 && !maps\mp\gametypes\_horde_util::hasagentsquadmember( level.players[0] ) )
        level.players[0] thread maps\mp\killstreaks\_killstreaks::givekillstreak( "agent", 0, 0, level.players[0] );
}

monitorroundend()
{
    if ( maps\mp\gametypes\_horde_util::isspecialround() )
        monitorspecialroundend();
    else
        monitornormalroundend();
}

monitornormalroundend()
{
    for (;;)
    {
        level waittill( "enemy_death" );

        if ( level.currentenemycount == level.maxenemycount && level.currentaliveenemycount == 0 )
        {
            notifyroundover();
            return;
        }
    }
}

monitorspecialroundend()
{
    var_0 = getspecialroundtimer();
    level thread maps\mp\gametypes\_horde_util::showteamsplashhorde( "horde_special_round" );
    sethudtimer( "round_time", var_0 );
    maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_0 );
    clearhudtimer();
    notifyroundover();
}

getspecialroundtimer()
{
    return level.specialroundtime;
}

notifyroundover()
{
    level notify( "round_ended" );
    level thread respawneliminatedplayers();
    level thread maps\mp\gametypes\_horde_util::playsoundtoallplayers( "mp_safe_round_end" );

    if ( !maps\mp\gametypes\_horde_util::isspecialround() )
        level thread maps\mp\_utility::leaderdialog( "round_end", level.playerteam, "status" );
}

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

    foreach ( var_1 in level.players )
    {
        if ( !maps\mp\gametypes\_horde_util::isonhumanteam( var_1 ) )
            continue;

        if ( maps\mp\gametypes\_horde_util::isplayerinlaststand( var_1 ) && !var_1.beingrevived )
            var_1 notify( "revive_trigger", var_1 );

        if ( var_1.sessionstate == "spectator" )
        {
            var_1.pers["lives"] = 1;
            var_1 thread maps\mp\gametypes\_playerlogic::spawnclient();
        }
    }
}

updateachievements()
{
    if ( level.currentroundnumber > 19 )
    {
        foreach ( var_1 in level.players )
            var_1 giveachievement( "EXTRA1" );
    }
}

updatehordesettings()
{
    updateachievements();

    if ( level.currentroundnumber == level.maxrounds )
    {
        level.finalkillcam_winner = level.playerteam;
        level thread maps\mp\gametypes\_gamelogic::endgame( level.playerteam, game["end_reason"][level.enemyteam + "_eliminated"] );
    }

    level.currentroundnumber = getnextroundnumber();
    level.maxenemycount = getmaxenemycount( level.currentroundnumber );
    level.currentenemycount = 0;
    level.maxaliveenemycount = getmaxaliveenemycount( level.currentroundnumber );
    level.currentaliveenemycount = 0;
    level.maxpickupsperround = getmaxpickupsperround();
    level.percentchancetodrop = getpercentchancetodrop();
    level.currentpickupcount = 0;
    level.currentammopickupcount = 0;
    level.chancetospawndog = 0;

    if ( chancefordoground() )
    {
        level.chancetospawndog = 55;
        level.lastdoground = level.currentroundnumber;
    }

    if ( level.currentroundnumber > 4 )
        setnojipscore( 1 );

    foreach ( var_1 in level.players )
    {
        var_1.roundsplayed++;

        if ( var_1.roundsplayed != level.currentroundnumber && var_1.roundsplayed > 9 )
            var_1.roundsplayed = level.currentroundnumber;

        maps\mp\gametypes\_horde_util::awardhorderoundnumber( var_1, var_1.roundsplayed );
    }
}

chancefordoground()
{
    if ( level.currentroundnumber < 4 )
        return 0;

    if ( maps\mp\gametypes\_horde_util::isspecialround( level.currentroundnumber ) )
        return 0;

    if ( level.lastdoground == level.currentroundnumber - 1 )
        return 0;

    if ( randomintrange( 1, 101 ) < 20 )
        return 1;

    if ( level.currentroundnumber - level.lastdoground > 4 )
        return 1;

    return 0;
}

getnextroundnumber()
{
    var_0 = level.currentroundnumber + 1;
    return var_0;
}

getrownumber( var_0 )
{
    var_0 = int( clamp( var_0, 1, 20 ) );
    var_0 = var_0 - 1;
    return var_0 * 4 + maps\mp\gametypes\_horde_util::getnumplayers();
}

getmaxrounds( var_0 )
{
    var_1 = 100;

    switch ( var_0 )
    {
        case 1:
        case 0:
            var_1 = 20;
            break;
        case 2:
            var_1 = 40;
            break;
        case 3:
            var_1 = 100;
            break;
        default:
            var_1 = 100;
            break;
    }

    return var_1;
}

getmaxenemycount( var_0 )
{
    var_1 = getrownumber( var_0 );
    var_2 = int( tablelookupbyrow( "mp/hordeSettings.csv", var_1, 1 ) );

    if ( var_0 > 20 )
    {
        var_3 = var_0 - 20;
        var_2 = var_2 + var_3;
    }

    return var_2;
}

getmaxaliveenemycount( var_0 )
{
    var_1 = getrownumber( var_0 );
    var_2 = int( tablelookupbyrow( "mp/hordeSettings.csv", var_1, 2 ) );

    if ( var_0 > 20 )
    {
        var_3 = var_0 - 20;
        var_4 = 1 + int( var_3 / 5 );
        var_2 = var_2 + 2 * var_4;
        var_2 = min( var_2, 20 );
    }

    return var_2;
}

waituntilmatchstart()
{
    maps\mp\_utility::gameflagwait( "prematch_done" );

    while ( !isdefined( level.bot_loadouts_initialized ) || level.bot_loadouts_initialized == 0 )
        common_scripts\utility::waitframe();

    while ( !level.players.size )
        common_scripts\utility::waitframe();
}

shownextroundmessage()
{
    if ( showintermissiontimer() )
        sethudtimer( "start_time", getroundintermissiontimer() );

    maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( getroundintermissiontimer() );
    clearhudtimer();
    setomnvar( "ui_horde_round_number", level.currentroundnumber );
    level thread respawneliminatedplayers();

    if ( !maps\mp\gametypes\_horde_util::isspecialround() )
    {
        var_0 = "mp_safe_round_start";

        if ( maps\mp\gametypes\_horde_util::isdoground() )
            var_0 = "mp_safe_round_boss";

        level childthread maps\mp\gametypes\_horde_util::playsoundtoallplayers( var_0 );
        level thread maps\mp\_utility::leaderdialog( "round_start", level.playerteam, "status" );
    }
    else
        level thread maps\mp\_utility::leaderdialog( "round_loot", level.playerteam, "status" );
}

showintermissiontimer()
{
    if ( level.currentroundnumber == 1 )
        return 0;

    if ( maps\mp\gametypes\_horde_util::isspecialround( level.currentroundnumber ) )
        return 0;

    if ( maps\mp\gametypes\_horde_util::isspecialround( level.currentroundnumber - 1 ) )
        return 0;

    return 1;
}

getroundintermissiontimer()
{
    if ( !showintermissiontimer() )
        return 5;

    return 20;
}

rundroplocations()
{
    level endon( "game_ended" );
    waituntilmatchstart();

    if ( !isdefined( level.hordedroplocations ) || !level.hordedroplocations.size )
        return;

    level childthread monitorsupportdropprogress();

    for (;;)
    {
        level waittill( "airSupport" );
        level childthread displayincomingairdropmessage();
        var_0 = maps\mp\gametypes\_horde_util::getnumplayers() + 1;
        var_0 = min( var_0, 4 );
        sortdroplocations();

        for ( var_1 = 0; var_1 < var_0; var_1++ )
        {
            var_2 = level.hordedroplocations[level.droplocationindex];
            level thread callairsupport( var_2.tracelocation );
            level.droplocationindex = getnextdroplocationindex( level.droplocationindex );
        }
    }
}

sortdroplocations()
{
    var_0 = ( 0, 0, 0 );
    var_1 = 0;

    foreach ( var_3 in level.players )
    {
        if ( !maps\mp\gametypes\_horde_util::isonhumanteam( var_3 ) || !isalive( var_3 ) )
            continue;

        var_1++;
        var_0 = var_0 + ( var_3.origin[0], var_3.origin[1], var_3.origin[2] );
    }

    var_5 = var_0 / var_1;
    level.hordedroplocations = sortbydistance( level.hordedroplocations, var_5 );
    level.droplocationindex = randomint( 3 );
}

getnextdroplocationindex( var_0 )
{
    var_1 = var_0 + 1;

    if ( var_1 == level.hordedroplocations.size )
        return 0;

    return var_1;
}

monitorsupportdropprogress()
{
    var_0 = getsupportbarsize();

    for (;;)
    {
        level common_scripts\utility::waittill_any( "pointsEarned", "host_migration_end" );

        if ( level.currentpointtotal >= var_0 )
        {
            level notify( "airSupport" );
            level.currentpointtotal = level.currentpointtotal - var_0;
            var_0 = getsupportbarsize();
        }

        setomnvar( "ui_horde_support_drop_progress", int( level.currentpointtotal / var_0 * 100 ) );
    }
}

getsupportbarsize()
{
    var_0 = getmaxenemycount( level.currentroundnumber );
    var_1 = int( level.currentroundnumber / 4 );
    var_2 = 45 + var_1 * 15;
    return var_0 * var_2;
}

activateplayerhud( var_0 )
{
    level endon( "game_ended" );
    var_0 endon( "disconnect" );
    var_0 waittill( "spawned_player" );
    common_scripts\utility::waitframe();
    var_1 = getarraykeys( var_0.weaponstate );

    foreach ( var_3 in var_1 )
        var_0.weaponstate[var_3]["barSize"] = getweaponbarsize( 1, var_3 );

    var_0 setclientomnvar( "ui_horde_weapon_progress", 0 );
    var_0 setclientomnvar( "ui_horde_weapon_level", 1 );
    var_5 = int( max( level.currentroundnumber, 1 ) );
    setomnvar( "ui_horde_round_number", var_5 );
    thread watchforhostmigrationsetround();
}

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

    for (;;)
    {
        level waittill( "host_migration_end" );
        var_0 = int( max( level.currentroundnumber, 1 ) );
        setomnvar( "ui_horde_round_number", var_0 );

        foreach ( var_2 in level.players )
        {
            if ( isai( var_2 ) )
                continue;

            if ( !isdefined( var_2 ) )
                continue;

            var_3 = maps\mp\gametypes\_horde_util::getplayerweaponhorde( var_2 );
            var_4 = getweaponbasename( var_3 );
            var_5 = var_2.weaponstate[var_4]["barSize"];
            var_2 setclientomnvar( "ui_horde_weapon_progress", int( var_2.weaponstate[var_4]["vaule"] / var_5 * 100 ) );
            var_2 setclientomnvar( "ui_horde_weapon_level", var_2.weaponstate[var_4]["level"] );

            if ( !isdefined( var_2.horde_perks ) )
                continue;

            if ( !var_2.horde_perks.size )
                continue;

            var_6 = var_2.horde_perks.size;

            for ( var_7 = 0; var_7 < var_6; var_7++ )
            {
                if ( !isdefined( var_2 ) )
                    continue;

                var_2 setclientomnvar( "ui_horde_update_perk", var_2.horde_perks[var_7]["index"] );
                wait 0.05;
            }
        }
    }
}

monitorweaponprogress( var_0 )
{
    level endon( "game_ended" );
    var_0 endon( "disconnect" );
    waituntilmatchstart();
    maps\mp\gametypes\_horde_util::awardhordweaponlevel( var_0, 1 );

    for (;;)
    {
        var_0 common_scripts\utility::waittill_any( "weaponPointsEarned", "weapon_change" );
        var_1 = maps\mp\gametypes\_horde_util::getplayerweaponhorde( var_0 );
        var_2 = getweaponbasename( var_1 );

        if ( !hasweaponstate( var_0, var_2 ) )
            continue;

        var_3 = var_0.weaponstate[var_2]["barSize"];

        if ( var_0.weaponstate[var_2]["vaule"] >= var_3 )
        {
            var_0 playlocalsound( "mp_safe_weapon_up" );
            playfx( level._effect["weapon_level"], var_0.origin + ( 0, 0, getweaponfxheight( var_0 ) ) );
            level thread updateweaponcamo( var_0, var_2, var_1 );
            var_0.weaponstate[var_2]["level"]++;
            var_0.weaponstate[var_2]["vaule"] = var_0.weaponstate[var_2]["vaule"] - var_3;

            if ( var_0.maxweaponlevel < var_0.weaponstate[var_2]["level"] )
            {
                var_0.maxweaponlevel = var_0.weaponstate[var_2]["level"];
                maps\mp\gametypes\_horde_util::awardhordweaponlevel( var_0, var_0.maxweaponlevel );
            }

            var_0 thread maps\mp\gametypes\_hud_message::splashnotify( "horde_weapon_level" );
            var_0.weaponstate[var_2]["barSize"] = getweaponbarsize( var_0.weaponstate[var_2]["level"], var_2 );
        }

        var_0 setclientomnvar( "ui_horde_weapon_progress", int( var_0.weaponstate[var_2]["vaule"] / var_3 * 100 ) );
        var_0 setclientomnvar( "ui_horde_weapon_level", var_0.weaponstate[var_2]["level"] );
    }
}

updateweaponcamo( var_0, var_1, var_2 )
{
    if ( !allowcamo( var_1 ) )
        return;

    level endon( "game_ended" );
    var_0 endon( "death" );
    var_0 endon( "disconnect" );
    var_0 notify( "camo_update" );
    var_0 endon( "camo_update" );
    var_3 = var_0 getweaponammoclip( var_2 );
    var_4 = var_0 getweaponammostock( var_2 );
    var_0 setweaponmodelvariant( var_2, getcamoindex( var_0.weaponstate[var_1]["level"] ) );
}

allowcamo( var_0 )
{
    if ( !level.allowcamoswap )
        return 0;

    switch ( var_0 )
    {
        case "iw6_m27_mp":
        case "iw6_ak12_mp":
        case "iw6_microtar_mp":
        case "iw6_vepr_mp":
        case "iw6_fp6_mp":
        case "iw6_mts255_mp":
        case "iw6_arx160_mp":
        case "iw6_kac_mp":
        case "iw6_usr_mp":
            return 1;
        default:
            return 0;
    }
}

getcamoindex( var_0 )
{
    var_1 = 0;
    var_2 = 4;

    switch ( var_0 )
    {
        case 1:
        case 0:
            var_1 = 0;
            break;
        case 2:
            var_1 = 1;
            break;
        case 3:
            var_1 = 2;
            break;
        case 4:
            var_1 = 3;
            break;
        case 5:
            var_1 = 4;
            break;
        case 7:
        case 6:
            var_1 = 5;
            break;
        case 9:
        case 8:
            var_1 = 6;
            break;
        case 11:
        case 10:
            var_1 = 7;
            break;
        case 13:
        case 12:
            var_1 = 8;
            break;
        case 15:
        case 14:
            var_1 = 9;
            break;
        case 17:
        case 16:
            var_1 = 10;
            break;
        case 19:
        case 18:
            var_1 = 11;
            break;
        case 21:
        case 20:
            var_1 = 12;
            break;
        case 23:
        case 22:
        default:
            var_1 = 13;
            break;
    }

    var_3 = tablelookup( "mp/camotable.csv", 0, var_1, var_2 );
    return int( var_3 );
}

getweaponfxheight( var_0 )
{
    var_1 = var_0 getstance();

    if ( var_1 == "stand" )
        return 48;

    if ( var_1 == "crouch" )
        return 32;

    return 12;
}

getweaponbarsize( var_0, var_1 )
{
    var_2 = weaponclass( var_1 ) == "sniper";
    var_3 = getmaxenemycount( var_0 );
    var_4 = var_3 * 0.8 * 45;

    if ( var_2 )
        var_4 = var_4 / 2.5;

    return var_4;
}

displayincomingairdropmessage()
{
    foreach ( var_1 in level.players )
    {
        if ( !maps\mp\gametypes\_horde_util::isonhumanteam( var_1 ) )
            continue;

        if ( var_1.sessionstate == "spectator" )
            continue;

        var_1 playlocalsound( "mp_safe_air_support" );
        var_1 thread maps\mp\gametypes\_hud_message::splashnotify( "horde_support_drop" );
    }
}

callairsupport( var_0 )
{
    playfx( level._effect["dropLocation"], var_0 + ( 0, 0, 2 ) );
    var_1 = "one";

    switch ( level.currentroundnumber )
    {
        case 3:
        case 2:
        case 1:
            var_1 = "a";
            break;
        case 6:
        case 5:
        case 4:
            var_1 = "b";
            break;
        case 9:
        case 8:
        case 7:
            var_1 = "c";
            break;
        case 12:
        case 11:
        case 10:
            var_1 = "d";
            break;
        default:
            var_1 = "e";
    }

    var_2 = level.players[0];

    foreach ( var_4 in level.players )
    {
        if ( !maps\mp\_utility::isreallyalive( var_4 ) )
            continue;

        if ( maps\mp\gametypes\_horde_util::isplayerinlaststand( var_4 ) )
            continue;

        var_2 = var_4;
        break;
    }

    if ( maps\mp\_utility::currentactivevehiclecount() > maps\mp\_utility::maxvehiclesallowed() || level.fauxvehiclecount + 1 > maps\mp\_utility::maxvehiclesallowed() )
        return;

    maps\mp\_utility::incrementfauxvehiclecount();
    level thread maps\mp\killstreaks\_airdrop::doflyby( var_2, var_0, randomfloat( 360 ), var_1 );
}

initspawns()
{
    level.spawnmins = ( 0, 0, 0 );
    level.spawnmaxs = ( 0, 0, 0 );
    maps\mp\gametypes\_spawnlogic::addstartspawnpoints( "mp_tdm_spawn_allies_start" );
    maps\mp\gametypes\_spawnlogic::addstartspawnpoints( "mp_tdm_spawn_axis_start" );
    maps\mp\gametypes\_spawnlogic::addspawnpoints( "allies", "mp_tdm_spawn" );
    maps\mp\gametypes\_spawnlogic::addspawnpoints( "axis", "mp_tdm_spawn" );
    level.mapcenter = maps\mp\gametypes\_spawnlogic::findboxcenter( level.spawnmins, level.spawnmaxs );
    setmapcenter( level.mapcenter );
}

getspawnpoint()
{
    if ( self.gamemodefirstspawn && isplayer( self ) )
        maps\mp\gametypes\_menus::addtoteam( level.playerteam, 1 );

    var_0 = self.team;

    if ( maps\mp\gametypes\_horde_util::isonhumanteam( self ) )
    {
        var_1 = maps\mp\gametypes\_spawnlogic::getteamspawnpoints( var_0 );

        if ( level.ingraceperiod )
            var_2 = maps\mp\gametypes\_spawnlogic::getspawnpoint_random( var_1 );
        else
            var_2 = maps\mp\gametypes\_spawnscoring::getspawnpoint_nearteam( var_1 );

        return var_2;
    }

    var_1 = maps\mp\gametypes\_spawnlogic::getteamspawnpoints( var_0 );
    var_2 = maps\mp\gametypes\_spawnscoring::getspawnpoint_safeguard( var_1 );
    return var_2;
}

getagentdamagescalar()
{
    var_0 = 0.25;
    var_1 = maps\mp\gametypes\_horde_util::getnumplayers();

    switch ( var_1 )
    {
        case 0:
            var_0 = 0.09;
            break;
        case 1:
            var_0 = 0.09;
            break;
        case 2:
            var_0 = 0.1;
            break;
        case 3:
            var_0 = 0.125;
            break;
        case 4:
        default:
            var_0 = 0.125;
            break;
    }

    return var_0;
}

modifyplayerdamagehorde( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 )
{
    if ( !isdefined( var_0 ) )
        return 0;

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

    if ( isdefined( var_1 ) && isplayer( var_1 ) )
    {
        if ( var_0 == var_1 && maps\mp\_utility::iskillstreakweapon( var_4 ) )
            var_2 = 0;

        var_8 = getweaponbasename( var_4 );

        if ( hasweaponstate( var_1, var_8 ) )
            var_2 = int( var_2 + var_2 * 0.1 * ( var_1.weaponstate[var_8]["level"] - 1 ) );

        if ( var_0.team == level.enemyteam && var_1.team == level.playerteam )
        {
            if ( var_3 == "MOD_MELEE" )
            {
                var_2 = var_0.maxhealth + 1;

                if ( var_0.horde_type == "Blaster" )
                    var_2 = int( var_0.maxhealth * 0.7 );
            }

            if ( maps\mp\_utility::iskillstreakweapon( var_4 ) )
                var_2 = int( var_2 + 20 * level.currentroundnumber );

            if ( isdefined( level.killstreakweildweapons[var_4] ) && level.killstreakweildweapons[var_4] == "heli_sniper" )
                var_2 = int( var_0.maxhealth ) + 1;

            if ( maps\mp\gametypes\_class::isvalidequipment( var_4, 0 ) )
            {
                if ( isexplosivedamagemod( var_3 ) )
                    var_2 = int( var_0.maxhealth ) + 1;

                if ( var_4 == "throwingknife_mp" )
                {
                    var_2 = var_0.maxhealth + 1;

                    if ( var_0.horde_type == "Blaster" )
                        var_2 = int( var_0.maxhealth * 0.7 );
                }
            }

            var_1 givepointsfordamage( var_0, var_2, var_3, var_4, var_5, var_6, var_7, 0 );
        }
    }

    if ( isdefined( var_1 ) && isdefined( var_1.owner ) && isplayer( var_1.owner ) )
    {
        var_9 = 0;

        if ( maps\mp\_utility::iskillstreakweapon( var_4 ) )
            var_2 = int( var_2 + 20 * level.currentroundnumber );

        if ( isagent( var_1 ) )
        {
            var_2 = int( var_2 + var_2 * 0.1 * ( level.currentroundnumber - 2 ) );
            var_9 = 1;
        }

        var_1.owner givepointsfordamage( var_0, var_2, var_3, var_4, var_5, var_6, var_7, var_9 );
    }

    if ( isplayer( var_0 ) || maps\mp\gametypes\_horde_util::isonhumanteam( var_0 ) )
    {
        if ( maps\mp\gametypes\_horde_util::isplayerinlaststand( var_0 ) && !var_0 maps\mp\_utility::touchingbadtrigger() )
            return 0;

        if ( isdefined( var_0.onhelisniper ) && var_0.onhelisniper )
            return 0;

        if ( var_4 == "semtexproj_mp" )
            var_2 = var_2 * 3;

        if ( isplayer( var_0 ) )
            var_2 = int( var_2 * 0.125 );
        else
            var_2 = int( var_2 * getagentdamagescalar() );

        if ( isdefined( var_1 ) && isagent( var_1 ) )
        {
            var_1 hudoutlineenable( level.enemyoutlinecolor, 0 );
            var_1.outlinecolor = level.enemyoutlinecolor;

            if ( var_3 == "MOD_MELEE" )
                var_2 = int( var_0.maxhealth / 2 ) + 1;

            if ( var_1.agent_type == "dog" )
                var_2 = int( var_0.maxhealth / 4 ) + 1;
        }

        if ( isdefined( var_0.isreviving ) && var_0.isreviving )
        {
            if ( isagent( var_0 ) )
                var_2 = 0;

            if ( isplayer( var_0 ) )
                var_2 = int( var_2 * 0.9 );
        }

        if ( var_0 maps\mp\_utility::isusingremote() && var_0 maps\mp\_utility::getremotename() == "remotemissile" )
            var_2 = int( var_2 * 0.9 );
    }

    return var_2;
}

givepointsfordamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 )
{
    var_8 = maps\mp\_utility::isheadshot( var_3, var_6, var_2, self );
    var_9 = var_2 == "MOD_MELEE" || var_2 == "MOD_IMPACT";
    var_10 = var_1 >= var_0.health;

    if ( var_9 && var_6 == "shield" )
        return;

    var_11 = undefined;

    if ( var_10 )
    {
        if ( var_9 )
            var_11 = "kill_melee";
        else if ( var_8 )
            var_11 = "kill_head";
        else
            var_11 = "kill_normal";

        self notify( "horde_kill", var_0, var_3, var_2 );
    }
    else if ( var_8 )
        var_11 = "damage_head";
    else
        var_11 = "damage_body";

    givepointsforevent( var_11, var_3, var_7 );
}

givepointsforevent( var_0, var_1, var_2 )
{
    var_3 = level.pointevents[var_0];
    self.pointnotifylua[self.pointnotifylua.size] = var_3;
    maps\mp\gametypes\_gamescore::giveplayerscore( var_0, self, undefined, 1, 1, 1 );
    thread maps\mp\gametypes\_rank::giverankxp( var_0 );
    level.currentpointtotal = level.currentpointtotal + var_3;
    level notify( "pointsEarned" );

    if ( var_2 )
        return;

    var_4 = getweaponbasename( var_1 );

    if ( hasweaponstate( self, var_4 ) )
    {
        self.weaponstate[var_4]["vaule"] = self.weaponstate[var_4]["vaule"] + var_3;
        self notify( "weaponPointsEarned" );
    }
}

monitorpointnotifylua( var_0 )
{
    level endon( "game_ended" );
    var_0 endon( "disconnect" );

    for (;;)
    {
        if ( var_0.pointnotifylua.size > 0 )
        {
            var_0 setclientomnvar( "ui_horde_award_points", var_0.pointnotifylua[var_0.pointnotifylua.size - 1] );
            var_0.pointnotifylua = removelastelement( var_0.pointnotifylua );
        }

        wait 0.05;
    }
}

removelastelement( var_0 )
{
    var_1 = [];

    for ( var_2 = 0; var_2 < var_0.size - 1; var_2++ )
        var_1[var_2] = var_0[var_2];

    return var_1;
}

onnormaldeath( var_0, var_1, var_2 )
{
    removeperkhud( var_0 );

    if ( !isdefined( var_1 ) )
        return;

    if ( game["state"] == "postgame" && game["teamScores"][var_1.team] > game["teamScores"][level.otherteam[var_1.team]] )
        var_1.finalkill = 1;
}

removeperkhud( var_0 )
{
    if ( isplayer( var_0 ) )
    {
        var_0 setclientomnvar( "ui_horde_update_perk", 0 );
        var_0.horde_perks = [];
    }
}

chancetospawnpickup( var_0 )
{
    if ( level.currentpickupcount == level.maxpickupsperround )
        return;

    level endon( "game_ended" );
    var_1 = randomintrange( 1, 101 );

    if ( var_1 > level.percentchancetodrop )
        return;

    var_2 = level.weaponpickupmodel;
    var_3 = level.weaponpickupfunc;

    if ( level.currentammopickupcount < level.maxammopickupsperround && common_scripts\utility::cointoss() )
    {
        var_2 = level.ammopickupmodel;
        var_3 = level.ammopickupfunc;
        level.currentammopickupcount++;
    }

    spawnpickup( var_0.origin + ( 0, 0, 14 ), var_2, var_3 );
}

spawnpickup( var_0, var_1, var_2 )
{
    var_3[0] = spawn( "script_model", ( 0, 0, 0 ) );
    var_3[0] setmodel( var_1 );
    var_3[0] hudoutlineenable( 1, 0 );
    var_4 = spawn( "trigger_radius", ( 0, 0, 0 ), 0, 32, 32 );
    var_5 = maps\mp\gametypes\_gameobjects::createuseobject( level.playerteam, var_4, var_3, ( 0, 0, 16 ) );
    maps\mp\_utility::_objective_delete( var_5.teamobjids["allies"] );
    maps\mp\_utility::_objective_delete( var_5.teamobjids["axis"] );
    maps\mp\gametypes\_objpoints::deleteobjpoint( var_5.objpoints["allies"] );
    maps\mp\gametypes\_objpoints::deleteobjpoint( var_5.objpoints["axis"] );
    var_6 = var_0;
    var_5.curorigin = var_6;
    var_5.trigger.origin = var_6;
    var_5.visuals[0].origin = var_6;
    var_5 maps\mp\gametypes\_gameobjects::setusetime( 0 );
    var_5 maps\mp\gametypes\_gameobjects::allowuse( "friendly" );
    var_5.onuse = var_2;
    level.currentpickupcount++;
    var_5 thread pickupbounce();
    var_5 thread pickuptimer();
}

pickupbounce()
{
    level endon( "game_ended" );
    self endon( "deleted" );
    self endon( "death" );
    var_0 = self;
    var_1 = self.curorigin;
    var_2 = self.curorigin + ( 0, 0, 12 );
    var_3 = 1.25;

    if ( isdefined( self.visuals ) && isdefined( self.visuals[0] ) )
        var_0 = self.visuals[0];

    for (;;)
    {
        var_0 moveto( var_2, var_3, 0.15, 0.15 );
        var_0 rotateyaw( 180, var_3 );
        wait( var_3 );
        var_0 moveto( var_1, var_3, 0.15, 0.15 );
        var_0 rotateyaw( 180, var_3 );
        wait( var_3 );
    }
}

pickuptimer()
{
    self endon( "deleted" );
    wait 15;
    thread pickupstartflashing();
    wait 8;
    level thread removepickup( self );
}

pickupstartflashing()
{
    self endon( "deleted" );

    for (;;)
    {
        self.visuals[0] hide();
        wait 0.25;
        self.visuals[0] show();
        wait 0.25;
    }
}

removepickup( var_0 )
{
    var_0 notify( "deleted" );
    wait 0.05;
    var_0.trigger delete();
    var_0.visuals[0] delete();
}

weaponpickup( var_0 )
{
    if ( !isplayer( var_0 ) )
        return;

    var_1 = maps\mp\gametypes\_horde_util::getplayerweaponhorde( var_0 );
    var_2 = getweaponbasename( var_1 );

    if ( hasweaponstate( var_0, var_2 ) )
    {
        var_3 = var_0.weaponstate[var_2]["barSize"];
        var_0.weaponstate[var_2]["vaule"] = var_3;
        var_0 notify( "weaponPointsEarned" );
    }

    level thread removepickup( self );
}

ammopickup( var_0 )
{
    foreach ( var_2 in level.players )
    {
        if ( maps\mp\gametypes\_horde_util::isonhumanteam( var_2 ) && maps\mp\_utility::isreallyalive( var_2 ) )
        {
            var_2 thread maps\mp\gametypes\_hud_message::splashnotify( "horde_team_restock" );
            maps\mp\gametypes\_horde_util::refillammohorde( var_2 );
            var_2.health = var_2.maxhealth;
        }
    }

    var_0 playlocalsound( "mp_safe_team_ammo" );
    playfx( level._effect["weapon_level"], var_0.origin + ( 0, 0, getweaponfxheight( var_0 ) ) );
    level thread removepickup( self );
}

hordemaydropweapon( var_0 )
{
    if ( var_0 == level.playerstartweaponname )
        return 0;

    return 1;
}

dropweaponfordeathhorde( var_0, var_1 )
{
    var_2 = maps\mp\gametypes\_horde_util::getplayerweaponhorde( self );

    if ( var_2 == level.intelminigun )
        var_2 = maps\mp\killstreaks\_killstreaks::getfirstprimaryweapon();

    if ( !hordemaydropweapon( var_2 ) )
        return;

    var_3 = ( 0, 0, 18 );
    var_4 = spawn( "script_model", self.origin + var_3 );
    var_4 hide();
    var_4 setmodel( "mp_weapon_crate" );
    var_4.owner = self;
    var_4.curorigin = self.origin + var_3;
    var_4.trackingweaponname = var_2;
    var_4 hudoutlineenable( 1, 0 );
    var_4.trigger = spawn( "trigger_radius", self.origin + var_3, 0, 32, 32 );

    foreach ( var_6 in level.players )
    {
        if ( var_4.owner == var_6 )
            var_4 showtoplayer( var_4.owner );
    }

    var_4 thread pickupbounce();
    var_4 thread watchweaponpickuphorde();
    var_4 thread removeweaponpickuphorde();
}

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

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

        if ( var_0 == self.owner )
            break;
    }

    maps\mp\gametypes\_horde_crates::trygivehordeweapon( var_0, self.trackingweaponname );
    var_0 thread maps\mp\gametypes\_hud_message::splashnotify( "horde_recycle" );
    var_0 playlocalsound( "mp_safe_weapon_up" );
    playfx( level._effect["weapon_level"], var_0.origin + ( 0, 0, getweaponfxheight( var_0 ) ) );
    self.trigger delete();
    self delete();
}

removeweaponpickuphorde()
{
    self endon( "death" );
    level endon( "game_ended" );
    self.owner common_scripts\utility::waittill_any( "started_spawnPlayer", "disconnect" );
    wait 22;
    thread startweaponpickupflashing();
    wait 8;

    if ( !isdefined( self ) )
        return;

    self.trigger delete();
    self delete();
}

startweaponpickupflashing()
{
    self endon( "trigger" );
    self endon( "death" );
    level endon( "game_ended" );

    for (;;)
    {
        self hide();
        wait 0.25;
        self showtoplayer( self.owner );
        wait 0.25;
    }
}

ondeadevent( var_0 )
{
    if ( var_0 != level.enemyteam )
    {
        iprintln( &"MP_GHOSTS_ELIMINATED" );
        logstring( "team eliminated, win: opfor, allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
        level.finalkillcam_winner = "axis";
        level thread maps\mp\gametypes\_gamelogic::endgame( "axis", game["end_reason"]["allies_eliminated"] );
    }
}

setspecialloadouts()
{
    level.hordeloadouts["allies"]["loadoutPrimary"] = "none";
    level.hordeloadouts["allies"]["loadoutPrimaryAttachment"] = "none";
    level.hordeloadouts["allies"]["loadoutPrimaryAttachment2"] = "none";
    level.hordeloadouts["allies"]["loadoutPrimaryBuff"] = "specialty_null";
    level.hordeloadouts["allies"]["loadoutPrimaryCamo"] = "none";
    level.hordeloadouts["allies"]["loadoutPrimaryReticle"] = "none";
    level.hordeloadouts["allies"]["loadoutSecondary"] = "iw6_mp443";
    level.hordeloadouts["allies"]["loadoutSecondaryAttachment"] = "xmags";
    level.hordeloadouts["allies"]["loadoutSecondaryAttachment2"] = "none";
    level.hordeloadouts["allies"]["loadoutSecondaryBuff"] = "specialty_null";
    level.hordeloadouts["allies"]["loadoutSecondaryCamo"] = "none";
    level.hordeloadouts["allies"]["loadoutSecondaryReticle"] = "none";
    level.hordeloadouts["allies"]["loadoutEquipment"] = "proximity_explosive_mp";
    level.hordeloadouts["allies"]["loadoutOffhand"] = "concussion_grenade_mp";
    level.hordeloadouts["allies"]["loadoutStreakType"] = "assault";
    level.hordeloadouts["allies"]["loadoutKillstreak1"] = "none";
    level.hordeloadouts["allies"]["loadoutKillstreak2"] = "none";
    level.hordeloadouts["allies"]["loadoutKillstreak3"] = "none";
    level.hordeloadouts["allies"]["loadoutJuggernaut"] = 0;
    level.hordeloadouts["allies"]["loadoutPerks"] = [ "specialty_falldamage" ];
    level.hordeloadouts["squadmate"]["loadoutPrimary"] = "iw6_ak12";
    level.hordeloadouts["squadmate"]["loadoutPrimaryAttachment"] = "none";
    level.hordeloadouts["squadmate"]["loadoutPrimaryAttachment2"] = "none";
    level.hordeloadouts["squadmate"]["loadoutPrimaryBuff"] = "specialty_null";
    level.hordeloadouts["squadmate"]["loadoutPrimaryCamo"] = "none";
    level.hordeloadouts["squadmate"]["loadoutPrimaryReticle"] = "none";
    level.hordeloadouts["squadmate"]["loadoutSecondary"] = "none";
    level.hordeloadouts["squadmate"]["loadoutSecondaryAttachment"] = "none";
    level.hordeloadouts["squadmate"]["loadoutSecondaryAttachment2"] = "none";
    level.hordeloadouts["squadmate"]["loadoutSecondaryBuff"] = "specialty_null";
    level.hordeloadouts["squadmate"]["loadoutSecondaryCamo"] = "none";
    level.hordeloadouts["squadmate"]["loadoutSecondaryReticle"] = "none";
    level.hordeloadouts["squadmate"]["loadoutEquipment"] = "proximity_explosive_mp";
    level.hordeloadouts["squadmate"]["loadoutOffhand"] = "concussion_grenade_mp";
    level.hordeloadouts["squadmate"]["loadoutStreakType"] = "assault";
    level.hordeloadouts["squadmate"]["loadoutKillstreak1"] = "none";
    level.hordeloadouts["squadmate"]["loadoutKillstreak2"] = "none";
    level.hordeloadouts["squadmate"]["loadoutKillstreak3"] = "none";
    level.hordeloadouts["squadmate"]["loadoutJuggernaut"] = 0;
    level.hordeloadouts["squadmate"]["loadoutPerks"] = [ "specialty_falldamage" ];
    level.hordeloadouts["axis"]["a"]["loadoutPrimary"] = "iw6_maul";
    level.hordeloadouts["axis"]["a"]["loadoutPrimaryAttachment"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutPrimaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutPrimaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["a"]["loadoutPrimaryCamo"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutPrimaryReticle"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutSecondary"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutSecondaryAttachment"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutSecondaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutSecondaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["a"]["loadoutSecondaryCamo"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutSecondaryReticle"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutEquipment"] = "specialty_null";
    level.hordeloadouts["axis"]["a"]["loadoutOffhand"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutStreakType"] = "assault";
    level.hordeloadouts["axis"]["a"]["loadoutKillstreak1"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutKillstreak2"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutKillstreak3"] = "none";
    level.hordeloadouts["axis"]["a"]["loadoutJuggernaut"] = 0;
    level.hordeloadouts["axis"]["a"]["name_localized"] = &"HORDE_RAVAGER";
    level.hordeloadouts["axis"]["a"]["type"] = "Ravager";
    level.hordeloadouts["axis"]["a"]["loadoutPerks"] = [ "specialty_falldamage" ];
    level.hordeloadouts["axis"]["b"]["loadoutPrimary"] = "iw6_vepr";
    level.hordeloadouts["axis"]["b"]["loadoutPrimaryAttachment"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutPrimaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutPrimaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["b"]["loadoutPrimaryCamo"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutPrimaryReticle"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutSecondary"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutSecondaryAttachment"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutSecondaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutSecondaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["b"]["loadoutSecondaryCamo"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutSecondaryReticle"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutEquipment"] = "specialty_null";
    level.hordeloadouts["axis"]["b"]["loadoutOffhand"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutStreakType"] = "assault";
    level.hordeloadouts["axis"]["b"]["loadoutKillstreak1"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutKillstreak2"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutKillstreak3"] = "none";
    level.hordeloadouts["axis"]["b"]["loadoutJuggernaut"] = 0;
    level.hordeloadouts["axis"]["b"]["name_localized"] = &"HORDE_ENFORCER";
    level.hordeloadouts["axis"]["b"]["type"] = "Enforcer";
    level.hordeloadouts["axis"]["b"]["loadoutPerks"] = [ "specialty_falldamage" ];
    level.hordeloadouts["axis"]["c"]["loadoutPrimary"] = "iw6_riotshield";
    level.hordeloadouts["axis"]["c"]["loadoutPrimaryAttachment"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutPrimaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutPrimaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["c"]["loadoutPrimaryCamo"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutPrimaryReticle"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutSecondary"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutSecondaryAttachment"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutSecondaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutSecondaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["c"]["loadoutSecondaryCamo"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutSecondaryReticle"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutEquipment"] = "specialty_null";
    level.hordeloadouts["axis"]["c"]["loadoutOffhand"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutStreakType"] = "assault";
    level.hordeloadouts["axis"]["c"]["loadoutKillstreak1"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutKillstreak2"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutKillstreak3"] = "none";
    level.hordeloadouts["axis"]["c"]["loadoutJuggernaut"] = 0;
    level.hordeloadouts["axis"]["c"]["name_localized"] = &"HORDE_STRIKER";
    level.hordeloadouts["axis"]["c"]["type"] = "Striker";
    level.hordeloadouts["axis"]["c"]["loadoutPerks"] = [ "specialty_falldamage" ];
    level.hordeloadouts["axis"]["d"]["loadoutPrimary"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutPrimaryAttachment"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutPrimaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutPrimaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["d"]["loadoutPrimaryCamo"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutPrimaryReticle"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutSecondary"] = "iw6_mk32horde";
    level.hordeloadouts["axis"]["d"]["loadoutSecondaryAttachment"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutSecondaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutSecondaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["d"]["loadoutSecondaryCamo"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutSecondaryReticle"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutEquipment"] = "specialty_null";
    level.hordeloadouts["axis"]["d"]["loadoutOffhand"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutStreakType"] = "assault";
    level.hordeloadouts["axis"]["d"]["loadoutKillstreak1"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutKillstreak2"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutKillstreak3"] = "none";
    level.hordeloadouts["axis"]["d"]["loadoutJuggernaut"] = 0;
    level.hordeloadouts["axis"]["d"]["name_localized"] = &"HORDE_BLASTER";
    level.hordeloadouts["axis"]["d"]["type"] = "Blaster";
    level.hordeloadouts["axis"]["d"]["loadoutPerks"] = [ "specialty_falldamage" ];
    level.hordeloadouts["axis"]["e"]["loadoutPrimary"] = "iw6_kac";
    level.hordeloadouts["axis"]["e"]["loadoutPrimaryAttachment"] = "flashsuppress";
    level.hordeloadouts["axis"]["e"]["loadoutPrimaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutPrimaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["e"]["loadoutPrimaryCamo"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutPrimaryReticle"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutSecondary"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutSecondaryAttachment"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutSecondaryAttachment2"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutSecondaryBuff"] = "specialty_null";
    level.hordeloadouts["axis"]["e"]["loadoutSecondaryCamo"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutSecondaryReticle"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutEquipment"] = "specialty_null";
    level.hordeloadouts["axis"]["e"]["loadoutOffhand"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutStreakType"] = "assault";
    level.hordeloadouts["axis"]["e"]["loadoutKillstreak1"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutKillstreak2"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutKillstreak3"] = "none";
    level.hordeloadouts["axis"]["e"]["loadoutJuggernaut"] = 0;
    level.hordeloadouts["axis"]["e"]["name_localized"] = &"HORDE_HAMMER";
    level.hordeloadouts["axis"]["e"]["type"] = "Hammer";
    level.hordeloadouts["axis"]["e"]["loadoutPerks"] = [ "specialty_falldamage" ];
}

gethordeenemyloadout()
{
    var_0 = level.hordeloadouts["axis"]["a"];

    if ( level.currentroundnumber < 5 )
        return var_0;

    if ( level.currentroundnumber < 9 )
    {
        if ( common_scripts\utility::cointoss() )
            var_0 = level.hordeloadouts["axis"]["b"];

        return var_0;
    }

    var_0 = level.hordeloadouts["axis"]["b"];

    if ( level.currentroundnumber < 13 )
    {
        if ( randomintrange( 1, 11 ) < 4 )
            var_0 = level.hordeloadouts["axis"]["c"];

        return var_0;
    }

    if ( level.currentroundnumber < 16 )
    {
        var_1 = randomintrange( 1, 11 );

        if ( var_1 < 4 )
            var_0 = level.hordeloadouts["axis"]["d"];

        return var_0;
    }

    if ( level.currentroundnumber < 24 )
    {
        var_1 = randomintrange( 1, 11 );

        if ( var_1 < 3 )
            var_0 = level.hordeloadouts["axis"]["c"];
        else if ( var_1 < 5 )
            var_0 = level.hordeloadouts["axis"]["d"];

        return var_0;
    }

    var_0 = level.hordeloadouts["axis"]["e"];
    var_1 = randomintrange( 1, 11 );

    if ( var_1 < 3 )
        var_0 = level.hordeloadouts["axis"]["c"];
    else if ( var_1 < 4 )
        var_0 = level.hordeloadouts["axis"]["d"];

    var_2 = 0;

    if ( var_0["type"] == "Blaster" )
    {
        var_3 = 0;

        foreach ( var_5 in level.participants )
        {
            if ( isai( var_5 ) && isdefined( var_5.horde_type ) )
            {
                if ( var_5.horde_type == var_0["type"] )
                {
                    var_3++;

                    if ( var_3 >= 4 )
                    {
                        var_2 = 1;
                        break;
                    }
                }
            }
        }
    }

    if ( var_2 )
    {
        var_0 = level.hordeloadouts["axis"]["a"];

        if ( common_scripts\utility::cointoss() )
            var_0 = level.hordeloadouts["axis"]["b"];
    }

    return var_0;
}
