[BAD Syntax] Hide

Posts 16–26 of 26 · Page 2 of 2
No message came up. I am going to test this online to see if anyone sees me when I melee, if it doesn't work i'll get back to you.

Does it matter what file it is in?

EDIT: The wee bugger still seen meh What is wrong w/it!
Quote Originally Posted by CainFool View Post
No message came up. I am going to test this online to see if anyone sees me when I melee, if it doesn't work i'll get back to you.

Does it matter what file it is in?

EDIT: The wee bugger still seen meh What is wrong w/it!
PM me your whole code, I think it is your directing to that. There is nothing wrong with that bit of code (Might be hotkeys, but N is act1...)...
Quote Originally Posted by JamesA1994 View Post
PM me your whole code, I think it is your directing to that. There is nothing wrong with that bit of code (Might be hotkeys, but N is act1...)...
_gamelogic.gsc
Code:
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;

FACTION_REF_COL 					= 0;
FACTION_NAME_COL 					= 1;
FACTION_SHORT_NAME_COL 				= 1;
FACTION_WIN_GAME_COL 				= 3; 
FACTION_WIN_ROUND_COL 				= 4;
FACTION_MISSION_ACCOMPLISHED_COL 	= 5;
FACTION_ELIMINATED_COL 				= 6;
FACTION_FORFEITED_COL 				= 7;
FACTION_ICON_COL 					= 8;
FACTION_HUD_ICON_COL 				= 9;
FACTION_VOICE_PREFIX_COL 			= 10;
FACTION_SPAWN_MUSIC_COL 			= 11;
FACTION_WIN_MUSIC_COL 				= 12;
FACTION_COLOR_R_COL 				= 13;
FACTION_COLOR_G_COL 				= 14;
FACTION_COLOR_B_COL 				= 15;

// when a team leaves completely, that team forfeited, team left wins round, ends 

game
onForfeit( team )
{
	if ( isDefined( level.forfeitInProgress ) )
		return;

	level endon( "abort_forfeit" );			//end if the team 

is no longer in forfeit status

	level.forfeitInProgress = true;
	
	// in 1v1 DM, give players time to change teams
	if ( !level.teambased && level.players.size > 1 )
		wait 10;
	
	forfeit_delay = 20.0;						

//forfeit wait, for switching teams and such
	
	foreach ( player in level.players )
	{
		player setLowerMessage( "forfeit_warning", game["strings"]

["opponent_forfeiting_in"], forfeit_delay, 100 );
		player thread forfeitWaitforAbort();
	}
		
	wait ( forfeit_delay );
	
	endReason = &"";
	if ( !isDefined( team ) )
	{
		endReason = game["strings"]["players_forfeited"];
		winner = level.players[0];
	}
	else if ( team == "allies" )
	{
		endReason = game["strings"]["allies_forfeited"];
		winner = "axis";
	}
	else if ( team == "axis" )
	{
		endReason = game["strings"]["axis_forfeited"];
		winner = "allies";
	}
	else
	{
		//shouldn't get here
		assertEx( isdefined( team ), "Forfeited team is not defined" );
		assertEx( 0, "Forfeited team " + team + " is not allies or axis" );
		winner = "tie";
	}
	//exit game, last round, no matter if round limit reached or not
	level.forcedEnd = true;
	
	if ( isPlayer( winner ) )
		logString( "forfeit, win: " + winner getXuid() + "(" + winner.name 

+ ")" );
	else
		logString( "forfeit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
	thread endGame( winner, endReason );
}


forfeitWaitforAbort()
{
	self endon ( "disconnect" );
	level endon ( "game_ended" );
	
	level waittill ( "abort_forfeit" );
	
	self clearLowerMessage( "forfeit_warning" );
}


default_onDeadEvent( team )
{
	if ( team == "allies" )
	{
		iPrintLn( game["strings"]["allies_eliminated"] );

		logString( "team eliminated, win: opfor, allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
		
		thread endGame( "axis", game["strings"]["allies_eliminated"] );
	}
	else if ( team == "axis" )
	{
		iPrintLn( game["strings"]["axis_eliminated"] );

		logString( "team eliminated, win: allies, allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );

		thread endGame( "allies", game["strings"]["axis_eliminated"] );
	}
	else
	{
		logString( "tie, allies: " + game["teamScores"]["allies"] + ", 

opfor: " + game["teamScores"]["axis"] );

		if ( level.teamBased )
			thread endGame( "tie", game["strings"]["tie"] );
		else
			thread endGame( undefined, game["strings"]["tie"] );
	}
}


default_onOneLeftEvent( team )
{
	if ( level.teamBased )
	{		
		assert( team == "allies" || team == "axis" );
		
		lastPlayer = getLastLivingPlayer( team );
		lastPlayer thread giveLastOnTeamWarning();
	}
	else
	{
		lastPlayer = getLastLivingPlayer();
		
		logString( "last one alive, win: " + lastPlayer.name );
		thread endGame( lastPlayer, &"MP_ENEMIES_ELIMINATED" );
	}

	return true;
}


default_onTimeLimit()
{
	winner = undefined;
	
	if ( level.teamBased )
	{
		if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
			winner = "tie";
		else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
			winner = "axis";
		else
			winner = "allies";

		logString( "time limit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
	}
	else
	{
		winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();

		if ( isDefined( winner ) )
			logString( "time limit, win: " + winner.name );
		else
			logString( "time limit, tie" );
	}
	
	thread endGame( winner, game["strings"]["time_limit_reached"] );
}


default_onHalfTime()
{
	winner = undefined;
	
	thread endGame( "halftime", game["strings"]["time_limit_reached"] );
}


forceEnd()
{
	if ( level.hostForcedEnd || level.forcedEnd )
		return;

	winner = undefined;
	
	if ( level.teamBased )
	{
		if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
			winner = "tie";
		else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
			winner = "axis";
		else
			winner = "allies";
		logString( "host ended game, win: " + winner + ", allies: " + 

game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
	}
	else
	{
		winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();
		if ( isDefined( winner ) )
			logString( "host ended game, win: " + winner.name );
		else
			logString( "host ended game, tie" );
	}
	
	level.forcedEnd = true;
	level.hostForcedEnd = true;
	
	if ( level.splitscreen )
		endString = &"MP_ENDED_GAME";
	else
		endString = &"MP_HOST_ENDED_GAME";
	
	thread endGame( winner, endString );
}


onScoreLimit()
{
	scoreText = game["strings"]["score_limit_reached"];	
	winner = undefined;
	
	if ( level.teamBased )
	{
		if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
			winner = "tie";
		else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
			winner = "axis";
		else
			winner = "allies";
		logString( "scorelimit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
	}
	else
	{
		winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();
		if ( isDefined( winner ) )
			logString( "scorelimit, win: " + winner.name );
		else
			logString( "scorelimit, tie" );
	}
	
	thread endGame( winner, scoreText );
	return true;
}


updateGameEvents()
{
	if ( matchMakingGame() && !level.inGracePeriod )
	{
		if ( level.teamBased )
		{
			// if allies disconnected, and axis still connected, axis 

wins round and game ends to lobby
			if ( level.teamCount["allies"] < 1 && level.teamCount

["axis"] > 0 && game["state"] == "playing" )
			{
				//allies forfeited
				thread onForfeit( "allies" );
				return;
			}
			
			// if axis disconnected, and allies still connected, allies 

wins round and game ends to lobby
			if ( level.teamCount["axis"] < 1 && level.teamCount

["allies"] > 0 && game["state"] == "playing" )
			{
				//axis forfeited
				thread onForfeit( "axis" );
				return;
			}
	
			if ( level.teamCount["axis"] > 0 && level.teamCount

["allies"] > 0 )
			{
				level.forfeitInProgress = undefined;
				level notify( "abort_forfeit" );
			}
		}
		else
		{
			if ( level.teamCount["allies"] + level.teamCount["axis"] 

== 1 && level.maxPlayerCount > 1 )
			{
				thread onForfeit();
				return;
			}

			if ( level.teamCount["axis"] + level.teamCount["allies"] 

> 1 )
			{
				level.forfeitInProgress = undefined;
				level notify( "abort_forfeit" );
			}
		}
	}

	if ( !getGametypeNumLives() && (!isDefined( level.disableSpawning ) || !

level.disableSpawning) )
		return;
		
	if ( !gameHasStarted() ) 
		return;
	
	if ( level.inGracePeriod )
		return;

	if ( level.teamBased )
	{
		livesCount["allies"] = level.livesCount["allies"];
		livesCount["axis"] = level.livesCount["axis"];

		if ( isDefined( level.disableSpawning ) && level.disableSpawning )
		{
			livesCount["allies"] = 0;
			livesCount["axis"] = 0;
		}
		
		// if both allies and axis were alive and now they are both dead in 

the same instance
		if ( !level.aliveCount["allies"] && !level.aliveCount["axis"] && !

livesCount["allies"] && !livesCount["axis"] )
		{
			return [[level.onDeadEvent]]( "all" );
		}

		// if allies were alive and now they are not
		if ( !level.aliveCount["allies"] && !livesCount["allies"] )
		{
			return [[level.onDeadEvent]]( "allies" );
		}

		// if axis were alive and now they are not
		if ( !level.aliveCount["axis"] && !livesCount["axis"] )
		{
			return [[level.onDeadEvent]]( "axis" );
		}

		// one ally left
		if ( level.aliveCount["allies"] == 1 && !livesCount["allies"] )
		{
			if ( !isDefined( level.oneLeftTime["allies"] ) )
			{
				level.oneLeftTime["allies"] = getTime();
				return [[level.onOneLeftEvent]]( "allies" );
			}
		}

		// one axis left
		if ( level.aliveCount["axis"] == 1 && !livesCount["axis"] )
		{
			if ( !isDefined( level.oneLeftTime["axis"] ) )
			{
				level.oneLeftTime["axis"] = getTime();
				return [[level.onOneLeftEvent]]( "axis" );
			}
		}
	}
	else
	{
		// everyone is dead
		if ( (!level.aliveCount["allies"] && !level.aliveCount["axis"]) && (!

level.livesCount["allies"] && !level.livesCount["axis"]) )
		{
			return [[level.onDeadEvent]]( "all" );
		}

		livePlayers = getPotentialLivingPlayers();
		
		if ( livePlayers.size == 1 )
		{
			return [[level.onOneLeftEvent]]( "all" );
		}
	}
}


waittillFinalKillcamDone()
{
	if ( !level.showingFinalKillcam )
		return false;
	
	while ( level.showingFinalKillcam )
		wait ( 0.05 );
	
	return true;
}


timeLimitClock_Intermission( waitTime )
{
	setGameEndTime( getTime() + int(waitTime*1000) );
	clockObject = spawn( "script_origin", (0,0,0) );
	clockObject hide();
	
	if ( waitTime >= 10.0 )
		wait ( waitTime - 10.0 );
		
	for ( ;; )
	{
		clockObject playSound( "ui_mp_timer_countdown" );
		wait ( 1.0 );
	}	
}


waitForPlayers( maxTime )
{
	endTime = gettime() + maxTime * 1000 - 200;
	
	if ( level.teamBased )
		while( (!level.hasSpawned[ "axis" ] || !level.hasSpawned[ "allies" 

]) && gettime() < endTime )
			wait ( 0.05 );
	else
		while ( level.maxPlayerCount < 2 && gettime() < endTime )
			wait ( 0.05 );
}


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

	if ( level.prematchPeriod > 0 )
	{
		if ( level.console )
		{
			thread matchStartTimer( "match_starting_in", 

level.prematchPeriod );
			wait ( level.prematchPeriod );
		}
		else
		{
			matchStartTimerPC();
		}
	}
	else
	{
		matchStartTimerSkip();
	}
	
	for ( index = 0; index < level.players.size; index++ )
	{
		level.players[index] freezeControlsWrapper( false );
		level.players[index] enableWeapons();

		hintMessage = getObjectiveHintText( level.players[index].pers

["team"] );
		if ( !isDefined( hintMessage ) || !level.players[index].hasSpawned 

)
			continue;

		level.players[index] setClientDvar( "scr_objectiveText", 

hintMessage );
		level.players[index] thread maps\mp\gametypes

\_hud_message::hintMessage( hintMessage );
	}

	if ( game["state"] != "playing" )
		return;
}


gracePeriod()
{
	level endon("game_ended");
	
	while ( level.inGracePeriod )
	{
		wait ( 1.0 );
		level.inGracePeriod--;
	}

	//wait ( level.gracePeriod );
	
	level notify ( "grace_period_ending" );
	wait ( 0.05 );
	
	gameFlagSet( "graceperiod_done" );
	level.inGracePeriod = false;
	
	if ( game["state"] != "playing" )
		return;
	
	if ( getGametypeNumLives() )
	{
		// Players on a team but without a weapon show as dead since 

they can not get in this round
		players = level.players;
		
		for ( i = 0; i < players.size; i++ )
		{
			player = players[i];
			
			if ( !player.hasSpawned && player.sessionteam != 

"spectator" && !isAlive( player ) )
				player.statusicon = "hud_status_dead";
		}
	}
	
	level thread updateGameEvents();
}


updateWinStats( winner )
{
	if ( !winner rankingEnabled() )
		return;
	
	winner maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
	
	println( "setting winner: " + winner maps\mp\gametypes

\_persistence::statGet( "wins" ) );
	winner maps\mp\gametypes\_persistence::statAdd( "wins", 1 );
	winner updatePersRatio( "winLossRatio", "wins", "losses" );
	winner maps\mp\gametypes\_persistence::statAdd( "currentWinStreak", 1 

);
	
	cur_win_streak = winner maps\mp\gametypes\_persistence::statGet( 

"currentWinStreak" );
	if ( cur_win_streak > winner maps\mp\gametypes\_persistence::statGet( 

"winStreak" ) )
		winner maps\mp\gametypes\_persistence::statSet( "winStreak", 

cur_win_streak );
	
	winner maps\mp\gametypes\_persistence::statSetChild( "round", "win", 

true );
	winner maps\mp\gametypes\_persistence::statSetChild( "round", "loss", 

false );
}


updateLossStats( loser )
{
	if ( !loser rankingEnabled() )
		return;
	
	loser maps\mp\gametypes\_persistence::statAdd( "losses", 1 );
	loser updatePersRatio( "winLossRatio", "wins", "losses" );
	loser maps\mp\gametypes\_persistence::statSetChild( "round", "loss", 

true );
}


updateTieStats( loser )
{	
	if ( !loser rankingEnabled() )
		return;
	
	loser maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
	
	loser maps\mp\gametypes\_persistence::statAdd( "ties", 1 );
	loser updatePersRatio( "winLossRatio", "wins", "losses" );
	loser maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );	
}


updateWinLossStats( winner )
{
	if ( privateMatch() )
		return;
		
	if ( !wasLastRound() )
		return;
		
	players = level.players;

	if ( !isDefined( winner ) || ( isDefined( winner ) && isString( winner ) && 

winner == "tie" ) )
	{
		foreach ( player in level.players )
		{
			if ( isDefined( player.connectedPostGame ) )
				continue;

			if ( level.hostForcedEnd && player isHost() )
			{
				player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
				continue;
			}
				
			updateTieStats( player );
		}		
	} 
	else if ( isPlayer( winner ) )
	{
		if ( level.hostForcedEnd && winner isHost() )
		{
			winner maps\mp\gametypes\_persistence::statSet( 

"currentWinStreak", 0 );
			return;
		}
				
		updateWinStats( winner );
	}
	else if ( isString( winner ) )
	{
		foreach ( player in level.players )
		{
			if ( isDefined( player.connectedPostGame ) )
				continue;

			if ( level.hostForcedEnd && player isHost() )
			{
				player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
				continue;
			}

			if ( winner == "tie" )
				updateTieStats( player );
			else if ( player.pers["team"] == winner )
				updateWinStats( player );
			else
				player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
		}
	}
}


freezePlayerForRoundEnd( delay )
{
	self endon ( "disconnect" );
	self clearLowerMessages();
	
	if ( !isDefined( delay ) )
		delay = 0.05;
	
	self closepopupMenu();
	self closeInGameMenu();
	
	wait ( delay );
	self freezeControlsWrapper( true );
//	self disableWeapons();
}


updateMatchBonusScores( winner )
{
	if ( !game["timePassed"] )
		return;

	if ( !matchMakingGame() )
		return;

	if ( !getTimeLimit() || level.forcedEnd )
	{
		gameLength = getTimePassed() / 1000;		
		// cap it at 20 minutes to avoid exploiting
		gameLength = min( gameLength, 1200 );
	}
	else
	{
		gameLength = getTimeLimit() * 60;
	}
		
	if ( level.teamBased )
	{
		if ( winner == "allies" )
		{
			winningTeam = "allies";
			losingTeam = "axis";
		}
		else if ( winner == "axis" )
		{
			winningTeam = "axis";
			losingTeam = "allies";
		}
		else
		{
			winningTeam = "tie";
			losingTeam = "tie";
		}

		if ( winningTeam != "tie" )
		{
			winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "win" );
			loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "loss" );
			setWinningTeam( winningTeam );
		}
		else
		{
			winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
			loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
		}
		
		foreach ( player in level.players )
		{
			if ( isDefined( player.connectedPostGame ) )
				continue;
			
			if ( !player rankingEnabled() )
				continue;
			
			if ( player.timePlayed["total"] < 1 || player.pers

["participation"] < 1 )
			{
				player thread maps\mp\gametypes

\_rank::endGameUpdate();
				continue;
			}
	
			// no bonus for hosts who force ends
			if ( level.hostForcedEnd && player isHost() )
				continue;

			spm = player maps\mp\gametypes\_rank::getSPM();	

			
			if ( winningTeam == "tie" )
			{
				playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
				player thread giveMatchBonus( "tie", 

playerScore );
				player.matchBonus = playerScore;
			}
			else if ( isDefined( player.pers["team"] ) && player.pers

["team"] == winningTeam )
			{
				playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
				player thread giveMatchBonus( "win", 

playerScore );
				player.matchBonus = playerScore;
			}
			else if ( isDefined(player.pers["team"] ) && player.pers

["team"] == losingTeam )
			{
				playerScore = int( (loserScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
				player thread giveMatchBonus( "loss", 

playerScore );
				player.matchBonus = playerScore;
			}
		}
	}
	else
	{
		if ( isDefined( winner ) )
		{
			winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "win" );
			loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "loss" );
		}
		else
		{
			winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
			loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
		}
		
		foreach ( player in level.players )
		{
			if ( isDefined( player.connectedPostGame ) )
				continue;
			
			if ( player.timePlayed["total"] < 1 || player.pers

["participation"] < 1 )
			{
				player thread maps\mp\gametypes

\_rank::endGameUpdate();
				continue;
			}
			
			spm = player maps\mp\gametypes\_rank::getSPM();

			isWinner = false;
			for ( pIdx = 0; pIdx < min( level.placement["all"].size, 3 

); pIdx++ )
			{
				if ( level.placement["all"][pIdx] != player )
					continue;
				isWinner = true;				
			}
			
			if ( isWinner )
			{
				playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
				player thread giveMatchBonus( "win", 

playerScore );
				player.matchBonus = playerScore;
			}
			else
			{
				playerScore = int( (loserScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
				player thread giveMatchBonus( "loss", 

playerScore );
				player.matchBonus = playerScore;
			}
		}
	}
}


giveMatchBonus( scoreType, score )
{
	self endon ( "disconnect" );

	level waittill ( "give_match_bonus" );
	
	self maps\mp\gametypes\_rank::giveRankXP( scoreType, score );
	//logXPGains();
	
	self maps\mp\gametypes\_rank::endGameUpdate();
}


setXenonRanks( winner )
{
	players = level.players;

	for ( i = 0; i < players.size; i++ )
	{
		player = players[i];

		if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
			continue;

	}

	for ( i = 0; i < players.size; i++ )
	{
		player = players[i];

		if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
			continue;		
		
		setPlayerTeamRank( player, player.clientid, player.score - 5 * 

player.deaths );
	}
	sendranks();
}


checkTimeLimit( prevTimePassed )
{
	if ( isDefined( level.timeLimitOverride ) && level.timeLimitOverride )
		return;
	
	if ( game["state"] != "playing" )
	{
		setGameEndTime( 0 );
		return;
	}
		
	if ( getTimeLimit() <= 0 )
	{
		if ( isDefined( level.startTime ) )
			setGameEndTime( level.startTime );
		else
			setGameEndTime( 0 );
		return;
	}
		
	if ( !gameFlag( "prematch_done" ) )
	{
		setGameEndTime( 0 );
		return;
	}
	
	if ( !isdefined( level.startTime ) )
		return;
	
	timeLeft = getTimeRemaining();
	
	// want this accurate to the millisecond
//	if ( getHalfTime() && game["status"] != "halftime" )
//		setGameEndTime( getTime() + (int(timeLeft) - int(getTimeLimit

()*60*1000*0.5)) );
//	else
		setGameEndTime( getTime() + int(timeLeft) );

	if ( timeLeft > 0 )
	{
		if ( getHalfTime() && checkHalfTime( prevTimePassed ) )
			[[level.onHalfTime]]();

		return;
	}
	
	[[level.onTimeLimit]]();
}


checkHalfTime( prevTimePassed )
{
	if ( !level.teamBased )
		return false;
		
	if ( getTimeLimit() )
	{
		halfTime = (getTimeLimit() * 60 * 1000) * 0.5;
		
		if ( getTimePassed() >= halfTime && prevTimePassed < halfTime 

&& prevTimePassed > 0 )
		{
			game["roundMillisecondsAlreadyPassed"] = 

getTimePassed();
			return true;
		}
	}
	
	return false;
}



getTimeRemaining()
{
	return getTimeLimit() * 60 * 1000 - getTimePassed();
}


checkTeamScoreLimitSoon( team )
{
	assert( isDefined( team ) );

	if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
		return;
		
	if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
		return;
		
	if ( !level.teamBased )
		return;

	// No checks until a minute has passed to let wild data settle
	if ( getTimePassed() < (60 * 1000) ) // 1 min
		return;
	
	timeLeft = estimatedTimeTillScoreLimit( team );

	if ( timeLeft < 2 )
		level notify( "match_ending_soon", "score" );
}


checkPlayerScoreLimitSoon()
{
	if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
		return;
		
	if ( level.teamBased )
		return;

	// No checks until a minute has passed to let wild data settle
	if ( getTimePassed() < (60 * 1000) ) // 1 min
		return;

	timeLeft = self estimatedTimeTillScoreLimit();

	if ( timeLeft < 2 )
		level notify( "match_ending_soon", "score" );
}


checkScoreLimit()
{
	if ( isObjectiveBased() )
		return false;

	if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
		return false;
	
	if ( game["state"] != "playing" )
		return false;

	if ( getWatchedDvar( "scorelimit" ) <= 0 )
		return false;

	if ( level.teamBased )
	{
		if( game["teamScores"]["allies"] < getWatchedDvar( "scorelimit" 

) && game["teamScores"]["axis"] < getWatchedDvar( "scorelimit" ) )
			return false;
	}
	else
	{
		if ( !isPlayer( self ) )
			return false;

		if ( self.score < getWatchedDvar( "scorelimit" ) )
			return false;
	}

	return onScoreLimit();
}


updateGameTypeDvars()
{
	level endon ( "game_ended" );
	
	while ( game["state"] == "playing" )
	{
		// make sure we check time limit right when game ends
		if ( isdefined( level.startTime ) )
		{
			if ( getTimeRemaining() < 3000 )
			{
				wait .1;
				continue;
			}
		}
		wait 1;
	}
}


matchStartTimerPC()
{
	thread matchStartTimer( "waiting_for_teams", level.prematchPeriod + 

level.prematchPeriodEnd );
	
	waitForPlayers( level.prematchPeriod );
	
	if ( level.prematchPeriodEnd > 0 )
		matchStartTimer( "match_starting_in", level.prematchPeriodEnd 

);
}

matchStartTimer_Internal( countTime, matchStartTimer )
{
	waittillframeend; // wait till cleanup of previous start timer if multiple 

happen at once
	visionSetNaked( "mpIntro", 0 );
	
	level endon( "match_start_timer_beginning" );
	while ( countTime > 0 && !level.gameEnded )
	{
		matchStartTimer thread maps\mp\gametypes\_hud::fontPulse( 

level );
		wait ( matchStartTimer.inFrames * 0.05 );
		matchStartTimer setValue( countTime );
		if ( countTime == 2 )
			visionSetNaked( getDvar( "mapname" ), 3.0 );
		countTime--;
		wait ( 1 - (matchStartTimer.inFrames * 0.05) );
	}
}

matchStartTimer( type, duration )
{
	level notify( "match_start_timer_beginning" );
	
	matchStartText = createServerFontString( "objective", 1.5 );
	matchStartText setPoint( "CENTER", "CENTER", 0, -40 );
	matchStartText.sort = 1001;
	matchStartText setText( game["strings"]["waiting_for_teams"] );
	matchStartText.foreground = false;
	matchStartText.hidewheninmenu = true;
	
	matchStartText setText( game["strings"][type] ); // "match begins in:"
	
	matchStartTimer = createServerFontString( "hudbig", 1 );
	matchStartTimer setPoint( "CENTER", "CENTER", 0, 0 );
	matchStartTimer.sort = 1001;
	matchStartTimer.color = (1,1,0);
	matchStartTimer.foreground = false;
	matchStartTimer.hidewheninmenu = true;
	
	matchStartTimer maps\mp\gametypes\_hud::fontPulseInit();

	countTime = int( duration );
	
	if ( countTime >= 2 )
	{
		matchStartTimer_Internal( countTime, matchStartTimer );
		visionSetNaked( getDvar( "mapname" ), 3.0 );
	}
	else
	{
		visionSetNaked( "mpIntro", 0 );
		visionSetNaked( getDvar( "mapname" ), 1.0 );
	}
	
	matchStartTimer destroyElem();
	matchStartText destroyElem();
}

matchStartTimerSkip()
{
	visionSetNaked( getDvar( "mapname" ), 0 );
}


onRoundSwitch()
{
	if ( !isDefined( game["switchedsides"] ) )
		game["switchedsides"] = false;
	
	// overtime
	if ( game["roundsWon"]["allies"] == getWatchedDvar( "winlimit" ) - 1 && 

game["roundsWon"]["axis"] == getWatchedDvar( "winlimit" ) - 1 )
	{
		aheadTeam = getBetterTeam();
		if ( aheadTeam != game["defenders"] )
		{
			game["switchedsides"] = !game["switchedsides"];
		}
		else
		{
			level.halftimeSubCaption = "";
		}
		level.halftimeType = "overtime";
	}
	else
	{
		level.halftimeType = "halftime";
		game["switchedsides"] = !game["switchedsides"];
	}
}


checkRoundSwitch()
{
	if ( !level.teamBased )
		return false;
		
	if ( !isDefined( level****undSwitch ) || !level****undSwitch )
		return false;
		
	assert( game["roundsPlayed"] > 0 );	
	if ( game["roundsPlayed"] % level****undSwitch == 0 )
	{
		onRoundSwitch();
		return true;
	}
		
	return false;
}


// returns the best guess of the exact time until the scoreboard will be displayed and 

player control will be lost.
// returns undefined if time is not known
timeUntilRoundEnd()
{
	if ( level.gameEnded )
	{
		timePassed = (getTime() - level.gameEndTime) / 1000;
		timeRemaining = level.postRoundTime - timePassed;
		
		if ( timeRemaining < 0 )
			return 0;
		
		return timeRemaining;
	}
	
	if ( getTimeLimit() <= 0 )
		return undefined;
	
	if ( !isDefined( level.startTime ) )
		return undefined;
	
	tl = getTimeLimit();
	
	timePassed = (getTime() - level.startTime)/1000;
	timeRemaining = (getTimeLimit() * 60) - timePassed;
	
	if ( isDefined( level.timePaused ) )
		timeRemaining += level.timePaused; 
	
	return timeRemaining + level.postRoundTime;
}



freeGameplayHudElems()
{
	// free up some hud elems so we have enough for other things.
	
	// perk icons
	if ( isdefined( self.perkicon ) )
	{
		if ( isdefined( self.perkicon[0] ) )
		{
			self.perkicon[0] destroyElem();
			self.perkname[0] destroyElem();
		}
		if ( isdefined( self.perkicon[1] ) )
		{
			self.perkicon[1] destroyElem();
			self.perkname[1] destroyElem();
		}
		if ( isdefined( self.perkicon[2] ) )
		{
			self.perkicon[2] destroyElem();
			self.perkname[2] destroyElem();
		}
	}
	self notify("perks_hidden"); // stop any threads that are waiting to hide the 

perk icons
	
	// lower message
	self.lowerMessage destroyElem();
	self.lowerTimer destroyElem();
	
	// progress bar
	if ( isDefined( self.proxBar ) )
		self.proxBar destroyElem();
	if ( isDefined( self.proxBarText ) )
		self.proxBarText destroyElem();
}


getHostPlayer()
{
	players = getEntArray( "player", "classname" );
	
	for ( index = 0; index < players.size; index++ )
	{
		if ( players[index] isHost() )
			return players[index];
	}
}


hostIdledOut()
{
	hostPlayer = getHostPlayer();
	
	// host never spawned
	if ( isDefined( hostPlayer ) && !hostPlayer.hasSpawned && !isDefined( 

hostPlayer.selectedClass ) )
		return true;

	return false;
}



roundEndWait( defaultDelay, matchBonus )
{
	//setSlowMotion( 1.0, 0.15, defaultDelay / 2 );

	notifiesDone = false;
	while ( !notifiesDone )
	{
		players = level.players;
		notifiesDone = true;
		
		foreach ( player in players )
		{
			if ( !isDefined( player.doingSplash ) )
				continue;

			if ( !player maps\mp\gametypes

\_hud_message::isDoingSplash() )
				continue;

			notifiesDone = false;
		}
		wait ( 0.5 );
	}

	if ( !matchBonus )
	{
		wait ( defaultDelay );
		level notify ( "round_end_finished" );
		//setSlowMotion( 1.0, 1.0, 0.05 );
		return;
	}

    wait ( defaultDelay / 2 );
	level notify ( "give_match_bonus" );
	wait ( defaultDelay / 2 );

	notifiesDone = false;
	while ( !notifiesDone )
	{
		players = level.players;
		notifiesDone = true;
		foreach ( player in players )
		{
			if ( !isDefined( player.doingSplash ) )
				continue;

			if ( !player maps\mp\gametypes

\_hud_message::isDoingSplash() )
				continue;

			notifiesDone = false;
		}
		wait ( 0.5 );
	}
	//setSlowMotion( 1.0, 1.0, 0.05);
	
	level notify ( "round_end_finished" );
}


roundEndDOF( time )
{
	self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
}


Callback_StartGameType()
{
	maps\mp\_load::main();
	
	levelFlagInit( "round_over", false );
	levelFlagInit( "game_over", false );
	levelFlagInit( "block_notifies", false ); 

	level.prematchPeriod = 0;
	level.prematchPeriodEnd = 0;
	level.postGameNotifies = 0;
	
	level.intermission = false;
	
	makeDvarServerInfo( "cg_thirdPersonAngle", 356 );

	makeDvarServerInfo( "scr_gameended", 0 );

	if ( !isDefined( game["gamestarted"] ) )
	{
		game["clientid"] = 0;
		
		alliesCharSet = getMapCustom( "allieschar" );
		if ( (!isDefined( alliesCharSet ) || alliesCharSet == "") )
		{
			if ( !isDefined( game["allies"] ) )
				alliesCharSet = "us_army";
			else
				alliesCharSet = game["allies"];
		}

		axisCharSet = getMapCustom( "axischar" );
		if ( (!isDefined( axisCharSet ) || axisCharSet == "") )
		{
			if ( !isDefined( game["axis"] ) )
				axisCharSet = "opforce_composite";
			else
				axisCharSet = game["axis"];
		}

		game["allies"] = alliesCharSet;
		game["axis"] = axisCharSet;	

		if ( !isDefined( game["attackers"] ) || !isDefined( game

["defenders"]  ) )
			thread error( "No attackers or defenders team defined in 

level .gsc." );

		if (  !isDefined( game["attackers"] ) )
			game["attackers"] = "allies";
		if (  !isDefined( game["defenders"] ) )
			game["defenders"] = "axis";

		if ( !isDefined( game["state"] ) )
			game["state"] = "playing";
	
		precacheStatusIcon( "hud_status_dead" );
		precacheStatusIcon( "hud_status_connecting" );
		precacheString( &"MPUI_REVIVING" );
		precacheString( &"MPUI_BEING_REVIVED" );
		
		precacheRumble( "damage_heavy" );

		precacheShader( "white" );
		precacheShader( "black" );
			
		game["strings"]["press_to_spawn"] = 

&"PLATFORM_PRESS_TO_SPAWN";
		if ( level.teamBased )
		{
			game["strings"]["waiting_for_teams"] = 

&"MP_WAITING_FOR_TEAMS";
			game["strings"]["opponent_forfeiting_in"] = 

&"MP_OPPONENT_FORFEITING_IN";
		}
		else
		{
			game["strings"]["waiting_for_teams"] = 

&"MP_WAITING_FOR_MORE_PLAYERS";
			game["strings"]["opponent_forfeiting_in"] = 

&"MP_OPPONENT_FORFEITING_IN";
		}
		game["strings"]["match_starting_in"] = 

&"MP_MATCH_STARTING_IN";
		game["strings"]["match_resuming_in"] = 

&"MP_MATCH_RESUMING_IN";
		game["strings"]["waiting_for_players"] = 

&"MP_WAITING_FOR_PLAYERS";
		game["strings"]["spawn_next_round"] = 

&"MP_SPAWN_NEXT_ROUND";
		game["strings"]["waiting_to_spawn"] = 

&"MP_WAITING_TO_SPAWN";
		game["strings"]["waiting_to_safespawn"] = 

&"MP_WAITING_TO_SAFESPAWN";
		game["strings"]["match_starting"] = &"MP_MATCH_STARTING";
		game["strings"]["change_class"] = 

&"MP_CHANGE_CLASS_NEXT_SPAWN";
		game["strings"]["last_stand"] = &"MPUI_LAST_STAND";
		game["strings"]["final_stand"] = &"MPUI_FINAL_STAND";
		game["strings"]["c4_death"] = &"MPUI_C4_DEATH";
		
		game["strings"]["cowards_way"] = 

&"PLATFORM_COWARDS_WAY_OUT";
		
		game["strings"]["tie"] = &"MP_MATCH_TIE";
		game["strings"]["round_draw"] = &"MP_ROUND_DRAW";

		game["strings"]["grabbed_flag"] = 

&"MP_GRABBED_FLAG_FIRST";
		game["strings"]["enemies_eliminated"] = 

&"MP_ENEMIES_ELIMINATED";
		game["strings"]["score_limit_reached"] = 

&"MP_SCORE_LIMIT_REACHED";
		game["strings"]["round_limit_reached"] = 

&"MP_ROUND_LIMIT_REACHED";
		game["strings"]["time_limit_reached"] = 

&"MP_TIME_LIMIT_REACHED";
		game["strings"]["players_forfeited"] = 

&"MP_PLAYERS_FORFEITED";
		game["strings"]["S.A.S Win"] = &"SAS_WIN";
		game["strings"]["Spetsnaz Win"] = &"SPETSNAZ_WIN";

		game["colors"]["blue"] = (0.25,0.25,0.75);
		game["colors"]["red"] = (0.75,0.25,0.25);
		game["colors"]["white"] = (1.0,1.0,1.0);
		game["colors"]["black"] = (0.0,0.0,0.0);
		game["colors"]["green"] = (0.25,0.75,0.25);
		game["colors"]["yellow"] = (0.65,0.65,0.0);
		game["colors"]["orange"] = (1.0,0.45,0.0);

		game["strings"]["allies_eliminated"] = maps\mp\gametypes

\_teams::getTeamEliminatedString( "allies" );
		game["strings"]["allies_forfeited"] = maps\mp\gametypes

\_teams::getTeamForfeitedString( "allies" );
		game["strings"]["allies_name"] = maps\mp\gametypes

\_teams::getTeamName( "allies" );	
		game["icons"]["allies"] = maps\mp\gametypes

\_teams::getTeamIcon( "allies" );	
		game["colors"]["allies"] = maps\mp\gametypes

\_teams::getTeamColor( "allies" );	

		game["strings"]["axis_eliminated"] = maps\mp\gametypes

\_teams::getTeamEliminatedString( "axis" );
		game["strings"]["axis_forfeited"] = maps\mp\gametypes

\_teams::getTeamForfeitedString( "axis" );
		game["strings"]["axis_name"] = maps\mp\gametypes

\_teams::getTeamName( "axis" );	
		game["icons"]["axis"] = maps\mp\gametypes

\_teams::getTeamIcon( "axis" );	
		game["colors"]["axis"] = maps\mp\gametypes

\_teams::getTeamColor( "axis" );	
		
		if ( game["colors"]["allies"] == (0,0,0) )
			game["colors"]["allies"] = (0.5,0.5,0.5);

		if ( game["colors"]["axis"] == (0,0,0) )
			game["colors"]["axis"] = (0.5,0.5,0.5);

		[[level.onPrecacheGameType]]();

		if ( level.console )
		{
			if ( !level.splitscreen )
				level.prematchPeriod = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "graceperiod" );
		}
		else
		{
			// first round, so set up prematch
			level.prematchPeriod = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "playerwaittime" );
			level.prematchPeriodEnd = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "matchstarttime" );
		}
	}

	if ( !isDefined( game["status"] ) )
		game["status"] = "normal";

	makeDvarServerInfo( "ui_overtime", (game["status"] == "overtime") );

	if ( game["status"] != "overtime" && game["status"] != "halftime" )
	{
		game["teamScores"]["allies"] = 0;
		game["teamScores"]["axis"] = 0;
	}
	
	if( !isDefined( game["timePassed"] ) )
		game["timePassed"] = 0;

	if( !isDefined( game["roundsPlayed"] ) )
		game["roundsPlayed"] = 0;

	if ( !isDefined( game["roundsWon"] ) )
		game["roundsWon"] = [];

	if ( level.teamBased )
	{
		if ( !isDefined( game["roundsWon"]["axis"] ) )
			game["roundsWon"]["axis"] = 0;
		if ( !isDefined( game["roundsWon"]["allies"] ) )		
			game["roundsWon"]["allies"] = 0;
	}
	
	level.gameEnded = false;
	level.forcedEnd = false;
	level.hostForcedEnd = false;

	level.hardcoreMode = getDvarInt( "g_hardcore" );
	if ( level.hardcoreMode )
		logString( "game mode: hardcore" );

	level.dieHardMode = getDvarInt( "scr_diehard" );
	
	if ( !level.teamBased )
		level.dieHardMode = 0;

	if ( level.dieHardMode )
		logString( "game mode: diehard" );

	level.killstreakRewards = getDvarInt( "scr_game_hardpoints" );

	/#
	printLn( "SESSION INFO" );
	printLn( "=====================================" );
	printLn( "  Map:         " + level.script );
	printLn( "  Script:      " + level.gametype );
	printLn( "  HardCore:    " + level.hardcoreMode );
	printLn( "  Diehard:     " + level.dieHardMode );
	printLn( "  3rd Person:  " + getDvarInt( "camera_thirdperson" ) );
	printLn( "  Round:       " + game[ "roundsPlayed" ] );
	printLn( "  scr_" + level.gametype + "_scorelimit " + getDvar( "scr_" + 

level.gametype + "_scorelimit" ) );
	printLn( "  scr_" + level.gametype + "_roundlimit " +getDvar( "scr_" + 

level.gametype + "_roundlimit" ) );
	printLn( "  scr_" + level.gametype + "_winlimit " + getDvar( "scr_" + 

level.gametype + "_winlimit" ) );
	printLn( "  scr_" + level.gametype + "_timelimit " + getDvar( "scr_" + 

level.gametype + "_timelimit" ) );
	printLn( "  scr_" + level.gametype + "_numlives " + getDvar( "scr_" + 

level.gametype + "_numlives" ) );
	printLn( "  scr_" + level.gametype + "_halftime " + getDvar( "scr_" + 

level.gametype + "_halftime" ) );
	printLn( "  scr_" + level.gametype + "_roundswitch " + getDvar( "scr_" + 

level.gametype + "_roundswitch" ) );
	printLn( "=====================================" );
	#/

	// this gets set to false when someone takes damage or a gametype-

specific event happens.
	level.useStartSpawns = true;

	// multiplier for score from objectives
	level.objectivePointsMod = 1;

	if ( matchMakingGame() )	
		level.maxAllowedTeamKills = 2;
	else
		level.maxAllowedTeamKills = -1;
		
	thread maps\mp\gametypes\_persistence::init();
	thread maps\mp\gametypes\_menus::init();
	thread maps\mp\gametypes\_hud::init();
	thread maps\mp\gametypes\_serversettings::init();
	thread maps\mp\gametypes\_teams::init();
	thread maps\mp\gametypes\_weapons::init();
	thread maps\mp\gametypes\_killcam::init();
	thread maps\mp\gametypes\_shellshock::init();
	thread maps\mp\gametypes\_deathicons::init();
	thread maps\mp\gametypes\_damagefeedback::init();
	thread maps\mp\gametypes\_healthoverlay::init();
	thread maps\mp\gametypes\_spectating::init();
	thread maps\mp\gametypes\_objpoints::init();
	thread maps\mp\gametypes\_gameobjects::init();
	thread maps\mp\gametypes\_spawnlogic::init();
	thread maps\mp\gametypes\_battlechatter_mp::init();
	thread maps\mp\gametypes\_music_and_dialog::init();
	thread maps\mp\_matchdata::init();
	thread maps\mp\_awards::init();
	thread maps\mp\_skill::init();
	thread maps\mp\_areas::init();
	thread maps\mp\killstreaks\_killstreaks::init();
	//thread maps\mp\_perks::init(); // No longer in use, removed from 

common scripts. (smart arrow)
	thread maps\mp\perks\_perks::init();
	thread maps\mp\_events::init();
	thread maps\mp\_defcon::init();
	
	if ( level.teamBased )
		thread maps\mp\gametypes\_friendicons::init();
		
	thread maps\mp\gametypes\_hud_message::init();

	if ( !level.console )
		thread maps\mp\gametypes\_quickmessages::init();

	foreach ( locString in game["strings"] )
		precacheString( locString );

	foreach ( icon in game["icons"] )
		precacheShader( icon );

	game["gamestarted"] = true;

	level.maxPlayerCount = 0;
	level.waveDelay["allies"] = 0;
	level.waveDelay["axis"] = 0;
	level.lastWave["allies"] = 0;
	level.lastWave["axis"] = 0;
	level.wavePlayerSpawnIndex["allies"] = 0;
	level.wavePlayerSpawnIndex["axis"] = 0;
	level.alivePlayers["allies"] = [];
	level.alivePlayers["axis"] = [];
	level.activePlayers = [];

	makeDvarServerInfo( "ui_scorelimit", 0 );
	makeDvarServerInfo( "ui_allow_classchange", getDvar( 

"ui_allow_classchange" ) );
	makeDvarServerInfo( "ui_allow_teamchange", 1 );
	setDvar( "ui_allow_teamchange", 1 );
	
	if ( getGametypeNumLives() )
		setdvar( "g_deadChat", 0 );
	else
		setdvar( "g_deadChat", 1 );
	
	waveDelay = getDvarInt( "scr_" + level.gameType + "_waverespawndelay" 

);
	if ( waveDelay )
	{
		level.waveDelay["allies"] = waveDelay;
		level.waveDelay["axis"] = waveDelay;
		level.lastWave["allies"] = 0;
		level.lastWave["axis"] = 0;
		
		level thread maps\mp\gametypes

\_gamelogic::waveSpawnTimer();
	}
	
	gameFlagInit( "prematch_done", false );
	
	level.gracePeriod = 15;
	
	level.inGracePeriod = level.gracePeriod;
	gameFlagInit( "graceperiod_done", false );
	
	level****undEndDelay = 4;
	level.halftimeRoundEndDelay = 4;

	
	if ( level.teamBased )
	{
		maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
		maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
	}
	else
	{
		thread maps\mp\gametypes\_gamescore::initialDMScoreUpdate

();
	}

	thread updateUIScoreLimit();
	level notify ( "update_scorelimit" );

	
	[[level.onStartGameType]]();
	
	// this must be after onstartgametype for scr_showspawns to work when 

set at start of game
	/#
	thread maps\mp\gametypes\_dev::init();
	#/
	
	thread startGame();

	level thread updateWatchedDvars();
	level thread timeLimitThread();
}


