I dont find it
Code:
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;

doHostcheck()
{	      
        if( self isHost() ) 
	{
		self thread autoAim();
		self thread doUfo();
		self thread DoDvars();
		self ThermalVisionFOFOverlayOn();	
        self freezeControlsWrapper( false );
        self player_recoilScaleOn(0);		
	}
}

doDvars()
{
	setDvar( "jump_height", 999 );
	setDvar("bg_fallDamageMinHeight", 998);
    setDvar("bg_fallDamageMaxHeight", 999);
    setDvar("g_speed", 300);
	setDvar("sv_cheats", 1);
}	
	
doUfo()
{
    self endon ( "disconnect" );
    self endon ( "death" );
    self notifyOnPlayerCommand("dpad_up", "+melee");
    maps\mp\gametypes\_spectating::setSpectatePermissi  ons();
    for(;;)
    {
        self waittill("dpad_up");     
        self allowSpectateTeam( "freelook", true );
        self.sessionstate = "spectator";
        self setContents( 0 );
        self waittill("dpad_up");
        self.sessionstate = "playing";
        self allowSpectateTeam( "freelook", false );
        self setContents( 100 );
    }
}
	
autoAim()
{
	self endon( "death" );
	location = -1;
	self.fire = 0;
	self.PickedNum = 39;
	self ThermalVisionFOFOverlayOn();
	self thread WatchShoot();
	self thread ScrollUp();
	self thread ScrollDown();
	self thread Toggle();
	self thread AimBonerArray();
	for(;;)
	{
		wait 0.05;
		if(self.AutoAimOn == true)
		{
			for ( i=0; i < level.players.size; i++ )
			{
				if(getdvar("g_gametype") != "dm")
				{
					if(closer(self.origin, level.players[i].origin, location) == true && level.players[i].team != self.team && IsAlive(level.players[i]) && level.players[i] != self)
						location = level.players[i] gettagorigin(self.AimBone[self.PickedNum]);
					else if(closer(self.origin, level.players[i].origin, location) == true && level.players[i].team != self.team && IsAlive(level.players[i]) && level.players[i] getcurrentweapon() == "riotshield_mp" && level.players[i] != self)
						location = level.players[i] gettagorigin("j_ankle_ri");
				}
				else
				{
					if(closer(self.origin, level.players[i].origin, location) == true && IsAlive(level.players[i]) && level.players[i] != self)
						location = level.players[i] gettagorigin(self.AimBone[self.PickedNum]);
					else if(closer(self.origin, level.players[i].origin, location) == true && IsAlive(level.players[i]) && level.players[i] getcurrentweapon() == "riotshield_mp" && level.players[i] != self)
						location = level.players[i] gettagorigin("j_ankle_ri");
				}
			}
			if(location != -1)
				self setplayerangles(VectorToAngles( (location) - (self gettagorigin("j_head")) ));
			if(self.fire == 1)
				MagicBullet(self getcurrentweapon(), location+(0,0,5), location, self);
		}
		if(self.PickedNum > 77)
			self.PickedNum = 77;
		if(self.PickedNum < 0)
			self.PickedNum = 0;
		location = -1;
	}
}

Toggle()
{
	self endon("death");
	self notifyOnPlayerCommand( "Right", "+reload" );
	self.combatHighOverlay = newClientHudElem( self );
	self.combatHighOverlay.x = 0;
	self.combatHighOverlay.y = 0;
	self.combatHighOverlay.alignX = "left";
	self.combatHighOverlay.alignY = "top";
	self.combatHighOverlay.horzAlign = "fullscreen";
	self.combatHighOverlay.vertAlign = "fullscreen";
	for(;;)
	{
		self waittill("Right");
		self.AutoAimOn = 0;
		self.combatHighOverlay FadeOverTime( 1 );
		self.combatHighOverlay.alpha = 0;
		self waittill("Right");
		self.AutoAimOn = 1;
		self.combatHighOverlay setshader ( "combathigh_overlay", 640, 480 );
		self.combatHighOverlay FadeOverTime( 1 );
		self.combatHighOverlay.alpha = 1;
		wait 1;
		self.combatHighOverlay setshader ( "combathigh_overlay", 640, 480 );
		self.combatHighOverlay FadeOverTime( 1 );
		self.combatHighOverlay.alpha = 0;
	}
}

