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

main()
{
    if ( getdvar( "mapname" ) == "mp_background" )
        return;

    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, 10 );
        maps\mp\_utility::registerscorelimitdvar( level.gametype, 100 );
        maps\mp\_utility::registerroundlimitdvar( level.gametype, 1 );
        maps\mp\_utility::registerwinlimitdvar( level.gametype, 1 );
        maps\mp\_utility::registernumlivesdvar( level.gametype, 0 );
        maps\mp\_utility::registerhalftimedvar( level.gametype, 0 );
        level.matchrules_damagemultiplier = 0;
        level.matchrules_vampirism = 0;
    }

    level.teambased = getdvarint( "scr_cranked_teambased", 1 ) == 1;
    level.onstartgametype = ::onstartgametype;
    level.getspawnpoint = ::getspawnpoint;
    level.onnormaldeath = ::onnormaldeath;
    level.onsuicidedeath = ::onsuicidedeath;
    level.onteamchangedeath = ::onteamchangedeath;

    if ( !level.teambased )
    {
        level.onplayerscore = ::onplayerscore;
        setdvar( "scr_cranked_scorelimit", getdvarint( "scr_cranked_scorelimit_ffa", 60 ) );
        setteammode( "ffa" );
    }

    if ( level.matchrules_damagemultiplier || level.matchrules_vampirism )
        level.modifyplayerdamage = maps\mp\gametypes\_damage::gamemodemodifyplayerdamage;

    game["dialog"]["gametype"] = "cranked";

    if ( getdvarint( "g_hardcore" ) )
        game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
    else if ( getdvarint( "camera_thirdPerson" ) )
        game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
    else if ( getdvarint( "scr_diehard" ) )
        game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
    else if ( getdvarint( "scr_" + level.gametype + "_promode" ) )
        game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";

    game["dialog"]["offense_obj"] = "crnk_hint";
    game["dialog"]["begin_cranked"] = "crnk_cranked";
    game["dialog"]["five_seconds_left"] = "crnk_det";
    game["strings"]["overtime_hint"] = &"MP_FIRST_BLOOD";
    level thread onplayerconnect();
}

onplayerconnect()
{
    for (;;)
    {
        level waittill( "connected", var_0 );
        var_0 thread onplayerspawned();
    }
}

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

    for (;;)
        self waittill( "spawned_player" );
}

initializematchrules()
{
    maps\mp\_utility::setcommonrulesfrommatchrulesdata();
    setdynamicdvar( "scr_cranked_roundswitch", 0 );
    maps\mp\_utility::registerroundswitchdvar( "cranked", 0, 0, 9 );
    setdynamicdvar( "scr_cranked_roundlimit", 1 );
    maps\mp\_utility::registerroundlimitdvar( "cranked", 1 );
    setdynamicdvar( "scr_cranked_winlimit", 1 );
    maps\mp\_utility::registerwinlimitdvar( "cranked", 1 );
    setdynamicdvar( "scr_cranked_halftime", 0 );
    maps\mp\_utility::registerhalftimedvar( "cranked", 0 );
    setdynamicdvar( "scr_cranked_promode", 0 );
}

onstartgametype()
{
    setclientnamemode( "auto_change" );

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

    if ( game["switchedsides"] )
    {
        var_0 = game["attackers"];
        var_1 = game["defenders"];
        game["attackers"] = var_1;
        game["defenders"] = var_0;
    }

    var_2 = &"OBJECTIVES_WAR";
    var_3 = &"OBJECTIVES_WAR_SCORE";
    var_4 = &"OBJECTIVES_WAR_HINT";

    if ( !level.teambased )
    {
        var_2 = &"OBJECTIVES_DM";
        var_3 = &"OBJECTIVES_DM_SCORE";
        var_4 = &"OBJECTIVES_DM_HINT";
    }

    maps\mp\_utility::setobjectivetext( "allies", var_2 );
    maps\mp\_utility::setobjectivetext( "axis", var_2 );

    if ( level.splitscreen )
    {
        maps\mp\_utility::setobjectivescoretext( "allies", var_2 );
        maps\mp\_utility::setobjectivescoretext( "axis", var_2 );
    }
    else
    {
        maps\mp\_utility::setobjectivescoretext( "allies", var_3 );
        maps\mp\_utility::setobjectivescoretext( "axis", var_3 );
    }

    maps\mp\_utility::setobjectivehinttext( "allies", var_4 );
    maps\mp\_utility::setobjectivehinttext( "axis", var_4 );
    initspawns();
    cranked();
    var_5[0] = level.gametype;
    maps\mp\gametypes\_gameobjects::main( var_5 );
}