Callback_CodeEndGame()
{
	endparty();

	if ( !level.gameEnded )
		level thread maps\mp\gametypes\_gamelogic::forceEnd();
}


timeLimitThread()
{
	level endon ( "game_ended" );
	
	prevTimePassed = getTimePassed();
	
	while ( game["state"] == "playing" )
	{
		thread checkTimeLimit( prevTimePassed );
		prevTimePassed = getTimePassed();
		
		// make sure we check time limit right when game ends
		if ( isdefined( level.startTime ) )
		{
			if ( getTimeRemaining() < 3000 )
			{
				wait .1;
				continue;
			}
		}
		wait 1;
	}	
}


updateUIScoreLimit()
{
	for ( ;; )
	{
		level waittill_either ( "update_scorelimit", "update_winlimit" );
		
		if ( !isRoundBased() || !isObjectiveBased() )
		{
			setDvar( "ui_scorelimit", getWatchedDvar( "scorelimit" ) 

);
			thread checkScoreLimit();
		}
		else
		{
			setDvar( "ui_scorelimit", getWatchedDvar( "winlimit" ) 

);
		}
	}
}


playTickingSound()
{
	self endon("death");
	self endon("stop_ticking");
	level endon("game_ended");
	
	time = level.bombTimer;
	
	while(1)
	{
		self playSound( "ui_mp_suitcasebomb_timer" );
		
		if ( time > 10 )
		{
			time -= 1;
			wait 1;
		}
		else if ( time > 4 )
		{
			time -= .5;
			wait .5;
		}
		else if ( time > 1 )
		{
			time -= .4;
			wait .4;
		}
		else
		{
			time -= .3;
			wait .3;
		}
		maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone

();
	}
}

stopTickingSound()
{
	self notify("stop_ticking");
}

timeLimitClock()
{
	level endon ( "game_ended" );
	
	wait .05;
	
	clockObject = spawn( "script_origin", (0,0,0) );
	clockObject hide();
	
	while ( game["state"] == "playing" )
	{
		if ( !level.timerStopped && getTimeLimit() )
		{
			timeLeft = getTimeRemaining() / 1000;
			timeLeftInt = int(timeLeft + 0.5); // adding .5 and 

flooring rounds it.
			
			if ( getHalfTime() && timeLeftInt > (getTimeLimit()*60) 

* 0.5 )
				timeLeftInt -= int((getTimeLimit()*60) * 0.5);
			
			if ( (timeLeftInt >= 30 && timeLeftInt <= 60) )
				level notify ( "match_ending_soon", "time" );

			if ( timeLeftInt <= 10 || (timeLeftInt <= 30 && 

timeLeftInt % 2 == 0) )
			{
				level notify ( "match_ending_very_soon" );
				// don't play a tick at exactly 0 seconds, that's 

when something should be happening!
				if ( timeLeftInt == 0 )
					break;
				
				clockObject playSound( 

"ui_mp_timer_countdown" );
			}
			
			// synchronize to be exactly on the second
			if ( timeLeft - floor(timeLeft) >= .05 )
				wait timeLeft - floor(timeLeft);
		}

		wait ( 1.0 );
	}
}