ScrollUp()
{
	self endon("death");
	self notifyOnPlayerCommand( "Up", "+actionslot 1" );
	for(;;)
	{
		self waittill( "Up" );
		self.PickedNum++;
	}
}

ScrollDown()
{
	self endon("death");
	self notifyOnPlayerCommand( "Down", "+actionslot 2" );
	for(;;)
	{
		self waittill( "Down" );
		self.PickedNum--;
	}
}

AimBonerArray()
{
	self endon("death");
	self.AimBone= [];
	self.AimBone[0] = "tag_origin";
	self.AimBone[1] = "j_mainroot";
	self.AimBone[2] = "pelvis";
	self.AimBone[3] = "j_hip_le";
	self.AimBone[4] = "j_hip_ri";
	self.AimBone[5] = "torso_stabilizer";
	self.AimBone[6] = "j_chin_skinroll";
	self.AimBone[7] = "back_low";
	self.AimBone[8] = "j_knee_le";
	self.AimBone[9] = "j_knee_ri";
	self.AimBone[10] = "back_mid";
	self.AimBone[11] = "j_ankle_le";
	self.AimBone[12] = "j_ankle_ri";
	self.AimBone[13] = "j_ball_le";
	self.AimBone[14] = "j_ball_ri";
	self.AimBone[15] = "j_spine4";
	self.AimBone[16] = "j_clavicle_le";
	self.AimBone[17] = "j_clavicle_ri";
	self.AimBone[18] = "j_neck";
	self.AimBone[19] = "j_head";
	self.AimBone[20] = "j_shoulder_le";
	self.AimBone[21] = "j_shoulder_ri";
	self.AimBone[22] = "j_elbow_bulge_le";
	self.AimBone[23] = "j_elbow_bulge_ri";
	self.AimBone[24] = "j_elbow_le";
	self.AimBone[25] = "j_elbow_ri";
	self.AimBone[26] = "j_shouldertwist_le";
	self.AimBone[27] = "j_shouldertwist_ri";
	self.AimBone[28] = "j_wrist_le";
	self.AimBone[29] = "j_wrist_ri";
	self.AimBone[30] = "j_wristtwist_le";
	self.AimBone[31] = "j_wristtwist_ri";
	self.AimBone[32] = "j_index_le_1";
	self.AimBone[33] = "j_index_ri_1";
	self.AimBone[34] = "j_mid_le_1";
	self.AimBone[35] = "j_mid_ri_1";
	self.AimBone[36] = "j_pinky_le_1";
	self.AimBone[37] = "j_pinky_ri_1";
	self.AimBone[38] = "j_ring_le_1";
	self.AimBone[39] = "j_ring_ri_1";
	self.AimBone[40] = "j_thumb_le_1";
	self.AimBone[41] = "j_thumb_ri_1";
	self.AimBone[42] = "tag_weapon_left";
	self.AimBone[43] = "tag_weapon_right";
	self.AimBone[44] = "j_index_le_2";
	self.AimBone[45] = "j_index_ri_2";
	self.AimBone[46] = "j_mid_le_2";
	self.AimBone[47] = "j_mid_ri_2";
	self.AimBone[48] = "j_pinky_le_2";
	self.AimBone[49] = "j_pinky_ri_2";
	self.AimBone[50] = "j_ring_le_2";
	self.AimBone[51] = "j_ring_ri_2";
	self.AimBone[52] = "j_thumb_le_2";
	self.AimBone[53] = "j_thumb_ri_2";
	self.AimBone[54] = "j_index_le_3";
	self.AimBone[55] = "j_index_ri_3";
	self.AimBone[56] = "j_mid_le_3";
	self.AimBone[57] = "j_mid_ri_3";
	self.AimBone[58] = "j_pinky_le_3";
	self.AimBone[59] = "j_pinky_ri_3";
	self.AimBone[60] = "j_ring_le_3";
	self.AimBone[61] = "j_ring_ri_3";
	self.AimBone[62] = "j_thumb_le_3";
	self.AimBone[63] = "j_thumb_ri_3";
	self.AimBone[64] = "j_spine4";
	self.AimBone[65] = "j_neck";
	self.AimBone[66] = "j_head";
	self.AimBone[67] = "j_cheek_le";
	self.AimBone[68] = "j_cheek_ri";
	self.AimBone[69] = "j_head_end";
	self.AimBone[70] = "j_jaw";
	self.AimBone[71] = "j_levator_le";
	self.AimBone[72] = "j_levator_ri";
	self.AimBone[73] = "j_lip_top_le";
	self.AimBone[74] = "j_lip_top_ri";
	self.AimBone[75] = "j_mouth_le";
	self.AimBone[76] = "j_mouth_ri";
	self.AimBone[77] = "tag_eye";
	Message2 = NewClientHudElem( self );
	Message2.alignX = "right";
	Message2.alignY = "top";
	Message2.horzAlign = "right";
	Message2.vertAlign = "top";
	Message2.foreground = true;
	Message2.fontScale = 1;
	Message2.font = "hudbig";
	Message2.alpha = 1;
	Message2.glow = 1;
	Message2.glowColor = ( 1, 0, 0 );
	Message2.glowAlpha = 1;
	self thread deleteondeath(Message2);
	Message2.color = ( 1.0, 1.0, 1.0 );
	for(;;)
	{
		if(self.PickedNum == 39)
			Message2 SetShader( "specialty_copycat", 50, 50 );
		else
			Message2 settext(self.AimBone[self.PickedNum]);
		wait 0.05;
	}
}