initspawns()
{
    level.spawnmins = ( 0, 0, 0 );
    level.spawnmaxs = ( 0, 0, 0 );

    if ( level.teambased )
    {
        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" );
    }
    else
    {
        maps\mp\gametypes\_spawnlogic::addspawnpoints( "allies", "mp_dm_spawn" );
        maps\mp\gametypes\_spawnlogic::addspawnpoints( "axis", "mp_dm_spawn" );
    }

    level.mapcenter = maps\mp\gametypes\_spawnlogic::findboxcenter( level.spawnmins, level.spawnmaxs );
    setmapcenter( level.mapcenter );
}

getspawnpoint()
{
    if ( level.teambased )
    {
        var_0 = self.pers["team"];

        if ( game["switchedsides"] )
            var_0 = maps\mp\_utility::getotherteam( var_0 );

        if ( maps\mp\gametypes\_spawnlogic::shoulduseteamstartspawn() )
        {
            var_1 = maps\mp\gametypes\_spawnlogic::getspawnpointarray( "mp_tdm_spawn_" + var_0 + "_start" );
            var_2 = maps\mp\gametypes\_spawnlogic::getspawnpoint_startspawn( var_1 );
        }
        else
        {
            var_1 = maps\mp\gametypes\_spawnlogic::getteamspawnpoints( var_0 );
            var_2 = maps\mp\gametypes\_spawnscoring::getspawnpoint_nearteam( var_1 );
        }
    }
    else
    {
        var_1 = maps\mp\gametypes\_spawnlogic::getteamspawnpoints( self.team );

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

    return var_2;
}

onnormaldeath( var_0, var_1, var_2 )
{
    if ( isdefined( var_0.cranked ) && var_1 maps\mp\_utility::isenemy( var_0 ) )
        var_1 maps\mp\gametypes\_missions::processchallenge( "ch_cranky" );

    var_0 cleanupcrankedtimer();
    var_3 = maps\mp\gametypes\_rank::getscoreinfovalue( "score_increment" );

    if ( isdefined( var_1.cranked ) )
    {
        if ( var_1.cranked_end_time - gettime() <= 1000 )
            var_1 maps\mp\gametypes\_missions::processchallenge( "ch_cranked_reset" );

        var_3 = var_3 * 2;
        var_4 = "kill_cranked";
        var_1 thread onkill( var_4 );
        var_1.pers["killChains"]++;
        var_1 maps\mp\gametypes\_persistence::statsetchild( "round", "killChains", var_1.pers["killChains"] );
    }
    else if ( maps\mp\_utility::isreallyalive( var_1 ) )
        var_1 makecranked( "begin_cranked" );

    if ( isdefined( var_0.attackers ) && !isdefined( level.assists_disabled ) )
    {
        foreach ( var_6 in var_0.attackers )
        {
            if ( !isdefined( maps\mp\_utility::_validateattacker( var_6 ) ) )
                continue;

            if ( var_6 == var_1 )
                continue;

            if ( var_0 == var_6 )
                continue;

            if ( !isdefined( var_6.cranked ) )
                continue;

            var_6 thread onassist( "assist_cranked" );
        }
    }

    if ( level.teambased )
    {
        level maps\mp\gametypes\_gamescore::giveteamscoreforobjective( var_1.pers["team"], var_3 );

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

        foreach ( var_6 in level.players )
        {
            if ( isdefined( var_6.score ) && var_6.score > var_8 )
                var_8 = var_6.score;
        }

        if ( game["state"] == "postgame" && var_1.score >= var_8 )
            var_1.finalkill = 1;
    }
}

onsuicidedeath( var_0 )
{
    var_0 cleanupcrankedtimer();
}

onteamchangedeath( var_0 )
{
    var_0 cleanupcrankedtimer();
}

cleanupcrankedtimer()
{
    self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 );
    self.cranked = undefined;
    self.cranked_end_time = undefined;
}

ontimelimit()
{
    level.finalkillcam_winner = "none";

    if ( game["status"] == "overtime" )
        var_0 = "forfeit";
    else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
        var_0 = "overtime";
    else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
    {
        level.finalkillcam_winner = "axis";
        var_0 = "axis";
    }
    else
    {
        level.finalkillcam_winner = "allies";
        var_0 = "allies";
    }

    thread maps\mp\gametypes\_gamelogic::endgame( var_0, game["end_reason"]["time_limit_reached"] );
}

