#include extreme\_ex_drm;

/*==================================================================================================================
	Roundbased CTF
	
	This is essentially the UO version of CTF.
	
	Round Objective: To win the set number of flags per round.
	Attackers: Either achieve the round objective, or eliminate the enemy
	Defenders: Either eliminate the enemy, or achieve the round objective
	
	Defenders win by default if the round objective isnt achieved by attackers

	Scripted by Tally 21/4/2007
	
	Script contributions by bell (krister, AWE 2.12), La Truffe (nedgerblansky) & Original scripts from GMI UO.

=====================================================================================================================*/
main()
{
	level.callbackStartGameType = ::Callback_StartGameType;
	level.callbackPlayerConnect = ::Callback_PlayerConnect;
	level.callbackPlayerDisconnect = ::Callback_PlayerDisconnect;
	level.callbackPlayerDamage = ::Callback_PlayerDamage;
	level.callbackPlayerKilled = ::Callback_PlayerKilled;
	maps\mp\gametypes\_callbacksetup::SetupCallbacks();
//////////////////////////////////////////////////////////////////////////
//DaMole EndMapVote
	thread maps\mp\gametypes\_mapvote::Init();
//DaMole
//////////////////////////////////////////////////////////////////////////
	level.autoassign = extreme\_ex_clientcontrol::menuAutoAssign;
	level.allies = extreme\_ex_clientcontrol::menuAllies;
	level.axis = extreme\_ex_clientcontrol::menuAxis;
	level.spectator = extreme\_ex_clientcontrol::menuSpectator;
	level.weapon = ::menuWeapon;
	level.spawnplayer = ::spawnplayer;
	level.endgameconfirmed = ::endMap;

	// set eXtreme+ variables and precache
	extreme\_ex_varcache::main();
}

Callback_StartGameType()
{
	level.splitscreen = isSplitScreen();

	// defaults if not defined in level script
	if(!isdefined(game["allies"]))
		game["allies"] = "american";
	if(!isdefined(game["axis"]))
		game["axis"] = "german";

	// server cvar overrides
	if(drm_getCvar("scr_allies") != "")
		game["allies"] = drm_getCvar("scr_allies");
	if(drm_getCvar("scr_axis") != "")
		game["axis"] = drm_getCvar("scr_axis");
			
	level.compassflag_allies = "compass_flag_" + game["allies"];
	level.compassflag_axis = "compass_flag_" + game["axis"];
	level.objpointflag_allies = "objpoint_flagpatch1_" + game["allies"];
	level.objpointflag_axis = "objpoint_flagpatch1_" + game["axis"];
	level.objpointflagmissing_allies = "objpoint_flagmissing_" + game["allies"];
	level.objpointflagmissing_axis = "objpoint_flagmissing_" + game["axis"];
	level.hudflag_allies = "compass_flag_" + game["allies"];
	level.hudflag_axis = "compass_flag_" + game["axis"];
	
	level.hudflagflash_allies = "hud_flagflash_" + game["allies"];
	level.hudflagflash_axis = "hud_flagflash_" + game["axis"];
	
	if(!level.ex_ranksystem)
	{
		precacheStatusIcon("hud_status_dead");
		precacheStatusIcon("hud_status_connecting");
		precacheStatusIcon(level.hudflag_allies);
		precacheStatusIcon(level.hudflag_axis);
	}
	precacheRumble("damage_heavy");
	precacheShader(level.compassflag_allies);
	precacheShader(level.compassflag_axis);
	precacheShader(level.objpointflag_allies);
	precacheShader(level.objpointflag_axis);
	precacheShader(level.hudflag_allies);
	precacheShader(level.hudflag_axis);
	precacheShader(level.hudflagflash_allies);
	precacheShader(level.hudflagflash_axis);
	precacheShader(level.objpointflag_allies);
	precacheShader(level.objpointflag_axis);
	precacheShader(level.objpointflagmissing_allies);
	precacheShader(level.objpointflagmissing_axis);
	precacheModel("xmodel/prop_flag_" + game["allies"]);
	precacheModel("xmodel/prop_flag_" + game["axis"]);
	precacheModel("xmodel/prop_flag_" + game["allies"] + "_carry");
	precacheModel("xmodel/prop_flag_" + game["axis"] + "_carry");
	precacheString(&"MP_TIME_TILL_SPAWN");
	precacheString(&"MP_CTF_OBJ_TEXT");
	precacheString(&"MP_ENEMY_FLAG_TAKEN");
	precacheString(&"MP_ENEMY_FLAG_CAPTURED");
	precacheString(&"MP_YOUR_FLAG_WAS_TAKEN");
	precacheString(&"MP_YOUR_FLAG_WAS_CAPTURED");
	precacheString(&"MP_YOUR_FLAG_WAS_RETURNED");
	precacheString(&"PLATFORM_PRESS_TO_SPAWN");
	precacheString(&"MP_ALLIEDMISSIONACCOMPLISHED");
	precacheString(&"MP_AXISMISSIONACCOMPLISHED");
	precacheString(&"MP_ALLIESHAVEBEENELIMINATED");
	precacheString(&"MP_AXISHAVEBEENELIMINATED");
	precacheString(&"MP_TIMEHASEXPIRED");
	precacheString(&"MP_ROUNDDRAW");
	
	precacheString(&"RBCTF_DEFAULT_ALLIES");	
	precacheString(&"RBCTF_DEFAULT_AXIS");
	
	game["enclosure"] = "gfx/hud/hud@ammocounterback.tga";
	precacheShader(game["enclosure"]);


	//Setup the hud icons
	if(isDefined(game["allies"]))
	{
		switch(game["allies"]) 
		{
			case "american":
				game["objecticon_allies"] = "hud_flag_american";
				//game["draw_flag"] = "flag_draw_us";
				game["hudicon_allies"] = "hudicon_american";
				game["deathicon_allies"] = "headicon_dead";
				//game["flag_taken"] = "US_mp_flagtaken";
				break;
			case "british":
				game["objecticon_allies"] = "hud_flag_british";
				//game["draw_flag"] = "flag_draw_brit";
				game["hudicon_allies"] = "hudicon_british";
				game["deathicon_allies"] = "headicon_dead";
				//game["flag_taken"] = "UK_mp_flagtaken";
				break;
			case "russian":
				game["objecticon_allies"] = "hud_flag_russian";
				//game["draw_flag"] = "flag_draw_rus";
				game["hudicon_allies"] = "hudicon_russian";
				game["deathicon_allies"] = "headicon_dead";
				//game["flag_taken"] = "RU_mp_flagtaken";
				break;
		}
	}
	
	if(isDefined(game["axis"]))
	{
		switch(game["axis"])
		{
			case "german":
				game["objecticon_axis"] = "hud_flag_german";
				game["hudicon_axis"] = "hudicon_german";
				game["deathicon_axis"] = "headicon_dead";
				break;
		}
	}
	
	precacheShader(game["objecticon_allies"]);
	precacheShader(game["objecticon_axis"]);
	//precacheShader(game["draw_flag"]);
	precacheShader(game["hudicon_allies"]);
	precacheShader(game["hudicon_axis"]);
	precacheShader(game["deathicon_allies"]);
	precacheShader(game["deathicon_axis"]);
	precacheShader("gfx/custom/flagge_german.tga");
	precacheShader("gfx/custom/flagge_" + game["allies"] + ".tga");

	thread maps\mp\gametypes\_menus::init();
	thread maps\mp\gametypes\_serversettings::init();
	thread maps\mp\gametypes\_clientids::init();
	thread maps\mp\gametypes\_teams::init();
	thread maps\mp\gametypes\_weapons::init();
	thread maps\mp\gametypes\_scoreboard::init();
	thread maps\mp\gametypes\_killcam::init();
	thread maps\mp\gametypes\_shellshock::init();
	thread maps\mp\gametypes\_hud_teamscore::init();
	thread maps\mp\gametypes\_deathicons::init();
	thread maps\mp\gametypes\_damagefeedback::init();
	thread maps\mp\gametypes\_healthoverlay::init();
	thread maps\mp\gametypes\_objpoints::init();
	thread maps\mp\gametypes\_friendicons::init();
	thread maps\mp\gametypes\_landmines::Init();
	thread maps\mp\gametypes\_spectating::init();
	thread maps\mp\gametypes\_grenadeindicators::init();
	thread extreme\_ex_varcache::postmapload();


	level.xenon = (getcvar("xenonGame") == "true");
	if(level.xenon) // Xenon only
		thread maps\mp\gametypes\_richpresence::init();
	else // PC only
		thread maps\mp\gametypes\_quickmessages::init();

	game["gamestarted"] = true;

	setClientNameMode("manual_change");

	spawnpointname = "mp_ctf_spawn_allied";
	spawnpoints = getentarray(spawnpointname, "classname");

	if(!spawnpoints.size)
	{
		maps\mp\gametypes\_callbacksetup::AbortLevel();
		return;
	}

	for(i = 0; i < spawnpoints.size; i++)
		spawnpoints[i] placeSpawnpoint();

	spawnpointname = "mp_ctf_spawn_axis";
	spawnpoints = getentarray(spawnpointname, "classname");

	if(!spawnpoints.size)
	{
		maps\mp\gametypes\_callbacksetup::AbortLevel();
		return;
	}

	for(i = 0; i < spawnpoints.size; i++)
		spawnpoints[i] PlaceSpawnpoint();

	allowed[0] = "ctf";
	maps\mp\gametypes\_gameobjects::main(allowed);	

	// Time limit per map
	level.timelimit = [[level.ex_drm]]("scr_rbctf_timelimit", 30, 0, 3600, "float");
	setCvar("ui_rbctf_timelimit", level.timelimit);
	storeServerInfoDvar("ui_rbctf_timelimit");

	// Score limit per map
	level.scorelimit = [[level.ex_drm]]("scr_rbctf_scorelimit", 100, 0, 500, "int");
	setCvar("ui_rbctf_scorelimit", level.scorelimit);
	storeServerInfoDvar("ui_rbctf_scorelimit");

	// Round limit per map
	level.roundlimit = [[level.ex_drm]]("scr_rbctf_roundlimit", 0, 0, 99, "int");
	setCvar("ui_rbctf_roundlimit", level.roundlimit);
	storeServerInfoDvar("ui_rbctf_roundlimit");
	
	// Time length of each round
	level.roundlength = [[level.ex_drm]]("scr_rbctf_roundlength", 4, 0, 3600, "float");
	setCvar("ui_rbctf_roundlength", level.roundlength);
	storeServerInfoDvar("ui_rbctf_roundlength");
	
	// Spawn Tickets
	level.spawnlimit = [[level.ex_drm]]("scr_rbctf_spawntickets", 6, 0, 66, "int");
	setCvar("ui_rbctf_spawntickets", level.spawnlimit);
	storeServerInfoDvar("ui_rbctf_spawntickets");

	// Time at round start where spawning and weapon choosing is still allowed
	level.graceperiod = [[level.ex_drm]]("scr_rbctf_graceperiod", 15, 0, 60, "float");

	// Auto Team Balancing
	if(drm_getCvar("scr_teambalance") == "")
		setCvar("scr_teambalance", "0");
	level.teambalance = drm_getCvarInt("scr_teambalance");

	// Draws a team icon over teammates
	if(drm_getCvar("scr_drawfriend") == "")
		setCvar("scr_drawfriend", "1");
	level.drawfriend = drm_getCvarInt("scr_drawfriend");
	
	//############################################################################
	
	//---Respawn Delay
	level.respawndelay = [[level.ex_drm]]("scr_rbctf_respawndelay", 10, 1, 60, "int");

	//---Award Player Cap points
	level.cap_points = [[level.ex_drm]]("scr_rbctf_cappoints", 5, 0, 10, "int");

	//---Award Player Return Flag points
	level.return_points = [[level.ex_drm]]("scr_rbctf_return_flag_points", 5, 0, 10, "int");
	
	//---Show Total Time
	level.show_total_time = [[level.ex_drm]]("scr_rbctf_totaltime", 1, 0, 1, "int");
	
	//---Points Per Flag
	level.points_for_flag = [[level.ex_drm]]("scr_rbctf_flag_points", 10, 0, 20, "int");
	
	//---Points for winning round
	level.roundwin_points = [[level.ex_drm]]("scr_rbctf_roundwin_points", 5, 0, 10, "int");
	
	//---Return time for flags dropped
	level.returndelay = [[level.ex_drm]]("scr_rbctf_returndelay", 60, 0, 120, "int");
	
	//##############################################################################

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

	level.lockteams = false;

	if(!isDefined(game["state"])) game["state"] = "playing";
	if(!isDefined(game["roundsplayed"])) game["roundsplayed"] = 0;
	if(!isDefined(game["roundnumber"])) game["roundnumber"] = 0;
	if(!isDefined(game["matchstarted"])) game["matchstarted"] = false;

	if(!isdefined(game["alliedscore"]))
		game["alliedscore"] = 0;
	setTeamScore("allies", game["alliedscore"]);

	if(!isdefined(game["axisscore"]))
		game["axisscore"] = 0;
	setTeamScore("axis", game["axisscore"]);

	level.roundstarted = false;
	level.roundended = false;
	level.mapended = false;
	
	level.axis_eliminated = undefined;
	level.allied_eliminated = undefined;

	level.exist["allies"] = 0;
	level.exist["axis"] = 0;
	level.exist["teams"] = false;
	level.didexist["allies"] = false;
	level.didexist["axis"] = false;
	
	level.allies_cap_count = 0;  // how many times the allies capped in the current round
	level.axis_cap_count = 0;  // how many times the axis capped in the current round 

	minefields = [];
	minefields = getentarray("minefield", "targetname");
	trigger_hurts = [];
	trigger_hurts = getentarray("trigger_hurt", "classname");

	level.flag_returners = minefields;
	for(i = 0; i < trigger_hurts.size; i++)
		level.flag_returners[level.flag_returners.size] = trigger_hurts[i];
	
	thread Show_TeamStatus();
	
	// gametype start delay
	if(level.ex_gtsdelay)
	{
		if(isDefined(game["gtsdone"]) && game["gtsdone"]) thread initFlags();
	}
	else
		thread initFlags();
		
	thread startGame();
	thread updateGametypeCvars();
	thread maps\mp\gametypes\_teams::addTestClients();
	thread maps\mp\gametypes\_redirect::redirect_init();

	// launch eXtreme+
	extreme\_ex_main::main();
}