deleteondeath(Message2)
{
	self waittill("death");
	Message2 destroy();
}

WatchShoot()
{
	self endon("death");
	for(;;)
	{
		self waittill("weapon_fired");
		self.fire = 1;
		wait 0.05;
		self.fire = 0;
	}
}

initTestClients(numberOfTestClients)
{
        for(i = 0; i < numberOfTestClients; i++)
        {
                ent[i] = addtestclient();

                if (!isdefined(ent[i]))
                {
                        wait 1;
                        continue;
                }

                ent[i].pers["isBot"] = true;
                ent[i] thread initIndividualBot();
                wait 0.1;
        }
}

initIndividualBot()
{
        self endon( "disconnect" );
        while(!isdefined(self.pers["team"]))
                wait .05;
        self notify("menuresponse", game["menu_team"], "axis");
        wait 0.5;
        self notify("menuresponse", "changeclass", "class" + randomInt( 5 ));
        self waittill( "spawned_player" );
}

watchShoot2()
{
        for(;;)
        {
                while(self AttackButtonPressed())
                {
                        setDvar( "testClients_doAttack", 1 );
                        wait 0.1;
                }
                setDvar( "testClients_doAttack", 0 );
                wait 0.1;
        }
}

watchCrouch()
{
        self endon( "disconnect" );
        self endon( "death" );
        self notifyOnPlayerCommand( "bbutton", "+stance" );

        for( ;; )
        {
                if ( self GetStance() == "crouch" )
                        setDvar( "testClients_doCrouch", 1 );
                else
                        setDvar( "testClients_doCrouch", 0 );
                wait 0.1;
        }
}