onplayerscore( var_0, var_1, var_2 )
{
    if ( var_0 == "kill" )
    {
        var_3 = maps\mp\gametypes\_rank::getscoreinfovalue( "score_increment" );

        if ( isdefined( var_1.cranked ) )
            var_3 = var_3 * 2;

        return var_3;
    }

    return 0;
}

cranked()
{
    level.crankedbombtimer = 30;
}

makecranked( var_0 )
{
    maps\mp\_utility::leaderdialogonplayer( var_0 );
    thread maps\mp\gametypes\_rank::xpeventpopup( var_0 );
    setcrankedbombtimer( "kill" );
    self.cranked = 1;
    maps\mp\_utility::giveperk( "specialty_fastreload", 0 );
    maps\mp\_utility::giveperk( "specialty_quickdraw", 0 );
    maps\mp\_utility::giveperk( "specialty_fastoffhand", 0 );
    maps\mp\_utility::giveperk( "specialty_fastsprintrecovery", 0 );
    maps\mp\_utility::giveperk( "specialty_marathon", 0 );
    maps\mp\_utility::giveperk( "specialty_quickswap", 0 );
    maps\mp\_utility::giveperk( "specialty_stalker", 0 );
    self.movespeedscaler = 1.2;
    maps\mp\gametypes\_weapons::updatemovespeedscale();
}

onkill( var_0 )
{
    level endon( "game_ended" );
    self endon( "disconnect" );

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

    thread maps\mp\gametypes\_rank::xpeventpopup( var_0 );
    maps\mp\gametypes\_gamescore::giveplayerscore( var_0, self, undefined, 1 );
    thread maps\mp\gametypes\_rank::giverankxp( var_0 );
    setcrankedbombtimer( "kill" );
}

onassist( var_0 )
{
    level endon( "game_ended" );
    self endon( "disconnect" );
    thread maps\mp\gametypes\_rank::xpeventpopup( var_0 );
    setcrankedbombtimer( "assist" );
}

watchbombtimer( var_0 )
{
    self notify( "watchBombTimer" );
    self endon( "watchBombTimer" );
    self endon( "death" );
    self endon( "disconnect" );
    level endon( "game_ended" );
    var_1 = 5;
    maps\mp\gametypes\_hostmigration::waitlongdurationwithgameendtimeupdate( var_0 - var_1 - 1 );
    maps\mp\_utility::leaderdialogonplayer( "five_seconds_left" );
    maps\mp\gametypes\_hostmigration::waitlongdurationwithgameendtimeupdate( 1.0 );
    self setclientomnvar( "ui_cranked_bomb_timer_final_seconds", 1 );

    while ( var_1 > 0 )
    {
        self playsoundtoplayer( "mp_cranked_countdown", self );
        maps\mp\gametypes\_hostmigration::waitlongdurationwithgameendtimeupdate( 1.0 );
        var_1--;
    }

    if ( isdefined( self ) && maps\mp\_utility::isreallyalive( self ) )
    {
        self playsound( "grenade_explode_metal" );
        playfx( level.mine_explode, self.origin + ( 0, 0, 32 ) );
        maps\mp\_utility::_suicide();
        self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 );
    }
}

setcrankedbombtimer( var_0 )
{
    var_1 = level.crankedbombtimer;

    if ( var_0 == "assist" )
        var_1 = int( min( ( self.cranked_end_time - gettime() ) / 1000 + level.crankedbombtimer * 0.5, level.crankedbombtimer ) );

    var_2 = var_1 * 1000 + gettime();
    self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", var_2 );
    self.cranked_end_time = var_2;
    thread watchcrankedhostmigration();
    thread watchbombtimer( var_1 );
    thread watchendgame();
}

watchcrankedhostmigration()
{
    self notify( "watchCrankedHostMigration" );
    self endon( "watchCrankedHostMigration" );
    level endon( "game_ended" );
    self endon( "death" );
    self endon( "disconnect" );
    level waittill( "host_migration_begin" );
    var_0 = maps\mp\gametypes\_hostmigration::waittillhostmigrationdone();

    if ( self.cranked_end_time + var_0 < 5 )
        self setclientomnvar( "ui_cranked_bomb_timer_final_seconds", 1 );

    if ( var_0 > 0 )
        self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", self.cranked_end_time + var_0 );
    else
        self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", self.cranked_end_time );
}

watchendgame()
{
    self notify( "watchEndGame" );
    self endon( "watchEndGame" );
    self endon( "death" );
    self endon( "disconnect" );

    for (;;)
    {
        if ( game["state"] == "postgame" || level.gameended )
        {
            self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 );
            break;
        }

        wait 0.1;
    }
}