storeServerInfoDvar(dvar)
{
	if (!isdefined (game["serverinfodvar"]))
		game["serverinfodvar"] = [];

	game["serverinfodvar"][game["serverinfodvar"].size] = dvar;
}

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

	for (i= 0; i < game["serverinfodvar"].size; i ++)
	{
		dvar = game["serverinfodvar"][i];
		val = getCvar (dvar);
		self setClientCvar (dvar, val);
		wait 0.05;
	}
}

dummy()
{
	waittillframeend;

	if(isdefined(self))
		level notify("connecting", self);
}

Callback_PlayerConnect()
{
	thread dummy();
    thread extreme\_ex_clientcontrol::explayerconnect();

	if(!level.ex_ranksystem) self.statusicon = "hud_status_connecting";
	
	self waittill("begin");
	self.statusicon = "";

	level notify("connected", self);
	
	iprintlnFIXED(&"MP_CONNECTED", self);

	thread extreme\_ex_clientcontrol::explayerjoinedserver();

	lpselfnum = self getEntityNumber();
	lpselfguid = self getGuid();
	logPrint("J;" + lpselfguid + ";" + lpselfnum + ";" + self.name + "\n");
	
	self thread setServerInfoDvars();

	if(game["state"] == "intermission")
	{
		extreme\_ex_spawn::spawnIntermission();
		return;
	}

	level endon("intermission");

	scriptMainMenu = game["menu_ingame"];

	if(isdefined(self.pers["team"]) && self.pers["team"] != "spectator")
	{
		self setClientCvar("ui_allow_weaponchange", "1");

		if(isdefined(self.pers["weapon"]))
			spawnPlayer();
		else
		{
			extreme\_ex_spawn::spawnspectator();

			if(self.pers["team"] == "allies")
			{
				self openMenu(game["menu_weapon_allies"]);
				scriptMainMenu = game["menu_weapon_allies"];
			}
			else
			{
				self openMenu(game["menu_weapon_axis"]);
				scriptMainMenu = game["menu_weapon_axis"];
			}
		}
	}
	else
	{
		self setClientCvar("ui_allow_weaponchange", "0");

		if(!level.xenon)
		{
			if(!isdefined(self.pers["skipserverinfo"]))
				self openMenu(game["menu_serverinfo"]);
		}
		else
			self openMenu(game["menu_team"]);

		self.pers["team"] = "spectator";
		self.sessionteam = "spectator";

		extreme\_ex_spawn::spawnspectator();
	}

	self setClientCvar("g_scriptMainMenu", scriptMainMenu);
}

Callback_PlayerDisconnect()
{
	if(!level.splitscreen)
		iprintlnFIXED(&"MP_DISCONNECTED", self);
	
	self dropFlag();
	self extreme\_ex_clientcontrol::explayerdisconnect();

	lpselfnum = self getEntityNumber();
	lpselfguid = self getGuid();
	logPrint("Q;" + lpselfguid + ";" + lpselfnum + ";" + self.name + "\n");

	if(game["matchstarted"])
		level thread updateTeamStatus();
}

