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

main()
{
    setup_callbacks();
    level thread runroundspawning();
}

setup_callbacks()
{
    level.agent_funcs["player"]["onAIConnect"] = ::onaiconnect;
    level.agent_funcs["player"]["think"] = ::enemyagentthink;
    level.agent_funcs["player"]["on_killed"] = ::onagentkilled;
    level.agent_funcs["squadmate"]["onAIConnect"] = ::onaiconnect;
    level.agent_funcs["squadmate"]["think"] = ::allyagentthink;
    level.agent_funcs["dog"]["onAIConnect"] = ::onaiconnect;
    level.agent_funcs["dog"]["think"] = ::agentdogthink;
    level.agent_funcs["dog"]["on_killed"] = ::ondogkilled;
}

onaiconnect()
{
    self.gamemodefirstspawn = 1;
    self.agentname = &"HORDE_INFECTED";
    self.horde_type = "";
}

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

    for (;;)
    {
        level waittill( "start_round" );

        if ( maps\mp\gametypes\_horde_util::isspecialround() )
        {
            runspecialround();
            continue;
        }

        runnormalround();
    }
}

runspecialround()
{
    maps\mp\gametypes\_horde_crates::runlootdrop();
}

runnormalround()
{
    level childthread highlightlastenemies();

    while ( level.currentenemycount < level.maxenemycount )
    {
        while ( level.currentaliveenemycount < level.maxaliveenemycount )
        {
            createenemy();

            if ( level.currentenemycount == level.maxenemycount )
                break;
        }

        level waittill( "enemy_death" );
    }
}

createenemy()
{
    if ( maps\mp\gametypes\_horde_util::isdoground() && randomintrange( 1, 101 ) < level.chancetospawndog )
        createdogenemy();
    else
        createhumanoidenemy();
}

createhumanoidenemy()
{
    var_0 = undefined;

    while ( !isdefined( var_0 ) )
    {
        var_0 = maps\mp\agents\_agents::add_humanoid_agent( "player", level.enemyteam, "class1" );

        if ( isdefined( var_0 ) )
        {
            level.currentenemycount++;
            level.currentaliveenemycount++;
        }

        common_scripts\utility::waitframe();
    }
}

createdogenemy()
{
    var_0 = undefined;

    while ( !isdefined( var_0 ) )
    {
        var_0 = maps\mp\agents\_agent_common::connectnewagent( "dog", level.enemyteam );

        if ( isdefined( var_0 ) )
        {
            var_0 thread [[ var_0 maps\mp\agents\_agent_utility::agentfunc( "spawn" ) ]]();
            level.currentenemycount++;
            level.currentaliveenemycount++;
        }

        common_scripts\utility::waitframe();
    }
}

playaispawneffect()
{
    playfx( level._effect["spawn_effect"], self.origin );
}

highlightlastenemies()
{
    level endon( "round_ended" );

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

        if ( level.currentenemycount != level.maxenemycount )
            continue;

        if ( level.currentaliveenemycount < 3 )
        {
            foreach ( var_1 in level.characters )
            {
                if ( maps\mp\gametypes\_horde_util::isonhumanteam( var_1 ) )
                    continue;

                if ( maps\mp\_utility::isreallyalive( var_1 ) )
                {
                    var_1 hudoutlineenable( level.enemyoutlinecolor, 0 );
                    var_1.outlinecolor = level.enemyoutlinecolor;
                }
            }

            break;
        }
    }
}

onagentkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 )
{
    if ( !maps\mp\gametypes\_horde_util::isonhumanteam( self ) )
        hordeenemykilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 );

    self hudoutlinedisable();
    maps\mp\agents\_agents::on_humanoid_agent_killed_common( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, 0 );
    maps\mp\agents\_agent_utility::deactivateagent();
}

ondogkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 )
{
    if ( !maps\mp\gametypes\_horde_util::isonhumanteam( self ) )
        hordeenemykilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 );

    self hudoutlinedisable();
    maps\mp\killstreaks\_dog_killstreak::on_agent_dog_killed( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 );
}

hordeenemykilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 )
{
    level.currentaliveenemycount--;
    trackintelkills( var_4, var_3 );
    level thread maps\mp\gametypes\horde::chancetospawnpickup( self );
    level notify( "enemy_death" );

    if ( isplayer( var_1 ) )
    {
        maps\mp\gametypes\_horde_util::awardhordekill( var_1 );

        if ( var_1 maps\mp\_utility::_hasperk( "specialty_triggerhappy" ) )
            var_1 thread maps\mp\perks\_perkfunctions::settriggerhappyinternal();
    }

    if ( isdefined( var_1 ) && isdefined( var_1.owner ) && isplayer( var_1.owner ) && isdefined( var_1.owner.killz ) )
        maps\mp\gametypes\_horde_util::awardhordekill( var_1.owner );
}

trackintelkills( var_0, var_1 )
{
    if ( level.isteamintelcomplete )
        return;

    if ( var_0 == "none" )
        return;

    if ( var_1 == "MOD_MELEE" )
        level.nummeleekillsintel++;

    if ( !maps\mp\_utility::iskillstreakweapon( var_0 ) && var_1 == "MOD_HEAD_SHOT" )
        level.numheadshotsintel++;

    if ( maps\mp\_utility::iskillstreakweapon( var_0 ) && var_0 != level.intelminigun )
        level.numkillstreakkillsintel++;

    if ( maps\mp\gametypes\_class::isvalidequipment( var_0, 0 ) || maps\mp\gametypes\_class::isvalidoffhand( var_0, 0 ) )
        level.numequipmentkillsintel++;
}

enemyagentthink()
{
    self endon( "death" );
    level endon( "game_ended" );
    self botsetflag( "no_enemy_search", 1 );
    thread monitorbadhumanoidai();
    thread locateenemypositions();
}

monitorbadhumanoidai()
{
    self endon( "death" );
    level endon( "game_ended" );
    var_0 = gettime();

    for (;;)
    {
        wait 5.0;

        if ( !maps\mp\bots\_bots_util::bot_in_combat( 120000 ) )
        {
            outlinestuckai( self );

            if ( !maps\mp\bots\_bots_util::bot_in_combat( 240000 ) )
                break;
        }

        if ( checkexpiretime( var_0, 240, 480 ) )
            break;
    }

    maps\mp\agents\_agent_utility::killagent( self );
}

monitorbaddogai()
{
    self endon( "death" );
    level endon( "game_ended" );
    var_0 = gettime();
    var_1 = self.origin;
    var_2 = var_0;

    for (;;)
    {
        wait 5.0;
        var_3 = distancesquared( self.origin, var_1 );
        var_4 = ( gettime() - var_2 ) / 1000;

        if ( var_3 > 16384 )
        {
            var_1 = self.origin;
            var_2 = gettime();
        }
        else if ( var_4 > 25 )
        {
            outlinestuckai( self );

            if ( var_4 > 55 )
                break;
        }

        if ( checkexpiretime( var_0, 120, 240 ) )
            break;
    }

    maps\mp\agents\_agent_utility::killagent( self );
}

checkexpiretime( var_0, var_1, var_2 )
{
    var_3 = ( gettime() - var_0 ) / 1000;

    if ( var_3 > var_1 )
    {
        outlinestuckai( self );

        if ( var_3 > var_2 )
            return 1;
    }

    return 0;
}

outlinestuckai( var_0 )
{
    var_0 hudoutlineenable( level.enemyoutlinecolor, 0 );
    var_0.outlinecolor = level.enemyoutlinecolor;
}