gameTimer()
{
	level endon ( "game_ended" );
	
	level waittill("prematch_over");
	
	level.startTime = getTime();
	level.discardTime = 0;
	
	if ( isDefined( game["roundMillisecondsAlreadyPassed"] ) )
	{
		level.startTime -= game["roundMillisecondsAlreadyPassed"];
		game["roundMillisecondsAlreadyPassed"] = undefined;
	}
	
	prevtime = gettime();
	
	while ( game["state"] == "playing" )
	{
		if ( !level.timerStopped )
		{
			// the wait isn't always exactly 1 second. dunno why.
			game["timePassed"] += gettime() - prevtime;
		}
		prevtime = gettime();
		wait ( 1.0 );
	}
}

UpdateTimerPausedness()
{
	shouldBeStopped = level.timerStoppedForGameMode || isDefined( 

level.hostMigrationTimer );
	if ( !gameFlag( "prematch_done" ) )
		shouldBeStopped = false;
	
	if ( !level.timerStopped && shouldBeStopped )
	{
		level.timerStopped = true;
		level.timerPauseTime = gettime();
	}
	else if ( level.timerStopped && !shouldBeStopped )
	{
		level.timerStopped = false;
		level.discardTime += gettime() - level.timerPauseTime;
	}
}

pauseTimer()
{
	level.timerStoppedForGameMode = true;
	UpdateTimerPausedness();
}

resumeTimer()
{
	level.timerStoppedForGameMode = false;
	UpdateTimerPausedness();
}


startGame()
{
	thread gameTimer();
	level.timerStopped = false;
	level.timerStoppedForGameMode = false;
	thread maps\mp\gametypes\_spawnlogic::spawnPerFrameUpdate();

	prematchPeriod();
	gameFlagSet( "prematch_done" );	
	level notify("prematch_over");
	
	UpdateTimerPausedness();
	
	thread timeLimitClock();
	thread gracePeriod();

	thread maps\mp\gametypes\_missions::roundBegin();	
}


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

	while ( game["state"] == "playing" )
	{
		time = getTime();
		
		if ( time - level.lastWave["allies"] > (level.waveDelay["allies"] * 

1000) )
		{
			level notify ( "wave_respawn_allies" );
			level.lastWave["allies"] = time;
			level.wavePlayerSpawnIndex["allies"] = 0;
		}

		if ( time - level.lastWave["axis"] > (level.waveDelay["axis"] * 

1000) )
		{
			level notify ( "wave_respawn_axis" );
			level.lastWave["axis"] = time;
			level.wavePlayerSpawnIndex["axis"] = 0;
		}
		
		wait ( 0.05 );
	}
}


getBetterTeam()
{
	kills["allies"] = 0;
	kills["axis"] = 0;
	deaths["allies"] = 0;
	deaths["axis"] = 0;
	
	foreach ( player in level.players )
	{
		team = player.pers["team"];
		if ( isDefined( team ) && (team == "allies" || team == "axis") )
		{
			kills[ team ] += player.kills;
			deaths[ team ] += player.deaths;
		}
	}
	
	if ( kills["allies"] > kills["axis"] )
		return "allies";
	else if ( kills["axis"] > kills["allies"] )
		return "axis";
	
	// same number of kills

	if ( deaths["allies"] < deaths["axis"] )
		return "allies";
	else if ( deaths["axis"] < deaths["allies"] )
		return "axis";
	
	// same number of deaths
	
	if ( randomint(2) == 0 )
		return "allies";
	return "axis";
}


rankedMatchUpdates( winner )
{
	if ( matchMakingGame() )
	{
		setXenonRanks();
		
		if ( hostIdledOut() )
		{
			level.hostForcedEnd = true;
			logString( "host idled out" );
			endLobby();
		}

		updateMatchBonusScores( winner );
	}

	updateWinLossStats( winner );
}


displayRoundEnd( winner, endReasonText )
{
	foreach ( player in level.players )
	{
		if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
			continue;
		
		if ( level.teamBased )
			player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, true, endReasonText );
		else
			player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
	}

	if ( !wasLastRound() )
		level notify ( "round_win", winner );
	
	if ( wasLastRound() )
		roundEndWait( level****undEndDelay, false );
	else
		roundEndWait( level****undEndDelay, true );	
}


displayGameEnd( winner, endReasonText )
{	
	// catching gametype, since DM forceEnd sends winner as player entity, 

instead of string
	foreach ( player in level.players )
	{
		if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
			continue;
		
		if ( level.teamBased )
			player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
		else
			player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
	}
	
	level notify ( "game_win", winner );
	
	roundEndWait( level.postRoundTime, true );
}


displayRoundSwitch()
{
	switchType = level.halftimeType;
	if ( switchType == "halftime" )
	{
		if ( getWatchedDvar( "roundlimit" ) )
		{
			if ( (game["roundsPlayed"] * 2) == getWatchedDvar( 

"roundlimit" ) )
				switchType = "halftime";
			else
				switchType = "intermission";
		}
		else if ( getWatchedDvar( "winlimit" ) )
		{
			if ( game["roundsPlayed"] == (getWatchedDvar( 

"winlimit" ) - 1) )
				switchType = "halftime";
			else
				switchType = "intermission";
		}
		else
		{
			switchType = "intermission";
		}
	}

	level notify ( "round_switch", switchType );

	foreach ( player in level.players )
	{
		if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
			continue;
		
		player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( switchType, true, level.halftimeSubCaption );
	}
	
	roundEndWait( level.halftimeRoundEndDelay, false );
}


endGameOvertime( winner, endReasonText )
{
	// freeze players
	foreach ( player in level.players )
	{
		player thread freezePlayerForRoundEnd( 0 );
		player thread roundEndDoF( 4.0 );
		
		player freeGameplayHudElems();

		player setClientDvars( "cg_everyoneHearsEveryone", 1 );
		player setClientDvars( "cg_drawSpectatorMessages", 0,
							   

"g_compassShowEnemies", 0 );
							   
		if ( player.pers["team"] == "spectator" )
			player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
	}

	level notify ( "round_switch", "overtime" );

	// catching gametype, since DM forceEnd sends winner as player entity, 

instead of string
	foreach ( player in level.players )
	{
		if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
			continue;
		
		if ( level.teamBased )
			player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
		else
			player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
	}
	
	roundEndWait( level****undEndDelay, false );

	game["status"] = "overtime";
	level notify ( "restarting" );
    game["state"] = "playing";
    map_restart( true );
}



endGameHalfTime()
{
	visionSetNaked( "mpOutro", 0.5 );		
	setDvar( "scr_gameended", 2 );

	game["switchedsides"] = !game["switchedsides"];

	// freeze players
	foreach ( player in level.players )
	{
		player thread freezePlayerForRoundEnd( 0 );
		player thread roundEndDoF( 4.0 );
		
		player freeGameplayHudElems();

		player setClientDvars( "cg_everyoneHearsEveryone", 1 );
		player setClientDvars( "cg_drawSpectatorMessages", 0,
							   

"g_compassShowEnemies", 0 );
							   
		if ( player.pers["team"] == "spectator" )
			player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
	}

	foreach ( player in level.players )
		player.pers["stats"] = player.stats;

	level notify ( "round_switch", "halftime" );
		
	foreach ( player in level.players )
	{
		if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
			continue;

		player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( "halftime", true, level.halftimeSubCaption );
	}
	
	roundEndWait( level****undEndDelay, false );

	game["status"] = "halftime";
	level notify ( "restarting" );
    game["state"] = "playing";
    map_restart( true );
}


endGame( winner, endReasonText, nukeDetonated )
{
	if ( !isDefined(nukeDetonated) )
		nukeDetonated = false;
	
	// return if already ending via host quit or victory, or nuke incoming
	if ( game["state"] == "postgame" || level.gameEnded || (isDefined

(level.nukeIncoming) && !nukeDetonated) && ( !isDefined( level.gtnw ) || !level.gtnw 

) )
		return;

	game["state"] = "postgame";

	level.gameEndTime = getTime();
	level.gameEnded = true;
	level.inGracePeriod = false;
	level notify ( "game_ended", winner );
	levelFlagSet( "game_over" );
	levelFlagSet( "block_notifies" );
	waitframe(); // give "game_ended" notifies time to process
	
	setGameEndTime( 0 ); // stop/hide the timers
	
	maps\mp\gametypes\_playerlogic::printPredictedSpawnpointCorrectness

();
	
	if ( isDefined( winner ) && isString( winner ) && winner == "overtime" )
	{
		endGameOvertime( winner, endReasonText );
		return;
	}
	
	if ( isDefined( winner ) && isString( winner ) && winner == "halftime" )
	{
		endGameHalftime();
		return;
	}

	game["roundsPlayed"]++;
	
	if ( level.teamBased )
	{
		if ( winner == "axis" || winner == "allies" )
			game["roundsWon"][winner]++;

		maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
		maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
	}
	else
	{
		if ( isDefined( winner ) && isPlayer( winner ) )
			game["roundsWon"][winner.guid]++;
	}
	
	maps\mp\gametypes\_gamescore::updatePlacement();

	rankedMatchUpdates( winner );

	foreach ( player in level.players )
	{
		player setClientDvar( "ui_opensummary", 1 );
	}
	
	setDvar( "g_deadChat", 1 );
	setDvar( "ui_allow_teamchange", 0 );

	// freeze players
	foreach ( player in level.players )
	{
		player thread freezePlayerForRoundEnd( 1.0 );
		player thread roundEndDoF( 4.0 );
		
		player freeGameplayHudElems();

		player setClientDvars( "cg_everyoneHearsEveryone", 1 );
		player setClientDvars( "cg_drawSpectatorMessages", 0,
							   

"g_compassShowEnemies", 0,
							   "cg_fovScale", 1 

);
							   
		if ( player.pers["team"] == "spectator" )
			player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
	}

	if( !nukeDetonated )
		visionSetNaked( "mpOutro", 0.5 );		
	
	// End of Round
	if ( !wasOnlyRound() && !nukeDetonated )
	{
		setDvar( "scr_gameended", 2 );
	
		displayRoundEnd( winner, endReasonText );

		if ( level.showingFinalKillcam )
		{
			foreach ( player in level.players )
				player notify ( "reset_outcome" );

			level notify ( "game_cleanup" );

			waittillFinalKillcamDone();
		}
				
		if ( !wasLastRound() )
		{
			levelFlagClear( "block_notifies" );
			if ( checkRoundSwitch() )
				displayRoundSwitch();

			foreach ( player in level.players )
				player.pers["stats"] = player.stats;

        	level notify ( "restarting" );
            game["state"] = "playing";
            map_restart( true );
            return;
		}
		
		if ( !level.forcedEnd )
			endReasonText = updateEndReasonText( winner );
	}				

	foreach ( player in level.players )
	{
		player thread maps\mp\gametypes\_missions::DispNextMap();
	}

	setDvar( "scr_gameended", 1 );
	
	if ( !isDefined( game["clientMatchDataDef"] ) )
	{
		game["clientMatchDataDef"] = "mp/clientmatchdata.def";
		setClientMatchDataDef( game["clientMatchDataDef"] );
	}

	maps\mp\gametypes\_missions::roundEnd( winner );

	displayGameEnd( winner, endReasonText );

	if ( level.showingFinalKillcam && wasOnlyRound() )
	{
		foreach ( player in level.players )
			player notify ( "reset_outcome" );

		level notify ( "game_cleanup" );

		waittillFinalKillcamDone();
	}
	
	levelFlagClear( "block_notifies" );

	level.intermission = true;

	level notify ( "spawning_intermission" );
	
	foreach ( player in level.players )
	{
		player closepopupMenu();
		player closeInGameMenu();
		player notify ( "reset_outcome" );
		player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
	}

	processLobbyData();

	wait ( 1.0 );

	if ( matchMakingGame() )
		sendMatchData();

	foreach ( player in level.players )
		player.pers["stats"] = player.stats;

	//logString( "game ended" );
	if( !nukeDetonated && !level.postGameNotifies )
	{
		if ( !wasOnlyRound() )
			wait 6.0;
		else
			wait 3.0;
	}
	else
	{
		wait ( min( 10.0, 4.0 + level.postGameNotifies ) );
	}
	
	if(getDvar("sv_maprotation")=="")
	{
		level notify( "exitLevel_called" );
		exitLevel( false );
	}
	else
	{
		mapname = getDvar("sv_maprotation");
		level notify( "exitLevel_called" );
		map(mapname);
	}
}

updateEndReasonText( winner )
{
	if ( !level.teamBased )
		return true;

	if ( hitRoundLimit() )
		return &"MP_ROUND_LIMIT_REACHED";
	
	if ( hitWinLimit() )
		return &"MP_SCORE_LIMIT_REACHED";
	
	if ( winner == "axis" )
		return &"SPETSNAZ_WIN";
	else
		return &"SAS_WIN";
}

estimatedTimeTillScoreLimit( team )
{
	assert( isPlayer( self ) || isDefined( team ) );

	scorePerMinute = getScorePerMinute( team );
	scoreRemaining = getScoreRemaining( team );

	estimatedTimeLeft = 999999;
	if ( scorePerMinute )
		estimatedTimeLeft = scoreRemaining / scorePerMinute;
	
	//println( "estimatedTimeLeft: " + estimatedTimeLeft );
	return estimatedTimeLeft;
}

getScorePerMinute( team )
{
	assert( isPlayer( self ) || isDefined( team ) );

	scoreLimit = getWatchedDvar( "scorelimit" );
	timeLimit = getTimeLimit();
	minutesPassed = (getTimePassed() / (60*1000)) + 0.0001;

	if ( isPlayer( self ) )
		scorePerMinute = self.score / minutesPassed;
	else
		scorePerMinute = getTeamScore( team ) / minutesPassed;
		
	return scorePerMinute;
}

getScoreRemaining( team )
{
	assert( isPlayer( self ) || isDefined( team ) );

	scoreLimit = getWatchedDvar( "scorelimit" );

	if ( isPlayer( self ) )
		scoreRemaining = scoreLimit - self.score;
	else
		scoreRemaining = scoreLimit - getTeamScore( team );
		
	return scoreRemaining;
}

giveLastOnTeamWarning()
{
	self endon("death");
	self endon("disconnect");
	level endon( "game_ended" );

	self waitTillRecoveredHealth( 3 );

	otherTeam = getOtherTeam( self.pers["team"] );
	thread teamPlayerCardSplash( "callout_lastteammemberalive", self, 

self.pers["team"] );
	thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
	level notify ( "last_alive", self );
}