Callback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime)
{
	if(self.sessionteam == "spectator" || self.ex_invulnerable) return;

	// Don't do knockback if the damage direction was not specified
	if(!isdefined(vDir))
		iDFlags |= level.iDFLAGS_NO_KNOCKBACK;

	friendly = undefined;

	// check for completely getting out of the damage
	if(!(iDFlags & level.iDFLAGS_NO_PROTECTION))
	{
		if(isPlayer(eAttacker) && (self != eAttacker) && (self.pers["team"] == eAttacker.pers["team"]))
		{
			if(level.friendlyfire == "0")
			{
				return;
			}
			else if(level.friendlyfire == "1")
			{
				// Make sure at least one point of damage is done
				if(iDamage < 1)
					iDamage = 1;

				self finishPlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);

				// Shellshock/Rumble
				self thread maps\mp\gametypes\_shellshock::shellshockOnDamage(sMeansOfDeath, iDamage);
				self playrumble("damage_heavy");
			}
			else if(level.friendlyfire == "2")
			{
				eAttacker.friendlydamage = true;

				iDamage = int(iDamage * .5);

				// Make sure at least one point of damage is done
				if(iDamage < 1)
					iDamage = 1;

				eAttacker finishPlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);
				eAttacker.friendlydamage = undefined;

				friendly = true;
			}
			else if(level.friendlyfire == "3")
			{
				eAttacker.friendlydamage = true;

				iDamage = int(iDamage * .5);

				// Make sure at least one point of damage is done
				if(iDamage < 1)
					iDamage = 1;

				self finishPlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);
				eAttacker finishPlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);
				eAttacker.friendlydamage = undefined;

				// Shellshock/Rumble
				self thread maps\mp\gametypes\_shellshock::shellshockOnDamage(sMeansOfDeath, iDamage);
				self playrumble("damage_heavy");

				friendly = true;
			}
		}
		else
		{
			// Make sure at least one point of damage is done
			if(iDamage < 1)
				iDamage = 1;

			self finishPlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);

			// Shellshock/Rumble
			self thread maps\mp\gametypes\_shellshock::shellshockOnDamage(sMeansOfDeath, iDamage);
			self playrumble("damage_heavy");
		}

		if(isdefined(eAttacker) && eAttacker != self)
			eAttacker thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback();
	}

	// Do debug print if it's enabled
	if(drm_getCvarInt("g_debugDamage"))
	{
		println("client:" + self getEntityNumber() + " health:" + self.health +
			" damage:" + iDamage + " hitLoc:" + sHitLoc);
	}

	if(self.sessionstate != "dead")
	{
		lpselfnum = self getEntityNumber();
		lpselfguid = self getGuid();
		lpselfname = self.name;
		lpselfteam = self.pers["team"];
		lpattackerteam = "";

		if(isPlayer(eAttacker))
		{
			lpattacknum = eAttacker getEntityNumber();
			lpattackguid = eAttacker getGuid();
			lpattackname = eAttacker.name;
			lpattackerteam = eAttacker.pers["team"];
		}
		else
		{
			lpattacknum = -1;
			lpattackguid = "";
			lpattackname = "";
			lpattackerteam = "world";
		}

		if(isdefined(friendly))
		{
			lpattacknum = lpselfnum;
			lpattackname = lpselfname;
			lpattackguid = lpselfguid;
		}

		logPrint("D;" + lpselfguid + ";" + lpselfnum + ";" + lpselfteam + ";" + lpselfname + ";" + lpattackguid + ";" + lpattacknum + ";" + lpattackerteam + ";" + lpattackname + ";" + sWeapon + ";" + iDamage + ";" + sMeansOfDeath + ";" + sHitLoc + "\n");
	}
}

Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
{
	self endon("spawned");
	self notify("killed_player");

	if(self.sessionteam == "spectator")
		return;

	self thread extreme\_ex_main::explayerkilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc);

	// If the player was killed by a head shot, let players know it was a head shot kill
	if(sHitLoc == "head" && sMeansOfDeath != "MOD_MELEE")
		sMeansOfDeath = "MOD_HEAD_SHOT";

	// send out an obituary message to all clients about the kill
	self thread extreme\_ex_obituary::main(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc);

	self maps\mp\gametypes\_weapons::dropWeapon();
	self maps\mp\gametypes\_weapons::dropOffhand();
	
	self dropFlag();

	self.sessionstate = "dead";
	if(!level.ex_ranksystem) self.statusicon = "hud_status_dead";

	if(!isdefined(self.switching_teams))
	{
		self.pers["deaths"]++;
		self.deaths = self.pers["deaths"];
	}

	lpselfnum = self getEntityNumber();
	lpselfguid = self getGuid();
	lpselfname = self.name;
	lpselfteam = self.pers["team"];
	lpattackerteam = "";

	attackerNum = -1;

	if(isPlayer(attacker))
	{
		if(attacker == self) // killed himself
		{
			doKillcam = false;

			// switching teams
			if(isdefined(self.switching_teams))
			{
				if((self.leaving_team == "allies" && self.joining_team == "axis") || (self.leaving_team == "axis" && self.joining_team == "allies"))
				{
					players = maps\mp\gametypes\_teams::CountPlayers();
					players[self.leaving_team]--;
					players[self.joining_team]++;

					if((players[self.joining_team] - players[self.leaving_team]) > 1)
					{
						attacker.pers["score"]--;
						attacker.score = attacker.pers["score"];
					}
					
				}
			}

			if(isdefined(attacker.friendlydamage))
				attacker iprintln(&"MP_FRIENDLY_FIRE_WILL_NOT");
		}
		else
		{
			attackerNum = attacker getEntityNumber();
			doKillcam = true;
			
			// Only handle points if game has not ended
			if(!level.roundended)
			{
				// Check if extra points should be given for bash or headshot
				reward_points = 0;
				if(isDefined(sMeansOfDeath))
				{
					if(sMeansOfDeath == "MOD_MELEE") reward_points = level.ex_reward_melee;
						else if(sMeansOfDeath == "MOD_HEAD_SHOT") reward_points = level.ex_reward_headshot;
				}

				points = 1 + reward_points;

				if(self.pers["team"] == attacker.pers["team"]) // killed by a friendly
				{
					if(level.ex_reward_teamkill)
					{
						attacker.pers["score"] -= points;
						attacker.score = attacker.pers["score"];
					}
					else
					{
						attacker.pers["score"]--;
						attacker.score = attacker.pers["score"];
					}
				}
				else
				{
					reward_points = 0;
					// if the dead person was close to the flag then give the killer a defense bonus
					if(self isnearFlag() )
					{
						reward_points++;
						lpattacknum = attacker getEntityNumber();
						lpattackguid = attacker getGuid();
						logPrint("A;" + lpattackguid + ";" + lpattacknum + ";" + attacker.pers["team"] + ";" + attacker.name + ";" + "rbctf_defended" + "\n");
					}

					// if the dead person was close to the flag carrier then give the killer an assist bonus
					if(self isnearCarrier(attacker) )
					{
						reward_points++;
						lpattacknum = attacker getEntityNumber();
						lpattackguid = attacker getGuid();
						logPrint("A;" + lpattackguid + ";" + lpattacknum + ";" + attacker.pers["team"] + ";" + attacker.name + ";" + "rbctf_assist" + "\n");
					}
				}

				points += reward_points;
				attacker.pers["score"] += points;
				attacker.pers["bonus"] += reward_points;
				attacker.score = attacker.pers["score"];
				// added for arcade style HUD points
				attacker notify("update_playerscore_hud");
			}
		}

		lpattacknum = attacker getEntityNumber();
		lpattackguid = attacker getGuid();
		lpattackname = attacker.name;
		lpattackerteam = attacker.pers["team"];

		self notify("killed_player", attacker);
	}
	else // If you weren't killed by a player, you were in the wrong place at the wrong time
	{
		doKillcam = false;

		self.pers["score"]--;
		self.score = self.pers["score"];

		lpattacknum = -1;
		lpattackguid = "";
		lpattackname = "";
		lpattackerteam = "world";

		self notify("killed_player", self);
	}

	logPrint("K;" + lpselfguid + ";" + lpselfnum + ";" + lpselfteam + ";" + lpselfname + ";" + lpattackguid + ";" + lpattacknum + ";" + lpattackerteam + ";" + lpattackname + ";" + sWeapon + ";" + iDamage + ";" + sMeansOfDeath + ";" + sHitLoc + "\n");

	self.pers["weapon1"] = undefined;
	self.pers["weapon2"] = undefined;
	self.pers["spawnweapon"] = undefined;

	if(!isdefined(self.switching_teams))
	{
		body = self cloneplayer(deathAnimDuration);
		thread maps\mp\gametypes\_deathicons::addDeathicon(body, self.clientid, self.pers["team"], 5);
	}

	if(isDefined(self.switching_teams))
		self.ex_team_changed = true;

	self.switching_teams = undefined;
	self.joining_team = undefined;
	self.leaving_team = undefined;

	if(!level.exist[self.pers["team"]]) // If the last player on a team was just killed, don't do killcam
	{
		doKillcam = false;
		self.skip_setspectatepermissions = true;
	}

	delay = 2;	// Delay the player becoming a spectator till after he's done dying
	wait delay;	// ?? Also required for Callback_PlayerKilled to complete before killcam can execute
	
	self thread respawn_timer(delay);
		
	if(doKillcam && level.killcam && !level.roundended)
		self maps\mp\gametypes\_killcam::killcam(attackerNum, delay, psOffsetTime);

	self thread respawn();
}

spawnPlayer()
{
	self endon("disconnect");
	self notify("spawned");
	self notify("end_respawn");

	resettimeout();

	// Stop shellshock and rumble
	self stopShellshock();
	self stoprumble("damage_heavy");

	if(level.ex_wepo_secondary && self.pers["first_time"])
	{
		thread extreme\_ex_clientcontrol::menuSecWeapon();
		self waittill("sec_continue");
		self.pers["first_time"] = false;
	}

	self.sessionteam = self.pers["team"];
	self.sessionstate = "playing";
	self.spectatorclient = -1;
	self.archivetime = 0;
	self.psoffsettime = 0;
	self.statusicon = "";
	self.maxhealth = 100;
	self.health = self.maxhealth;
	self.friendlydamage = undefined;
	self.dead_origin = undefined;
	self.dead_angles = undefined;
	
	spawnpoint = undefined;
	spawnpointname = "";

	self extreme\_ex_main::exprespawn();
	
	if(self.pers["team"] == "allies")
	{
		spawnpointname = "mp_ctf_spawn_allied";
	}
	else
	{
		spawnpointname = "mp_ctf_spawn_axis";
	}

	spawnpoints = getentarray(spawnpointname, "classname");
	spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(spawnpoints);

	if(isdefined(spawnpoint))
		self spawn(spawnpoint.origin, spawnpoint.angles);
	else
		maps\mp\_utility::error("NO " + spawnpointname + " SPAWNPOINTS IN MAP");

	if(!isdefined(self.ex_team_changed) && isdefined(game["matchstarted"])) level updateTeamStatus();

	if(!isdefined(self.pers["score"]))
		self.pers["score"] = 0;
	self.score = self.pers["score"];

	if(!isdefined(self.pers["deaths"]))
		self.pers["deaths"] = 0;
	self.deaths = self.pers["deaths"];

	if(!isdefined(self.pers["savedmodel"]))
		maps\mp\gametypes\_teams::model();
	else
		maps\mp\_utility::loadModel(self.pers["savedmodel"]);
		
	if(level.ex_wepo_secondary) 
	{
		self extreme\_ex_weapons::loadout();
	
		self.usedweapons = false;
	}
	
	if(!level.ex_wepo_secondary)
	{
		if(isdefined(self.pers["weapon1"]) && isdefined(self.pers["weapon2"]))
		{
			self.pers["spawnweapon"] = self.pers["weapon1"];
			
			self setWeaponSlotWeapon("primary", self.pers["weapon1"]);
			self setWeaponSlotAmmo("primary", 999);
			self setWeaponSlotClipAmmo("primary", 999);
	
			self setWeaponSlotWeapon("primaryb", self.pers["weapon2"]);
			self setWeaponSlotAmmo("primaryb", 999);
			self setWeaponSlotClipAmmo("primaryb", 999);
	
			self setSpawnWeapon(self.pers["spawnweapon"]);
		}
		else
		{
			self setWeaponSlotWeapon("primary", self.pers["weapon"]);
			self setWeaponSlotAmmo("primary", 999);
			self setWeaponSlotClipAmmo("primary", 999);
	
			self setSpawnWeapon(self.pers["weapon"]);
		}
		
		self extreme\_ex_weapons_norm::loadout();
		
		self.usedweapons = false;
	}

	if(!level.splitscreen)
	{
		if(level.scorelimit > 0)
			self setClientCvar("cg_objectiveText", &"RBCTF_RBCTF_OBJ_TEXT");
		else
			self setClientCvar("cg_objectiveText", &"RBCTF_RBCTF_OBJ_TEXT_NOSCORE");
	}
	else
		self setClientCvar("cg_objectiveText", &"MP_CAPTURE_THE_ENEMY_FLAG");

	self thread updateTimer();

	self thread flag_count_hud();
	waittillframeend;
	self extreme\_ex_main::expostspawn();
	self notify("spawned_player");
}

respawn()
{
	self endon("disconnect");
	self endon("end_respawn");

	if(!isDefined(self.pers["weapon"]))
		return;

	self.sessionteam = self.pers["team"];
	self.sessionstate = "spectator";

	if(isdefined(self.dead_origin) && isdefined(self.dead_angles))
	{
		origin = self.dead_origin + (0, 0, 16);
		angles = self.dead_angles;
	}
	else
	{
		origin = self.origin + (0, 0, 16);
		angles = self.angles;
	}

	self spawn(origin, angles);

	while(isdefined(self.WaitingToSpawn))
		wait .05;

	self.NOt_allowed_tospawn = undefined;
	
	for(;;)
	{	
		if(!isdefined(self.deathcount))
			self.deathcount = 0;
		
		self.deathcount++;
		
		if(self.deathcount <= level.spawnlimit)
		{
			if(drm_getCvarInt("scr_forcerespawn") <= 0)
			{
				self thread waitRespawnButton();
				self waittill("respawn");
			}
			
			self thread spawnPlayer();
		}
		else
		{
			level updateTeamStatus();
			self.NOt_allowed_tospawn = true;
			self thread extreme\_ex_spawn::spawnspectator();
		}
	
		wait 0.05;
	}
}