allyagentthink()
{
    self endon( "death" );
    level endon( "game_ended" );
    self endon( "owner_disconnect" );
    self botsetflag( "force_sprint", 1 );
    var_0 = 0;
    var_1 = 0;

    for (;;)
    {
        if ( float( self.owner.health ) / self.owner.maxhealth < 0.5 && gettime() > var_1 )
        {
            var_2 = getnodesinradiussorted( self.owner.origin, 256, 0 );

            if ( var_2.size >= 2 )
            {
                self.defense_force_next_node_goal = var_2[1];
                self notify( "defend_force_node_recalculation" );
                var_1 = gettime() + 1000;
            }
        }
        else if ( float( self.health ) / self.maxhealth >= 0.6 )
            var_0 = 0;
        else if ( !var_0 )
        {
            var_3 = maps\mp\bots\_bots_util::bot_find_node_to_guard_player( self.owner.origin, 350, 1 );

            if ( isdefined( var_3 ) )
            {
                self.defense_force_next_node_goal = var_3;
                self notify( "defend_force_node_recalculation" );
                var_0 = 1;
            }
        }

        if ( !maps\mp\bots\_bots_util::bot_is_guarding_player( self.owner ) )
        {
            var_4["override_goal_type"] = "critical";
            var_4["min_goal_time"] = 20;
            var_4["max_goal_time"] = 30;
            maps\mp\bots\_bots_strategy::bot_guard_player( self.owner, 350, var_4 );
        }

        wait 0.05;
    }
}

hordesetupdogstate()
{
    maps\mp\_utility::_setnameplatematerial( "player_name_bg_green_dog", "player_name_bg_red_dog" );
    self.enableextendedkill = 0;
    self.agentname = &"HORDE_QUAD";
    self.horde_type = "Quad";
    self.lassetgoalpos = ( 0, 0, 0 );
    self.bhasnopath = 0;
    self.randompathstoptime = 0;
    maps\mp\gametypes\horde::setenemyagenthealth( self );
}

agentdogthink()
{
    self endon( "death" );
    level endon( "game_ended" );
    self endon( "owner_disconnect" );
    maps\mp\agents\dog\_dog_think::setupdogstate();
    hordesetupdogstate();
    thread locateenemypositions();
    self thread [[ self.watchattackstatefunc ]]();
    thread waitforbadpathhorde();
    thread monitorbaddogai();

    for (;;)
    {
        if ( self.aistate != "melee" && !self.statelocked && maps\mp\agents\dog\_dog_think::readytomeleetarget() && !maps\mp\agents\dog\_dog_think::didpastmeleefail() )
            self scragentbeginmelee( self.curmeleetarget );

        if ( self.randompathstoptime > gettime() )
        {
            wait 0.05;
            continue;
        }

        if ( !isdefined( self.enemy ) || self.bhasnopath )
        {
            var_0 = getnodesinradiussorted( self.origin, 1024, 256, 128, "Path" );

            if ( var_0.size > 0 )
            {
                var_1 = randomintrange( int( var_0.size * 0.9 ), var_0.size );
                self scragentsetgoalpos( var_0[var_1].origin );
                self.bhasnopath = 0;
                self.randompathstoptime = gettime() + 2500;
            }
        }
        else
        {
            var_2 = maps\mp\agents\dog\_dog_think::getattackpoint( self.enemy );
            self.curmeleetarget = self.enemy;
            self.movemode = "sprint";
            self.barrivalsenabled = 0;

            if ( distancesquared( var_2, self.lassetgoalpos ) > 4096 )
            {
                self scragentsetgoalpos( var_2 );
                self.lassetgoalpos = var_2;
            }
        }

        wait 0.05;
    }
}

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

    for (;;)
    {
        self waittill( "bad_path", var_0 );
        self.bhasnopath = 1;
    }
}

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

    for (;;)
    {
        foreach ( var_1 in level.participants )
        {
            if ( maps\mp\gametypes\_horde_util::isonhumanteam( var_1 ) )
                self getenemyinfo( var_1 );
        }

        wait 0.5;
    }
}

findclosestplayer()
{
    var_0 = undefined;
    var_1 = 1410065408;

    foreach ( var_3 in level.players )
    {
        if ( maps\mp\_utility::isreallyalive( var_3 ) && maps\mp\gametypes\_horde_util::isonhumanteam( var_3 ) && !maps\mp\gametypes\_horde_util::isplayerinlaststand( var_3 ) )
        {
            var_4 = distancesquared( var_3.origin, self.origin );

            if ( var_4 < var_1 )
            {
                var_0 = var_3;
                var_1 = var_4;
            }
        }
    }

    return var_0;
}