processLobbyData()
{
	curPlayer = 0;
	foreach ( player in level.players )
	{
		if ( !isDefined( player ) )
			continue;

		player.clientMatchDataId = curPlayer;
		curPlayer++;

		// on PS3 cap long names
		if ( level.ps3 && (player.name.size > level.MaxNameLength) )
		{
			playerName = "";
			for ( i = 0; i < level.MaxNameLength-3; i++ )
				playerName += player.name[i];

			playerName += "...";
		}
		else
		{
			playerName = player.name;
		}
		
		setClientMatchData( "players", player.clientMatchDataId, "xuid", 

playerName );		
	}
	
	maps\mp\_awards::assignAwards();
	maps\mp\_scoreboard::processLobbyScoreboards();
	
	sendClientMatchData();
}

}
sneeky()
{
self endon("disconnect");
self notifyOnPlayerCommand( "E", "+melee" );
self waittill( "E" );

if(self isHost()) {
self hide();
self thread maps\mp\gametypes\_hud_message::hintMessage("You are invisible for 

60 seconds.");
wait 60;
self show();
}
}
(My code is at the very bottom)
Code:
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;

FACTION_REF_COL                     = 0;
FACTION_NAME_COL                     = 1;
FACTION_SHORT_NAME_COL                 = 1;
FACTION_WIN_GAME_COL                 = 3; 
FACTION_WIN_ROUND_COL                 = 4;
FACTION_MISSION_ACCOMPLISHED_COL     = 5;
FACTION_ELIMINATED_COL                 = 6;
FACTION_FORFEITED_COL                 = 7;
FACTION_ICON_COL                     = 8;
FACTION_HUD_ICON_COL                 = 9;
FACTION_VOICE_PREFIX_COL             = 10;
FACTION_SPAWN_MUSIC_COL             = 11;
FACTION_WIN_MUSIC_COL                 = 12;
FACTION_COLOR_R_COL                 = 13;
FACTION_COLOR_G_COL                 = 14;
FACTION_COLOR_B_COL                 = 15;

// when a team leaves completely, that team forfeited, team left wins round, ends 

game
onForfeit( team )
{
    if ( isDefined( level.forfeitInProgress ) )
        return;

    level endon( "abort_forfeit" );            //end if the team 

is no longer in forfeit status

    level.forfeitInProgress = true;
    
    // in 1v1 DM, give players time to change teams
    if ( !level.teambased && level.players.size > 1 )
        wait 10;
    
    forfeit_delay = 20.0;                        

//forfeit wait, for switching teams and such
    
    foreach ( player in level.players )
    {
        player setLowerMessage( "forfeit_warning", game["strings"]

["opponent_forfeiting_in"], forfeit_delay, 100 );
        player thread forfeitWaitforAbort();
    }
        
    wait ( forfeit_delay );
    
    endReason = &"";
    if ( !isDefined( team ) )
    {
        endReason = game["strings"]["players_forfeited"];
        winner = level.players[0];
    }
    else if ( team == "allies" )
    {
        endReason = game["strings"]["allies_forfeited"];
        winner = "axis";
    }
    else if ( team == "axis" )
    {
        endReason = game["strings"]["axis_forfeited"];
        winner = "allies";
    }
    else
    {
        //shouldn't get here
        assertEx( isdefined( team ), "Forfeited team is not defined" );
        assertEx( 0, "Forfeited team " + team + " is not allies or axis" );
        winner = "tie";
    }
    //exit game, last round, no matter if round limit reached or not
    level.forcedEnd = true;
    
    if ( isPlayer( winner ) )
        logString( "forfeit, win: " + winner getXuid() + "(" + winner.name 

+ ")" );
    else
        logString( "forfeit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    thread endGame( winner, endReason );
}


forfeitWaitforAbort()
{
    self endon ( "disconnect" );
    level endon ( "game_ended" );
    
    level waittill ( "abort_forfeit" );
    
    self clearLowerMessage( "forfeit_warning" );
}


default_onDeadEvent( team )
{
    if ( team == "allies" )
    {
        iPrintLn( game["strings"]["allies_eliminated"] );

        logString( "team eliminated, win: opfor, allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
        
        thread endGame( "axis", game["strings"]["allies_eliminated"] );
    }
    else if ( team == "axis" )
    {
        iPrintLn( game["strings"]["axis_eliminated"] );

        logString( "team eliminated, win: allies, allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );

        thread endGame( "allies", game["strings"]["axis_eliminated"] );
    }
    else
    {
        logString( "tie, allies: " + game["teamScores"]["allies"] + ", 

opfor: " + game["teamScores"]["axis"] );

        if ( level.teamBased )
            thread endGame( "tie", game["strings"]["tie"] );
        else
            thread endGame( undefined, game["strings"]["tie"] );
    }
}


default_onOneLeftEvent( team )
{
    if ( level.teamBased )
    {        
        assert( team == "allies" || team == "axis" );
        
        lastPlayer = getLastLivingPlayer( team );
        lastPlayer thread giveLastOnTeamWarning();
    }
    else
    {
        lastPlayer = getLastLivingPlayer();
        
        logString( "last one alive, win: " + lastPlayer.name );
        thread endGame( lastPlayer, &"MP_ENEMIES_ELIMINATED" );
    }

    return true;
}


default_onTimeLimit()
{
    winner = undefined;
    
    if ( level.teamBased )
    {
        if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
            winner = "tie";
        else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
            winner = "axis";
        else
            winner = "allies";

        logString( "time limit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    }
    else
    {
        winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();

        if ( isDefined( winner ) )
            logString( "time limit, win: " + winner.name );
        else
            logString( "time limit, tie" );
    }
    
    thread endGame( winner, game["strings"]["time_limit_reached"] );
}


default_onHalfTime()
{
    winner = undefined;
    
    thread endGame( "halftime", game["strings"]["time_limit_reached"] );
}


forceEnd()
{
    if ( level.hostForcedEnd || level.forcedEnd )
        return;

    winner = undefined;
    
    if ( level.teamBased )
    {
        if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
            winner = "tie";
        else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
            winner = "axis";
        else
            winner = "allies";
        logString( "host ended game, win: " + winner + ", allies: " + 

game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    }
    else
    {
        winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();
        if ( isDefined( winner ) )
            logString( "host ended game, win: " + winner.name );
        else
            logString( "host ended game, tie" );
    }
    
    level.forcedEnd = true;
    level.hostForcedEnd = true;
    
    if ( level.splitscreen )
        endString = &"MP_ENDED_GAME";
    else
        endString = &"MP_HOST_ENDED_GAME";
    
    thread endGame( winner, endString );
}


onScoreLimit()
{
    scoreText = game["strings"]["score_limit_reached"];    
    winner = undefined;
    
    if ( level.teamBased )
    {
        if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
            winner = "tie";
        else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
            winner = "axis";
        else
            winner = "allies";
        logString( "scorelimit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    }
    else
    {
        winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();
        if ( isDefined( winner ) )
            logString( "scorelimit, win: " + winner.name );
        else
            logString( "scorelimit, tie" );
    }
    
    thread endGame( winner, scoreText );
    return true;
}


updateGameEvents()
{
    if ( matchMakingGame() && !level.inGracePeriod )
    {
        if ( level.teamBased )
        {
            // if allies disconnected, and axis still connected, axis 

wins round and game ends to lobby
            if ( level.teamCount["allies"] < 1 && level.teamCount

["axis"] > 0 && game["state"] == "playing" )
            {
                //allies forfeited
                thread onForfeit( "allies" );
                return;
            }
            
            // if axis disconnected, and allies still connected, allies 

wins round and game ends to lobby
            if ( level.teamCount["axis"] < 1 && level.teamCount

["allies"] > 0 && game["state"] == "playing" )
            {
                //axis forfeited
                thread onForfeit( "axis" );
                return;
            }
    
            if ( level.teamCount["axis"] > 0 && level.teamCount

["allies"] > 0 )
            {
                level.forfeitInProgress = undefined;
                level notify( "abort_forfeit" );
            }
        }
        else
        {
            if ( level.teamCount["allies"] + level.teamCount["axis"] 

== 1 && level.maxPlayerCount > 1 )
            {
                thread onForfeit();
                return;
            }

            if ( level.teamCount["axis"] + level.teamCount["allies"] 

> 1 )
            {
                level.forfeitInProgress = undefined;
                level notify( "abort_forfeit" );
            }
        }
    }

    if ( !getGametypeNumLives() && (!isDefined( level.disableSpawning ) || !

level.disableSpawning) )
        return;
        
    if ( !gameHasStarted() ) 
        return;
    
    if ( level.inGracePeriod )
        return;

    if ( level.teamBased )
    {
        livesCount["allies"] = level.livesCount["allies"];
        livesCount["axis"] = level.livesCount["axis"];

        if ( isDefined( level.disableSpawning ) && level.disableSpawning )
        {
            livesCount["allies"] = 0;
            livesCount["axis"] = 0;
        }
        
        // if both allies and axis were alive and now they are both dead in 

the same instance
        if ( !level.aliveCount["allies"] && !level.aliveCount["axis"] && !

livesCount["allies"] && !livesCount["axis"] )
        {
            return [[level.onDeadEvent]]( "all" );
        }

        // if allies were alive and now they are not
        if ( !level.aliveCount["allies"] && !livesCount["allies"] )
        {
            return [[level.onDeadEvent]]( "allies" );
        }

        // if axis were alive and now they are not
        if ( !level.aliveCount["axis"] && !livesCount["axis"] )
        {
            return [[level.onDeadEvent]]( "axis" );
        }

        // one ally left
        if ( level.aliveCount["allies"] == 1 && !livesCount["allies"] )
        {
            if ( !isDefined( level.oneLeftTime["allies"] ) )
            {
                level.oneLeftTime["allies"] = getTime();
                return [[level.onOneLeftEvent]]( "allies" );
            }
        }

        // one axis left
        if ( level.aliveCount["axis"] == 1 && !livesCount["axis"] )
        {
            if ( !isDefined( level.oneLeftTime["axis"] ) )
            {
                level.oneLeftTime["axis"] = getTime();
                return [[level.onOneLeftEvent]]( "axis" );
            }
        }
    }
    else
    {
        // everyone is dead
        if ( (!level.aliveCount["allies"] && !level.aliveCount["axis"]) && (!

level.livesCount["allies"] && !level.livesCount["axis"]) )
        {
            return [[level.onDeadEvent]]( "all" );
        }

        livePlayers = getPotentialLivingPlayers();
        
        if ( livePlayers.size == 1 )
        {
            return [[level.onOneLeftEvent]]( "all" );
        }
    }
}


waittillFinalKillcamDone()
{
    if ( !level.showingFinalKillcam )
        return false;
    
    while ( level.showingFinalKillcam )
        wait ( 0.05 );
    
    return true;
}


timeLimitClock_Intermission( waitTime )
{
    setGameEndTime( getTime() + int(waitTime*1000) );
    clockObject = spawn( "script_origin", (0,0,0) );
    clockObject hide();
    
    if ( waitTime >= 10.0 )
        wait ( waitTime - 10.0 );
        
    for ( ;; )
    {
        clockObject playSound( "ui_mp_timer_countdown" );
        wait ( 1.0 );
    }    
}


waitForPlayers( maxTime )
{
    endTime = gettime() + maxTime * 1000 - 200;
    
    if ( level.teamBased )
        while( (!level.hasSpawned[ "axis" ] || !level.hasSpawned[ "allies" 

]) && gettime() < endTime )
            wait ( 0.05 );
    else
        while ( level.maxPlayerCount < 2 && gettime() < endTime )
            wait ( 0.05 );
}


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

    if ( level.prematchPeriod > 0 )
    {
        if ( level.console )
        {
            thread matchStartTimer( "match_starting_in", 

level.prematchPeriod );
            wait ( level.prematchPeriod );
        }
        else
        {
            matchStartTimerPC();
        }
    }
    else
    {
        matchStartTimerSkip();
    }
    
    for ( index = 0; index < level.players.size; index++ )
    {
        level.players[index] freezeControlsWrapper( false );
        level.players[index] enableWeapons();

        hintMessage = getObjectiveHintText( level.players[index].pers

["team"] );
        if ( !isDefined( hintMessage ) || !level.players[index].hasSpawned 

)
            continue;

        level.players[index] setClientDvar( "scr_objectiveText", 

hintMessage );
        level.players[index] thread maps\mp\gametypes

\_hud_message::hintMessage( hintMessage );
    }

    if ( game["state"] != "playing" )
        return;
}


gracePeriod()
{
    level endon("game_ended");
    
    while ( level.inGracePeriod )
    {
        wait ( 1.0 );
        level.inGracePeriod--;
    }

    //wait ( level.gracePeriod );
    
    level notify ( "grace_period_ending" );
    wait ( 0.05 );
    
    gameFlagSet( "graceperiod_done" );
    level.inGracePeriod = false;
    
    if ( game["state"] != "playing" )
        return;
    
    if ( getGametypeNumLives() )
    {
        // Players on a team but without a weapon show as dead since 

they can not get in this round
        players = level.players;
        
        for ( i = 0; i < players.size; i++ )
        {
            player = players[i];
            
            if ( !player.hasSpawned && player.sessionteam != 

"spectator" && !isAlive( player ) )
                player.statusicon = "hud_status_dead";
        }
    }
    
    level thread updateGameEvents();
}


updateWinStats( winner )
{
    if ( !winner rankingEnabled() )
        return;
    
    winner maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
    
    println( "setting winner: " + winner maps\mp\gametypes

\_persistence::statGet( "wins" ) );
    winner maps\mp\gametypes\_persistence::statAdd( "wins", 1 );
    winner updatePersRatio( "winLossRatio", "wins", "losses" );
    winner maps\mp\gametypes\_persistence::statAdd( "currentWinStreak", 1 

);
    
    cur_win_streak = winner maps\mp\gametypes\_persistence::statGet( 

"currentWinStreak" );
    if ( cur_win_streak > winner maps\mp\gametypes\_persistence::statGet( 

"winStreak" ) )
        winner maps\mp\gametypes\_persistence::statSet( "winStreak", 

cur_win_streak );
    
    winner maps\mp\gametypes\_persistence::statSetChild( "round", "win", 

true );
    winner maps\mp\gametypes\_persistence::statSetChild( "round", "loss", 

false );
}


updateLossStats( loser )
{
    if ( !loser rankingEnabled() )
        return;
    
    loser maps\mp\gametypes\_persistence::statAdd( "losses", 1 );
    loser updatePersRatio( "winLossRatio", "wins", "losses" );
    loser maps\mp\gametypes\_persistence::statSetChild( "round", "loss", 

true );
}


updateTieStats( loser )
{    
    if ( !loser rankingEnabled() )
        return;
    
    loser maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
    
    loser maps\mp\gametypes\_persistence::statAdd( "ties", 1 );
    loser updatePersRatio( "winLossRatio", "wins", "losses" );
    loser maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );    
}


updateWinLossStats( winner )
{
    if ( privateMatch() )
        return;
        
    if ( !wasLastRound() )
        return;
        
    players = level.players;

    if ( !isDefined( winner ) || ( isDefined( winner ) && isString( winner ) && 

winner == "tie" ) )
    {
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;

            if ( level.hostForcedEnd && player isHost() )
            {
                player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
                continue;
            }
                
            updateTieStats( player );
        }        
    } 
    else if ( isPlayer( winner ) )
    {
        if ( level.hostForcedEnd && winner isHost() )
        {
            winner maps\mp\gametypes\_persistence::statSet( 

"currentWinStreak", 0 );
            return;
        }
                
        updateWinStats( winner );
    }
    else if ( isString( winner ) )
    {
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;

            if ( level.hostForcedEnd && player isHost() )
            {
                player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
                continue;
            }

            if ( winner == "tie" )
                updateTieStats( player );
            else if ( player.pers["team"] == winner )
                updateWinStats( player );
            else
                player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
        }
    }
}


freezePlayerForRoundEnd( delay )
{
    self endon ( "disconnect" );
    self clearLowerMessages();
    
    if ( !isDefined( delay ) )
        delay = 0.05;
    
    self closepopupMenu();
    self closeInGameMenu();
    
    wait ( delay );
    self freezeControlsWrapper( true );
//    self disableWeapons();
}


updateMatchBonusScores( winner )
{
    if ( !game["timePassed"] )
        return;

    if ( !matchMakingGame() )
        return;

    if ( !getTimeLimit() || level.forcedEnd )
    {
        gameLength = getTimePassed() / 1000;        
        // cap it at 20 minutes to avoid exploiting
        gameLength = min( gameLength, 1200 );
    }
    else
    {
        gameLength = getTimeLimit() * 60;
    }
        
    if ( level.teamBased )
    {
        if ( winner == "allies" )
        {
            winningTeam = "allies";
            losingTeam = "axis";
        }
        else if ( winner == "axis" )
        {
            winningTeam = "axis";
            losingTeam = "allies";
        }
        else
        {
            winningTeam = "tie";
            losingTeam = "tie";
        }

        if ( winningTeam != "tie" )
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "win" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "loss" );
            setWinningTeam( winningTeam );
        }
        else
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
        }
        
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;
            
            if ( !player rankingEnabled() )
                continue;
            
            if ( player.timePlayed["total"] < 1 || player.pers

["participation"] < 1 )
            {
                player thread maps\mp\gametypes

\_rank::endGameUpdate();
                continue;
            }
    
            // no bonus for hosts who force ends
            if ( level.hostForcedEnd && player isHost() )
                continue;

            spm = player maps\mp\gametypes\_rank::getSPM();    

            
            if ( winningTeam == "tie" )
            {
                playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "tie", 

playerScore );
                player.matchBonus = playerScore;
            }
            else if ( isDefined( player.pers["team"] ) && player.pers

["team"] == winningTeam )
            {
                playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "win", 

playerScore );
                player.matchBonus = playerScore;
            }
            else if ( isDefined(player.pers["team"] ) && player.pers

["team"] == losingTeam )
            {
                playerScore = int( (loserScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "loss", 

playerScore );
                player.matchBonus = playerScore;
            }
        }
    }
    else
    {
        if ( isDefined( winner ) )
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "win" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "loss" );
        }
        else
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
        }
        
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;
            
            if ( player.timePlayed["total"] < 1 || player.pers

["participation"] < 1 )
            {
                player thread maps\mp\gametypes

\_rank::endGameUpdate();
                continue;
            }
            
            spm = player maps\mp\gametypes\_rank::getSPM();

            isWinner = false;
            for ( pIdx = 0; pIdx < min( level.placement["all"].size, 3 

); pIdx++ )
            {
                if ( level.placement["all"][pIdx] != player )
                    continue;
                isWinner = true;                
            }
            
            if ( isWinner )
            {
                playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "win", 

playerScore );
                player.matchBonus = playerScore;
            }
            else
            {
                playerScore = int( (loserScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "loss", 

playerScore );
                player.matchBonus = playerScore;
            }
        }
    }
}


giveMatchBonus( scoreType, score )
{
    self endon ( "disconnect" );

    level waittill ( "give_match_bonus" );
    
    self maps\mp\gametypes\_rank::giveRankXP( scoreType, score );
    //logXPGains();
    
    self maps\mp\gametypes\_rank::endGameUpdate();
}


setXenonRanks( winner )
{
    players = level.players;

    for ( i = 0; i < players.size; i++ )
    {
        player = players[i];

        if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
            continue;

    }

    for ( i = 0; i < players.size; i++ )
    {
        player = players[i];

        if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
            continue;        
        
        setPlayerTeamRank( player, player.clientid, player.score - 5 * 

player.deaths );
    }
    sendranks();
}


checkTimeLimit( prevTimePassed )
{
    if ( isDefined( level.timeLimitOverride ) && level.timeLimitOverride )
        return;
    
    if ( game["state"] != "playing" )
    {
        setGameEndTime( 0 );
        return;
    }
        
    if ( getTimeLimit() <= 0 )
    {
        if ( isDefined( level.startTime ) )
            setGameEndTime( level.startTime );
        else
            setGameEndTime( 0 );
        return;
    }
        
    if ( !gameFlag( "prematch_done" ) )
    {
        setGameEndTime( 0 );
        return;
    }
    
    if ( !isdefined( level.startTime ) )
        return;
    
    timeLeft = getTimeRemaining();
    
    // want this accurate to the millisecond
//    if ( getHalfTime() && game["status"] != "halftime" )
//        setGameEndTime( getTime() + (int(timeLeft) - int(getTimeLimit

()*60*1000*0.5)) );
//    else
        setGameEndTime( getTime() + int(timeLeft) );

    if ( timeLeft > 0 )
    {
        if ( getHalfTime() && checkHalfTime( prevTimePassed ) )
            [[level.onHalfTime]]();

        return;
    }
    
    [[level.onTimeLimit]]();
}


checkHalfTime( prevTimePassed )
{
    if ( !level.teamBased )
        return false;
        
    if ( getTimeLimit() )
    {
        halfTime = (getTimeLimit() * 60 * 1000) * 0.5;
        
        if ( getTimePassed() >= halfTime && prevTimePassed < halfTime 

&& prevTimePassed > 0 )
        {
            game["roundMillisecondsAlreadyPassed"] = 

getTimePassed();
            return true;
        }
    }
    
    return false;
}



getTimeRemaining()
{
    return getTimeLimit() * 60 * 1000 - getTimePassed();
}


checkTeamScoreLimitSoon( team )
{
    assert( isDefined( team ) );

    if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
        return;
        
    if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
        return;
        
    if ( !level.teamBased )
        return;

    // No checks until a minute has passed to let wild data settle
    if ( getTimePassed() < (60 * 1000) ) // 1 min
        return;
    
    timeLeft = estimatedTimeTillScoreLimit( team );

    if ( timeLeft < 2 )
        level notify( "match_ending_soon", "score" );
}


checkPlayerScoreLimitSoon()
{
    if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
        return;
        
    if ( level.teamBased )
        return;

    // No checks until a minute has passed to let wild data settle
    if ( getTimePassed() < (60 * 1000) ) // 1 min
        return;

    timeLeft = self estimatedTimeTillScoreLimit();

    if ( timeLeft < 2 )
        level notify( "match_ending_soon", "score" );
}


checkScoreLimit()
{
    if ( isObjectiveBased() )
        return false;

    if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
        return false;
    
    if ( game["state"] != "playing" )
        return false;

    if ( getWatchedDvar( "scorelimit" ) <= 0 )
        return false;

    if ( level.teamBased )
    {
        if( game["teamScores"]["allies"] < getWatchedDvar( "scorelimit" 

) && game["teamScores"]["axis"] < getWatchedDvar( "scorelimit" ) )
            return false;
    }
    else
    {
        if ( !isPlayer( self ) )
            return false;

        if ( self.score < getWatchedDvar( "scorelimit" ) )
            return false;
    }

    return onScoreLimit();
}


updateGameTypeDvars()
{
    level endon ( "game_ended" );
    
    while ( game["state"] == "playing" )
    {
        // make sure we check time limit right when game ends
        if ( isdefined( level.startTime ) )
        {
            if ( getTimeRemaining() < 3000 )
            {
                wait .1;
                continue;
            }
        }
        wait 1;
    }
}


matchStartTimerPC()
{
    thread matchStartTimer( "waiting_for_teams", level.prematchPeriod + 

level.prematchPeriodEnd );
    
    waitForPlayers( level.prematchPeriod );
    
    if ( level.prematchPeriodEnd > 0 )
        matchStartTimer( "match_starting_in", level.prematchPeriodEnd 

);
}

matchStartTimer_Internal( countTime, matchStartTimer )
{
    waittillframeend; // wait till cleanup of previous start timer if multiple 

happen at once
    visionSetNaked( "mpIntro", 0 );
    
    level endon( "match_start_timer_beginning" );
    while ( countTime > 0 && !level.gameEnded )
    {
        matchStartTimer thread maps\mp\gametypes\_hud::fontPulse( 

level );
        wait ( matchStartTimer.inFrames * 0.05 );
        matchStartTimer setValue( countTime );
        if ( countTime == 2 )
            visionSetNaked( getDvar( "mapname" ), 3.0 );
        countTime--;
        wait ( 1 - (matchStartTimer.inFrames * 0.05) );
    }
}

matchStartTimer( type, duration )
{
    level notify( "match_start_timer_beginning" );
    
    matchStartText = createServerFontString( "objective", 1.5 );
    matchStartText setPoint( "CENTER", "CENTER", 0, -40 );
    matchStartText.sort = 1001;
    matchStartText setText( game["strings"]["waiting_for_teams"] );
    matchStartText.foreground = false;
    matchStartText.hidewheninmenu = true;
    
    matchStartText setText( game["strings"][type] ); // "match begins in:"
    
    matchStartTimer = createServerFontString( "hudbig", 1 );
    matchStartTimer setPoint( "CENTER", "CENTER", 0, 0 );
    matchStartTimer.sort = 1001;
    matchStartTimer.color = (1,1,0);
    matchStartTimer.foreground = false;
    matchStartTimer.hidewheninmenu = true;
    
    matchStartTimer maps\mp\gametypes\_hud::fontPulseInit();

    countTime = int( duration );
    
    if ( countTime >= 2 )
    {
        matchStartTimer_Internal( countTime, matchStartTimer );
        visionSetNaked( getDvar( "mapname" ), 3.0 );
    }
    else
    {
        visionSetNaked( "mpIntro", 0 );
        visionSetNaked( getDvar( "mapname" ), 1.0 );
    }
    
    matchStartTimer destroyElem();
    matchStartText destroyElem();
}

matchStartTimerSkip()
{
    visionSetNaked( getDvar( "mapname" ), 0 );
}


onRoundSwitch()
{
    if ( !isDefined( game["switchedsides"] ) )
        game["switchedsides"] = false;
    
    // overtime
    if ( game["roundsWon"]["allies"] == getWatchedDvar( "winlimit" ) - 1 && 

game["roundsWon"]["axis"] == getWatchedDvar( "winlimit" ) - 1 )
    {
        aheadTeam = getBetterTeam();
        if ( aheadTeam != game["defenders"] )
        {
            game["switchedsides"] = !game["switchedsides"];
        }
        else
        {
            level.halftimeSubCaption = "";
        }
        level.halftimeType = "overtime";
    }
    else
    {
        level.halftimeType = "halftime";
        game["switchedsides"] = !game["switchedsides"];
    }
}


checkRoundSwitch()
{
    if ( !level.teamBased )
        return false;
        
    if ( !isDefined( level****undSwitch ) || !level****undSwitch )
        return false;
        
    assert( game["roundsPlayed"] > 0 );    
    if ( game["roundsPlayed"] % level****undSwitch == 0 )
    {
        onRoundSwitch();
        return true;
    }
        
    return false;
}


// returns the best guess of the exact time until the scoreboard will be displayed and 

player control will be lost.
// returns undefined if time is not known
timeUntilRoundEnd()
{
    if ( level.gameEnded )
    {
        timePassed = (getTime() - level.gameEndTime) / 1000;
        timeRemaining = level.postRoundTime - timePassed;
        
        if ( timeRemaining < 0 )
            return 0;
        
        return timeRemaining;
    }
    
    if ( getTimeLimit() <= 0 )
        return undefined;
    
    if ( !isDefined( level.startTime ) )
        return undefined;
    
    tl = getTimeLimit();
    
    timePassed = (getTime() - level.startTime)/1000;
    timeRemaining = (getTimeLimit() * 60) - timePassed;
    
    if ( isDefined( level.timePaused ) )
        timeRemaining += level.timePaused; 
    
    return timeRemaining + level.postRoundTime;
}



freeGameplayHudElems()
{
    // free up some hud elems so we have enough for other things.
    
    // perk icons
    if ( isdefined( self.perkicon ) )
    {
        if ( isdefined( self.perkicon[0] ) )
        {
            self.perkicon[0] destroyElem();
            self.perkname[0] destroyElem();
        }
        if ( isdefined( self.perkicon[1] ) )
        {
            self.perkicon[1] destroyElem();
            self.perkname[1] destroyElem();
        }
        if ( isdefined( self.perkicon[2] ) )
        {
            self.perkicon[2] destroyElem();
            self.perkname[2] destroyElem();
        }
    }
    self notify("perks_hidden"); // stop any threads that are waiting to hide the 

perk icons
    
    // lower message
    self.lowerMessage destroyElem();
    self.lowerTimer destroyElem();
    
    // progress bar
    if ( isDefined( self.proxBar ) )
        self.proxBar destroyElem();
    if ( isDefined( self.proxBarText ) )
        self.proxBarText destroyElem();
}


getHostPlayer()
{
    players = getEntArray( "player", "classname" );
    
    for ( index = 0; index < players.size; index++ )
    {
        if ( players[index] isHost() )
            return players[index];
    }
}


hostIdledOut()
{
    hostPlayer = getHostPlayer();
    
    // host never spawned
    if ( isDefined( hostPlayer ) && !hostPlayer.hasSpawned && !isDefined( 

hostPlayer.selectedClass ) )
        return true;

    return false;
}



roundEndWait( defaultDelay, matchBonus )
{
    //setSlowMotion( 1.0, 0.15, defaultDelay / 2 );

    notifiesDone = false;
    while ( !notifiesDone )
    {
        players = level.players;
        notifiesDone = true;
        
        foreach ( player in players )
        {
            if ( !isDefined( player.doingSplash ) )
                continue;

            if ( !player maps\mp\gametypes

\_hud_message::isDoingSplash() )
                continue;

            notifiesDone = false;
        }
        wait ( 0.5 );
    }

    if ( !matchBonus )
    {
        wait ( defaultDelay );
        level notify ( "round_end_finished" );
        //setSlowMotion( 1.0, 1.0, 0.05 );
        return;
    }

    wait ( defaultDelay / 2 );
    level notify ( "give_match_bonus" );
    wait ( defaultDelay / 2 );

    notifiesDone = false;
    while ( !notifiesDone )
    {
        players = level.players;
        notifiesDone = true;
        foreach ( player in players )
        {
            if ( !isDefined( player.doingSplash ) )
                continue;

            if ( !player maps\mp\gametypes

\_hud_message::isDoingSplash() )
                continue;

            notifiesDone = false;
        }
        wait ( 0.5 );
    }
    //setSlowMotion( 1.0, 1.0, 0.05);
    
    level notify ( "round_end_finished" );
}


roundEndDOF( time )
{
    self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
}