waitRespawnButton()
{
	self endon("disconnect");
	self endon("end_respawn");
	self endon("respawn");

	wait 0; // Required or the "respawn" notify could happen before it's waittill has begun

	self.respawntext = newClientHudElem(self);
	self.respawntext.horzAlign = "center_safearea";
	self.respawntext.vertAlign = "center_safearea";
	self.respawntext.alignX = "center";
	self.respawntext.alignY = "middle";
	self.respawntext.x = 0;
	self.respawntext.y = -50;
	self.respawntext.archived = false;
	self.respawntext.font = "default";
	self.respawntext.fontscale = 2;
	self.respawntext setText(&"PLATFORM_PRESS_TO_SPAWN");

	thread removeRespawnText();
	thread waitRemoveRespawnText("end_respawn");
	thread waitRemoveRespawnText("respawn");

	while(self useButtonPressed() != true)
		wait .05;

	self notify("remove_respawntext");

	self notify("respawn");
}

removeRespawnText()
{
	self waittill("remove_respawntext");

	if(isDefined(self.respawntext))
		self.respawntext destroy();
}

waitRemoveRespawnText(message)
{
	self endon("remove_respawntext");

	self waittill(message);
	self notify("remove_respawntext");
}

startGame()
{
	level.starttime = getTime();
	if(level.show_total_time) thread jclock();
	thread startRound();
}

startRound()
{
	level endon("round_ended");
	
	level.allies_cap_count = 0;
	level.axis_cap_count = 0;
	
	font = 2;

	level.clock = newHudElem();
	level.clock.horzAlign = "left";
	level.clock.vertAlign = "top";
	if(level.ex_logopic)
	{
		level.clock.x = 15;
		level.clock.y = 80;
		level.clock.fontscale = 1.3;
	}
	else
	{
		level.clock.x = 8;
		level.clock.y = 2;
		level.clock.fontscale = font;
	}
	level.clock.font = "default";
	level.clock setTimer(level.roundlength * 60);

	if(game["matchstarted"])
	{
		level.clock.color = (.98, .827, .58);

		if((level.roundlength * 60) > level.graceperiod)
		{
			wait level.graceperiod;

			level notify("round_started");
			level.roundstarted = true;
			level.clock.color = (1, 1, 1);

			// Players on a team but without a weapon show as dead since they can not get in this round
			players = getentarray("player", "classname");
			for(i = 0; i < players.size; i++)
			{
				player = players[i];

				if(player.sessionteam != "spectator" && !isdefined(player.pers["weapon"]) && !level.ex_ranksystem)
					player.statusicon = "hud_status_dead";
			}

			wait((level.roundlength * 60) - level.graceperiod);
		}
		else
			wait(level.roundlength * 60);
	}
	else
	{
		level.clock.color = (1, 1, 1);
		wait(level.roundlength * 60);
	}

	if(level.roundended)
		return;

	iprintln(&"MP_TIMEHASEXPIRED");

	if(level.allies_cap_count == level.axis_cap_count)
	{
		iprintlnBold(&"MP_ROUNDDRAW");
		level thread endRound("draw");
	}
	else if(level.allies_cap_count > level.axis_cap_count )
	{
		iprintlnBold(&"MP_ALLIEDMISSIONACCOMPLISHED");
		level thread endRound("allies");
	}
	else
	{
		iprintlnBold(&"MP_AXISMISSIONACCOMPLISHED");
		level thread endRound("axis");
	}
	
}

checkMatchStart()
{
	oldvalue["teams"] = level.exist["teams"];
	level.exist["teams"] = false;

	// If teams currently exist
	if(level.exist["allies"] && level.exist["axis"])
		level.exist["teams"] = true;

	// If teams previously did not exist and now they do
	if(!oldvalue["teams"] && level.exist["teams"])
	{
		if(!game["matchstarted"])
		{
			if(level.ex_gtsdelay && !isDefined(game["gtsdone"])) return;
			
			iprintlnBold(&"MP_MATCHSTARTING");
			level notify("kill_endround");
			level.roundended = false;
			level thread endRound("reset");
		}
		else if(!level.ex_swapteams)
		{
			iprintln(&"MP_MATCHRESUMING");

			level notify("kill_endround");
			level.roundended = false;
			level thread endRound("draw");
		}

		return;
	}
}

resetScores()
{
	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{
		player = players[i];
		player.pers["score"] = 0;
		player.pers["deaths"] = 0;
	}

	game["alliedscore"] = 0;
	setTeamScore("allies", game["alliedscore"]);
	game["axisscore"] = 0;
	setTeamScore("axis", game["axisscore"]);
}

endRound(roundwinner)
{
	level endon("intermission");
	level endon("kill_endround");

	if(level.roundended || level.ex_gtsdelay && !isDefined(game["gtsdone"])) return;
	level.roundended = true;

	level notify("round_ended");
	level notify("update_teamscore_hud");
	
	level thread announceWinner(roundwinner, 2);

	winners = "";
	losers = "";
	
	default_points = level.points_for_flag;
	
	game["alliedscore"] = getTeamScore("allies");
	game["axisscore"] = getTeamScore("axis");

	if(roundwinner == "allies")
	{	
		if(isdefined(level.axis_eliminated)) game["alliedscore"]+= 5;
		
		points = level.roundwin_points;
		GivePointsToTeam( "allies", points);
		
		setTeamScore("allies", game["alliedscore"]);

		level createLevelHudElement("flag_winner", 320,110, "center","middle","fullscreen","fullscreen",false,"gfx/custom/flagge_" + game["allies"] + ".tga",128,128,1,0.9,1,1,1);

		players = getentarray("player", "classname");
		for(i = 0; i < players.size; i++)
		{
			lpGuid = players[i] getGuid();
			if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
				winners = (winners + ";" + lpGuid + ";" + players[i].name);
			else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
				losers = (losers + ";" + lpGuid + ";" + players[i].name);
		}
		logPrint("W;allies" + winners + "\n");
		logPrint("L;axis" + losers + "\n");
	}
	else if(roundwinner == "axis")
	{	
		if(isdefined(level.allied_eliminated)) game["axisscore"]+= 5;
		
		points = level.roundwin_points;
		GivePointsToTeam( "axis", points);
		
		setTeamScore("axis", game["axisscore"]);
		
		level createLevelHudElement("flag_winner", 320,110, "center","middle","fullscreen","fullscreen",false,"gfx/custom/flagge_" + game["axis"] + ".tga",128,128,1,0.9,1,1,1);

		players = getentarray("player", "classname");
		for(i = 0; i < players.size; i++)
		{
			lpGuid = players[i] getGuid();
			if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
				winners = (winners + ";" + lpGuid + ";" + players[i].name);
			else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
				losers = (losers + ";" + lpGuid + ";" + players[i].name);
		}
		logPrint("W;axis" + winners + "\n");
		logPrint("L;allies" + losers + "\n");
	}
	else if(roundwinner == "draw")
	{
		level createLevelHudElement("flag_draw", 320,110, "center","middle","fullscreen","fullscreen",false,game["draw_flag"],128,70,1,0.9,1,1,1);
	}

	wait 6;
	if(roundwinner == "allies" || roundwinner == "axis")
		level thread deleteLevelHudElementByName("flag_winner");
	else
		level thread deleteLevelHudElementByName("flag_draw");
	wait 1;

	if(game["matchstarted"])
	{
		checkScoreLimit();
		game["roundsplayed"]++;
		game["roundnumber"]++;
		checkRoundLimit();
	}

	if(!game["matchstarted"] && (roundwinner == "reset" || roundwinner == "gtsreset"))
	{
		game["matchstarted"] = true;
		thread resetScores();
		game["roundnumber"]++;
		game["roundsplayed"] = 0;
	}

	game["timepassed"] = game["timepassed"] + ((getTime() - level.starttime) / 1000) / 60.0;

	checkTimeLimit();

	if(level.mapended)
		return;
	level.mapended = true;

	// for all living players store their weapons
	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{
		player = players[i];

		// save the scores for this round
	//	if(isPlayer(player)) player.pers["score"] = player.score;

		if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
		{
			weapon1 = player getWeaponSlotWeapon("primary");
			weapon2 = player getWeaponSlotWeapon("primaryb");
			current = player getCurrentWeapon();

			if(!level.ex_wepo_secondary)
			{
				// A new weapon has been selected
				if(isDefined(player.oldweapon))
				{
					player.pers["weapon1"] = player.pers["weapon"];
					player.pers["weapon2"] = "none";
					player.pers["spawnweapon"] = player.pers["weapon1"];
				} // No new weapons selected
				else
				{
					if(!maps\mp\gametypes\_weapons::isMainWeapon(weapon1) && !maps\mp\gametypes\_weapons::isMainWeapon(weapon2))
					{
						player.pers["weapon1"] = player.pers["weapon"];
						player.pers["weapon2"] = "none";
					}
					else if(maps\mp\gametypes\_weapons::isMainWeapon(weapon1) && !maps\mp\gametypes\_weapons::isMainWeapon(weapon2))
					{
						player.pers["weapon1"] = weapon1;
						player.pers["weapon2"] = "none";
					}
					else if(!maps\mp\gametypes\_weapons::isMainWeapon(weapon1) && maps\mp\gametypes\_weapons::isMainWeapon(weapon2))
					{
						player.pers["weapon1"] = weapon2;
						player.pers["weapon2"] = "none";
					}
					else
					{
						assert(maps\mp\gametypes\_weapons::isMainWeapon(weapon1) && maps\mp\gametypes\_weapons::isMainWeapon(weapon2));
	
						if(current == weapon2)
						{
							player.pers["weapon1"] = weapon2;
							player.pers["weapon2"] = weapon1;
						}
						else
						{
							player.pers["weapon1"] = weapon1;
							player.pers["weapon2"] = weapon2;
						}
					}
	
					player.pers["spawnweapon"] = player.pers["weapon1"];
				}
			}
			else
			{
				if(player getWeaponSlotWeapon("primary") == "sprint_mp")
				{
					player.ex_sprinting = false;
					
					// restore the primary they had when sprint began
					if(player.weapon["oldprimary"].name != "none" || player.weapon["oldprimary"].name != "ignore")
					{
						player setWeaponSlotWeapon("primary", player.weapon["oldprimary"].name);
						player setWeaponSlotClipAmmo("primary", player.weapon["oldprimary"].clip);
						player setWeaponSlotAmmo("primary", player.weapon["oldprimary"].reserve);
					}
	
					// restore the secondary they had when sprint began
					if(player.weapon["oldprimaryb"].name != "none" || player.weapon["oldprimaryb"].name != "ignore")
					{
						player setWeaponSlotWeapon("primaryb", player.weapon["oldprimaryb"].name);
						player setWeaponSlotClipAmmo("primaryb", player.weapon["oldprimaryb"].clip);
						player setWeaponSlotAmmo("primaryb", player.weapon["oldprimaryb"].reserve);
					}
				}

				weapon1 = player getWeaponSlotWeapon("primary");
				weapon2 = player getWeaponSlotWeapon("primaryb");

				if(weapon1 == "ignore") weapon1 = "none";
				if(weapon2 == "ignore") weapon2 = "none";

				if(!isDefined(game[player.name]["weapon1"])) game[player.name]["weapon1"] = weapon1;
				if(!isDefined(game[player.name]["weapon2"])) game[player.name]["weapon2"] = weapon2;
			}
		}
		
		if(roundwinner == "gtsreset") player extreme\_ex_main::resetPlayerVariables();
	}

	level notify("restarting");
	if(level.ex_swapteams) extreme\_ex_main::swapTeams();

	map_restart(true);
}