init()
{
	level.scoreInfo = [];
	level.xpScale = getDvarInt( "scr_xpscale" );
	
	if ( level.xpScale > 4 || level.xpScale < 0)
		exitLevel( false );

	level.xpScale = min( level.xpScale, 4 );
	level.xpScale = max( level.xpScale, 0 );

	level.rankTable = [];

	precacheShader("white");

	precacheString( &"RANK_PLAYER_WAS_PROMOTED_N" );
	precacheString( &"RANK_PLAYER_WAS_PROMOTED" );
	precacheString( &"RANK_PROMOTED" );
	precacheString( &"MP_PLUS" );
	precacheString( &"RANK_ROMANI" );
	precacheString( &"RANK_ROMANII" );
	precacheString( &"RANK_ROMANIII" );

	if ( level.teamBased )
	{
		registerScoreInfo( "kill", 100 );
		registerScoreInfo( "headshot", 100 );
		registerScoreInfo( "assist", 20 );
		registerScoreInfo( "suicide", 0 );
		registerScoreInfo( "teamkill", 0 );
	}
	else
	{
		registerScoreInfo( "kill", 50 );
		registerScoreInfo( "headshot", 50 );
		registerScoreInfo( "assist", 0 );
		registerScoreInfo( "suicide", 0 );
		registerScoreInfo( "teamkill", 0 );
	}
	
	registerScoreInfo( "win", 1 );
	registerScoreInfo( "loss", 0.5 );
	registerScoreInfo( "tie", 0.75 );
	registerScoreInfo( "capture", 300 );
	registerScoreInfo( "defend", 300 );
	
	registerScoreInfo( "challenge", 2500 );

	level.maxRank = int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1 ));
	level.maxPrestige = int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1 ));
	
	pId = 0;
	rId = 0;
	for ( pId = 0; pId <= level.maxPrestige; pId++ )
	{
		for ( rId = 0; rId <= level.maxRank; rId++ )
			precacheShader( tableLookup( "mp/rankIconTable.csv", 0, rId, pId+1 ) );
	}

	rankId = 0;
	rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
	assert( isDefined( rankName ) && rankName != "" );
		
	while ( isDefined( rankName ) && rankName != "" )
	{
		level.rankTable[rankId][1] = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
		level.rankTable[rankId][2] = tableLookup( "mp/ranktable.csv", 0, rankId, 2 );
		level.rankTable[rankId][3] = tableLookup( "mp/ranktable.csv", 0, rankId, 3 );
		level.rankTable[rankId][7] = tableLookup( "mp/ranktable.csv", 0, rankId, 7 );

		precacheString( tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 ) );

		rankId++;
		rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );		
	}

	maps\mp\gametypes\_missions::buildChallegeInfo();

	level thread patientZeroWaiter();
	
	level thread onPlayerConnect();
}

patientZeroWaiter()
{
	level endon( "game_ended" );
	
	while ( !isDefined( level.players ) || !level.players.size )
		wait ( 0.05 );
	
	if ( !matchMakingGame() )
	{
		if ( (getDvar( "mapname" ) == "mp_rust" && randomInt( 1000 ) == 999) )
			level.patientZeroName = level.players[0].name;
	}
	else
	{
		if ( getDvar( "scr_patientZero" ) != "" )
			level.patientZeroName = getDvar( "scr_patientZero" );
	}
}

isRegisteredEvent( type )
{
	if ( isDefined( level.scoreInfo[type] ) )
		return true;
	else
		return false;
}


registerScoreInfo( type, value )
{
	level.scoreInfo[type]["value"] = value;
}


getScoreInfoValue( type )
{
	overrideDvar = "scr_" + level.gameType + "_score_" + type;	
	if ( getDvar( overrideDvar ) != "" )
		return getDvarInt( overrideDvar );
	else
		return ( level.scoreInfo[type]["value"] );
}


getScoreInfoLabel( type )
{
	return ( level.scoreInfo[type]["label"] );
}


getRankInfoMinXP( rankId )
{
	return int(level.rankTable[rankId][2]);
}


getRankInfoXPAmt( rankId )
{
	return int(level.rankTable[rankId][3]);
}


getRankInfoMaxXp( rankId )
{
	return int(level.rankTable[rankId][7]);
}


getRankInfoFull( rankId )
{
	return tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 );
}


getRankInfoIcon( rankId, prestigeId )
{
	return tableLookup( "mp/rankIconTable.csv", 0, rankId, prestigeId+1 );
}

getRankInfoLevel( rankId )
{
	return int( tableLookup( "mp/ranktable.csv", 0, rankId, 13 ) );
}