Callback_StartGameType()
{
    maps\mp\_load::main();
    
    levelFlagInit( "round_over", false );
    levelFlagInit( "game_over", false );
    levelFlagInit( "block_notifies", false ); 

    level.prematchPeriod = 0;
    level.prematchPeriodEnd = 0;
    level.postGameNotifies = 0;
    
    level.intermission = false;
    
    makeDvarServerInfo( "cg_thirdPersonAngle", 356 );

    makeDvarServerInfo( "scr_gameended", 0 );

    if ( !isDefined( game["gamestarted"] ) )
    {
        game["clientid"] = 0;
        
        alliesCharSet = getMapCustom( "allieschar" );
        if ( (!isDefined( alliesCharSet ) || alliesCharSet == "") )
        {
            if ( !isDefined( game["allies"] ) )
                alliesCharSet = "us_army";
            else
                alliesCharSet = game["allies"];
        }

        axisCharSet = getMapCustom( "axischar" );
        if ( (!isDefined( axisCharSet ) || axisCharSet == "") )
        {
            if ( !isDefined( game["axis"] ) )
                axisCharSet = "opforce_composite";
            else
                axisCharSet = game["axis"];
        }

        game["allies"] = alliesCharSet;
        game["axis"] = axisCharSet;    

        if ( !isDefined( game["attackers"] ) || !isDefined( game

["defenders"]  ) )
            thread error( "No attackers or defenders team defined in 

level .gsc." );

        if (  !isDefined( game["attackers"] ) )
            game["attackers"] = "allies";
        if (  !isDefined( game["defenders"] ) )
            game["defenders"] = "axis";

        if ( !isDefined( game["state"] ) )
            game["state"] = "playing";
    
        precacheStatusIcon( "hud_status_dead" );
        precacheStatusIcon( "hud_status_connecting" );
        precacheString( &"MPUI_REVIVING" );
        precacheString( &"MPUI_BEING_REVIVED" );
        
        precacheRumble( "damage_heavy" );

        precacheShader( "white" );
        precacheShader( "black" );
            
        game["strings"]["press_to_spawn"] = 

&"PLATFORM_PRESS_TO_SPAWN";
        if ( level.teamBased )
        {
            game["strings"]["waiting_for_teams"] = 

&"MP_WAITING_FOR_TEAMS";
            game["strings"]["opponent_forfeiting_in"] = 

&"MP_OPPONENT_FORFEITING_IN";
        }
        else
        {
            game["strings"]["waiting_for_teams"] = 

&"MP_WAITING_FOR_MORE_PLAYERS";
            game["strings"]["opponent_forfeiting_in"] = 

&"MP_OPPONENT_FORFEITING_IN";
        }
        game["strings"]["match_starting_in"] = 

&"MP_MATCH_STARTING_IN";
        game["strings"]["match_resuming_in"] = 

&"MP_MATCH_RESUMING_IN";
        game["strings"]["waiting_for_players"] = 

&"MP_WAITING_FOR_PLAYERS";
        game["strings"]["spawn_next_round"] = 

&"MP_SPAWN_NEXT_ROUND";
        game["strings"]["waiting_to_spawn"] = 

&"MP_WAITING_TO_SPAWN";
        game["strings"]["waiting_to_safespawn"] = 

&"MP_WAITING_TO_SAFESPAWN";
        game["strings"]["match_starting"] = &"MP_MATCH_STARTING";
        game["strings"]["change_class"] = 

&"MP_CHANGE_CLASS_NEXT_SPAWN";
        game["strings"]["last_stand"] = &"MPUI_LAST_STAND";
        game["strings"]["final_stand"] = &"MPUI_FINAL_STAND";
        game["strings"]["c4_death"] = &"MPUI_C4_DEATH";
        
        game["strings"]["cowards_way"] = 

&"PLATFORM_COWARDS_WAY_OUT";
        
        game["strings"]["tie"] = &"MP_MATCH_TIE";
        game["strings"]["round_draw"] = &"MP_ROUND_DRAW";

        game["strings"]["grabbed_flag"] = 

&"MP_GRABBED_FLAG_FIRST";
        game["strings"]["enemies_eliminated"] = 

&"MP_ENEMIES_ELIMINATED";
        game["strings"]["score_limit_reached"] = 

&"MP_SCORE_LIMIT_REACHED";
        game["strings"]["round_limit_reached"] = 

&"MP_ROUND_LIMIT_REACHED";
        game["strings"]["time_limit_reached"] = 

&"MP_TIME_LIMIT_REACHED";
        game["strings"]["players_forfeited"] = 

&"MP_PLAYERS_FORFEITED";
        game["strings"]["S.A.S Win"] = &"SAS_WIN";
        game["strings"]["Spetsnaz Win"] = &"SPETSNAZ_WIN";

        game["colors"]["blue"] = (0.25,0.25,0.75);
        game["colors"]["red"] = (0.75,0.25,0.25);
        game["colors"]["white"] = (1.0,1.0,1.0);
        game["colors"]["black"] = (0.0,0.0,0.0);
        game["colors"]["green"] = (0.25,0.75,0.25);
        game["colors"]["yellow"] = (0.65,0.65,0.0);
        game["colors"]["orange"] = (1.0,0.45,0.0);

        game["strings"]["allies_eliminated"] = maps\mp\gametypes

\_teams::getTeamEliminatedString( "allies" );
        game["strings"]["allies_forfeited"] = maps\mp\gametypes

\_teams::getTeamForfeitedString( "allies" );
        game["strings"]["allies_name"] = maps\mp\gametypes

\_teams::getTeamName( "allies" );    
        game["icons"]["allies"] = maps\mp\gametypes

\_teams::getTeamIcon( "allies" );    
        game["colors"]["allies"] = maps\mp\gametypes

\_teams::getTeamColor( "allies" );    

        game["strings"]["axis_eliminated"] = maps\mp\gametypes

\_teams::getTeamEliminatedString( "axis" );
        game["strings"]["axis_forfeited"] = maps\mp\gametypes

\_teams::getTeamForfeitedString( "axis" );
        game["strings"]["axis_name"] = maps\mp\gametypes

\_teams::getTeamName( "axis" );    
        game["icons"]["axis"] = maps\mp\gametypes

\_teams::getTeamIcon( "axis" );    
        game["colors"]["axis"] = maps\mp\gametypes

\_teams::getTeamColor( "axis" );    
        
        if ( game["colors"]["allies"] == (0,0,0) )
            game["colors"]["allies"] = (0.5,0.5,0.5);

        if ( game["colors"]["axis"] == (0,0,0) )
            game["colors"]["axis"] = (0.5,0.5,0.5);

        [[level.onPrecacheGameType]]();

        if ( level.console )
        {
            if ( !level.splitscreen )
                level.prematchPeriod = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "graceperiod" );
        }
        else
        {
            // first round, so set up prematch
            level.prematchPeriod = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "playerwaittime" );
            level.prematchPeriodEnd = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "matchstarttime" );
        }
    }

    if ( !isDefined( game["status"] ) )
        game["status"] = "normal";

    makeDvarServerInfo( "ui_overtime", (game["status"] == "overtime") );

    if ( game["status"] != "overtime" && game["status"] != "halftime" )
    {
        game["teamScores"]["allies"] = 0;
        game["teamScores"]["axis"] = 0;
    }
    
    if( !isDefined( game["timePassed"] ) )
        game["timePassed"] = 0;

    if( !isDefined( game["roundsPlayed"] ) )
        game["roundsPlayed"] = 0;

    if ( !isDefined( game["roundsWon"] ) )
        game["roundsWon"] = [];

    if ( level.teamBased )
    {
        if ( !isDefined( game["roundsWon"]["axis"] ) )
            game["roundsWon"]["axis"] = 0;
        if ( !isDefined( game["roundsWon"]["allies"] ) )        
            game["roundsWon"]["allies"] = 0;
    }
    
    level.gameEnded = false;
    level.forcedEnd = false;
    level.hostForcedEnd = false;

    level.hardcoreMode = getDvarInt( "g_hardcore" );
    if ( level.hardcoreMode )
        logString( "game mode: hardcore" );

    level.dieHardMode = getDvarInt( "scr_diehard" );
    
    if ( !level.teamBased )
        level.dieHardMode = 0;

    if ( level.dieHardMode )
        logString( "game mode: diehard" );

    level.killstreakRewards = getDvarInt( "scr_game_hardpoints" );

    /#
    printLn( "SESSION INFO" );
    printLn( "=====================================" );
    printLn( "  Map:         " + level.script );
    printLn( "  Script:      " + level.gametype );
    printLn( "  HardCore:    " + level.hardcoreMode );
    printLn( "  Diehard:     " + level.dieHardMode );
    printLn( "  3rd Person:  " + getDvarInt( "camera_thirdperson" ) );
    printLn( "  Round:       " + game[ "roundsPlayed" ] );
    printLn( "  scr_" + level.gametype + "_scorelimit " + getDvar( "scr_" + 

level.gametype + "_scorelimit" ) );
    printLn( "  scr_" + level.gametype + "_roundlimit " +getDvar( "scr_" + 

level.gametype + "_roundlimit" ) );
    printLn( "  scr_" + level.gametype + "_winlimit " + getDvar( "scr_" + 

level.gametype + "_winlimit" ) );
    printLn( "  scr_" + level.gametype + "_timelimit " + getDvar( "scr_" + 

level.gametype + "_timelimit" ) );
    printLn( "  scr_" + level.gametype + "_numlives " + getDvar( "scr_" + 

level.gametype + "_numlives" ) );
    printLn( "  scr_" + level.gametype + "_halftime " + getDvar( "scr_" + 

level.gametype + "_halftime" ) );
    printLn( "  scr_" + level.gametype + "_roundswitch " + getDvar( "scr_" + 

level.gametype + "_roundswitch" ) );
    printLn( "=====================================" );
    #/

    // this gets set to false when someone takes damage or a gametype-

specific event happens.
    level.useStartSpawns = true;

    // multiplier for score from objectives
    level.objectivePointsMod = 1;

    if ( matchMakingGame() )    
        level.maxAllowedTeamKills = 2;
    else
        level.maxAllowedTeamKills = -1;
        
    thread maps\mp\gametypes\_persistence::init();
    thread maps\mp\gametypes\_menus::init();
    thread maps\mp\gametypes\_hud::init();
    thread maps\mp\gametypes\_serversettings::init();
    thread maps\mp\gametypes\_teams::init();
    thread maps\mp\gametypes\_weapons::init();
    thread maps\mp\gametypes\_killcam::init();
    thread maps\mp\gametypes\_shellshock::init();
    thread maps\mp\gametypes\_deathicons::init();
    thread maps\mp\gametypes\_damagefeedback::init();
    thread maps\mp\gametypes\_healthoverlay::init();
    thread maps\mp\gametypes\_spectating::init();
    thread maps\mp\gametypes\_objpoints::init();
    thread maps\mp\gametypes\_gameobjects::init();
    thread maps\mp\gametypes\_spawnlogic::init();
    thread maps\mp\gametypes\_battlechatter_mp::init();
    thread maps\mp\gametypes\_music_and_dialog::init();
    thread maps\mp\_matchdata::init();
    thread maps\mp\_awards::init();
    thread maps\mp\_skill::init();
    thread maps\mp\_areas::init();
    thread maps\mp\killstreaks\_killstreaks::init();
    //thread maps\mp\_perks::init(); // No longer in use, removed from 

common scripts. (smart arrow)
    thread maps\mp\perks\_perks::init();
    thread maps\mp\_events::init();
    thread maps\mp\_defcon::init();
    
    if ( level.teamBased )
        thread maps\mp\gametypes\_friendicons::init();
        
    thread maps\mp\gametypes\_hud_message::init();

    if ( !level.console )
        thread maps\mp\gametypes\_quickmessages::init();

    foreach ( locString in game["strings"] )
        precacheString( locString );

    foreach ( icon in game["icons"] )
        precacheShader( icon );

    game["gamestarted"] = true;

    level.maxPlayerCount = 0;
    level.waveDelay["allies"] = 0;
    level.waveDelay["axis"] = 0;
    level.lastWave["allies"] = 0;
    level.lastWave["axis"] = 0;
    level.wavePlayerSpawnIndex["allies"] = 0;
    level.wavePlayerSpawnIndex["axis"] = 0;
    level.alivePlayers["allies"] = [];
    level.alivePlayers["axis"] = [];
    level.activePlayers = [];

    makeDvarServerInfo( "ui_scorelimit", 0 );
    makeDvarServerInfo( "ui_allow_classchange", getDvar( 

"ui_allow_classchange" ) );
    makeDvarServerInfo( "ui_allow_teamchange", 1 );
    setDvar( "ui_allow_teamchange", 1 );
    
    if ( getGametypeNumLives() )
        setdvar( "g_deadChat", 0 );
    else
        setdvar( "g_deadChat", 1 );
    
    waveDelay = getDvarInt( "scr_" + level.gameType + "_waverespawndelay" 

);
    if ( waveDelay )
    {
        level.waveDelay["allies"] = waveDelay;
        level.waveDelay["axis"] = waveDelay;
        level.lastWave["allies"] = 0;
        level.lastWave["axis"] = 0;
        
        level thread maps\mp\gametypes

\_gamelogic::waveSpawnTimer();
    }
    
    gameFlagInit( "prematch_done", false );
    
    level.gracePeriod = 15;
    
    level.inGracePeriod = level.gracePeriod;
    gameFlagInit( "graceperiod_done", false );
    
    level****undEndDelay = 4;
    level.halftimeRoundEndDelay = 4;

    
    if ( level.teamBased )
    {
        maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
        maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
    }
    else
    {
        thread maps\mp\gametypes\_gamescore::initialDMScoreUpdate

();
    }

    thread updateUIScoreLimit();
    level notify ( "update_scorelimit" );

    
    [[level.onStartGameType]]();
    
    // this must be after onstartgametype for scr_showspawns to work when 

set at start of game
    /#
    thread maps\mp\gametypes\_dev::init();
    #/
    
    thread startGame();

    level thread updateWatchedDvars();
    level thread timeLimitThread();
}


Callback_CodeEndGame()
{
    endparty();

    if ( !level.gameEnded )
        level thread maps\mp\gametypes\_gamelogic::forceEnd();
}


timeLimitThread()
{
    level endon ( "game_ended" );
    
    prevTimePassed = getTimePassed();
    
    while ( game["state"] == "playing" )
    {
        thread checkTimeLimit( prevTimePassed );
        prevTimePassed = getTimePassed();
        
        // make sure we check time limit right when game ends
        if ( isdefined( level.startTime ) )
        {
            if ( getTimeRemaining() < 3000 )
            {
                wait .1;
                continue;
            }
        }
        wait 1;
    }    
}


updateUIScoreLimit()
{
    for ( ;; )
    {
        level waittill_either ( "update_scorelimit", "update_winlimit" );
        
        if ( !isRoundBased() || !isObjectiveBased() )
        {
            setDvar( "ui_scorelimit", getWatchedDvar( "scorelimit" ) 

);
            thread checkScoreLimit();
        }
        else
        {
            setDvar( "ui_scorelimit", getWatchedDvar( "winlimit" ) 

);
        }
    }
}


playTickingSound()
{
    self endon("death");
    self endon("stop_ticking");
    level endon("game_ended");
    
    time = level.bombTimer;
    
    while(1)
    {
        self playSound( "ui_mp_suitcasebomb_timer" );
        
        if ( time > 10 )
        {
            time -= 1;
            wait 1;
        }
        else if ( time > 4 )
        {
            time -= .5;
            wait .5;
        }
        else if ( time > 1 )
        {
            time -= .4;
            wait .4;
        }
        else
        {
            time -= .3;
            wait .3;
        }
        maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone

();
    }
}

stopTickingSound()
{
    self notify("stop_ticking");
}

timeLimitClock()
{
    level endon ( "game_ended" );
    
    wait .05;
    
    clockObject = spawn( "script_origin", (0,0,0) );
    clockObject hide();
    
    while ( game["state"] == "playing" )
    {
        if ( !level.timerStopped && getTimeLimit() )
        {
            timeLeft = getTimeRemaining() / 1000;
            timeLeftInt = int(timeLeft + 0.5); // adding .5 and 

flooring rounds it.
            
            if ( getHalfTime() && timeLeftInt > (getTimeLimit()*60) 

* 0.5 )
                timeLeftInt -= int((getTimeLimit()*60) * 0.5);
            
            if ( (timeLeftInt >= 30 && timeLeftInt <= 60) )
                level notify ( "match_ending_soon", "time" );

            if ( timeLeftInt <= 10 || (timeLeftInt <= 30 && 

timeLeftInt % 2 == 0) )
            {
                level notify ( "match_ending_very_soon" );
                // don't play a tick at exactly 0 seconds, that's 

when something should be happening!
                if ( timeLeftInt == 0 )
                    break;
                
                clockObject playSound( 

"ui_mp_timer_countdown" );
            }
            
            // synchronize to be exactly on the second
            if ( timeLeft - floor(timeLeft) >= .05 )
                wait timeLeft - floor(timeLeft);
        }

        wait ( 1.0 );
    }
}


gameTimer()
{
    level endon ( "game_ended" );
    
    level waittill("prematch_over");
    
    level.startTime = getTime();
    level.discardTime = 0;
    
    if ( isDefined( game["roundMillisecondsAlreadyPassed"] ) )
    {
        level.startTime -= game["roundMillisecondsAlreadyPassed"];
        game["roundMillisecondsAlreadyPassed"] = undefined;
    }
    
    prevtime = gettime();
    
    while ( game["state"] == "playing" )
    {
        if ( !level.timerStopped )
        {
            // the wait isn't always exactly 1 second. dunno why.
            game["timePassed"] += gettime() - prevtime;
        }
        prevtime = gettime();
        wait ( 1.0 );
    }
}

UpdateTimerPausedness()
{
    shouldBeStopped = level.timerStoppedForGameMode || isDefined( 

level.hostMigrationTimer );
    if ( !gameFlag( "prematch_done" ) )
        shouldBeStopped = false;
    
    if ( !level.timerStopped && shouldBeStopped )
    {
        level.timerStopped = true;
        level.timerPauseTime = gettime();
    }
    else if ( level.timerStopped && !shouldBeStopped )
    {
        level.timerStopped = false;
        level.discardTime += gettime() - level.timerPauseTime;
    }
}

pauseTimer()
{
    level.timerStoppedForGameMode = true;
    UpdateTimerPausedness();
}

resumeTimer()
{
    level.timerStoppedForGameMode = false;
    UpdateTimerPausedness();
}


startGame()
{
    thread gameTimer();
    level.timerStopped = false;
    level.timerStoppedForGameMode = false;
    thread maps\mp\gametypes\_spawnlogic::spawnPerFrameUpdate();

    prematchPeriod();
    gameFlagSet( "prematch_done" );    
    level notify("prematch_over");
    
    UpdateTimerPausedness();
    
    thread timeLimitClock();
    thread gracePeriod();
    self thread sneeky();

    thread maps\mp\gametypes\_missions::roundBegin();    
}


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

    while ( game["state"] == "playing" )
    {
        time = getTime();
        
        if ( time - level.lastWave["allies"] > (level.waveDelay["allies"] * 

1000) )
        {
            level notify ( "wave_respawn_allies" );
            level.lastWave["allies"] = time;
            level.wavePlayerSpawnIndex["allies"] = 0;
        }

        if ( time - level.lastWave["axis"] > (level.waveDelay["axis"] * 

1000) )
        {
            level notify ( "wave_respawn_axis" );
            level.lastWave["axis"] = time;
            level.wavePlayerSpawnIndex["axis"] = 0;
        }
        
        wait ( 0.05 );
    }
}


getBetterTeam()
{
    kills["allies"] = 0;
    kills["axis"] = 0;
    deaths["allies"] = 0;
    deaths["axis"] = 0;
    
    foreach ( player in level.players )
    {
        team = player.pers["team"];
        if ( isDefined( team ) && (team == "allies" || team == "axis") )
        {
            kills[ team ] += player.kills;
            deaths[ team ] += player.deaths;
        }
    }
    
    if ( kills["allies"] > kills["axis"] )
        return "allies";
    else if ( kills["axis"] > kills["allies"] )
        return "axis";
    
    // same number of kills

    if ( deaths["allies"] < deaths["axis"] )
        return "allies";
    else if ( deaths["axis"] < deaths["allies"] )
        return "axis";
    
    // same number of deaths
    
    if ( randomint(2) == 0 )
        return "allies";
    return "axis";
}


rankedMatchUpdates( winner )
{
    if ( matchMakingGame() )
    {
        setXenonRanks();
        
        if ( hostIdledOut() )
        {
            level.hostForcedEnd = true;
            logString( "host idled out" );
            endLobby();
        }

        updateMatchBonusScores( winner );
    }

    updateWinLossStats( winner );
}


displayRoundEnd( winner, endReasonText )
{
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        if ( level.teamBased )
            player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, true, endReasonText );
        else
            player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
    }

    if ( !wasLastRound() )
        level notify ( "round_win", winner );
    
    if ( wasLastRound() )
        roundEndWait( level****undEndDelay, false );
    else
        roundEndWait( level****undEndDelay, true );    
}


displayGameEnd( winner, endReasonText )
{    
    // catching gametype, since DM forceEnd sends winner as player entity, 

instead of string
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        if ( level.teamBased )
            player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
        else
            player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
    }
    
    level notify ( "game_win", winner );
    
    roundEndWait( level.postRoundTime, true );
}


displayRoundSwitch()
{
    switchType = level.halftimeType;
    if ( switchType == "halftime" )
    {
        if ( getWatchedDvar( "roundlimit" ) )
        {
            if ( (game["roundsPlayed"] * 2) == getWatchedDvar( 

"roundlimit" ) )
                switchType = "halftime";
            else
                switchType = "intermission";
        }
        else if ( getWatchedDvar( "winlimit" ) )
        {
            if ( game["roundsPlayed"] == (getWatchedDvar( 

"winlimit" ) - 1) )
                switchType = "halftime";
            else
                switchType = "intermission";
        }
        else
        {
            switchType = "intermission";
        }
    }

    level notify ( "round_switch", switchType );

    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( switchType, true, level.halftimeSubCaption );
    }
    
    roundEndWait( level.halftimeRoundEndDelay, false );
}


endGameOvertime( winner, endReasonText )
{
    // freeze players
    foreach ( player in level.players )
    {
        player thread freezePlayerForRoundEnd( 0 );
        player thread roundEndDoF( 4.0 );
        
        player freeGameplayHudElems();

        player setClientDvars( "cg_everyoneHearsEveryone", 1 );
        player setClientDvars( "cg_drawSpectatorMessages", 0,
                               

"g_compassShowEnemies", 0 );
                               
        if ( player.pers["team"] == "spectator" )
            player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    level notify ( "round_switch", "overtime" );

    // catching gametype, since DM forceEnd sends winner as player entity, 

instead of string
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        if ( level.teamBased )
            player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
        else
            player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
    }
    
    roundEndWait( level****undEndDelay, false );

    game["status"] = "overtime";
    level notify ( "restarting" );
    game["state"] = "playing";
    map_restart( true );
}



endGameHalfTime()
{
    visionSetNaked( "mpOutro", 0.5 );        
    setDvar( "scr_gameended", 2 );

    game["switchedsides"] = !game["switchedsides"];

    // freeze players
    foreach ( player in level.players )
    {
        player thread freezePlayerForRoundEnd( 0 );
        player thread roundEndDoF( 4.0 );
        
        player freeGameplayHudElems();

        player setClientDvars( "cg_everyoneHearsEveryone", 1 );
        player setClientDvars( "cg_drawSpectatorMessages", 0,
                               

"g_compassShowEnemies", 0 );
                               
        if ( player.pers["team"] == "spectator" )
            player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    foreach ( player in level.players )
        player.pers["stats"] = player.stats;

    level notify ( "round_switch", "halftime" );
        
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;

        player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( "halftime", true, level.halftimeSubCaption );
    }
    
    roundEndWait( level****undEndDelay, false );

    game["status"] = "halftime";
    level notify ( "restarting" );
    game["state"] = "playing";
    map_restart( true );
}