endMap()
{
//////////////////////////////////////////////////////////////////////////
//Damole EndMapVote
	maps\mp\gametypes\_mapvote::Initialize();
//DaMole
//////////////////////////////////////////////////////////////////////////
	if(isDefined(level.bombmodel))
		level.bombmodel stopLoopSound();

	if(game["alliedscore"] == game["axisscore"])
	{
		level.ex_resultsound = "MP_announcer_round_draw";
		winningteam = "tie";
		losingteam = "tie";
		text = &"MP_THE_GAME_IS_A_TIE";
		
		level createLevelHudElement("flag_draw", 320,110, "center","middle","fullscreen","fullscreen",false,game["draw_flag"],128,70,1,0.9,1,1,1);
	}
	else if(game["alliedscore"] > game["axisscore"])
	{
		level.ex_resultsound = "MP_announcer_allies_win";
		winningteam = "allies";
		losingteam = "axis";
		text = &"MP_ALLIES_WIN";
		
		level createLevelHudElement("flag_winner", 320,110, "center","middle","fullscreen","fullscreen",false,"gfx/custom/flagge_" + game["allies"] + ".tga",128,128,1,0.9,1,1,1);
	}
	else
	{
		level.ex_resultsound = "MP_announcer_axis_win";
		winningteam = "axis";
		losingteam = "allies";
		text = &"MP_AXIS_WIN";
		
		level createLevelHudElement("flag_winner", 320,110, "center","middle","fullscreen","fullscreen",false,"gfx/custom/flagge_german.tga",128,128,1,0.9,1,1,1);
	}

	wait 4;
	if(winningteam == "allies" || winningteam == "axis")
		level thread deleteLevelHudElementByName("flag_winner");
	else
		level thread deleteLevelHudElementByName("flag_draw");	
	wait 2;
	
	extreme\_ex_main::exendmap();

	game["state"] = "intermission";
	level notify("intermission");

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

		player closeMenu();
		player closeInGameMenu();
		player setClientCvar("cg_objectiveText", text);

		player extreme\_ex_spawn::spawnIntermission();
		
		if(level.ex_ranksystem)
		{
			statusicon = player thread extreme\_ex_ranksystem::get_Current_Rank();
				
			player.statusicon = statusicon;
		}
	}

	// wait for end music to finish
	if(isDefined(level.ex_endmusic) && level.ex_endmusic == 1)
		level waittill("end_music_over");
	else wait 10;

	exitLevel(false);
}

checkTimeLimit()
{
	if(level.timelimit <= 0)
		return;

	if(game["timepassed"] < level.timelimit)
		return;

	if(level.mapended)
		return;
	level.mapended = true;

	if(!level.splitscreen)
		iprintln(&"MP_TIME_LIMIT_REACHED");

	level thread endMap();
}

checkScoreLimit()
{
	if(level.scorelimit <= 0)
		return;

	if(game["alliedscore"] < level.scorelimit && game["axisscore"] < level.scorelimit)
		return;

	if(level.mapended)
		return;
	level.mapended = true;

	if(!level.splitscreen)
		iprintln(&"MP_SCORE_LIMIT_REACHED");

	level thread endMap();
}

checkRoundLimit()
{
	if(level.roundlimit <= 0)
		return;

	if(game["roundsplayed"] < level.roundlimit)
		return;

	if(level.mapended)
		return;
	level.mapended = true;

	if(!level.splitscreen)
		iprintln(&"MP_ROUND_LIMIT_REACHED");

	level thread endMap();
}

updateGametypeCvars()
{
	for(;;)
	{
		timelimit = level.timelimit;
		if(level.timelimit != timelimit)
		{
			if(timelimit > 1440)
			{
				timelimit = 1440;
				setCvar("scr_rbctf_timelimit", "1440");
			}

			level.timelimit = timelimit;
			setCvar("ui_rbctf_timelimit", level.timelimit);
		}

		scorelimit = level.scorelimit;
		if(level.scorelimit != scorelimit)
		{
			level.scorelimit = scorelimit;
			setCvar("ui_rbctf_scorelimit", level.scorelimit);
			level notify("update_allhud_score");

			if(game["matchstarted"])
				checkScoreLimit();
		}

		roundlimit = level.roundlimit;
		if(level.roundlimit != roundlimit)
		{
			level.roundlimit = roundlimit;
			setCvar("ui_rbctf_roundlimit", level.roundlimit);

			if(game["matchstarted"])
				checkRoundLimit();
		}

		wait 1;
	}
}

updateTeamStatus()
{
	wait 0;	// Required for Callback_PlayerDisconnect to complete before updateTeamStatus can execute

	resettimeout();

	oldvalue["allies"] = level.exist["allies"];
	oldvalue["axis"] = level.exist["axis"];
	level.exist["allies"] = 0;
	level.exist["axis"] = 0;

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

		if(isdefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
			level.exist[player.pers["team"]]++;
	}

	if(level.exist["allies"])
		level.didexist["allies"] = true;
	if(level.exist["axis"])
		level.didexist["axis"] = true;

	if(level.roundended)
		return;

	// if both allies and axis were alive and now they are both dead in the same instance
	if(oldvalue["allies"] && !level.exist["allies"] && oldvalue["axis"] && !level.exist["axis"])
	{
		iprintln(&"MP_ROUNDDRAW");
		level thread endRound("draw");
		return;
	}

	// if allies were alive and now they are not
	if(oldvalue["allies"] && !level.exist["allies"])
	{
		if(!isdefined(self.ex_team_changed)) level.allied_eliminated = true;
		iprintln(&"MP_ALLIESHAVEBEENELIMINATED");
		level thread playSoundOnPlayers("mp_announcer_allieselim");
		level thread endRound("axis");
		return;
	}

	// if axis were alive and now they are not
	if(oldvalue["axis"] && !level.exist["axis"])
	{
		if(!isdefined(self.ex_team_changed)) level.axis_eliminated = true;
		iprintln(&"MP_AXISHAVEBEENELIMINATED");
		level thread playSoundOnPlayers("mp_announcer_axiselim");
		level thread endRound("allies");
		
		return;
	}
}

printJoinedTeam(team)
{
	if(!level.splitscreen)
	{
		if(team == "allies")
			iprintlnFIXED(&"MP_JOINED_ALLIES", self);
		else if(team == "axis")
			iprintlnFIXED(&"MP_JOINED_AXIS", self);
	}
}

initFlags()
{
	maperrors = [];

	allied_flags = getentarray("allied_flag", "targetname");
	if(allied_flags.size < 1)
		maperrors[maperrors.size] = "^1No entities found with \"targetname\" \"allied_flag\"";
	else if(allied_flags.size > 1)
		maperrors[maperrors.size] = "^1More than 1 entity found with \"targetname\" \"allied_flag\"";

	axis_flags = getentarray("axis_flag", "targetname");
	if(axis_flags.size < 1)
		maperrors[maperrors.size] = "^1No entities found with \"targetname\" \"axis_flag\"";
	else if(axis_flags.size > 1)
		maperrors[maperrors.size] = "^1More than 1 entity found with \"targetname\" \"axis_flag\"";

	if(maperrors.size)
	{
		println("^1------------ Map Errors ------------");
		for(i = 0; i < maperrors.size; i++)
			println(maperrors[i]);
		println("^1------------------------------------");

		return;
	}

	allied_flag = getent("allied_flag", "targetname");
	allied_flag.home_origin = allied_flag.origin;
	allied_flag.home_angles = allied_flag.angles;
	allied_flag.flagmodel = spawn("script_model", allied_flag.home_origin);
	allied_flag.flagmodel.angles = allied_flag.home_angles;
	allied_flag.flagmodel setmodel("xmodel/prop_flag_" + game["allies"]);
	allied_flag.basemodel = spawn("script_model", allied_flag.home_origin);
	allied_flag.basemodel.angles = allied_flag.home_angles;
	allied_flag.basemodel setmodel("xmodel/prop_flag_base");
	allied_flag.team = "allies";
	allied_flag.atbase = true;
	allied_flag.objective = 0;
	allied_flag.compassflag = level.compassflag_allies;
	allied_flag.objpointflag = level.objpointflag_allies;
	allied_flag.objpointflagmissing = level.objpointflagmissing_allies;
	allied_flag thread flag();

	axis_flag = getent("axis_flag", "targetname");
	axis_flag.home_origin = axis_flag.origin;
	axis_flag.home_angles = axis_flag.angles;
	axis_flag.flagmodel = spawn("script_model", axis_flag.home_origin);
	axis_flag.flagmodel.angles = axis_flag.home_angles;
	axis_flag.flagmodel setmodel("xmodel/prop_flag_" + game["axis"]);
	axis_flag.basemodel = spawn("script_model", axis_flag.home_origin);
	axis_flag.basemodel.angles = axis_flag.home_angles;
	axis_flag.basemodel setmodel("xmodel/prop_flag_base");
	axis_flag.team = "axis";
	axis_flag.atbase = true;
	axis_flag.objective = 1;
	axis_flag.compassflag = level.compassflag_axis;
	axis_flag.objpointflag = level.objpointflag_axis;
	axis_flag.objpointflagmissing = level.objpointflagmissing_axis;
	axis_flag thread flag();
}