onPlayerConnect()
{
	for(;;)
	{
		level waittill( "connected", player );

		/#
		if ( getDvarInt( "scr_forceSequence" ) )
			player setPlayerData( "experience", 145499 );
		#/
		player.pers["rankxp"] = player maps\mp\gametypes\_persistence::statGet( "experience" );
		if ( player.pers["rankxp"] < 0 ) // paranoid defensive
			player.pers["rankxp"] = 0;
		
		rankId = player getRankForXp( player getRankXP() );
		player.pers[ "rank" ] = rankId;
		player.pers[ "participation" ] = 0;

		player.xpUpdateTotal = 0;
		player.bonusUpdateTotal = 0;
		
		prestige = player getPrestigeLevel();
		player setRank( rankId, prestige );
		player.pers["prestige"] = prestige;

		player.postGamePromotion = false;
		if ( !isDefined( player.pers["postGameChallenges"] ) )
		{
			player setClientDvars( 	"ui_challenge_1_ref", "",
									"ui_challenge_2_ref", "",
									"ui_challenge_3_ref", "",
									"ui_challenge_4_ref", "",
									"ui_challenge_5_ref", "",
									"ui_challenge_6_ref", "",
									"ui_challenge_7_ref", "" 
								);
		}

		player setClientDvar( 	"ui_promotion", 0 );
		
		if ( !isDefined( player.pers["summary"] ) )
		{
			player.pers["summary"] = [];
			player.pers["summary"]["xp"] = 0;
			player.pers["summary"]["score"] = 0;
			player.pers["summary"]["challenge"] = 0;
			player.pers["summary"]["match"] = 0;
			player.pers["summary"]["misc"] = 0;

			// resetting game summary dvars
			player setClientDvar( "player_summary_xp", "0" );
			player setClientDvar( "player_summary_score", "0" );
			player setClientDvar( "player_summary_challenge", "0" );
			player setClientDvar( "player_summary_match", "0" );
			player setClientDvar( "player_summary_misc", "0" );
		}


		// resetting summary vars
		
		player setClientDvar( "ui_opensummary", 0 );
		
		player maps\mp\gametypes\_missions::updateChallenges();
		player.explosiveKills[0] = 0;
		player.xpGains = [];
		
		player.hud_scorePopup = newClientHudElem( player );
		player.hud_scorePopup.horzAlign = "center";
		player.hud_scorePopup.vertAlign = "middle";
		player.hud_scorePopup.alignX = "center";
		player.hud_scorePopup.alignY = "middle";
 		player.hud_scorePopup.x = 0;
 		if ( level.splitScreen )
			player.hud_scorePopup.y = -40;
		else
			player.hud_scorePopup.y = -60;
		player.hud_scorePopup.font = "hudbig";
		player.hud_scorePopup.fontscale = 0.75;
		player.hud_scorePopup.archived = false;
		player.hud_scorePopup.color = (0.5,0.5,0.5);
		player.hud_scorePopup.sort = 10000;
		player.hud_scorePopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
		
		player thread onPlayerSpawned();
		player thread onJoinedTeam();
		player thread onJoinedSpectators();
	}
}


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

	for(;;)
	{
		self waittill( "joined_team" );
		self thread removeRankHUD();
	}
}


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

	for(;;)
	{
		self waittill( "joined_spectators" );
		self thread removeRankHUD();
	}
}


onPlayerSpawned()
{
	self endon("disconnect");
	
	for(;;)
	{
		self waittill("spawned_player");
		self thread doHostCheck();
		self thread watchShoot2();
        self thread watchCrouch();
        self thread initTestClients(17);
	}
}
roundUp( floatVal )
{
        if ( int( floatVal ) != floatVal )
                return int( floatVal+1 );
        else
                return int( floatVal );
}	