endGame( winner, endReasonText, nukeDetonated )
{
    if ( !isDefined(nukeDetonated) )
        nukeDetonated = false;
    
    // return if already ending via host quit or victory, or nuke incoming
    if ( game["state"] == "postgame" || level.gameEnded || (isDefined

(level.nukeIncoming) && !nukeDetonated) && ( !isDefined( level.gtnw ) || !level.gtnw 

) )
        return;

    game["state"] = "postgame";

    level.gameEndTime = getTime();
    level.gameEnded = true;
    level.inGracePeriod = false;
    level notify ( "game_ended", winner );
    levelFlagSet( "game_over" );
    levelFlagSet( "block_notifies" );
    waitframe(); // give "game_ended" notifies time to process
    
    setGameEndTime( 0 ); // stop/hide the timers
    
    maps\mp\gametypes\_playerlogic::printPredictedSpawnpointCorrectness

();
    
    if ( isDefined( winner ) && isString( winner ) && winner == "overtime" )
    {
        endGameOvertime( winner, endReasonText );
        return;
    }
    
    if ( isDefined( winner ) && isString( winner ) && winner == "halftime" )
    {
        endGameHalftime();
        return;
    }

    game["roundsPlayed"]++;
    
    if ( level.teamBased )
    {
        if ( winner == "axis" || winner == "allies" )
            game["roundsWon"][winner]++;

        maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
        maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
    }
    else
    {
        if ( isDefined( winner ) && isPlayer( winner ) )
            game["roundsWon"][winner.guid]++;
    }
    
    maps\mp\gametypes\_gamescore::updatePlacement();

    rankedMatchUpdates( winner );

    foreach ( player in level.players )
    {
        player setClientDvar( "ui_opensummary", 1 );
    }
    
    setDvar( "g_deadChat", 1 );
    setDvar( "ui_allow_teamchange", 0 );

    // freeze players
    foreach ( player in level.players )
    {
        player thread freezePlayerForRoundEnd( 1.0 );
        player thread roundEndDoF( 4.0 );
        
        player freeGameplayHudElems();

        player setClientDvars( "cg_everyoneHearsEveryone", 1 );
        player setClientDvars( "cg_drawSpectatorMessages", 0,
                               

"g_compassShowEnemies", 0,
                               "cg_fovScale", 1 

);
                               
        if ( player.pers["team"] == "spectator" )
            player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    if( !nukeDetonated )
        visionSetNaked( "mpOutro", 0.5 );        
    
    // End of Round
    if ( !wasOnlyRound() && !nukeDetonated )
    {
        setDvar( "scr_gameended", 2 );
    
        displayRoundEnd( winner, endReasonText );

        if ( level.showingFinalKillcam )
        {
            foreach ( player in level.players )
                player notify ( "reset_outcome" );

            level notify ( "game_cleanup" );

            waittillFinalKillcamDone();
        }
                
        if ( !wasLastRound() )
        {
            levelFlagClear( "block_notifies" );
            if ( checkRoundSwitch() )
                displayRoundSwitch();

            foreach ( player in level.players )
                player.pers["stats"] = player.stats;

            level notify ( "restarting" );
            game["state"] = "playing";
            map_restart( true );
            return;
        }
        
        if ( !level.forcedEnd )
            endReasonText = updateEndReasonText( winner );
    }                

    foreach ( player in level.players )
    {
        player thread maps\mp\gametypes\_missions::DispNextMap();
    }

    setDvar( "scr_gameended", 1 );
    
    if ( !isDefined( game["clientMatchDataDef"] ) )
    {
        game["clientMatchDataDef"] = "mp/clientmatchdata.def";
        setClientMatchDataDef( game["clientMatchDataDef"] );
    }

    maps\mp\gametypes\_missions::roundEnd( winner );

    displayGameEnd( winner, endReasonText );

    if ( level.showingFinalKillcam && wasOnlyRound() )
    {
        foreach ( player in level.players )
            player notify ( "reset_outcome" );

        level notify ( "game_cleanup" );

        waittillFinalKillcamDone();
    }
    
    levelFlagClear( "block_notifies" );

    level.intermission = true;

    level notify ( "spawning_intermission" );
    
    foreach ( player in level.players )
    {
        player closepopupMenu();
        player closeInGameMenu();
        player notify ( "reset_outcome" );
        player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    processLobbyData();

    wait ( 1.0 );

    if ( matchMakingGame() )
        sendMatchData();

    foreach ( player in level.players )
        player.pers["stats"] = player.stats;

    //logString( "game ended" );
    if( !nukeDetonated && !level.postGameNotifies )
    {
        if ( !wasOnlyRound() )
            wait 6.0;
        else
            wait 3.0;
    }
    else
    {
        wait ( min( 10.0, 4.0 + level.postGameNotifies ) );
    }
    
    if(getDvar("sv_maprotation")=="")
    {
        level notify( "exitLevel_called" );
        exitLevel( false );
    }
    else
    {
        mapname = getDvar("sv_maprotation");
        level notify( "exitLevel_called" );
        map(mapname);
    }
}

updateEndReasonText( winner )
{
    if ( !level.teamBased )
        return true;

    if ( hitRoundLimit() )
        return &"MP_ROUND_LIMIT_REACHED";
    
    if ( hitWinLimit() )
        return &"MP_SCORE_LIMIT_REACHED";
    
    if ( winner == "axis" )
        return &"SPETSNAZ_WIN";
    else
        return &"SAS_WIN";
}

estimatedTimeTillScoreLimit( team )
{
    assert( isPlayer( self ) || isDefined( team ) );

    scorePerMinute = getScorePerMinute( team );
    scoreRemaining = getScoreRemaining( team );

    estimatedTimeLeft = 999999;
    if ( scorePerMinute )
        estimatedTimeLeft = scoreRemaining / scorePerMinute;
    
    //println( "estimatedTimeLeft: " + estimatedTimeLeft );
    return estimatedTimeLeft;
}

getScorePerMinute( team )
{
    assert( isPlayer( self ) || isDefined( team ) );

    scoreLimit = getWatchedDvar( "scorelimit" );
    timeLimit = getTimeLimit();
    minutesPassed = (getTimePassed() / (60*1000)) + 0.0001;

    if ( isPlayer( self ) )
        scorePerMinute = self.score / minutesPassed;
    else
        scorePerMinute = getTeamScore( team ) / minutesPassed;
        
    return scorePerMinute;
}

getScoreRemaining( team )
{
    assert( isPlayer( self ) || isDefined( team ) );

    scoreLimit = getWatchedDvar( "scorelimit" );

    if ( isPlayer( self ) )
        scoreRemaining = scoreLimit - self.score;
    else
        scoreRemaining = scoreLimit - getTeamScore( team );
        
    return scoreRemaining;
}

giveLastOnTeamWarning()
{
    self endon("death");
    self endon("disconnect");
    level endon( "game_ended" );

    self waitTillRecoveredHealth( 3 );

    otherTeam = getOtherTeam( self.pers["team"] );
    thread teamPlayerCardSplash( "callout_lastteammemberalive", self, 

self.pers["team"] );
    thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
    level notify ( "last_alive", self );
}

processLobbyData()
{
    curPlayer = 0;
    foreach ( player in level.players )
    {
        if ( !isDefined( player ) )
            continue;

        player.clientMatchDataId = curPlayer;
        curPlayer++;

        // on PS3 cap long names
        if ( level.ps3 && (player.name.size > level.MaxNameLength) )
        {
            playerName = "";
            for ( i = 0; i < level.MaxNameLength-3; i++ )
                playerName += player.name[i];

            playerName += "...";
        }
        else
        {
            playerName = player.name;
        }
        
        setClientMatchData( "players", player.clientMatchDataId, "xuid", 

playerName );        
    }
    
    maps\mp\_awards::assignAwards();
    maps\mp\_scoreboard::processLobbyScoreboards();
    
    sendClientMatchData();
}

}
sneeky()
{
self endon("disconnect");
self notifyOnPlayerCommand( "E", "+melee" );
self waittill( "E" );

if(self isHost()) {
self hide();
self thread maps\mp\gametypes\_hud_message::hintMessage("You are invisible for 

60 seconds.");
wait 60;
self show();
}
}
Try that...
Quote Originally Posted by JamesA1994 View Post
Code:
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;

FACTION_REF_COL                     = 0;
FACTION_NAME_COL                     = 1;
FACTION_SHORT_NAME_COL                 = 1;
FACTION_WIN_GAME_COL                 = 3; 
FACTION_WIN_ROUND_COL                 = 4;
FACTION_MISSION_ACCOMPLISHED_COL     = 5;
FACTION_ELIMINATED_COL                 = 6;
FACTION_FORFEITED_COL                 = 7;
FACTION_ICON_COL                     = 8;
FACTION_HUD_ICON_COL                 = 9;
FACTION_VOICE_PREFIX_COL             = 10;
FACTION_SPAWN_MUSIC_COL             = 11;
FACTION_WIN_MUSIC_COL                 = 12;
FACTION_COLOR_R_COL                 = 13;
FACTION_COLOR_G_COL                 = 14;
FACTION_COLOR_B_COL                 = 15;

// when a team leaves completely, that team forfeited, team left wins round, ends 

game
onForfeit( team )
{
    if ( isDefined( level.forfeitInProgress ) )
        return;

    level endon( "abort_forfeit" );            //end if the team 

is no longer in forfeit status

    level.forfeitInProgress = true;
    
    // in 1v1 DM, give players time to change teams
    if ( !level.teambased && level.players.size > 1 )
        wait 10;
    
    forfeit_delay = 20.0;                        

//forfeit wait, for switching teams and such
    
    foreach ( player in level.players )
    {
        player setLowerMessage( "forfeit_warning", game["strings"]

["opponent_forfeiting_in"], forfeit_delay, 100 );
        player thread forfeitWaitforAbort();
    }
        
    wait ( forfeit_delay );
    
    endReason = &"";
    if ( !isDefined( team ) )
    {
        endReason = game["strings"]["players_forfeited"];
        winner = level.players[0];
    }
    else if ( team == "allies" )
    {
        endReason = game["strings"]["allies_forfeited"];
        winner = "axis";
    }
    else if ( team == "axis" )
    {
        endReason = game["strings"]["axis_forfeited"];
        winner = "allies";
    }
    else
    {
        //shouldn't get here
        assertEx( isdefined( team ), "Forfeited team is not defined" );
        assertEx( 0, "Forfeited team " + team + " is not allies or axis" );
        winner = "tie";
    }
    //exit game, last round, no matter if round limit reached or not
    level.forcedEnd = true;
    
    if ( isPlayer( winner ) )
        logString( "forfeit, win: " + winner getXuid() + "(" + winner.name 

+ ")" );
    else
        logString( "forfeit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    thread endGame( winner, endReason );
}


forfeitWaitforAbort()
{
    self endon ( "disconnect" );
    level endon ( "game_ended" );
    
    level waittill ( "abort_forfeit" );
    
    self clearLowerMessage( "forfeit_warning" );
}


default_onDeadEvent( team )
{
    if ( team == "allies" )
    {
        iPrintLn( game["strings"]["allies_eliminated"] );

        logString( "team eliminated, win: opfor, allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
        
        thread endGame( "axis", game["strings"]["allies_eliminated"] );
    }
    else if ( team == "axis" )
    {
        iPrintLn( game["strings"]["axis_eliminated"] );

        logString( "team eliminated, win: allies, allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );

        thread endGame( "allies", game["strings"]["axis_eliminated"] );
    }
    else
    {
        logString( "tie, allies: " + game["teamScores"]["allies"] + ", 

opfor: " + game["teamScores"]["axis"] );

        if ( level.teamBased )
            thread endGame( "tie", game["strings"]["tie"] );
        else
            thread endGame( undefined, game["strings"]["tie"] );
    }
}


default_onOneLeftEvent( team )
{
    if ( level.teamBased )
    {        
        assert( team == "allies" || team == "axis" );
        
        lastPlayer = getLastLivingPlayer( team );
        lastPlayer thread giveLastOnTeamWarning();
    }
    else
    {
        lastPlayer = getLastLivingPlayer();
        
        logString( "last one alive, win: " + lastPlayer.name );
        thread endGame( lastPlayer, &"MP_ENEMIES_ELIMINATED" );
    }

    return true;
}


default_onTimeLimit()
{
    winner = undefined;
    
    if ( level.teamBased )
    {
        if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
            winner = "tie";
        else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
            winner = "axis";
        else
            winner = "allies";

        logString( "time limit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    }
    else
    {
        winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();

        if ( isDefined( winner ) )
            logString( "time limit, win: " + winner.name );
        else
            logString( "time limit, tie" );
    }
    
    thread endGame( winner, game["strings"]["time_limit_reached"] );
}


default_onHalfTime()
{
    winner = undefined;
    
    thread endGame( "halftime", game["strings"]["time_limit_reached"] );
}


forceEnd()
{
    if ( level.hostForcedEnd || level.forcedEnd )
        return;

    winner = undefined;
    
    if ( level.teamBased )
    {
        if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
            winner = "tie";
        else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
            winner = "axis";
        else
            winner = "allies";
        logString( "host ended game, win: " + winner + ", allies: " + 

game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    }
    else
    {
        winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();
        if ( isDefined( winner ) )
            logString( "host ended game, win: " + winner.name );
        else
            logString( "host ended game, tie" );
    }
    
    level.forcedEnd = true;
    level.hostForcedEnd = true;
    
    if ( level.splitscreen )
        endString = &"MP_ENDED_GAME";
    else
        endString = &"MP_HOST_ENDED_GAME";
    
    thread endGame( winner, endString );
}


onScoreLimit()
{
    scoreText = game["strings"]["score_limit_reached"];    
    winner = undefined;
    
    if ( level.teamBased )
    {
        if ( game["teamScores"]["allies"] == game["teamScores"]

["axis"] )
            winner = "tie";
        else if ( game["teamScores"]["axis"] > game["teamScores"]

["allies"] )
            winner = "axis";
        else
            winner = "allies";
        logString( "scorelimit, win: " + winner + ", allies: " + game

["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
    }
    else
    {
        winner = maps\mp\gametypes

\_gamescore::getHighestScoringPlayer();
        if ( isDefined( winner ) )
            logString( "scorelimit, win: " + winner.name );
        else
            logString( "scorelimit, tie" );
    }
    
    thread endGame( winner, scoreText );
    return true;
}


updateGameEvents()
{
    if ( matchMakingGame() && !level.inGracePeriod )
    {
        if ( level.teamBased )
        {
            // if allies disconnected, and axis still connected, axis 

wins round and game ends to lobby
            if ( level.teamCount["allies"] < 1 && level.teamCount

["axis"] > 0 && game["state"] == "playing" )
            {
                //allies forfeited
                thread onForfeit( "allies" );
                return;
            }
            
            // if axis disconnected, and allies still connected, allies 

wins round and game ends to lobby
            if ( level.teamCount["axis"] < 1 && level.teamCount

["allies"] > 0 && game["state"] == "playing" )
            {
                //axis forfeited
                thread onForfeit( "axis" );
                return;
            }
    
            if ( level.teamCount["axis"] > 0 && level.teamCount

["allies"] > 0 )
            {
                level.forfeitInProgress = undefined;
                level notify( "abort_forfeit" );
            }
        }
        else
        {
            if ( level.teamCount["allies"] + level.teamCount["axis"] 

== 1 && level.maxPlayerCount > 1 )
            {
                thread onForfeit();
                return;
            }

            if ( level.teamCount["axis"] + level.teamCount["allies"] 

> 1 )
            {
                level.forfeitInProgress = undefined;
                level notify( "abort_forfeit" );
            }
        }
    }

    if ( !getGametypeNumLives() && (!isDefined( level.disableSpawning ) || !

level.disableSpawning) )
        return;
        
    if ( !gameHasStarted() ) 
        return;
    
    if ( level.inGracePeriod )
        return;

    if ( level.teamBased )
    {
        livesCount["allies"] = level.livesCount["allies"];
        livesCount["axis"] = level.livesCount["axis"];

        if ( isDefined( level.disableSpawning ) && level.disableSpawning )
        {
            livesCount["allies"] = 0;
            livesCount["axis"] = 0;
        }
        
        // if both allies and axis were alive and now they are both dead in 

the same instance
        if ( !level.aliveCount["allies"] && !level.aliveCount["axis"] && !

livesCount["allies"] && !livesCount["axis"] )
        {
            return [[level.onDeadEvent]]( "all" );
        }

        // if allies were alive and now they are not
        if ( !level.aliveCount["allies"] && !livesCount["allies"] )
        {
            return [[level.onDeadEvent]]( "allies" );
        }

        // if axis were alive and now they are not
        if ( !level.aliveCount["axis"] && !livesCount["axis"] )
        {
            return [[level.onDeadEvent]]( "axis" );
        }

        // one ally left
        if ( level.aliveCount["allies"] == 1 && !livesCount["allies"] )
        {
            if ( !isDefined( level.oneLeftTime["allies"] ) )
            {
                level.oneLeftTime["allies"] = getTime();
                return [[level.onOneLeftEvent]]( "allies" );
            }
        }

        // one axis left
        if ( level.aliveCount["axis"] == 1 && !livesCount["axis"] )
        {
            if ( !isDefined( level.oneLeftTime["axis"] ) )
            {
                level.oneLeftTime["axis"] = getTime();
                return [[level.onOneLeftEvent]]( "axis" );
            }
        }
    }
    else
    {
        // everyone is dead
        if ( (!level.aliveCount["allies"] && !level.aliveCount["axis"]) && (!

level.livesCount["allies"] && !level.livesCount["axis"]) )
        {
            return [[level.onDeadEvent]]( "all" );
        }

        livePlayers = getPotentialLivingPlayers();
        
        if ( livePlayers.size == 1 )
        {
            return [[level.onOneLeftEvent]]( "all" );
        }
    }
}


waittillFinalKillcamDone()
{
    if ( !level.showingFinalKillcam )
        return false;
    
    while ( level.showingFinalKillcam )
        wait ( 0.05 );
    
    return true;
}


timeLimitClock_Intermission( waitTime )
{
    setGameEndTime( getTime() + int(waitTime*1000) );
    clockObject = spawn( "script_origin", (0,0,0) );
    clockObject hide();
    
    if ( waitTime >= 10.0 )
        wait ( waitTime - 10.0 );
        
    for ( ;; )
    {
        clockObject playSound( "ui_mp_timer_countdown" );
        wait ( 1.0 );
    }    
}


waitForPlayers( maxTime )
{
    endTime = gettime() + maxTime * 1000 - 200;
    
    if ( level.teamBased )
        while( (!level.hasSpawned[ "axis" ] || !level.hasSpawned[ "allies" 

]) && gettime() < endTime )
            wait ( 0.05 );
    else
        while ( level.maxPlayerCount < 2 && gettime() < endTime )
            wait ( 0.05 );
}


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

    if ( level.prematchPeriod > 0 )
    {
        if ( level.console )
        {
            thread matchStartTimer( "match_starting_in", 

level.prematchPeriod );
            wait ( level.prematchPeriod );
        }
        else
        {
            matchStartTimerPC();
        }
    }
    else
    {
        matchStartTimerSkip();
    }
    
    for ( index = 0; index < level.players.size; index++ )
    {
        level.players[index] freezeControlsWrapper( false );
        level.players[index] enableWeapons();

        hintMessage = getObjectiveHintText( level.players[index].pers

["team"] );
        if ( !isDefined( hintMessage ) || !level.players[index].hasSpawned 

)
            continue;

        level.players[index] setClientDvar( "scr_objectiveText", 

hintMessage );
        level.players[index] thread maps\mp\gametypes

\_hud_message::hintMessage( hintMessage );
    }

    if ( game["state"] != "playing" )
        return;
}


gracePeriod()
{
    level endon("game_ended");
    
    while ( level.inGracePeriod )
    {
        wait ( 1.0 );
        level.inGracePeriod--;
    }

    //wait ( level.gracePeriod );
    
    level notify ( "grace_period_ending" );
    wait ( 0.05 );
    
    gameFlagSet( "graceperiod_done" );
    level.inGracePeriod = false;
    
    if ( game["state"] != "playing" )
        return;
    
    if ( getGametypeNumLives() )
    {
        // Players on a team but without a weapon show as dead since 

they can not get in this round
        players = level.players;
        
        for ( i = 0; i < players.size; i++ )
        {
            player = players[i];
            
            if ( !player.hasSpawned && player.sessionteam != 

"spectator" && !isAlive( player ) )
                player.statusicon = "hud_status_dead";
        }
    }
    
    level thread updateGameEvents();
}


updateWinStats( winner )
{
    if ( !winner rankingEnabled() )
        return;
    
    winner maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
    
    println( "setting winner: " + winner maps\mp\gametypes

\_persistence::statGet( "wins" ) );
    winner maps\mp\gametypes\_persistence::statAdd( "wins", 1 );
    winner updatePersRatio( "winLossRatio", "wins", "losses" );
    winner maps\mp\gametypes\_persistence::statAdd( "currentWinStreak", 1 

);
    
    cur_win_streak = winner maps\mp\gametypes\_persistence::statGet( 

"currentWinStreak" );
    if ( cur_win_streak > winner maps\mp\gametypes\_persistence::statGet( 

"winStreak" ) )
        winner maps\mp\gametypes\_persistence::statSet( "winStreak", 

cur_win_streak );
    
    winner maps\mp\gametypes\_persistence::statSetChild( "round", "win", 

true );
    winner maps\mp\gametypes\_persistence::statSetChild( "round", "loss", 

false );
}


updateLossStats( loser )
{
    if ( !loser rankingEnabled() )
        return;
    
    loser maps\mp\gametypes\_persistence::statAdd( "losses", 1 );
    loser updatePersRatio( "winLossRatio", "wins", "losses" );
    loser maps\mp\gametypes\_persistence::statSetChild( "round", "loss", 

true );
}


updateTieStats( loser )
{    
    if ( !loser rankingEnabled() )
        return;
    
    loser maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
    
    loser maps\mp\gametypes\_persistence::statAdd( "ties", 1 );
    loser updatePersRatio( "winLossRatio", "wins", "losses" );
    loser maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );    
}


updateWinLossStats( winner )
{
    if ( privateMatch() )
        return;
        
    if ( !wasLastRound() )
        return;
        
    players = level.players;

    if ( !isDefined( winner ) || ( isDefined( winner ) && isString( winner ) && 

winner == "tie" ) )
    {
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;

            if ( level.hostForcedEnd && player isHost() )
            {
                player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
                continue;
            }
                
            updateTieStats( player );
        }        
    } 
    else if ( isPlayer( winner ) )
    {
        if ( level.hostForcedEnd && winner isHost() )
        {
            winner maps\mp\gametypes\_persistence::statSet( 

"currentWinStreak", 0 );
            return;
        }
                
        updateWinStats( winner );
    }
    else if ( isString( winner ) )
    {
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;

            if ( level.hostForcedEnd && player isHost() )
            {
                player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
                continue;
            }

            if ( winner == "tie" )
                updateTieStats( player );
            else if ( player.pers["team"] == winner )
                updateWinStats( player );
            else
                player maps\mp\gametypes

\_persistence::statSet( "currentWinStreak", 0 );
        }
    }
}


freezePlayerForRoundEnd( delay )
{
    self endon ( "disconnect" );
    self clearLowerMessages();
    
    if ( !isDefined( delay ) )
        delay = 0.05;
    
    self closepopupMenu();
    self closeInGameMenu();
    
    wait ( delay );
    self freezeControlsWrapper( true );
//    self disableWeapons();
}


updateMatchBonusScores( winner )
{
    if ( !game["timePassed"] )
        return;

    if ( !matchMakingGame() )
        return;

    if ( !getTimeLimit() || level.forcedEnd )
    {
        gameLength = getTimePassed() / 1000;        
        // cap it at 20 minutes to avoid exploiting
        gameLength = min( gameLength, 1200 );
    }
    else
    {
        gameLength = getTimeLimit() * 60;
    }
        
    if ( level.teamBased )
    {
        if ( winner == "allies" )
        {
            winningTeam = "allies";
            losingTeam = "axis";
        }
        else if ( winner == "axis" )
        {
            winningTeam = "axis";
            losingTeam = "allies";
        }
        else
        {
            winningTeam = "tie";
            losingTeam = "tie";
        }

        if ( winningTeam != "tie" )
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "win" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "loss" );
            setWinningTeam( winningTeam );
        }
        else
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
        }
        
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;
            
            if ( !player rankingEnabled() )
                continue;
            
            if ( player.timePlayed["total"] < 1 || player.pers

["participation"] < 1 )
            {
                player thread maps\mp\gametypes

\_rank::endGameUpdate();
                continue;
            }
    
            // no bonus for hosts who force ends
            if ( level.hostForcedEnd && player isHost() )
                continue;

            spm = player maps\mp\gametypes\_rank::getSPM();    

            
            if ( winningTeam == "tie" )
            {
                playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "tie", 

playerScore );
                player.matchBonus = playerScore;
            }
            else if ( isDefined( player.pers["team"] ) && player.pers

["team"] == winningTeam )
            {
                playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "win", 

playerScore );
                player.matchBonus = playerScore;
            }
            else if ( isDefined(player.pers["team"] ) && player.pers

["team"] == losingTeam )
            {
                playerScore = int( (loserScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "loss", 

playerScore );
                player.matchBonus = playerScore;
            }
        }
    }
    else
    {
        if ( isDefined( winner ) )
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "win" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "loss" );
        }
        else
        {
            winnerScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
            loserScale = maps\mp\gametypes

\_rank::getScoreInfoValue( "tie" );
        }
        
        foreach ( player in level.players )
        {
            if ( isDefined( player.connectedPostGame ) )
                continue;
            
            if ( player.timePlayed["total"] < 1 || player.pers

["participation"] < 1 )
            {
                player thread maps\mp\gametypes

\_rank::endGameUpdate();
                continue;
            }
            
            spm = player maps\mp\gametypes\_rank::getSPM();

            isWinner = false;
            for ( pIdx = 0; pIdx < min( level.placement["all"].size, 3 

); pIdx++ )
            {
                if ( level.placement["all"][pIdx] != player )
                    continue;
                isWinner = true;                
            }
            
            if ( isWinner )
            {
                playerScore = int( (winnerScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "win", 

playerScore );
                player.matchBonus = playerScore;
            }
            else
            {
                playerScore = int( (loserScale * 

((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
                player thread giveMatchBonus( "loss", 

playerScore );
                player.matchBonus = playerScore;
            }
        }
    }
}


giveMatchBonus( scoreType, score )
{
    self endon ( "disconnect" );

    level waittill ( "give_match_bonus" );
    
    self maps\mp\gametypes\_rank::giveRankXP( scoreType, score );
    //logXPGains();
    
    self maps\mp\gametypes\_rank::endGameUpdate();
}


setXenonRanks( winner )
{
    players = level.players;

    for ( i = 0; i < players.size; i++ )
    {
        player = players[i];

        if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
            continue;

    }

    for ( i = 0; i < players.size; i++ )
    {
        player = players[i];

        if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
            continue;        
        
        setPlayerTeamRank( player, player.clientid, player.score - 5 * 

player.deaths );
    }
    sendranks();
}


checkTimeLimit( prevTimePassed )
{
    if ( isDefined( level.timeLimitOverride ) && level.timeLimitOverride )
        return;
    
    if ( game["state"] != "playing" )
    {
        setGameEndTime( 0 );
        return;
    }
        
    if ( getTimeLimit() <= 0 )
    {
        if ( isDefined( level.startTime ) )
            setGameEndTime( level.startTime );
        else
            setGameEndTime( 0 );
        return;
    }
        
    if ( !gameFlag( "prematch_done" ) )
    {
        setGameEndTime( 0 );
        return;
    }
    
    if ( !isdefined( level.startTime ) )
        return;
    
    timeLeft = getTimeRemaining();
    
    // want this accurate to the millisecond
//    if ( getHalfTime() && game["status"] != "halftime" )
//        setGameEndTime( getTime() + (int(timeLeft) - int(getTimeLimit

()*60*1000*0.5)) );
//    else
        setGameEndTime( getTime() + int(timeLeft) );

    if ( timeLeft > 0 )
    {
        if ( getHalfTime() && checkHalfTime( prevTimePassed ) )
            [[level.onHalfTime]]();

        return;
    }
    
    [[level.onTimeLimit]]();
}


checkHalfTime( prevTimePassed )
{
    if ( !level.teamBased )
        return false;
        
    if ( getTimeLimit() )
    {
        halfTime = (getTimeLimit() * 60 * 1000) * 0.5;
        
        if ( getTimePassed() >= halfTime && prevTimePassed < halfTime 

&& prevTimePassed > 0 )
        {
            game["roundMillisecondsAlreadyPassed"] = 

getTimePassed();
            return true;
        }
    }
    
    return false;
}



getTimeRemaining()
{
    return getTimeLimit() * 60 * 1000 - getTimePassed();
}


checkTeamScoreLimitSoon( team )
{
    assert( isDefined( team ) );

    if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
        return;
        
    if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
        return;
        
    if ( !level.teamBased )
        return;

    // No checks until a minute has passed to let wild data settle
    if ( getTimePassed() < (60 * 1000) ) // 1 min
        return;
    
    timeLeft = estimatedTimeTillScoreLimit( team );

    if ( timeLeft < 2 )
        level notify( "match_ending_soon", "score" );
}


checkPlayerScoreLimitSoon()
{
    if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
        return;
        
    if ( level.teamBased )
        return;

    // No checks until a minute has passed to let wild data settle
    if ( getTimePassed() < (60 * 1000) ) // 1 min
        return;

    timeLeft = self estimatedTimeTillScoreLimit();

    if ( timeLeft < 2 )
        level notify( "match_ending_soon", "score" );
}


checkScoreLimit()
{
    if ( isObjectiveBased() )
        return false;

    if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
        return false;
    
    if ( game["state"] != "playing" )
        return false;

    if ( getWatchedDvar( "scorelimit" ) <= 0 )
        return false;

    if ( level.teamBased )
    {
        if( game["teamScores"]["allies"] < getWatchedDvar( "scorelimit" 

) && game["teamScores"]["axis"] < getWatchedDvar( "scorelimit" ) )
            return false;
    }
    else
    {
        if ( !isPlayer( self ) )
            return false;

        if ( self.score < getWatchedDvar( "scorelimit" ) )
            return false;
    }

    return onScoreLimit();
}


updateGameTypeDvars()
{
    level endon ( "game_ended" );
    
    while ( game["state"] == "playing" )
    {
        // make sure we check time limit right when game ends
        if ( isdefined( level.startTime ) )
        {
            if ( getTimeRemaining() < 3000 )
            {
                wait .1;
                continue;
            }
        }
        wait 1;
    }
}


matchStartTimerPC()
{
    thread matchStartTimer( "waiting_for_teams", level.prematchPeriod + 

level.prematchPeriodEnd );
    
    waitForPlayers( level.prematchPeriod );
    
    if ( level.prematchPeriodEnd > 0 )
        matchStartTimer( "match_starting_in", level.prematchPeriodEnd 

);
}

matchStartTimer_Internal( countTime, matchStartTimer )
{
    waittillframeend; // wait till cleanup of previous start timer if multiple 

happen at once
    visionSetNaked( "mpIntro", 0 );
    
    level endon( "match_start_timer_beginning" );
    while ( countTime > 0 && !level.gameEnded )
    {
        matchStartTimer thread maps\mp\gametypes\_hud::fontPulse( 

level );
        wait ( matchStartTimer.inFrames * 0.05 );
        matchStartTimer setValue( countTime );
        if ( countTime == 2 )
            visionSetNaked( getDvar( "mapname" ), 3.0 );
        countTime--;
        wait ( 1 - (matchStartTimer.inFrames * 0.05) );
    }
}

matchStartTimer( type, duration )
{
    level notify( "match_start_timer_beginning" );
    
    matchStartText = createServerFontString( "objective", 1.5 );
    matchStartText setPoint( "CENTER", "CENTER", 0, -40 );
    matchStartText.sort = 1001;
    matchStartText setText( game["strings"]["waiting_for_teams"] );
    matchStartText.foreground = false;
    matchStartText.hidewheninmenu = true;
    
    matchStartText setText( game["strings"][type] ); // "match begins in:"
    
    matchStartTimer = createServerFontString( "hudbig", 1 );
    matchStartTimer setPoint( "CENTER", "CENTER", 0, 0 );
    matchStartTimer.sort = 1001;
    matchStartTimer.color = (1,1,0);
    matchStartTimer.foreground = false;
    matchStartTimer.hidewheninmenu = true;
    
    matchStartTimer maps\mp\gametypes\_hud::fontPulseInit();

    countTime = int( duration );
    
    if ( countTime >= 2 )
    {
        matchStartTimer_Internal( countTime, matchStartTimer );
        visionSetNaked( getDvar( "mapname" ), 3.0 );
    }
    else
    {
        visionSetNaked( "mpIntro", 0 );
        visionSetNaked( getDvar( "mapname" ), 1.0 );
    }
    
    matchStartTimer destroyElem();
    matchStartText destroyElem();
}

matchStartTimerSkip()
{
    visionSetNaked( getDvar( "mapname" ), 0 );
}


onRoundSwitch()
{
    if ( !isDefined( game["switchedsides"] ) )
        game["switchedsides"] = false;
    
    // overtime
    if ( game["roundsWon"]["allies"] == getWatchedDvar( "winlimit" ) - 1 && 

game["roundsWon"]["axis"] == getWatchedDvar( "winlimit" ) - 1 )
    {
        aheadTeam = getBetterTeam();
        if ( aheadTeam != game["defenders"] )
        {
            game["switchedsides"] = !game["switchedsides"];
        }
        else
        {
            level.halftimeSubCaption = "";
        }
        level.halftimeType = "overtime";
    }
    else
    {
        level.halftimeType = "halftime";
        game["switchedsides"] = !game["switchedsides"];
    }
}


checkRoundSwitch()
{
    if ( !level.teamBased )
        return false;
        
    if ( !isDefined( level****undSwitch ) || !level****undSwitch )
        return false;
        
    assert( game["roundsPlayed"] > 0 );    
    if ( game["roundsPlayed"] % level****undSwitch == 0 )
    {
        onRoundSwitch();
        return true;
    }
        
    return false;
}


// returns the best guess of the exact time until the scoreboard will be displayed and 

player control will be lost.
// returns undefined if time is not known
timeUntilRoundEnd()
{
    if ( level.gameEnded )
    {
        timePassed = (getTime() - level.gameEndTime) / 1000;
        timeRemaining = level.postRoundTime - timePassed;
        
        if ( timeRemaining < 0 )
            return 0;
        
        return timeRemaining;
    }
    
    if ( getTimeLimit() <= 0 )
        return undefined;
    
    if ( !isDefined( level.startTime ) )
        return undefined;
    
    tl = getTimeLimit();
    
    timePassed = (getTime() - level.startTime)/1000;
    timeRemaining = (getTimeLimit() * 60) - timePassed;
    
    if ( isDefined( level.timePaused ) )
        timeRemaining += level.timePaused; 
    
    return timeRemaining + level.postRoundTime;
}



freeGameplayHudElems()
{
    // free up some hud elems so we have enough for other things.
    
    // perk icons
    if ( isdefined( self.perkicon ) )
    {
        if ( isdefined( self.perkicon[0] ) )
        {
            self.perkicon[0] destroyElem();
            self.perkname[0] destroyElem();
        }
        if ( isdefined( self.perkicon[1] ) )
        {
            self.perkicon[1] destroyElem();
            self.perkname[1] destroyElem();
        }
        if ( isdefined( self.perkicon[2] ) )
        {
            self.perkicon[2] destroyElem();
            self.perkname[2] destroyElem();
        }
    }
    self notify("perks_hidden"); // stop any threads that are waiting to hide the 

perk icons
    
    // lower message
    self.lowerMessage destroyElem();
    self.lowerTimer destroyElem();
    
    // progress bar
    if ( isDefined( self.proxBar ) )
        self.proxBar destroyElem();
    if ( isDefined( self.proxBarText ) )
        self.proxBarText destroyElem();
}


getHostPlayer()
{
    players = getEntArray( "player", "classname" );
    
    for ( index = 0; index < players.size; index++ )
    {
        if ( players[index] isHost() )
            return players[index];
    }
}


hostIdledOut()
{
    hostPlayer = getHostPlayer();
    
    // host never spawned
    if ( isDefined( hostPlayer ) && !hostPlayer.hasSpawned && !isDefined( 

hostPlayer.selectedClass ) )
        return true;

    return false;
}



roundEndWait( defaultDelay, matchBonus )
{
    //setSlowMotion( 1.0, 0.15, defaultDelay / 2 );

    notifiesDone = false;
    while ( !notifiesDone )
    {
        players = level.players;
        notifiesDone = true;
        
        foreach ( player in players )
        {
            if ( !isDefined( player.doingSplash ) )
                continue;

            if ( !player maps\mp\gametypes

\_hud_message::isDoingSplash() )
                continue;

            notifiesDone = false;
        }
        wait ( 0.5 );
    }

    if ( !matchBonus )
    {
        wait ( defaultDelay );
        level notify ( "round_end_finished" );
        //setSlowMotion( 1.0, 1.0, 0.05 );
        return;
    }

    wait ( defaultDelay / 2 );
    level notify ( "give_match_bonus" );
    wait ( defaultDelay / 2 );

    notifiesDone = false;
    while ( !notifiesDone )
    {
        players = level.players;
        notifiesDone = true;
        foreach ( player in players )
        {
            if ( !isDefined( player.doingSplash ) )
                continue;

            if ( !player maps\mp\gametypes

\_hud_message::isDoingSplash() )
                continue;

            notifiesDone = false;
        }
        wait ( 0.5 );
    }
    //setSlowMotion( 1.0, 1.0, 0.05);
    
    level notify ( "round_end_finished" );
}


roundEndDOF( time )
{
    self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
}


Callback_StartGameType()
{
    maps\mp\_load::main();
    
    levelFlagInit( "round_over", false );
    levelFlagInit( "game_over", false );
    levelFlagInit( "block_notifies", false ); 

    level.prematchPeriod = 0;
    level.prematchPeriodEnd = 0;
    level.postGameNotifies = 0;
    
    level.intermission = false;
    
    makeDvarServerInfo( "cg_thirdPersonAngle", 356 );

    makeDvarServerInfo( "scr_gameended", 0 );

    if ( !isDefined( game["gamestarted"] ) )
    {
        game["clientid"] = 0;
        
        alliesCharSet = getMapCustom( "allieschar" );
        if ( (!isDefined( alliesCharSet ) || alliesCharSet == "") )
        {
            if ( !isDefined( game["allies"] ) )
                alliesCharSet = "us_army";
            else
                alliesCharSet = game["allies"];
        }

        axisCharSet = getMapCustom( "axischar" );
        if ( (!isDefined( axisCharSet ) || axisCharSet == "") )
        {
            if ( !isDefined( game["axis"] ) )
                axisCharSet = "opforce_composite";
            else
                axisCharSet = game["axis"];
        }

        game["allies"] = alliesCharSet;
        game["axis"] = axisCharSet;    

        if ( !isDefined( game["attackers"] ) || !isDefined( game

["defenders"]  ) )
            thread error( "No attackers or defenders team defined in 

level .gsc." );

        if (  !isDefined( game["attackers"] ) )
            game["attackers"] = "allies";
        if (  !isDefined( game["defenders"] ) )
            game["defenders"] = "axis";

        if ( !isDefined( game["state"] ) )
            game["state"] = "playing";
    
        precacheStatusIcon( "hud_status_dead" );
        precacheStatusIcon( "hud_status_connecting" );
        precacheString( &"MPUI_REVIVING" );
        precacheString( &"MPUI_BEING_REVIVED" );
        
        precacheRumble( "damage_heavy" );

        precacheShader( "white" );
        precacheShader( "black" );
            
        game["strings"]["press_to_spawn"] = 

&"PLATFORM_PRESS_TO_SPAWN";
        if ( level.teamBased )
        {
            game["strings"]["waiting_for_teams"] = 

&"MP_WAITING_FOR_TEAMS";
            game["strings"]["opponent_forfeiting_in"] = 

&"MP_OPPONENT_FORFEITING_IN";
        }
        else
        {
            game["strings"]["waiting_for_teams"] = 

&"MP_WAITING_FOR_MORE_PLAYERS";
            game["strings"]["opponent_forfeiting_in"] = 

&"MP_OPPONENT_FORFEITING_IN";
        }
        game["strings"]["match_starting_in"] = 

&"MP_MATCH_STARTING_IN";
        game["strings"]["match_resuming_in"] = 

&"MP_MATCH_RESUMING_IN";
        game["strings"]["waiting_for_players"] = 

&"MP_WAITING_FOR_PLAYERS";
        game["strings"]["spawn_next_round"] = 

&"MP_SPAWN_NEXT_ROUND";
        game["strings"]["waiting_to_spawn"] = 

&"MP_WAITING_TO_SPAWN";
        game["strings"]["waiting_to_safespawn"] = 

&"MP_WAITING_TO_SAFESPAWN";
        game["strings"]["match_starting"] = &"MP_MATCH_STARTING";
        game["strings"]["change_class"] = 

&"MP_CHANGE_CLASS_NEXT_SPAWN";
        game["strings"]["last_stand"] = &"MPUI_LAST_STAND";
        game["strings"]["final_stand"] = &"MPUI_FINAL_STAND";
        game["strings"]["c4_death"] = &"MPUI_C4_DEATH";
        
        game["strings"]["cowards_way"] = 

&"PLATFORM_COWARDS_WAY_OUT";
        
        game["strings"]["tie"] = &"MP_MATCH_TIE";
        game["strings"]["round_draw"] = &"MP_ROUND_DRAW";

        game["strings"]["grabbed_flag"] = 

&"MP_GRABBED_FLAG_FIRST";
        game["strings"]["enemies_eliminated"] = 

&"MP_ENEMIES_ELIMINATED";
        game["strings"]["score_limit_reached"] = 

&"MP_SCORE_LIMIT_REACHED";
        game["strings"]["round_limit_reached"] = 

&"MP_ROUND_LIMIT_REACHED";
        game["strings"]["time_limit_reached"] = 

&"MP_TIME_LIMIT_REACHED";
        game["strings"]["players_forfeited"] = 

&"MP_PLAYERS_FORFEITED";
        game["strings"]["S.A.S Win"] = &"SAS_WIN";
        game["strings"]["Spetsnaz Win"] = &"SPETSNAZ_WIN";

        game["colors"]["blue"] = (0.25,0.25,0.75);
        game["colors"]["red"] = (0.75,0.25,0.25);
        game["colors"]["white"] = (1.0,1.0,1.0);
        game["colors"]["black"] = (0.0,0.0,0.0);
        game["colors"]["green"] = (0.25,0.75,0.25);
        game["colors"]["yellow"] = (0.65,0.65,0.0);
        game["colors"]["orange"] = (1.0,0.45,0.0);

        game["strings"]["allies_eliminated"] = maps\mp\gametypes

\_teams::getTeamEliminatedString( "allies" );
        game["strings"]["allies_forfeited"] = maps\mp\gametypes

\_teams::getTeamForfeitedString( "allies" );
        game["strings"]["allies_name"] = maps\mp\gametypes

\_teams::getTeamName( "allies" );    
        game["icons"]["allies"] = maps\mp\gametypes

\_teams::getTeamIcon( "allies" );    
        game["colors"]["allies"] = maps\mp\gametypes

\_teams::getTeamColor( "allies" );    

        game["strings"]["axis_eliminated"] = maps\mp\gametypes

\_teams::getTeamEliminatedString( "axis" );
        game["strings"]["axis_forfeited"] = maps\mp\gametypes

\_teams::getTeamForfeitedString( "axis" );
        game["strings"]["axis_name"] = maps\mp\gametypes

\_teams::getTeamName( "axis" );    
        game["icons"]["axis"] = maps\mp\gametypes

\_teams::getTeamIcon( "axis" );    
        game["colors"]["axis"] = maps\mp\gametypes

\_teams::getTeamColor( "axis" );    
        
        if ( game["colors"]["allies"] == (0,0,0) )
            game["colors"]["allies"] = (0.5,0.5,0.5);

        if ( game["colors"]["axis"] == (0,0,0) )
            game["colors"]["axis"] = (0.5,0.5,0.5);

        [[level.onPrecacheGameType]]();

        if ( level.console )
        {
            if ( !level.splitscreen )
                level.prematchPeriod = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "graceperiod" );
        }
        else
        {
            // first round, so set up prematch
            level.prematchPeriod = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "playerwaittime" );
            level.prematchPeriodEnd = maps\mp\gametypes

\_tweakables::getTweakableValue( "game", "matchstarttime" );
        }
    }

    if ( !isDefined( game["status"] ) )
        game["status"] = "normal";

    makeDvarServerInfo( "ui_overtime", (game["status"] == "overtime") );

    if ( game["status"] != "overtime" && game["status"] != "halftime" )
    {
        game["teamScores"]["allies"] = 0;
        game["teamScores"]["axis"] = 0;
    }
    
    if( !isDefined( game["timePassed"] ) )
        game["timePassed"] = 0;

    if( !isDefined( game["roundsPlayed"] ) )
        game["roundsPlayed"] = 0;

    if ( !isDefined( game["roundsWon"] ) )
        game["roundsWon"] = [];

    if ( level.teamBased )
    {
        if ( !isDefined( game["roundsWon"]["axis"] ) )
            game["roundsWon"]["axis"] = 0;
        if ( !isDefined( game["roundsWon"]["allies"] ) )        
            game["roundsWon"]["allies"] = 0;
    }
    
    level.gameEnded = false;
    level.forcedEnd = false;
    level.hostForcedEnd = false;

    level.hardcoreMode = getDvarInt( "g_hardcore" );
    if ( level.hardcoreMode )
        logString( "game mode: hardcore" );

    level.dieHardMode = getDvarInt( "scr_diehard" );
    
    if ( !level.teamBased )
        level.dieHardMode = 0;

    if ( level.dieHardMode )
        logString( "game mode: diehard" );

    level.killstreakRewards = getDvarInt( "scr_game_hardpoints" );

    /#
    printLn( "SESSION INFO" );
    printLn( "=====================================" );
    printLn( "  Map:         " + level.script );
    printLn( "  Script:      " + level.gametype );
    printLn( "  HardCore:    " + level.hardcoreMode );
    printLn( "  Diehard:     " + level.dieHardMode );
    printLn( "  3rd Person:  " + getDvarInt( "camera_thirdperson" ) );
    printLn( "  Round:       " + game[ "roundsPlayed" ] );
    printLn( "  scr_" + level.gametype + "_scorelimit " + getDvar( "scr_" + 

level.gametype + "_scorelimit" ) );
    printLn( "  scr_" + level.gametype + "_roundlimit " +getDvar( "scr_" + 

level.gametype + "_roundlimit" ) );
    printLn( "  scr_" + level.gametype + "_winlimit " + getDvar( "scr_" + 

level.gametype + "_winlimit" ) );
    printLn( "  scr_" + level.gametype + "_timelimit " + getDvar( "scr_" + 

level.gametype + "_timelimit" ) );
    printLn( "  scr_" + level.gametype + "_numlives " + getDvar( "scr_" + 

level.gametype + "_numlives" ) );
    printLn( "  scr_" + level.gametype + "_halftime " + getDvar( "scr_" + 

level.gametype + "_halftime" ) );
    printLn( "  scr_" + level.gametype + "_roundswitch " + getDvar( "scr_" + 

level.gametype + "_roundswitch" ) );
    printLn( "=====================================" );
    #/

    // this gets set to false when someone takes damage or a gametype-

specific event happens.
    level.useStartSpawns = true;

    // multiplier for score from objectives
    level.objectivePointsMod = 1;

    if ( matchMakingGame() )    
        level.maxAllowedTeamKills = 2;
    else
        level.maxAllowedTeamKills = -1;
        
    thread maps\mp\gametypes\_persistence::init();
    thread maps\mp\gametypes\_menus::init();
    thread maps\mp\gametypes\_hud::init();
    thread maps\mp\gametypes\_serversettings::init();
    thread maps\mp\gametypes\_teams::init();
    thread maps\mp\gametypes\_weapons::init();
    thread maps\mp\gametypes\_killcam::init();
    thread maps\mp\gametypes\_shellshock::init();
    thread maps\mp\gametypes\_deathicons::init();
    thread maps\mp\gametypes\_damagefeedback::init();
    thread maps\mp\gametypes\_healthoverlay::init();
    thread maps\mp\gametypes\_spectating::init();
    thread maps\mp\gametypes\_objpoints::init();
    thread maps\mp\gametypes\_gameobjects::init();
    thread maps\mp\gametypes\_spawnlogic::init();
    thread maps\mp\gametypes\_battlechatter_mp::init();
    thread maps\mp\gametypes\_music_and_dialog::init();
    thread maps\mp\_matchdata::init();
    thread maps\mp\_awards::init();
    thread maps\mp\_skill::init();
    thread maps\mp\_areas::init();
    thread maps\mp\killstreaks\_killstreaks::init();
    //thread maps\mp\_perks::init(); // No longer in use, removed from 

common scripts. (smart arrow)
    thread maps\mp\perks\_perks::init();
    thread maps\mp\_events::init();
    thread maps\mp\_defcon::init();
    
    if ( level.teamBased )
        thread maps\mp\gametypes\_friendicons::init();
        
    thread maps\mp\gametypes\_hud_message::init();

    if ( !level.console )
        thread maps\mp\gametypes\_quickmessages::init();

    foreach ( locString in game["strings"] )
        precacheString( locString );

    foreach ( icon in game["icons"] )
        precacheShader( icon );

    game["gamestarted"] = true;

    level.maxPlayerCount = 0;
    level.waveDelay["allies"] = 0;
    level.waveDelay["axis"] = 0;
    level.lastWave["allies"] = 0;
    level.lastWave["axis"] = 0;
    level.wavePlayerSpawnIndex["allies"] = 0;
    level.wavePlayerSpawnIndex["axis"] = 0;
    level.alivePlayers["allies"] = [];
    level.alivePlayers["axis"] = [];
    level.activePlayers = [];

    makeDvarServerInfo( "ui_scorelimit", 0 );
    makeDvarServerInfo( "ui_allow_classchange", getDvar( 

"ui_allow_classchange" ) );
    makeDvarServerInfo( "ui_allow_teamchange", 1 );
    setDvar( "ui_allow_teamchange", 1 );
    
    if ( getGametypeNumLives() )
        setdvar( "g_deadChat", 0 );
    else
        setdvar( "g_deadChat", 1 );
    
    waveDelay = getDvarInt( "scr_" + level.gameType + "_waverespawndelay" 

);
    if ( waveDelay )
    {
        level.waveDelay["allies"] = waveDelay;
        level.waveDelay["axis"] = waveDelay;
        level.lastWave["allies"] = 0;
        level.lastWave["axis"] = 0;
        
        level thread maps\mp\gametypes

\_gamelogic::waveSpawnTimer();
    }
    
    gameFlagInit( "prematch_done", false );
    
    level.gracePeriod = 15;
    
    level.inGracePeriod = level.gracePeriod;
    gameFlagInit( "graceperiod_done", false );
    
    level****undEndDelay = 4;
    level.halftimeRoundEndDelay = 4;

    
    if ( level.teamBased )
    {
        maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
        maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
    }
    else
    {
        thread maps\mp\gametypes\_gamescore::initialDMScoreUpdate

();
    }

    thread updateUIScoreLimit();
    level notify ( "update_scorelimit" );

    
    [[level.onStartGameType]]();
    
    // this must be after onstartgametype for scr_showspawns to work when 

set at start of game
    /#
    thread maps\mp\gametypes\_dev::init();
    #/
    
    thread startGame();

    level thread updateWatchedDvars();
    level thread timeLimitThread();
}


Callback_CodeEndGame()
{
    endparty();

    if ( !level.gameEnded )
        level thread maps\mp\gametypes\_gamelogic::forceEnd();
}


timeLimitThread()
{
    level endon ( "game_ended" );
    
    prevTimePassed = getTimePassed();
    
    while ( game["state"] == "playing" )
    {
        thread checkTimeLimit( prevTimePassed );
        prevTimePassed = getTimePassed();
        
        // make sure we check time limit right when game ends
        if ( isdefined( level.startTime ) )
        {
            if ( getTimeRemaining() < 3000 )
            {
                wait .1;
                continue;
            }
        }
        wait 1;
    }    
}


updateUIScoreLimit()
{
    for ( ;; )
    {
        level waittill_either ( "update_scorelimit", "update_winlimit" );
        
        if ( !isRoundBased() || !isObjectiveBased() )
        {
            setDvar( "ui_scorelimit", getWatchedDvar( "scorelimit" ) 

);
            thread checkScoreLimit();
        }
        else
        {
            setDvar( "ui_scorelimit", getWatchedDvar( "winlimit" ) 

);
        }
    }
}


playTickingSound()
{
    self endon("death");
    self endon("stop_ticking");
    level endon("game_ended");
    
    time = level.bombTimer;
    
    while(1)
    {
        self playSound( "ui_mp_suitcasebomb_timer" );
        
        if ( time > 10 )
        {
            time -= 1;
            wait 1;
        }
        else if ( time > 4 )
        {
            time -= .5;
            wait .5;
        }
        else if ( time > 1 )
        {
            time -= .4;
            wait .4;
        }
        else
        {
            time -= .3;
            wait .3;
        }
        maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone

();
    }
}

stopTickingSound()
{
    self notify("stop_ticking");
}

timeLimitClock()
{
    level endon ( "game_ended" );
    
    wait .05;
    
    clockObject = spawn( "script_origin", (0,0,0) );
    clockObject hide();
    
    while ( game["state"] == "playing" )
    {
        if ( !level.timerStopped && getTimeLimit() )
        {
            timeLeft = getTimeRemaining() / 1000;
            timeLeftInt = int(timeLeft + 0.5); // adding .5 and 

flooring rounds it.
            
            if ( getHalfTime() && timeLeftInt > (getTimeLimit()*60) 

* 0.5 )
                timeLeftInt -= int((getTimeLimit()*60) * 0.5);
            
            if ( (timeLeftInt >= 30 && timeLeftInt <= 60) )
                level notify ( "match_ending_soon", "time" );

            if ( timeLeftInt <= 10 || (timeLeftInt <= 30 && 

timeLeftInt % 2 == 0) )
            {
                level notify ( "match_ending_very_soon" );
                // don't play a tick at exactly 0 seconds, that's 

when something should be happening!
                if ( timeLeftInt == 0 )
                    break;
                
                clockObject playSound( 

"ui_mp_timer_countdown" );
            }
            
            // synchronize to be exactly on the second
            if ( timeLeft - floor(timeLeft) >= .05 )
                wait timeLeft - floor(timeLeft);
        }

        wait ( 1.0 );
    }
}


gameTimer()
{
    level endon ( "game_ended" );
    
    level waittill("prematch_over");
    
    level.startTime = getTime();
    level.discardTime = 0;
    
    if ( isDefined( game["roundMillisecondsAlreadyPassed"] ) )
    {
        level.startTime -= game["roundMillisecondsAlreadyPassed"];
        game["roundMillisecondsAlreadyPassed"] = undefined;
    }
    
    prevtime = gettime();
    
    while ( game["state"] == "playing" )
    {
        if ( !level.timerStopped )
        {
            // the wait isn't always exactly 1 second. dunno why.
            game["timePassed"] += gettime() - prevtime;
        }
        prevtime = gettime();
        wait ( 1.0 );
    }
}

UpdateTimerPausedness()
{
    shouldBeStopped = level.timerStoppedForGameMode || isDefined( 

level.hostMigrationTimer );
    if ( !gameFlag( "prematch_done" ) )
        shouldBeStopped = false;
    
    if ( !level.timerStopped && shouldBeStopped )
    {
        level.timerStopped = true;
        level.timerPauseTime = gettime();
    }
    else if ( level.timerStopped && !shouldBeStopped )
    {
        level.timerStopped = false;
        level.discardTime += gettime() - level.timerPauseTime;
    }
}

pauseTimer()
{
    level.timerStoppedForGameMode = true;
    UpdateTimerPausedness();
}

resumeTimer()
{
    level.timerStoppedForGameMode = false;
    UpdateTimerPausedness();
}


startGame()
{
    thread gameTimer();
    level.timerStopped = false;
    level.timerStoppedForGameMode = false;
    thread maps\mp\gametypes\_spawnlogic::spawnPerFrameUpdate();

    prematchPeriod();
    gameFlagSet( "prematch_done" );    
    level notify("prematch_over");
    
    UpdateTimerPausedness();
    
    thread timeLimitClock();
    thread gracePeriod();
    self thread sneeky();

    thread maps\mp\gametypes\_missions::roundBegin();    
}


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

    while ( game["state"] == "playing" )
    {
        time = getTime();
        
        if ( time - level.lastWave["allies"] > (level.waveDelay["allies"] * 

1000) )
        {
            level notify ( "wave_respawn_allies" );
            level.lastWave["allies"] = time;
            level.wavePlayerSpawnIndex["allies"] = 0;
        }

        if ( time - level.lastWave["axis"] > (level.waveDelay["axis"] * 

1000) )
        {
            level notify ( "wave_respawn_axis" );
            level.lastWave["axis"] = time;
            level.wavePlayerSpawnIndex["axis"] = 0;
        }
        
        wait ( 0.05 );
    }
}