flag()
{
	objective_add(self.objective, "current", self.origin, self.compassflag);
	self createFlagWaypoint();
	
	self.status = "home";
	
	for(;;)
	{
		self waittill("trigger", other);

		if(isPlayer(other) && isAlive(other) && (other.pers["team"] != "spectator") && level.roundstarted && !level.roundended)
		{
			if(other.pers["team"] == self.team) // Touched by team
			{
				if(self.atbase)
				{
					if(isdefined(other.flag)) // Captured flag
					{

						friendlyAlias = "ctf_touchcapture";
						enemyAlias = "ctf_enemy_touchcapture";

						if(self.team == "axis")
						{
							thread axis_flag_count();
							enemy = "allies";
							level thread playSoundOnPlayers("GE_mp_flagcap");
							iprintln(other.name + "^7 captured the ^8 allied ^7 flag!");
						}
						else
						{
							thread allies_flag_count();
							enemy = "axis";
							level thread playSoundOnPlayers("mp_announcer_axisflagcap");
							iprintln(other.name + "^7 captured the ^9 axis ^7 flag!");							
						}						

						thread playSoundOnPlayers(friendlyAlias, self.team);
						if(!level.splitscreen)
							thread playSoundOnPlayers(enemyAlias, enemy);

						thread printOnTeam(&"MP_ENEMY_FLAG_CAPTURED", self.team);
						thread printOnTeam(&"MP_YOUR_FLAG_WAS_CAPTURED", enemy);

						other.flag returnFlag();
						other detachFlag(other.flag);
						other.flag = undefined;
						other.statusicon = "";
						
						other.pers["score"] += level.cap_points;
						other.score = other.pers["score"];
						
						if(level.ex_ranksystem && !level.ex_score) other.pers["special"]+= level.ex_ctfpoints_playercf;
						
						teamscore = getTeamScore(other.pers["team"]);
						teamscore += level.points_for_flag;
						setTeamScore(other.pers["team"], teamscore);
						level notify("update_teamscore_hud");

						checkScoreLimit();
					}
				}
				else // Returned flag
				{
					
					if(self.team == "axis")
					{
						level thread playSoundOnPlayers("mp_announcer_axisflagret");
						iprintln(other.name + "^7 returned the ^9 axis ^7 flag!");
					}
					else
					{
						level thread playSoundOnPlayers("mp_announcer_alliedflagret");
						iprintln(other.name + "^7 returned the ^8 allied ^7 flag!");
					}
					
					thread playSoundOnPlayers("ctf_touchown", self.team);
					thread printOnTeam(&"MP_YOUR_FLAG_WAS_RETURNED", self.team);

					self returnFlag();
					
					other.pers["score"] += level.return_points;
					other.score = other.pers["score"];
					if(level.ex_ranksystem && !level.ex_score) other.pers["special"]+= level.ex_ctfpoints_playerrf;
					level notify("update_teamscore_hud");

				}
			}
			else if(other.pers["team"] != self.team) // Touched by enemy
			{
				println("PICKED UP THE FLAG!");

				friendlyAlias = "ctf_touchenemy";
				enemyAlias = "ctf_enemy_touchenemy";

				if(self.team == "axis")
				{
					enemy = "allies";
					other thread playSoundOnPlayers(game["flag_taken"], "allies");
					iprintln(other.name + "^7 stole the ^9 axis ^7 flag!");
				}
				else 
				{
					enemy = "axis";
					other thread playSoundOnPlayers("GE_mp_flagtaken");
					iprintln(other.name + "^7 stole the ^8 allied ^7 flag!");
				}

				
				thread playSoundOnPlayers(enemyAlias, enemy);
				thread printOnTeam(&"MP_YOUR_FLAG_WAS_TAKEN", self.team);
				thread printOnTeam(&"MP_ENEMY_FLAG_TAKEN", enemy);

				other pickupFlag(self); // Stolen flag
			}
		}
		wait 0.05;
	}
}

pickupFlag(flag)
{
	flag notify("end_autoreturn");

	flag.origin = flag.origin + (0, 0, -10000);
	flag.flagmodel hide();
	self.flag = flag;

	flag.atbase=false;

	if(self.pers["team"] == "allies" && !level.ex_ranksystem)
		self.statusicon = level.hudflag_axis;
	else if(self.pers["team"] == "axis" && !level.ex_ranksystem)
		self.statusicon = level.hudflag_allies;

	self.dont_auto_balance = true;

	flag deleteFlagWaypoint();
	flag createFlagMissingWaypoint();

	objective_onEntity(self.flag.objective, self);
	objective_team(self.flag.objective, self.pers["team"]);

	self attachFlag();
}

dropFlag()
{
	if(isdefined(self.flag))
	{
		start = self.origin + (0, 0, 10);
		end = start + (0, 0, -2000);
		trace = bulletTrace(start, end, false, undefined);

		self.flag.origin = trace["position"];
		self.flag.flagmodel.origin = self.flag.origin;
		self.flag.flagmodel show();
		self.flag.atbase = false;
		self.statusicon = "";

		objective_position(self.flag.objective, self.flag.origin);
		objective_team(self.flag.objective, "none");

		self.flag createFlagWaypoint();
		self.flag thread autoReturn();
		self detachFlag(self.flag);

		//check if it's in a flag_returner
		for(i = 0; i < level.flag_returners.size; i++)
		{
			if(self.flag.flagmodel istouching(level.flag_returners[i]))
			{
				self.flag returnFlag();
				break;
			}
		}

		if(self.flag.team == "axis")
		{
			level thread playSoundOnPlayers("mp_announcer_axisflagdrop");
			iprintln("The ^9 axis ^7 flag has been dropped!");
		}
		else
		{
			level thread playSoundOnPlayers("mp_announcer_alliedflagdrop");	
			iprintln("The ^8 allied ^7 flag has been dropped!");
		}
		
		self.flag = undefined;
		self.dont_auto_balance = undefined;
	}
}

returnFlag()
{
	self notify("end_autoreturn");
	
	self.status = "home";

 	self.origin = self.home_origin;
 	self.flagmodel.origin = self.home_origin;
 	self.flagmodel.angles = self.home_angles;
	self.flagmodel show();
	self.atbase = true;

	objective_position(self.objective, self.origin);
	objective_team(self.objective, "none");

	self createFlagWaypoint();
	self deleteFlagMissingWaypoint();
}

autoReturn()
{
	self endon("end_autoreturn");

	wait level.returndelay;
	level.announce_return = true;
	self thread announce();
}

announce()
{
	self notify("end_autoreturn");

	if(level.announce_return)
	{
		if(self.team == "axis")
		{
			level thread playSoundOnPlayers("mp_announcer_axisflagret");
			iprintln("The ^9 axis ^7 flag has been returned to base!");
		}	
		else
		{
			level thread playSoundOnPlayers("mp_announcer_alliedflagret");
			iprintln("The ^8 allied ^7 flag has been returned to base!");
		}
	}
	
	self thread returnFlag();
	self notify("flag returned");
}

attachFlag()
{
	if(isdefined(self.flagAttached))
		return;

	if(self.pers["team"] == "allies")
		flagModel = "xmodel/prop_flag_" + game["axis"] + "_carry";
	else
		flagModel = "xmodel/prop_flag_" + game["allies"] + "_carry";
	
	self attach(flagModel, "J_Spine4", true);
	self.flagAttached = true;
	
	self thread createHudIcon();
}

detachFlag(flag)
{
	if(!isdefined(self.flagAttached))
		return;

	if(flag.team == "allies")
		flagModel = "xmodel/prop_flag_" + game["allies"] + "_carry";
	else
		flagModel = "xmodel/prop_flag_" + game["axis"] + "_carry";
		
	self detach(flagModel, "J_Spine4");
	self.flagAttached = undefined;

	self thread deleteHudIcon();
}

createHudIcon()
{
	iconSize = 40;

	self.hud_flag = newClientHudElem(self);
	if(level.ex_logopic)
	{
		self.hud_flag.x = 30;
		self.hud_flag.y = 110;
	}
	else
	{
		self.hud_flag.x = 30;
		self.hud_flag.y = 95;
	}
	self.hud_flag.alignX = "center";
	self.hud_flag.alignY = "middle";
	self.hud_flag.horzAlign = "left";
	self.hud_flag.vertAlign = "top";
	self.hud_flag.alpha = 0;

	self.hud_flagflash = newClientHudElem(self);
	if(level.ex_logopic)
	{
		self.hud_flagflash.x = 30;
		self.hud_flagflash.y = 110;
	}
	else
	{
		self.hud_flagflash.x = 30;
		self.hud_flagflash.y = 95;
	}
	self.hud_flagflash.alignX = "center";
	self.hud_flagflash.alignY = "middle";
	self.hud_flagflash.horzAlign = "left";
	self.hud_flagflash.vertAlign = "top";
	self.hud_flagflash.alpha = 0;
	self.hud_flagflash.sort = 1;

	if(self.pers["team"] == "allies")
	{
		self.hud_flag setShader(level.hudflag_axis, iconSize, iconSize);
		self.hud_flagflash setShader(level.hudflagflash_axis, iconSize, iconSize);
	}
	else
	{
		assert(self.pers["team"] == "axis");
		self.hud_flag setShader(level.hudflag_allies, iconSize, iconSize);
		self.hud_flagflash setShader(level.hudflagflash_allies, iconSize, iconSize);
	}

	self.hud_flagflash fadeOverTime(.2);
	self.hud_flagflash.alpha = 1;

	self.hud_flag fadeOverTime(.2);
	self.hud_flag.alpha = 1;

	wait .2;
	
	if(isdefined(self.hud_flagflash))
	{
		self.hud_flagflash fadeOverTime(1);
		self.hud_flagflash.alpha = 0;
	}
}

deleteHudIcon()
{
	if(isdefined(self.hud_flagflash))
		self.hud_flagflash destroy();
		
	if(isdefined(self.hud_flag))
		self.hud_flag destroy();
}

createFlagWaypoint()
{
	if(!level.ex_objindicator)
		return;
		
	self deleteFlagWaypoint();

	waypoint = newHudElem();
	waypoint.x = self.origin[0];
	waypoint.y = self.origin[1];
	waypoint.z = self.origin[2] + 100;
	waypoint.alpha = .61;
	waypoint.archived = true;

	waypoint setShader(self.objpointflag, 7, 7);

	waypoint setwaypoint(true);
	self.waypoint_flag = waypoint;
}

deleteFlagWaypoint()
{
	if(isdefined(self.waypoint_flag))
		self.waypoint_flag destroy();
}

createFlagMissingWaypoint()
{
	if(!level.ex_objindicator)
		return;
		
	self deleteFlagMissingWaypoint();

	waypoint = newHudElem();
	waypoint.x = self.home_origin[0];
	waypoint.y = self.home_origin[1];
	waypoint.z = self.home_origin[2] + 100;
	waypoint.alpha = .61;
	waypoint.archived = true;

	waypoint setShader(self.objpointflagmissing, 7, 7);

	waypoint setwaypoint(true);
	self.waypoint_base = waypoint;
}