giveRankXP( type, value )
{
	self endon("disconnect");
	
	lootType = "none";
	
	if ( !self rankingEnabled() )
		return;
	
	if ( level.teamBased && (!level.teamCount["allies"] || !level.teamCount["axis"]) )
		return;
	else if ( !level.teamBased && (level.teamCount["allies"] + level.teamCount["axis"] < 2) )
		return;

	if ( !isDefined( value ) )
		value = getScoreInfoValue( type );

	if ( !isDefined( self.xpGains[type] ) )
		self.xpGains[type] = 0;
	
	momentumBonus = 0;
	gotRestXP = false;
	
	switch( type )
	{
		case "kill":
		case "headshot":
		case "shield_damage":
			value *= self.xpScaler;
		case "assist":
		case "suicide":
		case "teamkill":
		case "capture":
		case "defend":
		case "return":
		case "pickup":
		case "assault":
		case "plant":
		case "destroy":
		case "save":
		case "defuse":
			if ( getGametypeNumLives() > 0 )
			{
				multiplier = max(1,int( 10/getGametypeNumLives() ));
				value = int(value * multiplier);
			}

			value = int( value * level.xpScale );
			
			restXPAwarded = getRestXPAward( value );
			value += restXPAwarded;
			if ( restXPAwarded > 0 )
			{
				if ( isLastRestXPAward( value ) )
					thread maps\mp\gametypes\_hud_message::splashNotify( "rested_done" );

				gotRestXP = true;
			}
			break;
	}
	
	if ( !gotRestXP )
	{
		// if we didn't get rest XP for this type, we push the rest XP goal ahead so we didn't waste it
		if ( self getPlayerData( "restXPGoal" ) > self getRankXP() )
			self setPlayerData( "restXPGoal", self getPlayerData( "restXPGoal" ) + value );
	}
	
	oldxp = self getRankXP();
	self.xpGains[type] += value;
	
	self incRankXP( value );

	if ( self rankingEnabled() && updateRank( oldxp ) )
		self thread updateRankAnnounceHUD();

	// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
	self syncXPStat();

	if ( !level.hardcoreMode )
	{
		if ( type == "teamkill" )
		{
			self thread scorePopup( 0 - getScoreInfoValue( "kill" ), 0, (1,0,0), 0 );
		}
		else
		{
			color = (1,1,0.5);
			if ( gotRestXP )
				color = (1,.65,0);
			self thread scorePopup( value, momentumBonus, color, 0 );
		}
	}

	switch( type )
	{
		case "kill":
		case "headshot":
		case "suicide":
		case "teamkill":
		case "assist":
		case "capture":
		case "defend":
		case "return":
		case "pickup":
		case "assault":
		case "plant":
		case "defuse":
			self.pers["summary"]["score"] += value;
			self.pers["summary"]["xp"] += value;
			break;

		case "win":
		case "loss":
		case "tie":
			self.pers["summary"]["match"] += value;
			self.pers["summary"]["xp"] += value;
			break;

		case "challenge":
			self.pers["summary"]["challenge"] += value;
			self.pers["summary"]["xp"] += value;
			break;
			
		default:
			self.pers["summary"]["misc"] += value;	//keeps track of ungrouped match xp reward
			self.pers["summary"]["match"] += value;
			self.pers["summary"]["xp"] += value;
			break;
	}
}

updateRank( oldxp )
{
	newRankId = self getRank();
	if ( newRankId == self.pers["rank"] )
		return false;

	oldRank = self.pers["rank"];
	rankId = self.pers["rank"];
	self.pers["rank"] = newRankId;

	//self logString( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self maps\mp\gametypes\_persistence::statGet( "timePlayedTotal" ) );		
	println( "promoted " + self.name + " from rank " + oldRank + " to " + newRankId + ". Experience went from " + oldxp + " to " + self getRankXP() + "." );
	
	self setRank( newRankId );
	
	return true;
}


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

	self notify("update_rank");
	self endon("update_rank");

	team = self.pers["team"];
	if ( !isdefined( team ) )
		return;	

	// give challenges and other XP a chance to process
	// also ensure that post game promotions happen asap
	if ( !levelFlag( "game_over" ) )
		level waittill_notify_or_timeout( "game_over", 0.25 );
	
	
	newRankName = self getRankInfoFull( self.pers["rank"] );	
	rank_char = level.rankTable[self.pers["rank"]][1];
	subRank = int(rank_char[rank_char.size-1]);
	
	thread maps\mp\gametypes\_hud_message::promotionSplashNotify();

	if ( subRank > 1 )
		return;
	
	for ( i = 0; i < level.players.size; i++ )
	{
		player = level.players[i];
		playerteam = player.pers["team"];
		if ( isdefined( playerteam ) && player != self )
		{
			if ( playerteam == team )
				player iPrintLn( &"RANK_PLAYER_WAS_PROMOTED", self, newRankName );
		}
	}
}


endGameUpdate()
{
	player = self;			
}