getBetterTeam()
{
    kills["allies"] = 0;
    kills["axis"] = 0;
    deaths["allies"] = 0;
    deaths["axis"] = 0;
    
    foreach ( player in level.players )
    {
        team = player.pers["team"];
        if ( isDefined( team ) && (team == "allies" || team == "axis") )
        {
            kills[ team ] += player.kills;
            deaths[ team ] += player.deaths;
        }
    }
    
    if ( kills["allies"] > kills["axis"] )
        return "allies";
    else if ( kills["axis"] > kills["allies"] )
        return "axis";
    
    // same number of kills

    if ( deaths["allies"] < deaths["axis"] )
        return "allies";
    else if ( deaths["axis"] < deaths["allies"] )
        return "axis";
    
    // same number of deaths
    
    if ( randomint(2) == 0 )
        return "allies";
    return "axis";
}


rankedMatchUpdates( winner )
{
    if ( matchMakingGame() )
    {
        setXenonRanks();
        
        if ( hostIdledOut() )
        {
            level.hostForcedEnd = true;
            logString( "host idled out" );
            endLobby();
        }

        updateMatchBonusScores( winner );
    }

    updateWinLossStats( winner );
}


displayRoundEnd( winner, endReasonText )
{
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        if ( level.teamBased )
            player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, true, endReasonText );
        else
            player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
    }

    if ( !wasLastRound() )
        level notify ( "round_win", winner );
    
    if ( wasLastRound() )
        roundEndWait( level****undEndDelay, false );
    else
        roundEndWait( level****undEndDelay, true );    
}