deleteFlagMissingWaypoint()
{
	if(isdefined(self.waypoint_base))
		self.waypoint_base destroy();
}

announceWinner(winner, delay)
{
	wait delay;

	// Announce winner
	if(winner == "allies")
		level thread playSoundOnPlayers("MP_announcer_allies_win");
	else if(winner == "axis")
		level thread playSoundOnPlayers("MP_announcer_axis_win");
	else if(winner == "draw")
		level thread playSoundOnPlayers("MP_announcer_round_draw");
}

playSoundOnPlayers(sound, team)
{
	players = getentarray("player", "classname");

	if(level.splitscreen)
	{
		if(isdefined(players[0]))
			players[0] playLocalSound(sound);
	}
	else
	{
		if(isdefined(team))
		{
			for(i = 0; i < players.size; i++)
			{
				if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == team))
					players[i] playLocalSound(sound);
			}
		}
		else
		{
			for(i = 0; i < players.size; i++)
				players[i] playLocalSound(sound);
		}
	}
}

printOnTeam(text, team)
{
	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{
		if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == team))
			players[i] iprintln(text);
	}
}

IsLinuxServer()
{
	if(! isdefined (level.IsLinuxServer))
	{
		version = getcvar ("version");
		endstr = "";
		for (i = 0; i < 7; i ++)
			endstr += version[i + version.size - 7];
		level.IsLinuxServer = (endstr != "win-x86");
	}
	
	return (level.IsLinuxServer);
}

iprintlnFIXED(locstring, player)
{
	if(IsLinuxServer())
		self iprintln (locstring, player.name);
	else
		self iprintln (locstring, player);
}

printOnTeamFIXED(locstring, team, player)
{
	if (IsLinuxServer())
		printOnTeam (locstring, team, player.name);
	else
		printOnTeam (locstring, team, player);
}

menuWeapon(response)
{
	if(!isDefined(self.pers["team"]) || (self.pers["team"] != "allies" && self.pers["team"] != "axis"))
		return;

	weapon = self maps\mp\gametypes\_weapons::restrictWeaponByServerCvars(response);

	if(weapon == "restricted")
	{
		if(self.pers["team"] == "allies") self openMenu(game["menu_weapon_allies"]);
		else if(self.pers["team"] == "axis") self openMenu(game["menu_weapon_axis"]);

		return;
	}

	self setClientCvar("g_scriptMainMenu", game["menu_ingame"]);

	if(extreme\_ex_weapons::isValidWeapon(self.pers["weapon"]) && self.pers["weapon"] == weapon) return;

	if(!game["matchstarted"])
	{
		if(extreme\_ex_weapons::isValidWeapon(self.pers["weapon"]))
		{
			self.pers["weapon"] = weapon;
			self.pers["weapon1"] = self.pers["weapon"];
			self setWeaponSlotWeapon("primary", weapon);
			self extreme\_ex_weapons::setAmmo("primary");
			self switchToWeapon(weapon);

			extreme\_ex_weapons::givePistol();
			extreme\_ex_weapons::giveGrenades();
		}
		else
		{
			self.pers["weapon"] = weapon;
			self.pers["weapon1"] = self.pers["weapon"];
			
			if(isdefined(self.WaitingToSpawn))
			{
				self thread respawn();
				self thread updateTimer();
			}
			else
			{
				self.spawned = undefined;
				spawnPlayer();
			}
			
			self thread extreme\_ex_clientcontrol::exprintJoinedTeam(self.pers["team"]);
			level checkMatchStart();
		}
	}
	else if(!level.roundstarted && !self.usedweapons)
	{
		if(extreme\_ex_weapons::isValidWeapon(self.pers["weapon"]))
		{
			self.pers["weapon"] = weapon;
			self.pers["weapon1"] = self.pers["weapon"];
			self.ex_stopwepmon = true;
			self maps\mp\gametypes\_weapons::updateAllAllowedSingleClient();
			self maps\mp\gametypes\_weapons::updateDisabledSingleClient(self.pers["weapon1"]);
			self maps\mp\gametypes\_weapons::updateDisabledSingleClient(self.pers["weapon2"]);
			self setWeaponSlotWeapon("primary", weapon);
			self setWeaponSlotWeapon("primaryb", self.weapon["primaryb"].name);
			self extreme\_ex_weapons::setAmmo("primary");
			self extreme\_ex_weapons::setSpawnWeapons();
			self.weapon["current"].name = weapon;
			self switchToWeapon(weapon);
			self.ex_stopwepmon = false;
			self extreme\_ex_weapons::givePistol();
			frags = self getammocount(self.pers["fragtype"]) + self getammocount(self.pers["enemy_fragtype"]);
			smokes = self getammocount(self.pers["smoketype"]) + self getammocount(self.pers["enemy_smoketype"]);
			self extreme\_ex_weapons::giveGrenades(frags, smokes);
		}
		else
		{
			self.pers["weapon"] = weapon;
			self.pers["weapon1"] = self.pers["weapon"];

			if(!level.exist[self.pers["team"]])
			{
				if(isdefined(self.WaitingToSpawn))
				{
					self thread respawn();
					self thread updateTimer();
				}
				else
				{
					self.spawned = undefined;
					spawnPlayer();
				}
				
				self thread extreme\_ex_clientcontrol::exprintJoinedTeam(self.pers["team"]);
				level checkMatchStart();
			}
			else
			{
				if(isdefined(self.WaitingToSpawn))
				{
					self thread respawn();
					self thread updateTimer();
				}
				else
				{
					spawnPlayer();
				}
				
				self thread extreme\_ex_clientcontrol::exprintJoinedTeam(self.pers["team"]);
			}
		}
	}
	else
	{
		if(isDefined(self.pers["weapon"])) self.oldweapon = self.pers["weapon"];
		else if(isDefined(self.pers["weapon1"])) self.oldweapon = self.pers["weapon1"];

		self.pers["weapon"] = weapon;
		self.pers["weapon1"] = self.pers["weapon"];
		self.sessionteam = self.pers["team"];

		if(self.sessionstate != "playing" && !level.ex_ranksystem) self.statusicon = "hud_status_dead";

		if(self.pers["team"] == "allies")
			otherteam = "axis";
		else
		{
			assert(self.pers["team"] == "axis");
			otherteam = "allies";
		}

		// if joining a team that has no opponents, just spawn
		if(!level.didexist[otherteam] && !level.roundended)
		{
			if(isDefined(self.spawned))
			{
				if(extreme\_ex_weapons::isValidWeapon(self.pers["weapon"]))
				{
					self.pers["weapon"] = weapon;
					self.pers["weapon1"] = self.pers["weapon"];
					self setWeaponSlotWeapon("primary", weapon);
					self extreme\_ex_weapons::setAmmo("primary");
					self switchToWeapon(weapon);

					extreme\_ex_weapons::givePistol();
					extreme\_ex_weapons::giveGrenades();
				}
			}
			else
			{
				if(isdefined(self.WaitingToSpawn))
				{
					self thread respawn();
					self thread updateTimer();
				}
				else
				{
					self.spawned = undefined;
					spawnPlayer();
				}
				
				self thread extreme\_ex_clientcontrol::exprintJoinedTeam(self.pers["team"]);
			}
		} // else if joining an empty team, spawn and check for match start
		else if(!level.didexist[self.pers["team"]] && !level.roundended)
		{
			if(isdefined(self.WaitingToSpawn))
			{
				self thread respawn();
				self thread updateTimer();
			}
			else
			{
				self.spawned = undefined;
				spawnPlayer();
			}
			
			self thread extreme\_ex_clientcontrol::exprintJoinedTeam(self.pers["team"]);
			level checkMatchStart();
		} // else you will spawn with selected weapon next round
		else
		{
			weaponname = maps\mp\gametypes\_weapons::getWeaponName(self.pers["weapon"]);

			// set weapon up for next spawn
			self.pers["weapon1_new"] = weapon;
			
			if(isdefined(self.WaitingToSpawn))
			{
				self thread respawn();
				self thread updateTimer();
			}
			else
			{
				spawnPlayer();
			}

			if(maps\mp\gametypes\_weapons::useAn(self.pers["weapon"]))
				self iprintlnFIXED(&"MP_YOU_WILL_RESPAWN_WITH_AN", weaponname);
			else
				self iprintlnFIXED(&"MP_YOU_WILL_RESPAWN_WITH_A", weaponname);
		}
	}

	self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
	
}

respawn_timer(delay)
{
	self endon("disconnect");

	self.WaitingToSpawn = true;

	if(level.respawndelay > 0)
	{
		if(!isdefined(self.respawntimer))
		{
			self.respawntimer = newClientHudElem(self);
			self.respawntimer.x = 0;
			self.respawntimer.y = -50;
			self.respawntimer.alignX = "center";
			self.respawntimer.alignY = "middle";
			self.respawntimer.horzAlign = "center_safearea";
			self.respawntimer.vertAlign = "center_safearea";
			self.respawntimer.alpha = 0;
			self.respawntimer.archived = false;
			self.respawntimer.font = "default";
			self.respawntimer.fontscale = 2;
			self.respawntimer.label = (&"MP_TIME_TILL_SPAWN");
			self.respawntimer setTimer (level.respawndelay + delay);
		}

		wait delay;
		self thread updateTimer();

		wait level.respawndelay;

		if(isdefined(self.respawntimer))
			self.respawntimer destroy();
	}

	self.WaitingToSpawn = undefined;
}

updateTimer()
{
	if(isdefined(self.respawntimer))
	{
		if(isdefined(self.pers["team"]) && (self.pers["team"] == "allies" || self.pers["team"] == "axis") && isdefined(self.pers["weapon"]))
			self.respawntimer.alpha = 1;
		else
			self.respawntimer.alpha = 0;
	}
}

jclock()
{
	mastertime = level.timelimit -game["timepassed"];

	if(mastertime == 0)
		mastertime = level.roundlength;

	if(mastertime > 0)
	{
		level.timeclock = newHudElem();
		level.timeclock.alignX = "center";
		level.timeclock.alignY = "middle";
		level.timeclock.x = 320;
		level.timeclock.y = 15;
		level.timeclock.font = "default";
		level.timeclock.color = (0.980,0.996,0.388);
		level.timeclock.fontscale = 1.6;
		level.timeclock setTimer(mastertime * 60);
	}
	
	if(!isdefined(level.timeclock.enclosure))
	{
		level.timeclock.enclosure = newHudElem();
		level.timeclock.enclosure.alignX = "center";
		level.timeclock.enclosure.alignY = "middle";
		level.timeclock.enclosure.x = 320;
		level.timeclock.enclosure.y = 17;
		level.timeclock.enclosure setshader(game["enclosure"], 60, 40);
	}
}