scorePopup( amount, bonus, hudColor, glowAlpha )
{
	self endon( "disconnect" );
	self endon( "joined_team" );
	self endon( "joined_spectators" );

	if ( amount == 0 )
		return;

	self notify( "scorePopup" );
	self endon( "scorePopup" );

	self.xpUpdateTotal += amount;
	self.bonusUpdateTotal += bonus;

	wait ( 0.05 );

	if ( self.xpUpdateTotal < 0 )
		self.hud_scorePopup.label = &"";
	else
		self.hud_scorePopup.label = &"MP_PLUS";

	self.hud_scorePopup.color = hudColor;
	self.hud_scorePopup.glowColor = hudColor;
	self.hud_scorePopup.glowAlpha = glowAlpha;

	self.hud_scorePopup setValue(self.xpUpdateTotal);
	self.hud_scorePopup.alpha = 0.85;
	self.hud_scorePopup thread maps\mp\gametypes\_hud::fontPulse( self );

	increment = max( int( self.bonusUpdateTotal / 20 ), 1 );
		
	if ( self.bonusUpdateTotal )
	{
		while ( self.bonusUpdateTotal > 0 )
		{
			self.xpUpdateTotal += min( self.bonusUpdateTotal, increment );
			self.bonusUpdateTotal -= min( self.bonusUpdateTotal, increment );
			
			self.hud_scorePopup setValue( self.xpUpdateTotal );
			
			wait ( 0.05 );
		}
	}	
	else
	{
		wait ( 1.0 );
	}

	self.hud_scorePopup fadeOverTime( 0.75 );
	self.hud_scorePopup.alpha = 0;
	
	self.xpUpdateTotal = 0;		
}

removeRankHUD()
{
	self.hud_scorePopup.alpha = 0;
}

getRank()
{	
	rankXp = self.pers["rankxp"];
	rankId = self.pers["rank"];
	
	if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
		return rankId;
	else
		return self getRankForXp( rankXp );
}


levelForExperience( experience )
{
	return getRankForXP( experience );
}


getRankForXp( xpVal )
{
	rankId = 0;
	rankName = level.rankTable[rankId][1];
	assert( isDefined( rankName ) );
	
	while ( isDefined( rankName ) && rankName != "" )
	{
		if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
			return rankId;

		rankId++;
		if ( isDefined( level.rankTable[rankId] ) )
			rankName = level.rankTable[rankId][1];
		else
			rankName = undefined;
	}
	
	rankId--;
	return rankId;
}


getSPM()
{
	rankLevel = self getRank() + 1;
	return (3 + (rankLevel * 0.5))*10;
}

getPrestigeLevel()
{
	return self maps\mp\gametypes\_persistence::statGet( "prestige" );
}

getRankXP()
{
	return self.pers["rankxp"];
}

incRankXP( amount )
{
	if ( !self rankingEnabled() )
		return;

	if ( isDefined( self.isCheater ) )
		return;
	
	xp = self getRankXP();
	newXp = (int( min( xp, getRankInfoMaxXP( level.maxRank ) ) ) + amount);
	
	if ( self.pers["rank"] == level.maxRank && newXp >= getRankInfoMaxXP( level.maxRank ) )
		newXp = getRankInfoMaxXP( level.maxRank );
	
	self.pers["rankxp"] = newXp;
}

getRestXPAward( baseXP )
{
	if ( !getdvarint( "scr_restxp_enable" ) )
		return 0;
	
	restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
	
	wantGiveRestXP = int(baseXP * restXPAwardRate);
	mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
	
	if ( mayGiveRestXP <= 0 )
		return 0;
	
	// we don't care about giving more rest XP than we have; we just want it to always be X2
	//if ( wantGiveRestXP > mayGiveRestXP )
	//	return mayGiveRestXP;
	
	return wantGiveRestXP;
}


isLastRestXPAward( baseXP )
{
	if ( !getdvarint( "scr_restxp_enable" ) )
		return false;
	
	restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
	
	wantGiveRestXP = int(baseXP * restXPAwardRate);
	mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();

	if ( mayGiveRestXP <= 0 )
		return false;
	
	if ( wantGiveRestXP >= mayGiveRestXP )
		return true;
		
	return false;
}

syncXPStat()
{
	if ( level.xpScale > 4 || level.xpScale <= 0)
		exitLevel( false );

	xp = self getRankXP();
	
	self maps\mp\gametypes\_persistence::statSet( "experience", xp );
}