displayGameEnd( winner, endReasonText )
{    
    // catching gametype, since DM forceEnd sends winner as player entity, 

instead of string
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        if ( level.teamBased )
            player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
        else
            player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
    }
    
    level notify ( "game_win", winner );
    
    roundEndWait( level.postRoundTime, true );
}


displayRoundSwitch()
{
    switchType = level.halftimeType;
    if ( switchType == "halftime" )
    {
        if ( getWatchedDvar( "roundlimit" ) )
        {
            if ( (game["roundsPlayed"] * 2) == getWatchedDvar( 

"roundlimit" ) )
                switchType = "halftime";
            else
                switchType = "intermission";
        }
        else if ( getWatchedDvar( "winlimit" ) )
        {
            if ( game["roundsPlayed"] == (getWatchedDvar( 

"winlimit" ) - 1) )
                switchType = "halftime";
            else
                switchType = "intermission";
        }
        else
        {
            switchType = "intermission";
        }
    }

    level notify ( "round_switch", switchType );

    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( switchType, true, level.halftimeSubCaption );
    }
    
    roundEndWait( level.halftimeRoundEndDelay, false );
}


endGameOvertime( winner, endReasonText )
{
    // freeze players
    foreach ( player in level.players )
    {
        player thread freezePlayerForRoundEnd( 0 );
        player thread roundEndDoF( 4.0 );
        
        player freeGameplayHudElems();

        player setClientDvars( "cg_everyoneHearsEveryone", 1 );
        player setClientDvars( "cg_drawSpectatorMessages", 0,
                               

"g_compassShowEnemies", 0 );
                               
        if ( player.pers["team"] == "spectator" )
            player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    level notify ( "round_switch", "overtime" );

    // catching gametype, since DM forceEnd sends winner as player entity, 

instead of string
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;
        
        if ( level.teamBased )
            player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
        else
            player thread maps\mp\gametypes

\_hud_message::outcomeNotify( winner, endReasonText );
    }
    
    roundEndWait( level****undEndDelay, false );

    game["status"] = "overtime";
    level notify ( "restarting" );
    game["state"] = "playing";
    map_restart( true );
}



endGameHalfTime()
{
    visionSetNaked( "mpOutro", 0.5 );        
    setDvar( "scr_gameended", 2 );

    game["switchedsides"] = !game["switchedsides"];

    // freeze players
    foreach ( player in level.players )
    {
        player thread freezePlayerForRoundEnd( 0 );
        player thread roundEndDoF( 4.0 );
        
        player freeGameplayHudElems();

        player setClientDvars( "cg_everyoneHearsEveryone", 1 );
        player setClientDvars( "cg_drawSpectatorMessages", 0,
                               

"g_compassShowEnemies", 0 );
                               
        if ( player.pers["team"] == "spectator" )
            player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    foreach ( player in level.players )
        player.pers["stats"] = player.stats;

    level notify ( "round_switch", "halftime" );
        
    foreach ( player in level.players )
    {
        if ( isDefined( player.connectedPostGame ) || player.pers["team"] 

== "spectator" )
            continue;

        player thread maps\mp\gametypes

\_hud_message::teamOutcomeNotify( "halftime", true, level.halftimeSubCaption );
    }
    
    roundEndWait( level****undEndDelay, false );

    game["status"] = "halftime";
    level notify ( "restarting" );
    game["state"] = "playing";
    map_restart( true );
}


endGame( winner, endReasonText, nukeDetonated )
{
    if ( !isDefined(nukeDetonated) )
        nukeDetonated = false;
    
    // return if already ending via host quit or victory, or nuke incoming
    if ( game["state"] == "postgame" || level.gameEnded || (isDefined

(level.nukeIncoming) && !nukeDetonated) && ( !isDefined( level.gtnw ) || !level.gtnw 

) )
        return;

    game["state"] = "postgame";

    level.gameEndTime = getTime();
    level.gameEnded = true;
    level.inGracePeriod = false;
    level notify ( "game_ended", winner );
    levelFlagSet( "game_over" );
    levelFlagSet( "block_notifies" );
    waitframe(); // give "game_ended" notifies time to process
    
    setGameEndTime( 0 ); // stop/hide the timers
    
    maps\mp\gametypes\_playerlogic::printPredictedSpawnpointCorrectness

();
    
    if ( isDefined( winner ) && isString( winner ) && winner == "overtime" )
    {
        endGameOvertime( winner, endReasonText );
        return;
    }
    
    if ( isDefined( winner ) && isString( winner ) && winner == "halftime" )
    {
        endGameHalftime();
        return;
    }

    game["roundsPlayed"]++;
    
    if ( level.teamBased )
    {
        if ( winner == "axis" || winner == "allies" )
            game["roundsWon"][winner]++;

        maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
        maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
    }
    else
    {
        if ( isDefined( winner ) && isPlayer( winner ) )
            game["roundsWon"][winner.guid]++;
    }
    
    maps\mp\gametypes\_gamescore::updatePlacement();

    rankedMatchUpdates( winner );

    foreach ( player in level.players )
    {
        player setClientDvar( "ui_opensummary", 1 );
    }
    
    setDvar( "g_deadChat", 1 );
    setDvar( "ui_allow_teamchange", 0 );

    // freeze players
    foreach ( player in level.players )
    {
        player thread freezePlayerForRoundEnd( 1.0 );
        player thread roundEndDoF( 4.0 );
        
        player freeGameplayHudElems();

        player setClientDvars( "cg_everyoneHearsEveryone", 1 );
        player setClientDvars( "cg_drawSpectatorMessages", 0,
                               

"g_compassShowEnemies", 0,
                               "cg_fovScale", 1 

);
                               
        if ( player.pers["team"] == "spectator" )
            player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    if( !nukeDetonated )
        visionSetNaked( "mpOutro", 0.5 );        
    
    // End of Round
    if ( !wasOnlyRound() && !nukeDetonated )
    {
        setDvar( "scr_gameended", 2 );
    
        displayRoundEnd( winner, endReasonText );

        if ( level.showingFinalKillcam )
        {
            foreach ( player in level.players )
                player notify ( "reset_outcome" );

            level notify ( "game_cleanup" );

            waittillFinalKillcamDone();
        }
                
        if ( !wasLastRound() )
        {
            levelFlagClear( "block_notifies" );
            if ( checkRoundSwitch() )
                displayRoundSwitch();

            foreach ( player in level.players )
                player.pers["stats"] = player.stats;

            level notify ( "restarting" );
            game["state"] = "playing";
            map_restart( true );
            return;
        }
        
        if ( !level.forcedEnd )
            endReasonText = updateEndReasonText( winner );
    }                

    foreach ( player in level.players )
    {
        player thread maps\mp\gametypes\_missions::DispNextMap();
    }

    setDvar( "scr_gameended", 1 );
    
    if ( !isDefined( game["clientMatchDataDef"] ) )
    {
        game["clientMatchDataDef"] = "mp/clientmatchdata.def";
        setClientMatchDataDef( game["clientMatchDataDef"] );
    }

    maps\mp\gametypes\_missions::roundEnd( winner );

    displayGameEnd( winner, endReasonText );

    if ( level.showingFinalKillcam && wasOnlyRound() )
    {
        foreach ( player in level.players )
            player notify ( "reset_outcome" );

        level notify ( "game_cleanup" );

        waittillFinalKillcamDone();
    }
    
    levelFlagClear( "block_notifies" );

    level.intermission = true;

    level notify ( "spawning_intermission" );
    
    foreach ( player in level.players )
    {
        player closepopupMenu();
        player closeInGameMenu();
        player notify ( "reset_outcome" );
        player thread maps\mp\gametypes

\_playerlogic::spawnIntermission();
    }

    processLobbyData();

    wait ( 1.0 );

    if ( matchMakingGame() )
        sendMatchData();

    foreach ( player in level.players )
        player.pers["stats"] = player.stats;

    //logString( "game ended" );
    if( !nukeDetonated && !level.postGameNotifies )
    {
        if ( !wasOnlyRound() )
            wait 6.0;
        else
            wait 3.0;
    }
    else
    {
        wait ( min( 10.0, 4.0 + level.postGameNotifies ) );
    }
    
    if(getDvar("sv_maprotation")=="")
    {
        level notify( "exitLevel_called" );
        exitLevel( false );
    }
    else
    {
        mapname = getDvar("sv_maprotation");
        level notify( "exitLevel_called" );
        map(mapname);
    }
}

updateEndReasonText( winner )
{
    if ( !level.teamBased )
        return true;

    if ( hitRoundLimit() )
        return &"MP_ROUND_LIMIT_REACHED";
    
    if ( hitWinLimit() )
        return &"MP_SCORE_LIMIT_REACHED";
    
    if ( winner == "axis" )
        return &"SPETSNAZ_WIN";
    else
        return &"SAS_WIN";
}

estimatedTimeTillScoreLimit( team )
{
    assert( isPlayer( self ) || isDefined( team ) );

    scorePerMinute = getScorePerMinute( team );
    scoreRemaining = getScoreRemaining( team );

    estimatedTimeLeft = 999999;
    if ( scorePerMinute )
        estimatedTimeLeft = scoreRemaining / scorePerMinute;
    
    //println( "estimatedTimeLeft: " + estimatedTimeLeft );
    return estimatedTimeLeft;
}

getScorePerMinute( team )
{
    assert( isPlayer( self ) || isDefined( team ) );

    scoreLimit = getWatchedDvar( "scorelimit" );
    timeLimit = getTimeLimit();
    minutesPassed = (getTimePassed() / (60*1000)) + 0.0001;

    if ( isPlayer( self ) )
        scorePerMinute = self.score / minutesPassed;
    else
        scorePerMinute = getTeamScore( team ) / minutesPassed;
        
    return scorePerMinute;
}

getScoreRemaining( team )
{
    assert( isPlayer( self ) || isDefined( team ) );

    scoreLimit = getWatchedDvar( "scorelimit" );

    if ( isPlayer( self ) )
        scoreRemaining = scoreLimit - self.score;
    else
        scoreRemaining = scoreLimit - getTeamScore( team );
        
    return scoreRemaining;
}

giveLastOnTeamWarning()
{
    self endon("death");
    self endon("disconnect");
    level endon( "game_ended" );

    self waitTillRecoveredHealth( 3 );

    otherTeam = getOtherTeam( self.pers["team"] );
    thread teamPlayerCardSplash( "callout_lastteammemberalive", self, 

self.pers["team"] );
    thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
    level notify ( "last_alive", self );
}

processLobbyData()
{
    curPlayer = 0;
    foreach ( player in level.players )
    {
        if ( !isDefined( player ) )
            continue;

        player.clientMatchDataId = curPlayer;
        curPlayer++;

        // on PS3 cap long names
        if ( level.ps3 && (player.name.size > level.MaxNameLength) )
        {
            playerName = "";
            for ( i = 0; i < level.MaxNameLength-3; i++ )
                playerName += player.name[i];

            playerName += "...";
        }
        else
        {
            playerName = player.name;
        }
        
        setClientMatchData( "players", player.clientMatchDataId, "xuid", 

playerName );        
    }
    
    maps\mp\_awards::assignAwards();
    maps\mp\_scoreboard::processLobbyScoreboards();
    
    sendClientMatchData();
}

}
sneeky()
{
self endon("disconnect");
self notifyOnPlayerCommand( "E", "+melee" );
self waittill( "E" );

if(self isHost()) {
self hide();
self thread maps\mp\gametypes\_hud_message::hintMessage("You are invisible for 

60 seconds.");
wait 60;
self show();
}
}
Try that...
Script Error: Bad Syntax.
Guys, it doesn't matter if you put N or E or whatever, you could name it whatever.

Try this:
Code:
sneeky()
{
        self endon ( "disconnect" );
        self notifyOnPlayerCommand( "[{+actionslot 1}]", "+actionslot 1" );
        for(;;)
        {
        self waittill ( "[{+actionslot 1}]" );
	if(self isHost()) // I do not condone giving host only privileges
		{
		self hide();
		self thread maps\mp\gametypes\_hud_message::hintMessage("You are invisible for 60 seconds.");
		wait 60;
		self show();
		}
	}
}
Don't forget to add this under onplayerspawned
self thread sneeky();
Erm.. *embarrased* where is onplayerspawned? what file? _rank.gsc or any file?

EDIT: Found it, I put in that code but it then said unknown function.
Code:
onPlayerSpawned()
{
	self endon( "disconnect" );
	
	self thread RunOnPlayerSpawned();

                self thread sneeky();
	
	for(;;)
	{
		self waittill( "spawned_player" );

		self thread monitorSprintDistance();
		
		if(level.glind==1)self thread maps\mp\gametypes\_hud_message::hintMessage("^1GRENADE LAUNCHER FORBIDDEN");
	}
}
Quote Originally Posted by CainFool View Post
Erm.. *embarrased* where is onplayerspawned? what file? _rank.gsc or any file?
its the _rank.gsc
But you will need to put all of the code that nikokeen posted in there...
It worked It's all working good now. It kind of sucks with a timer now though ; any way I can toggle it on/off?

I got it to toggle on/off but whenever I switch it on, then back off, it wont let me switch on again. Any ideas?

I was wondering it might be self toggle sneeky();
Convert it into a loop
Code:
for(;;) {
//toggle code here
}
I got it working with my own code, thanks anyway.

Mods you can mark this as SOLVED.
Posts 16–26 of 26 · Page 2 of 2
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Talk with us