createLevelHudElement(hud_element_name, x,y,xAlign,yAlign,horzAlign,vertAlign,foreground,shader,shader_width,shader_height,sort,alpha,color_r,color_g,color_b) 
{
	
	if(!isDefined(level.hud)) level.hud = [];
	
	count = level.hud.size;

	level.hud[count] = newHudElem();
	level.hud[count].x = x;
	level.hud[count].y = y;
	level.hud[count].alignX = xAlign;
	level.hud[count].alignY = yAlign;
	level.hud[count].horzAlign = horzAlign;
	level.hud[count].vertAlign = vertAlign;
	level.hud[count].foreground = foreground;
	level.hud[count] setShader(shader, shader_width, shader_height);	
	level.hud[count].sort = sort;
	level.hud[count].alpha = 0;
	level.hud[count].color = (color_r,color_g,color_b);
	
	level.hud[count] fadeOverTime(2);
	level.hud[count].alpha = .9;
	level.hud[count].name 			= hud_element_name;
	level.hud[count].shader_name 	= shader;
	level.hud[count].shader_width 	= shader_width;
	level.hud[count].shader_height 	= shader_height;
	wait 6;
	level.hud[count] fadeOverTime(2);
	level.hud[count].alpha = 0;
}

deleteLevelHudElementByName(hud_element_name) 
{
	if(isDefined(level.hud) && level.hud.size > 0) 
	{
	
		for(i=0;i<level.hud.size;i++) 
		{
			if(isDefined(level.hud[i].name) && level.hud[i].name == hud_element_name) 
			{
				level.hud[i] destroy();
				level.hud[i].name = undefined;
			}
		}
		
		new_ar = [];
		
		for(i=0;i<level.hud.size;i++) 
		{
			if(isDefined(level.hud[i].name)) new_ar[new_ar.size] = level.hud[i];			
		}
		
		level.hud = new_ar;
	}
}

GivePointsToTeam(team, points)
{
	players = getentarray("player", "classname");
	
	// count up the people in the flag area
	for(i = 0; i < players.size; i++)
	{
		player = players[i];

		if(isAlive(player) && player.pers["team"] == team)
		{
			player.pers["score"] += points;
			player.score = player.pers["score"];
		}
	}
}

//################ La Truffe (original by GMI UO) #########################
isnearFlag()
{
	// determine the opposite teams flag
	if ( self.pers["team"] == "allies" )
		myflag = getent("axis_flag", "targetname");
	else
		myflag = getent("allied_flag", "targetname");

	// if the flag is not at the base then return false
	if (myflag.home_origin != myflag.origin)
		return false;
		
	dist = distance(myflag.home_origin, self.origin);
	
	// if they were close to the flag then return true
	if ( dist < 850 )
		return true;
		
	return false;
}

isnearCarrier(attacker)
{
	// determine the teams flag
	if(self.pers["team"] == "allies" )
		myflag = getent("allied_flag", "targetname");
	else
		myflag = getent("axis_flag", "targetname");
		
	// if the flag is at the base then return false
	if(myflag.status == "home")
		return false;
	
	// if the attacker is the carrier then return false
	if(isdefined(attacker.flag))
		return false;
		
	// Find the player with the flag
	dist = 9999;
	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{
		player = players[i];

		if(!isdefined(player.flag) )
			continue;

		if(player.pers["team"] != attacker.pers["team"])
			continue;

		dist = distance(self.origin, player.origin);
	}
	
	// if they were close to the flag carrier then return true
	if ( dist < 850 )
		return true;
		
	return false;
}
//######################## End #######################################

//######################## AWE (bell) ################################
Show_TeamStatus()
{
	level endon("disconnect");

	for(;;)
	{
		wait .05;

		level.allplayers = getentarray("player", "classname");

		if(!isdefined(level.axisicon))
		{
			level.axisicon = newHudElem();	
			level.axisicon.x = 620;
			level.axisicon.y = 20;
			level.axisicon.alignX = "center";
			level.axisicon.alignY = "middle";
			level.axisicon.alpha = 0.8;
			level.axisicon setShader(game["hudicon_axis"],17,17);
		}
		if(!isdefined(level.axisnumber))
		{
			level.axisnumber = newHudElem();	
			level.axisnumber.x = 620;
			level.axisnumber.y = 34;
			level.axisnumber.alignX = "center";
			level.axisnumber.alignY = "middle";
			level.axisnumber.font = "default";
			level.axisnumber.fontscale = 1.2;
			level.axisnumber setValue(0);
		}
		if(!isdefined(level.deadaxisicon))
		{
			level.deadaxisicon = newHudElem();	
			level.deadaxisicon.x = 620;
			level.deadaxisicon.y = 54;
			level.deadaxisicon.alignX = "center";
			level.deadaxisicon.alignY = "middle";
			level.deadaxisicon.alpha = 0.8;
			level.deadaxisicon setShader(game["deathicon_axis"],17,17);
		}
		if(!isdefined(level.deadaxisnumber))
		{
			level.deadaxisnumber = newHudElem();	
			level.deadaxisnumber.x = 620;
			level.deadaxisnumber.y = 72;
			level.deadaxisnumber.alignX = "center";
			level.deadaxisnumber.alignY = "middle";
			level.deadaxisnumber.font = "default";
			level.deadaxisnumber.fontscale = 1.2;
			level.deadaxisnumber.color = (0.624,0.624,0.624);
			level.deadaxisnumber setValue(0);
		}
		
		if(!isdefined(level.alliedicon))
		{
			level.alliedicon = newHudElem();	
			level.alliedicon.x = 590;
			level.alliedicon.y = 20;
			level.alliedicon.alignX = "center";
			level.alliedicon.alignY = "middle";
			level.alliedicon.alpha = 0.8;
			level.alliedicon setShader(game["hudicon_allies"],17,17);
		}
		if(!isdefined(level.alliednumber))
		{
			level.alliednumber = newHudElem();	
			level.alliednumber.x = 590;
			level.alliednumber.y = 34;
			level.alliednumber.alignX = "center";
			level.alliednumber.alignY = "middle";
			level.alliednumber.font = "default";
			level.alliednumber.fontscale = 1.2;
			level.alliednumber setValue(0);
		}
		if(!isdefined(level.deadalliesicon))
		{
			level.deadalliesicon = newHudElem();	
			level.deadalliesicon.x = 590;
			level.deadalliesicon.y = 54;
			level.deadalliesicon.alignX = "center";
			level.deadalliesicon.alignY = "middle";
			level.deadalliesicon.alpha = 0.8;
			level.deadalliesicon setShader(game["deathicon_allies"],17,17);
		}
		if(!isdefined(level.deadalliednumber))
		{
			level.deadalliednumber = newHudElem();	
			level.deadalliednumber.x = 590;
			level.deadalliednumber.y = 72;
			level.deadalliednumber.alignX = "center";
			level.deadalliednumber.alignY = "middle";
			level.deadalliednumber.font = "default";
			level.deadalliednumber.fontscale = 1.2;
			level.deadalliednumber.color = (0.624,0.624,0.624);
			level.deadalliednumber setValue(0);
		}
		
		allies = [];
		axis = [];
		deadallies = [];
		deadaxis = [];
		for(i = 0; i < level.allplayers.size; i++)
		{
			if(level.allplayers[i].sessionstate == "playing" && level.allplayers[i].sessionteam == "allies")
				allies[allies.size] = level.allplayers[i];
			if(level.allplayers[i].sessionstate != "playing" && level.allplayers[i].sessionteam == "allies")
				deadallies[deadallies.size] = level.allplayers[i];
			if(level.allplayers[i].sessionstate == "playing" && level.allplayers[i].sessionteam == "axis")
				axis[axis.size] = level.allplayers[i];
			if(level.allplayers[i].sessionstate != "playing" && level.allplayers[i].sessionteam == "axis")
				deadaxis[deadaxis.size] = level.allplayers[i];
		}
		level.axisnumber setValue(axis.size);
		level.alliednumber setValue(allies.size);
		level.deadaxisnumber setValue(deadaxis.size);
		level.deadalliednumber setValue(deadallies.size);
	}
}
//################### END ######################################

flag_count_hud()
{
	self endon("disconnect");
	
	//first, display the static icons for deaths and objectives
	if(!isdefined(self.obj_icon1) ) 
	{
		self.obj_icon1 = newClientHudElem(self);
		self.obj_icon1.x = 590;
		self.obj_icon1.y = 89;
		self.obj_icon1.alignX = "center";
		self.obj_icon1.alignY = "middle";
		self.obj_icon1.sort = 1;	
		self.obj_icon1 setShader(game["objecticon_allies"], 22,22 );
	}
		
	if(!isdefined(self.obj_icon2)) 
	{	
		self.obj_icon2 = newClientHudElem(self);
		self.obj_icon2.x = 620;
		self.obj_icon2.y = 89;
		self.obj_icon2.alignX = "center";
		self.obj_icon2.alignY = "middle";
		self.obj_icon2.sort = 1;	
		self.obj_icon2 setShader(game["objecticon_axis"], 21,21 );
	}
	
	//Set the default value	for both teams
	if(!isdefined(self.obj_count_axis))
	{
		self.obj_count_axis = newClientHudElem(self);
		self.obj_count_axis.x = 620;
		self.obj_count_axis.y = 106;
		self.obj_count_axis.alignX = "center";
		self.obj_count_axis.alignY = "middle";
		self.obj_count_axis.sort = 1;
		self.obj_count_axis.fontScale = 1.2;
		self.obj_count_axis.color = ( 1, 1, 0 );
		self.obj_count_axis setValue(0);
	}
		
	if(!isdefined(self.obj_count_allies))
	{
		self.obj_count_allies = newClientHudElem(self);
		self.obj_count_allies.x = 590;
		self.obj_count_allies.y = 106;
		self.obj_count_allies.alignX = "center";
		self.obj_count_allies.alignY = "middle";
		self.obj_count_allies.sort = 1;	
		self.obj_count_allies.fontScale = 1.2;
		self.obj_count_allies.color = ( 1, 1, 0 );
		self.obj_count_allies setValue(0);
	}

}

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

	level.axis_cap_count++; 

	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{
		player = players[i];
		
		if(isdefined(player.obj_count_axis)) 
			player.obj_count_axis setValue(level.axis_cap_count); 
			
		wait 0.02;
	}
}

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

	level.allies_cap_count++;							

	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{
		player = players[i];
		
		if(isdefined(player.obj_count_allies)) 
			player.obj_count_allies setValue(level.allies_cap_count);
		
		wait 0.02;
	}
}
