#include extreme\_ex_drm;

/*
	==============
	 Conquest TDM
	==============
	Objective: 	Score points and take ground for your team by eliminating players on the 
	opposing team and advancing spawn points.
	Map ends:	When one team reaches the score limit, or time limit is reached
	Respawning:	No wait / Near teammates based on objectives. Players generally spawn 
	behind their teammates relative to the direction of enemies, but the areas 
	that are used for spawning are determined by the current objective that was last taken.

	Original Developers:
  
    innocent bystander
    admin, after hourz
    bystander@after-hourz.com
  
	Visit www.after-hourz.com for kickass public COD servers and a great community.
  
  Credits:
  * Mark 'Slyk' Dittman - Mapper extrodanaire and the initial developer of 
    Conquest TDM on Spearhead.
  * [MC]Hammer - Some utility string transform code is incorporated, and his
    CoDaM HUD code was used and modifed for this gametype.
  * The whole After Hourz community, but especially Painkiller, Fart, Shep, 
    Kamikazee Driver, Poopybuttocks, and Shep for ideas, motivation and friendship.
  * Last but not least, many members of the COD community with help in learning this
    language and patiently answering my questions, including [MC]Hammer, 
    ScorpioMidget, Ravir, [IW]HkySk8r187, and others I probably fail to mention. 
    
    Thanks to you all!
    
	Level requirements
	------------------
		Spawnpoints:
			classname	=	mp_teamdeathmatch_spawn
			script_gameobjectname = cnq or conquest (optional). Set if you only want 
			these spawns used for the conquest game type, otherwise all TDM-spawn 
			gametypes will use it as well. targetname = Either "defenders#" or 
			"attackers#", where # is the objective you want this set of spawns to 
			be associated with, for example "attackers1", "defenders2". This is 
			the group number of the spawns, and is tied directly to the spawn 
			objective's script_idnumber (see below).Spawnpoints are team-based, 
			unlike regular TDM spawns. This is done through setting	a targetname. 
			Obtaining an objective with a particular idnumber will mean that all 
			the team spawns with this matching script_idnumber will be chosen to 
			spawn the player, and the script will place them near their team from 
			among the spawns in this numerical grouping.

		Spectator Spawnpoints:
			classname		mp_teamdeathmatch_intermission
			Spectators spawn from these and intermission is viewed from these positions.
			At least one is required, any more and they are randomly chosen between.

	  Objectives:
	    There are 2 types of objectives, spawn objectives and optional 
	    bonus objectives. All Objectives must be controlled in linear order, 
	    meaning you must control previous objectives to take other objectives. 
	    Spawn objectives allow teams to move their spawns forward toward the 
	    enemy base, while at the same time pushing back their opponents spawns.
	    Bonus objectives, if used in a given map, are at the ends of each chain 
	    and give a team a point bonus, and are not used to move spawn positions.
	  
	    Creating Spawn Objectives
	    =========================
	    
      Spawn Objective Triggers
      ------------------------
      Triggers are placed where you want players to take objectives. Typical
      triggers are modeled as switches, or some other player-activated thing.
      But you can really make it whatever you want that fits your map's style.
      Place the trigger in the map position you want it.
      
      * classname = trigger_use or trigger_multiple (depending on your map). 
        Most CNQ maps use trigger_use.
      * script_gameobjectname = cnq or conquest
      * delay = (time in sections between triggers OPTIONAL) - If you want to 
        delay an objective from being retaken, put an integer value in for this
        reprenting the number of seconds before the objective can be retaken by
        the other team. Default is immediately if not provided.
      * hintstring = (your descriptive text) This tells players what to do if 
        you choose to use trigger_use classes. Typical text would be something
        like "Press [Use} to take this objective!"
      
	    Spawn Objectives
	    ----------------	  
	    * classname = script_model
			* script_gameobjectname = cnq or conquest
			* targetname = spawnobjective
			* script_idnumber = an integer number. This is the numeric order of the 
			  spawn objective. Typically there are a number of spawn objectives that 
			  number starting with 1 and increasing	to the number of objectives in 
			  your map. Most CNQ maps have between 3 and 5 spawn objectives, but 
			  there's no real limit other than there must be at least 1. The number 
			  you give this sets the path of the battle in your map, as teams will 
			  have to progress up and down the chain of	spawn objectives.
			* script_objective_name = (your descriptive text) - Used in game 
			  messages to tell players the name of their next objective. If not 
			  supplied a default name is used.
			
			Targeting the trigger
			---------------------
			Select a script_model representing the objective. Then select the trigger
			you want it associated with, and press Control+K. This should draw a target
			line from the script_model to the trigger. Place the trigger where you want
			the playere to take their objective, and move the script model to be in the
			same position so it will appear in the players compass as the correct 
			location. You have just created an objective.	Repeat this process for more 
			objectives, just remember to increment the script_model.script_idnumber 
			with each new objective.

	    Creating Bonus Objectives
	    =========================
      Bonus Objectives are entirely option, and up to the mapper. They are not 
      used at all in spawn logic, but basically represent a point bonus to the 
      team that takes it. Typically they are placed in the final spawn 
      location of the opposing team, since there is no place to push them back.

			Bonus Objective Triggers
			----------------
      Triggers are placed where you want players to take objectives. Typical
      triggers are modeled as switches, or some other player-activated thing.
      But you can really make it whatever you want that fits your map's style.
      Place the trigger in the map position you want it.
      
      * classname = trigger_use or trigger_multiple (depending on your map). 
        Most CNQ maps use trigger_use.
      * script_gameobjectname = cnq or conquest
      * delay = (time in sections between triggers OPTIONAL) - If you want to 
        delay an bonus from being achieved again, put an integer value in for this
        reprenting the number of seconds before the bonus can be earned again.
        Default is 60 seconds if not provided.
      * hintstring = (your descriptive text) This tells players what to do if 
        you choose to use trigger_use classes. Typical text would be something
        like "Press [Use} to take this objective!"
			
	    Bonus Objectives
	    ----------------	  
	    * classname = script_model
			* script_gameobjectname = cnq or conquest
			* targetname = bonusobjective
			* script_team = defenders or attackers - Defines who's bonus objective this
			  is. There can be one per team.
			* script_objective_name = (your descriptive text) - Used in game 
			  messages to tell players the name of their next objective. If not 
			  supplied a default name is used.
	    		
			Targeting the trigger
			---------------------
			Select a script_model representing the objective. Then select the trigger
			you want it associated with, and press Control+K. This should draw a target
			line from the script_model to the trigger. Place the trigger where you want
			the playere to take their objective, and move the script model to be in the
			same position so it will appear in the players compass as the correct 
			location. You have just created an objective.	There can only be one bonus
			objective per team, created in this manner. 
			
	Level script requirements
	-------------------------
		Team Definitions:
			game["allies"] = "american";
			game["axis"] = "german";
			This sets the nationalities of the teams. Allies can be american, british, 
			or russian. Axis can be german.
	
			game["attackers"] = "allies";
			game["defenders"] = "axis";
			This sets which team is attacking and which team is defending. Attackers 
			take objectives, defenders take them back. 
	
		If using minefields or exploders:
			maps\mp\_load::main();
		
	Optional level script settings
	------------------------------
	  Custom callbacks:
	    A variety of callbacks exist so that mappers can have hooks into the game
	    logic for their own animations or other map-specific effects in the map 
	    script file. These are completely optional, and you do not have to 
	    provide them unless you desire such control.

      If you want this capability, in your map file create lines similar to 
      this for each callback you want to use:
      
      level.cnqCallbackSpawnObjectiveComplete = ::Your_Specific_Function_Name;
      level.cnqCallbackBonusObjectiveComplete =  ::Your_Other_Function_Name;

    Available callbacks are:
    
	level.cnqCallbackStartMap() - if defined, called at the start of the map
    level.cnqCallbackEndMap() - if defined, called at the start of the map
    level.cnqCallbackSpawnObjectiveComplete(objective, player) - if defined, called
      when a player completes an objective. The callback will be passed a 
      handle to the objective that was taken, and the player than did it.
    level.cnqCallbackSpawnObjectiveRegen (objective) - if defined, called when
      a spawn objective is available to be taken again.
    level.cnqCallbackBonusObjectiveComplete(objective, player) - if defined, called
      when a player completes a bonus objective. The callback will be passed a 
      handle to the objective that was taken, and the player than did it.
    level.cnqCallbackBonusObjectiveRegen (objective) - if defined, called when
      a bonus objective is available to be taken again.
*/

/*----------------------------------------------------------------
	Port Over to COD2:
	------------------
	Tally & UncleBone
--------------------------------------------------------------------*/
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();
	
	//Campaign Mode Per Map
	level.rbcnq_campaign_mode = [[level.ex_drm]]("scr_rbcnq_campaign", 0, 0, 1, "int");
	level.rbcnq_lastwinner = [[level.ex_drm]]("scr_rbcnq_lastwinner", "", "", "", "string");
	
	//Campaign Mode Per Round
	level.rbcnq_swap_roundwinner = [[level.ex_drm]]("scr_rbcnq_swap_roundwinner", 0, 0, 1, "int");
	level.rbcnq_roundwinner = [[level.ex_drm]]("scr_rbcnq_roundwinner", "", "", "", "string");

	// 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");
		
		if(level.rbcnq_campaign_mode == 1) 
		{
			if(level.rbcnq_lastwinner != "") //ok, campaign mode. Last map winner attacks, loser defends
			{      
				if(level.rbcnq_lastwinner == "allies") 
				{	
					game["attackers"] = "allies";
					game["defenders"] = "axis";
				} 
				else 
				{
					game["attackers"] = "axis";
					game["defenders"] = "allies";
				}
			} 
			else //they want campaign, but it's the first map
			{ 
				game["attackers"] = "allies";
				game["defenders"] = "axis";
			}
		} 
		else if(level.rbcnq_campaign_mode == 0)
		{
			if(!isdefined(game["attackers"]))
				game["attackers"] = "allies";
			if(!isdefined(game["defenders"]))
				game["defenders"] = "axis";
		}
	
		
		if(!level.ex_ranksystem)
		{
			precacheStatusIcon("hud_status_dead");
			precacheStatusIcon("hud_status_connecting");
		}
		precacheRumble("damage_heavy");
		precacheShader("white");
		
		game["enclosure"] = "gfx/hud/hud@ammocounterback.tga";
		precacheShader(game["enclosure"]);
		
		precacheShader("gfx/custom/flagge_german.tga");
		precacheShader("gfx/custom/flagge_" + game["allies"] + ".tga");
		
		//Setup the hud icons and team specific stuff
		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["allies_area_secured"] = "US_area_secured";
					game["allies_ground_taken"] = "US_ground_taken";
					game["allies_losing_ground"] = "US_losing_ground";
					game["objective_allies"] = "objective_american";
					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["allies_area_secured"] = "UK_area_secured";
					game["allies_ground_taken"] = "UK_ground_taken";
					game["allies_losing_ground"] = "UK_losing_ground";
					game["objective_allies"] = "objective_british";
					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["allies_area_secured"] = "RU_area_secured";
					game["allies_ground_taken"] = "RU_ground_taken";
					game["allies_losing_ground"] = "RU_losing_ground";
					game["objective_allies"] = "objective_russian";
					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";
					game["german_area_secured"] = "GE_area_secured";
					game["german_ground_taken"] = "GE_ground_taken";
					game["german_losing_ground"] = "GE_losing_ground";
					game["objective_axis"] = "objective_german";
					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(game["objective_allies"]);
		precacheShader(game["objective_axis"]);
		
		precacheString(&"MP_TIME_TILL_SPAWN");
		precacheString(&"PLATFORM_PRESS_TO_SPAWN");
		
		precacheString(&"RBCNQ_NOT_TEAM_BONUS");
		precacheString(&"RBCNQ_NOT_YET_BONUS");
		precacheString(&"RBCNQ_OBJ_NOT_CURRENT");
		precacheString(&"RBCNQ_OBJ_ALREADY_TAKEN");
		
		precacheString(&"MP_KILL_AXIS_PLAYERS");
		precacheString(&"MP_KILL_ALLIED_PLAYERS");
		precacheString(&"MP_ALLIES_KILL_AXIS_PLAYERS");
		precacheString(&"MP_ALLIEDMISSIONACCOMPLISHED");
		precacheString(&"MP_AXISMISSIONACCOMPLISHED");
		precacheString(&"MP_ALLIESHAVEBEENELIMINATED");
		precacheString(&"MP_AXISHAVEBEENELIMINATED");
		precacheString(&"MP_TIMEHASEXPIRED");
		precacheString(&"MP_ROUNDDRAW");
		precacheString(&"MP_THE_GAME_IS_A_TIE");

		if(!isdefined(game["rbcnq_attackers_obj_text"])) 
		{
			if ( game["attackers"] == "allies" )
				game["rbcnq_attackers_obj_text"] = (&"MP_KILL_AXIS_PLAYERS");
			else 
				game["rbcnq_attackers_obj_text"] = (&"MP_KILL_ALLIED_PLAYERS");
		}
		
		if(!isdefined(game["rbcnq_defenders_obj_text"])) 
		{
			if ( game["defenders"] == "allies" )
				game["rbcnq_defenders_obj_text"] = (&"MP_KILL_AXIS_PLAYERS");
			else 
				game["rbcnq_defenders_obj_text"] = (&"MP_KILL_ALLIED_PLAYERS");
		}
		
		if(!isdefined(game["rbcnq_neutral_obj_text"]))
			game["rbcnq_neutral_obj_text"] = (&"MP_ALLIES_KILL_AXIS_PLAYERS");

	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\_friendicons::init();
	thread maps\mp\gametypes\_spectating::init();
	thread maps\mp\gametypes\_grenadeindicators::init();
	thread maps\mp\gametypes\_landmines::init();
	thread extreme\_ex_varcache::postmapload();
	
	game["gamestarted"] = true;

	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();

	setClientNameMode("auto_change");

	spawnpointname = "mp_tdm_spawn";
	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] = "cnq";
	allowed[1] = "conquest";
	maps\mp\gametypes\_gameobjects::main(allowed);

	// Time limit per map
	level.timelimit = [[level.ex_drm]]("scr_rbcnq_timelimit", 30, 0, 1440, "float" );
	setCvar("ui_rbcnq_timelimit", level.timelimit);
	storeServerInfoDvar("ui_rbcnq_timelimit");

	// Score limit per map
	level.scorelimit = [[level.ex_drm]]("scr_rbcnq_scorelimit", 300, 0, 999, "int");
	setCvar("ui_rbcnq_scorelimit", level.scorelimit);
	storeServerInfoDvar("ui_rbcnq_scorelimit");

	// Round limit per map
	level.roundlimit = [[level.ex_drm]]("scr_rbcnq_roundlimit", 0, 0, 99, "int");
	setCvar("ui_rbcnq_roundlimit", level.roundlimit);
	storeServerInfoDvar("ui_rbcnq_roundlimit");
	
	// Time length of each round
	level.roundlength = [[level.ex_drm]]("scr_rbcnq_roundlength", 4, 0, 3600, "float");
	setCvar("ui_rbcnq_roundlength", level.roundlength);
	storeServerInfoDvar("ui_rbcnq_roundlength");
	
	// Spawn Tickets
	level.spawnlimit = [[level.ex_drm]]("scr_rbcnq_spawn_tickets", 4, 0, 99, "int");
	setCvar("ui_rbcnq_spawn_tickets", level.spawnlimit);
	storeServerInfoDvar("ui_rbcnq_spawn_tickets");
	
	// Time at round start where spawning and weapon choosing is still allowed
	level.graceperiod = [[level.ex_drm]]("scr_rbcnq_graceperiod", 15, 0, 60, "float");

	if(drm_getCvar("scr_rbcnq_debug") == "")		// Debug messages
		setcvar("scr_rbcnq_debug", "0");
	
	//#######################################################################################
		
	// Points to award player for achieving objective
	level.player_obj_points = [[level.ex_drm]]("scr_rbcnq_player_objective_points", 5, 0, 40, "int");

	// Points to award team for achieving objective
	level.team_obj_points = [[level.ex_drm]]("scr_rbcnq_team_objective_points", 5, 0, 30, "int");

	// Points to award player for achieving bonus objective
	level.player_bonus_points = [[level.ex_drm]]("scr_rbcnq_player_bonus_points", 10, 0, 50, "int");

	// Points to award team for achieving bonus objective
	level.team_bonus_points = [[level.ex_drm]]("scr_rbcnq_team_bonus_points", 10, 0, 40, "int");

	level.respawndelay = [[level.ex_drm]]("scr_rbcnq_respawn_wave_time", 10, 0, 30, "int");
	
	//Time to Cap Objective
	level.captime = [[level.ex_drm]]("scr_rbcnq_captime", 5, 0, 10, "int");
	
	level.roundwin_points = [[level.ex_drm]]("scr_rbcnq_roundwin_points", 5, 0, 10, "int");
	
	level.reset_scores = [[level.ex_drm]]("scr_rbcnq_round_reset_scores", 0, 0, 1, "int");

	//#######################################################################################
	
	level.lockteams = false;

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

	if(!isdefined(game["axisscore"])) game["axisscore"] = 0;
	setTeamScore("axis", game["axisscore"]);
	
	if(!isdefined(game["timepassed"])) game["timepassed"] = 0;
	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;

	level.roundstarted = false;
	level.roundended = false;
	level.mapended = false;
	
	level.exist["allies"] = 0;
	level.exist["axis"] = 0;
	level.exist["teams"] = false;
	level.didexist["allies"] = false;
	level.didexist["axis"] = false;
	
	level.objectivearray = [];
	level.objCount = [];
	level.objCount["attackers"] = 0;
	level.objCount["defenders"] = 0;
	
	level.allies_cap_count = 0;
	level.axis_cap_count = 0;
	
	level.axis_eliminated = undefined;
	level.allied_eliminated = undefined;
	
	if(game["gamestarted"] && game["roundnumber"] >= 2)
	{
		if(level.rbcnq_swap_roundwinner == 1) // Campaign mode per round
		{
			if(level.rbcnq_roundwinner != "") //ok, campaign mode. Last round winner attacks, loser defends
			{      
				if(level.rbcnq_roundwinner == "allies") 
				{	
					game["attackers"] = "allies";
					game["defenders"] = "axis";
				} 
				else 
				{
					game["attackers"] = "axis";
					game["defenders"] = "allies";
				}
			}
			else //they want campaign, but it's the first round
			{
				game["attackers"] = "allies";
				game["defenders"] = "axis";
			}
		}
	}
	
	thread startObjectives();
	//thread Show_TeamStatus();
	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);

	iprintln(&"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");

	if(level.splitscreen)
	{
		if(isdefined(self.pers["weapon"]))
			scriptMainMenu = game["menu_ingame_onteam"];
		else
			scriptMainMenu = game["menu_ingame_spectator"];
	}
	else
		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)
		iprintln(&"MP_DISCONNECTED", self);
	
	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.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;

			// 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
			{
				attacker.pers["score"] += points;
				attacker.pers["bonus"] += reward_points;
				attacker.score = attacker.pers["score"];
				//teamscore += points;
				//setTeamScore(attacker.pers["team"], teamscore);
				//checkScoreLimit();
			}
		}

		// added for arcade style HUD points
		attacker notify("update_playerscore_hud");

		lpattacknum = attacker getEntityNumber();
		lpattackguid = attacker getGuid();
		lpattackname = attacker.name;
		lpattackerteam = attacker.pers["team"];
	}
	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);
	}
	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 extreme\_ex_main::exprespawn();

	spawnpointname = "mp_tdm_spawn";
	spawnpoints = getentarray(spawnpointname, "classname");
	
	if(!isdefined(self.ex_team_changed) && isdefined(game["matchstarted"])) level updateTeamStatus();

	printObjectiveStates();

	if(isdefined(level.objectivearray)) 
	{
		locationToUse = drm_getCvar("scr_rbcnq_initialobjective");
		
		for (n = 0; n < level.objectivearray.size; n++) 
		{
			spawnObjective = level.objectivearray[n];
			if (isOff(spawnObjective))
				continue;
			locationToUse = spawnObjective.script_idnumber;
		}
		
		printDebug( "Basing spawns on objective #" + locationToUse);
		teamRole = "";
		
		if (self.pers["team"] == game["attackers"])
			teamRole = "attackers";
		else
			teamRole = "defenders";
		
		spawngroup = teamRole + locationToUse;
		printDebug( "Attempting to use spawngroup " + spawngroup );
		spawnpoints = getentarray(spawngroup, "targetname");
		if (isdefined(spawnpoints)) 
		{
			if (spawnpoints.size == 0) 
			{
				spawnpoints = getentarray(spawnpointname, "classname");
				printDebug( "0 spawns found, switching to regular TDM spawns" );
			}	
		} 
		else 
		{
			spawnpoints = getentarray(spawnpointname, "classname");
			printDebug( "No spawns found, switching to regular TDM spawns" );
		}
	}
	printDebug( "Found " + spawnpoints.size + " spawn points.");
	
	if (drm_getCvar("scr_rbcnq_spawnmethod") == "random")
		spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(spawnpoints);
	else
		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.pers["savedmodel"]))
		maps\mp\gametypes\_teams::model();
	else
		maps\mp\_utility::loadModel(self.pers["savedmodel"]);

	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;
	}
	
	//###
	self setObjectiveTextAll();
	//###
	
	self thread updateTimer();

	self thread flag_count_hud();
	self extreme\_ex_main::expostspawn();

	waittillframeend;
	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();
	thread jclock();
	thread startRound();
}

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

	if(!level.splitscreen)
		thread sayObjective();
	
	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;

	if(!level.exist[game["attackers"]] || !level.exist[game["defenders"]])
	{
		iprintln(&"MP_TIMEHASEXPIRED");
		level thread endRound("draw");
		return;
	}

	iprintln(&"MP_TIMEHASEXPIRED");
	
	game["alliedscore"] = getTeamScore("allies");
	game["axisscore"] = getTeamScore("axis");

	if(game["alliedscore"] == game["axisscore"])
	{
		iprintlnBold(&"MP_ROUNDDRAW");
		level thread endRound("draw");
	}
	else if(game["alliedscore"] > game["axisscore"])
	{
		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"]))
			{
				game["roundstarted"] = true;
				return;
			}
			
			iprintlnBold(&"MP_MATCHSTARTING");
			game["roundstarted"] = true;

			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 = "";
	
	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(level.rbcnq_swap_roundwinner == 1) 
		{
			if(roundwinner != "draw")
			{
				setcvar("scr_rbcnq_roundwinner", roundwinner);
			}
			else
				setcvar("scr_rbcnq_roundwinner", game["attackers"]);
		}
	}

	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.reset_scores) thread resetScores();
	if(level.ex_swapteams == 1 && !isdefined(level.rbcnq_swap_roundwinner)) extreme\_ex_main::swapTeams();
	if(level.ex_swapteams == 2 && !isdefined(level.rbcnq_swap_roundwinner) && game["roundnumber"] == level.half_time) extreme\_ex_main::swapTeams();
	map_restart(true);
}

endMap()
{
//////////////////////////////////////////////////////////////////////////
//Damole EndMapVote
	maps\mp\gametypes\_mapvote::Initialize();
//DaMole
//////////////////////////////////////////////////////////////////////////
	game["state"] = "intermission";
	level notify("intermission");

	game["alliedscore"] = getTeamScore("allies");
	game["axisscore"] = getTeamScore("axis");

	if(game["alliedscore"] == game["axisscore"])
	{
		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"])
	{
		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
	{
		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);
	}
	
	iprintlnbold(text);

	winners = "";
	losers = "";

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

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

		if((winningteam == "allies") || (winningteam == "axis"))
		{
			lpGuid = player getGuid();
			if((isDefined(player.pers["team"])) && (player.pers["team"] == winningteam))
				winners = (winners + ";" + lpGuid + ";" + player.name);
			else if((isDefined(player.pers["team"])) && (player.pers["team"] == losingteam))
				losers = (losers + ";" + lpGuid + ";" + player.name);
		}

		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;
		}
	}

	if((winningteam == "allies") || (winningteam == "axis"))
	{
		logPrint("W;" + winningteam + winners + "\n");
		logPrint("L;" + losingteam + losers + "\n");
	}
	
	if(level.rbcnq_campaign_mode == 1) 
	{
		if(winningteam != "tie")
		{
			setcvar("scr_rbcnq_lastwinner", winningteam);
		}
		else
			setcvar("scr_rbcnq_lastwinner", game["attackers"]);
	}

	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_rbcnq_timelimit", "1440");
			}

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

		scorelimit = level.scorelimit;
		if(level.scorelimit != scorelimit)
		{
			level.scorelimit = scorelimit;
			setCvar("ui_rbcnq_scorelimit", level.scorelimit);
			level notify("update_teamscore_hud");

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

		roundlimit = level.roundlimit;
		if(level.roundlimit != roundlimit)
		{
			level.roundlimit = roundlimit;
			setCvar("ui_rbcnq_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")
			iprintln(&"MP_JOINED_ALLIES", self);
		else if(team == "axis")
			iprintln(&"MP_JOINED_AXIS", self);
	}
}

sayObjective()
{
	wait 2;

	attacksounds["american"] = "US_mp_cmd_movein";
	attacksounds["british"] = "UK_mp_cmd_movein";
	attacksounds["russian"] = "RU_mp_cmd_movein";
	attacksounds["german"] = "GE_mp_cmd_movein";

	level playSoundOnPlayers(attacksounds[game[game["attackers"]]], game["attackers"]);
}
//#################################################
startObjectives() 
{

	startSpawnObjectives();
	startBonusObjectives();
	setObjectives();
	adjustObjectivesCount();
  
}

startSpawnObjectives()
{
	level endon("round_ended");
	
	if(drm_getCvar("scr_rbcnq_initialobjective") == "") // Initial switch on, admin setting
	{ 
		if (isdefined(game["rbcnq_initialobjective"])) // Initial switch, optional mapper setting
		{ 
			setcvar("scr_rbcnq_initialobjective", game["rbcnq_initialobjective"]);
		}
		else
		{
			setcvar("scr_rbcnq_initialobjective", "1");
		}
	}
		
	level.conquest_objectives = getentarray("spawnobjective","targetname");
	printDebug ("Found " + level.conquest_objectives.size + " spawn objectives in this map.");
		
	for(i = 0; i < level.conquest_objectives.size; i++)
	{
		//first, find the triggers each objective targets and set them
		objective = level.conquest_objectives[i];
		flipOff(objective); //turn all off to start
		
		if(isdefined(objective.target) )
		{
			targets = getentarray (objective.target,"targetname");
			for (t = 0; t < targets.size; t++)
			{
				if(targets[t].classname == "trigger_use" || targets[t].classname == "trigger_multiple")
				{
					objective.trigger = targets[t];
				}
			}
		}

		objective notify ("round_ended");
		objective thread objective_think();
		
		level.objectivearray[objective.script_idnumber - 1] = objective;
	
	}
	
	found = 0;
	for (i = 0; i < level.objectivearray.size; i++) 
	{
		if (level.objectivearray[i].script_idnumber <= drm_getCvarint("scr_rbcnq_initialobjective"))
		{
			flipObjective(level.objectivearray[i]);
			found = 1;
		} 
		else 
		{
			break;
		}
	}
}

startBonusObjectives() 
{

	level endon("round_ended");

	level.bonus_objectives = getentarray("bonusobjective","targetname");
	printDebug ("Found " + level.bonus_objectives.size + " bonus objectives in this map.");
	
	for(i = 0; i < level.bonus_objectives.size; i++) 	
	{
		//first, find the triggers each objective targets and set them
		objective = level.bonus_objectives[i];
		
		if (isdefined (objective.target)) 
		{
			targets = getentarray (objective.target,"targetname");

			for (t = 0; t < targets.size; t++) 
			{
				if(targets[t].classname == "trigger_use" || targets[t].classname == "trigger_multiple") 
				{
					objective.trigger = targets[t];
					objective thread bonus_objective_think();
					break;
				}
			}    
		}
		
	}
    
}

objective_think()
{
	//level endon("round_ended");
	
	if(!isdefined(game["roundstarted"])) return;
	
	for(;;)
	{
		delaytime = 0.9;
	
		self.trigger waittill("trigger", other);										// Wait until objective trigggered.
		
		if(isDefined(self.beingCapped))													// If someone is already capping objective
			continue;
			
		if(isPlayer(other) && level.roundstarted && !level.roundended)															// If trigger was made by player.
		{	
			allSpawnObjectives = level.objectivearray;									// Set local variable to the objective array.
	
			if (!isdefined(allSpawnObjectives))											// If undefined continue.
				continue;
	
			for (n = 0; n < allSpawnObjectives.size; n++)								// Loop through array.
			{	
				if(self.script_idnumber == allSpawnObjectives[n].script_idnumber)		// If objective ID is equal to array ID.
				{
					
					if(other.pers["team"] == game["attackers"]) 						// If players team is equal to the attacking team.
					{
	
						if(isOn(self))													// If Objective is on, continue.
						{
							other iprintln(&"RBCNQ_OBJ_ALREADY_TAKEN");
								continue;
						}

						// Attackers can always turn on the 1st objective
						// Otherwise, they can turn an objecetive on only if the previous one is also on.
						previousObjective = allSpawnObjectives[n-1];
						
						// If 'n' is equal to 0 or previousObjective is on.
						if ((n == 0) || (isdefined(previousObjective) && isOn(previousObjective)))	
						{
							while(isAlive(other) && other isOnGround() && other useButtonPressed())
							{	
								self.beingCapped = true;							// Player is capping objective
								
								if(!isdefined(other.progressbackground))
								{
									other.progressbackground = newClientHudElem(other);
									other.progressbackground.x = 0;
									other.progressbackground.y = 104;
									other.progressbackground.alignX = "center";
									other.progressbackground.alignY = "middle";
									other.progressbackground.horzAlign = "center_safearea";
									other.progressbackground.vertAlign = "center_safearea";
									other.progressbackground.alpha = 0.5;
								}
								other.progressbackground setShader("black", (192 + 4), 12);
				
								if(!isdefined(other.progressbar))
								{
									other.progressbar = newClientHudElem(other);
									other.progressbar.x = int(192 / (-2.0));
									other.progressbar.y = 104;
									other.progressbar.alignX = "left";
									other.progressbar.alignY = "middle";
									other.progressbar.horzAlign = "center_safearea";
									other.progressbar.vertAlign = "center_safearea";
								}
								other.progressbar setShader("white", 0, 8);
								other.progressbar scaleOverTime(level.captime, 192, 8);
								
								other playsound("MP_bomb_plant");
								other linkto(self); 	// Stop Player moving while capping
								other disableWeapon();	// No guns while capping
								other.progresstime = 0; // Time player has been capping
								
								while(isAlive(other) && other useButtonPressed() && (other.progresstime < level.captime)) // Change Variables
								{
									other.progresstime += 0.05;
									wait 0.05;
								}
				
								other.progressbackground destroy(); // Destroy Bar Background
								other.progressbar destroy();		// Destroy Bar
								other enableWeapon();				// Enable Players Weapon
								other unlink();						// Unlink Player
								self.beingCapped = undefined; 		// Nobody is capping objective
								
								if(other.progresstime >= level.captime)	
								{
									thread performObjectiveCompleteTasks(self, other, "spawn");
									if (isdefined(self.trigger.delay) && (self.trigger.delay > 0.5))
									delaytime = self.trigger.delay / 1000;
								}
								else
									continue;
							}
							
						} 
						else 
						{
							other iprintln(&"RBCNQ_OBJ_NOT_CURRENT");
						}
					} 
					else 					// Defenders
					{ 
						
						if (isOff(self)) 	// If Objective is off, continue.
						{
							other iprintln(&"RBCNQ_OBJ_ALREADY_TAKEN");
								continue;
						}
	
						// Defenders can always turn on the last objective and the next to be turned off
						previousObjective = allSpawnObjectives[n+1];
						if ((n == allSpawnObjectives.size - 1) || (isdefined(previousObjective) && isOff(previousObjective))) 
						{
							while(other isTouching(self.trigger) && isAlive(other) && other isOnGround() && other useButtonPressed())
							{
								self.beingCapped = true;						// Objective is being capped
								
								if(!isdefined(other.progressbackground))
								{
									other.progressbackground = newClientHudElem(other);
									other.progressbackground.x = 0;
									other.progressbackground.y = 104;
									other.progressbackground.alignX = "center";
									other.progressbackground.alignY = "middle";
									other.progressbackground.horzAlign = "center_safearea";
									other.progressbackground.vertAlign = "center_safearea";
									other.progressbackground.alpha = 0.5;
								}
								other.progressbackground setShader("black", (192 + 4), 12);
				
								if(!isdefined(other.progressbar))
								{
									other.progressbar = newClientHudElem(other);
									other.progressbar.x = int(192 / (-2.0));
									other.progressbar.y = 104;
									other.progressbar.alignX = "left";
									other.progressbar.alignY = "middle";
									other.progressbar.horzAlign = "center_safearea";
									other.progressbar.vertAlign = "center_safearea";
								}
								other.progressbar setShader("white", 0, 8);
								other.progressbar scaleOverTime(level.captime, 192, 8);
								
								other playsound("MP_bomb_plant");
								other linkto(self); 	// Stop Player moving while capping
								other disableWeapon();	// No guns while capping
								other.progresstime = 0; // Time player has been capping
								
								while(isAlive(other) && other useButtonPressed() && (other.progresstime < level.captime))
								{
									other.progresstime += 0.05;
									wait 0.05;
								}
				
								other.progressbackground destroy(); // Destroy Bar Background
								other.progressbar destroy();		// Destroy Bar
								other enableWeapon();				// Enable Players Weapon
								other unlink();						// Unlink Player
								self.beingCapped = undefined;		// Nobody is capping
								
								if(other.progresstime >= level.captime)	
								{
									if(level.roundended) break;
									thread performObjectiveCompleteTasks(self, other, "spawn");
									if (isdefined(self.trigger.delay) && (self.trigger.delay > 0.5))
									delaytime = self.trigger.delay / 1000;
								}
								else
									continue;
							}
						} 
						else 
						{
							other iprintln(&"RBCNQ_OBJ_NOT_CURRENT");
						}
					} 	// if(other.per["team"])
				} 		// if(self.script_idnumber)
			} 			// for()
		} 				// if(isPlayer)
		
		wait delaytime;
		if (isdefined(level.cnqCallbackSpawnObjectiveRegen))
			thread [[level.cnqCallbackSpawnObjectiveRegen]](self);
			
		/* This is currently stopping players from capping just after failing to cap. 
		If the player stops capping, they then have to wait the delay to attempt to recap. */
			
	} 					// Outer for()
	
}

bonus_objective_think()
{
	//level endon("round_ended");
	
	if(!isdefined(game["roundstarted"])) return;
	
	self thread countdownUntilAvailable(60); //initial wait, so teams don't earn bonus in 1st minute before everyone is spawned in.
	
	for(;;)
	{	
		self.trigger waittill("trigger", other);
	
		other.progresstime = 0;

		printDebug("Bonus triggered by " + other.name + " playing for the " + other.pers["team"]);
	
		if(isPlayer(other) && isAlive(other) && other isOnGround() && (other.pers["team"] != "spectator") && level.roundstarted && !level.roundended) 
		{
			if(!isdefined(level.objectivearray))
				continue;
				
			teamRole = "attackers";
			if (other.pers["team"] == game["defenders"])
				teamRole = "defenders";
		
			if(isdefined(self.script_team) && (self.script_team == teamRole)) //if it's their bonus objective
			{ 
				if(level.objCount[teamRole] == level.objectivearray.size) //and they control all the regular objectives
				{ 
					if(self.isAvailable == 1) //and it's not in a wait state
					{
						while(isAlive(other) && other isOnGround() && other useButtonPressed())
						{
							wait 0.02;
								
							if(!isdefined(other.progressbackground))
							{
								other.progressbackground = newClientHudElem(other);
								other.progressbackground.x = 0;
								other.progressbackground.y = 104;
								other.progressbackground.alignX = "center";
								other.progressbackground.alignY = "middle";
								other.progressbackground.horzAlign = "center_safearea";
								other.progressbackground.vertAlign = "center_safearea";
								other.progressbackground.alpha = 0.5;
							}
							other.progressbackground setShader("black", (192 + 4), 12);
				
							if(!isdefined(other.progressbar))
							{
								other.progressbar = newClientHudElem(other);
								other.progressbar.x = int(192 / (-2.0));
								other.progressbar.y = 104;
								other.progressbar.alignX = "left";
								other.progressbar.alignY = "middle";
								other.progressbar.horzAlign = "center_safearea";
								other.progressbar.vertAlign = "center_safearea";
							}
							other.progressbar setShader("white", 0, 8);
							other.progressbar scaleOverTime(level.captime, 192, 8);
							
							other playsound("MP_bomb_plant");
							other linkto(self); 	// Stop Player moving while capping
							other disableWeapon();	// No guns while capping
							other.progresstime = 0; // Time player has been capping
								
							while(isAlive(other) && other useButtonPressed() && (other.progresstime < level.captime)) // Change Variables
							{
								other.progresstime += 0.05;
								wait 0.05;
							}
				
							other.progressbackground destroy(); // Destroy Bar Background
							other.progressbar destroy();		// Destroy Bar
							other enableWeapon();				// Enable Players Weapon
							other unlink();						// Unlink Player
							other.beingCapped = undefined;		// Nobody capping
								
							if(other.progresstime >= level.captime)	
							{
								if(level.roundended) break;
								self.isAvailable = 0;
								thread performObjectiveCompleteTasks(self, other, "bonus");
								self thread countdownUntilAvailable();
							}
							else
								continue;
						}
					} 
					else 
					{
						other iprintln(&"RBCNQ_NOT_YET_BONUS");
					}
				} 
				else 
				{
					other iprintln(&"RBCNQ_OBJ_NOT_CURRENT");
				}	
			} 
			else 
			{
				other iprintln(&"RBCNQ_NOT_TEAM_BONUS");
			}
		} //if isPlayer
		
		wait 0.5;
	} //outside for loop
}

countdownUntilAvailable(delayTime) 
{ 
	self.isAvailable = 0;
	if (!isdefined(delayTime)) 
	{
		if (isdefined(self.trigger.delay) && (self.trigger.delay > 0.5)) 
		{
			delayTime  = self.trigger.delay / 1000; //don't know why, but delay comes through as map # * 1000
		} 
		else 
		{
			delayTime = 60; 
		}
	}
	 
	printDebug ("Delay time on trigger is " + delaytime + " seconds.");
	wait delayTime;
	self.isAvailable = 1;
	thread updatePlayerInfo();
	if (isdefined(level.cnqCallbackBonusObjectiveRegen))
		thread [[level.cnqCallbackBonusObjectiveRegen]](self);
}

flipObjective(spawnObjective) 
{
	if (isOn(spawnObjective)) 
	{
		flipOff(spawnObjective);
	} 
	else 
	{
		flipOn(spawnObjective);
	}  
	  printObjectiveStates();
}

getNumObjectivesControlled( team ) 
{

  if (team == game["attackers"])  
    return level.objCount["attackers"];
  else
    return level.objCount["defenders"];
  
}

setObjectives() 
{
	deleteObjectivesFromHud();
	addObjectiveToHud_attackers(getNextObjective(game["attackers"]), game["attackers"]);
	addObjectiveToHud_defenders(getNextObjective(game["defenders"]), game["defenders"]);
}

addObjectiveToHud_attackers(objective, team) 
{
	if(isdefined(objective)) 
	{	
		hudIndex = 0;
		
		if(game["attackers"] == "allies")
		{
			objective_add(hudIndex, "current", objective.origin, game["objective_allies"]);
			objective_position(hudIndex, objective.origin);
			objective_team(hudIndex,team);
		}
		else
		{
			objective_add(hudIndex, "current", objective.origin, game["objective_axis"]);
			objective_position(hudIndex, objective.origin);
			objective_team(hudIndex,team);
		}
	}
}

addObjectiveToHud_defenders(objective, team) 
{
	if(isdefined(objective)) 
	{	

		hudIndex = 1;
		
		if(game["defenders"] == "axis")
		{
			objective_add(hudIndex, "current", objective.origin, game["objective_axis"]);
			objective_position(hudIndex, objective.origin);
			objective_team(hudIndex,team);
		}
		else
		{
			objective_add(hudIndex, "current", objective.origin, game["objective_allies"]);
			objective_position(hudIndex, objective.origin);
			objective_team(hudIndex,team);
		}
	}
}

deleteObjectivesFromHud() 
{
	objective_delete(0);
	objective_delete(1);
}

adjustObjectivesCount() 
{
	if ( isdefined(level.objCount) ) 
	{
		if (isdefined(level.objCount["attackers"]) )
			level.objCount["attackers"] = 0;	
		if (isdefined(level.objCount["defenders"]) )
			level.objCount["defenders"] = 0;
      
		for (n = 0; n < level.objectivearray.size; n++) 
		{	
			if (isOn(level.objectivearray[n])) 
			{
				level.objCount["attackers"] = level.objCount["attackers"] +1;
			} 
			else 
			{
				level.objCount["defenders"] = level.objCount["defenders"]+1;
			}
		}
	}
}

flipOff(objective) 
{
	objective.script_nodestate = "0";
	objective.team = game["defenders"];
}

flipOn(objective) 
{
	objective.script_nodestate = "1";
	objective.team = game["attackers"];
}

printObjectiveStates() 
{	
  if (drm_getCvar("scr_rbcnq_debug") != "1" )
    return;
    
	if (isdefined(level.objectivearray))  
	{
		for (n = 0; n < level.objectivearray.size; n++) 
		{
			spawnObjective = level.objectivearray[n];
			if ( isdefined(spawnObjective)) 
			{
				if (isOn(spawnObjective)) 
				{
					printDebug ("Objective number " + spawnObjective.script_idnumber + " is on.");
				} 
				else 
				{
					printDebug ("Objective number " + spawnObjective.script_idnumber + " is off.");
				}  
			}			
			else 
			{
				printDebug ("The spawnObjective at position " + n + " is not defined!!!!");
			}
		}
		
	} 
	else 
	{
		printDebug ("level.objectivearray is not defined!!!!");
	}
}

printDebug(text) 
{
  if (drm_getCvar("scr_rbcnq_debug") == "1" )
    iprintln ("DEBUG: " + text);
}

performObjectiveCompleteTasks(objective, player, objectiveType) 
{
	if (objectiveType == "spawn") 
	{
		flipObjective(objective);
		level.firstSwitchThrown = true;
	}
	
	awardPoints(player, objectiveType);
	  
	if (objectiveType == "spawn") 
	{
		if (isdefined(level.cnqCallbackSpawnObjectiveComplete))
		  thread [[level.cnqCallbackSpawnObjectiveComplete]](objective, player);
	} 
	else 
	{
		if (isdefined(level.cnqCallbackBonusObjectiveComplete))
		  thread [[level.cnqCallbackBonusObjectiveComplete]](objective, player);
	}
	  
	logAction(player);
	if(level.mapended) // if map is over, bail out
		return;
	
	updatePlayerInfo();
	displayGameMessage(objective, player, objectiveType);
}

updatePlayerInfo() 
{
  setObjectives();
  adjustObjectivesCount();
  setObjectiveTextAll(); 
}

displayGameMessage (objective, player, objectiveType) 
{
  
  if (isdefined (objective.script_objective_name))
    objectiveName = objective.script_objective_name;
  else 
    objectiveName = "the objective";

	message = player.name + " ^7has reached ^2" + objectiveName + "^7.";
  
	if(objectiveType == "spawn")
	{
		message = message + " The " + getColor(player.pers["team"]) + toUpper(player.pers["team"]) + " ^7are advancing!";

		if(player.pers["team"] == "allies")
		{
			level.allies_cap_count++;
			thread allies_cap_count();
			thread axis_sub_cap_count();
			player thread allied_ObjectiveSounds();
		}
		else
		{
			level.axis_cap_count++;
			thread axis_cap_count();
			thread allies_sub_cap_count();
			player thread axis_ObjectiveSounds();
		}
	}

	if(objectiveType == "bonus")
	{
		message = message + " The " + getColor(player.pers["team"]) + toUpper(player.pers["team"]) + " ^7have earned a bonus!";
		
		if(player.pers["team"] == "allies")
		{
			level.allies_cap_count++;
			thread allies_cap_count();
			thread axis_sub_cap_count();
			player thread allied_BonusObjSounds();
		}
		else if(player.pers["team"] == "axis")
		{
			level.axis_cap_count++;
			thread axis_cap_count();
			thread allies_sub_cap_count();
			player thread axis_BonusObjSounds();
		}
	}

	iprintln (message);  
	self setObjectiveTextAll(); 
}

logAction(player) 
{
 	lpselfnum = player getEntityNumber();
	lpselfname = player.name;
	lpselfteam = player.pers["team"];
	lpselfguid = player getGuid();
	logPrint("A;" + lpselfguid + ";" + lpselfnum + ";" + lpselfteam + ";" + lpselfname + ";" + "cnq_objective" + "\n");
}

awardPoints(player, objectiveType) 
{
	if(objectiveType == "bonus") 
	{
		playerPoints = level.player_bonus_points;
		teamPoints = level.team_bonus_points;
	} 
	else 
	{
		playerPoints = level.player_obj_points;
		teamPoints = level.team_obj_points;
	} 
	
	player.pers["score"] += playerPoints;
	player.score = player.pers["score"];
	player checkScoreLimit();
	player notify("update_playerscore_hud");

	if(level.ex_ranksystem && !level.ex_score)
	{
		if(objectiveType == "bonus") 
		{
			Points2 = level.player_bonus_points;
			level.ex_cnq_points2 = Points2;
			player.pers["special"]+= level.ex_cnq_points2;
		}
		else
		{
			Points1 = level.player_obj_points;
			level.ex_cnq_points = Points1;
			player.pers["special"]+= level.ex_cnq_points;
		}
	}
	
	teamscore = getTeamScore(player.pers["team"]);
	teamscore += teamPoints;
	setTeamScore(player.pers["team"], teamscore);
	
	level notify("update_teamscore_hud");
}

isOn(spawnObjective) 
{
  return (spawnObjective.script_nodestate == "1");
}

isOff(spawnObjective) 
{
  return (spawnObjective.script_nodestate == "0");
}

getColor( team ) 
{
	color = "^7";
	switch ( team ) 
	{
		case "allies":
			color = "^4";
			break;
			
		case "axis":
			color = "^1";
			break;
	}
	return ( color );
}


getNextObjective(team) 
{
	if (team == game["attackers"]) 
	{
    	  
		for (i = 0; i < level.objectivearray.size; i++) 
		{
			if (isOff(level.objectivearray[i])) 
			{
				return level.objectivearray[i];
			}
		}
		teamRole = "attackers";

	} 
	else 
	{ 
		for (i = level.objectivearray.size - 1; i >= 0; i--) 
		{
			if (isOn(level.objectivearray[i])) 
			{
				return level.objectivearray[i];
			}
		}
		teamRole = "defenders";

	}
	//no spawn objectives currently, so check for a bonus objective
	for (i = 0; i < level.bonus_objectives.size; i++) 
	{   
		available = 0;
		if (isdefined(level.bonus_objectives[i].isAvailable))
			available = level.bonus_objectives[i].isAvailable;
    
		if ( level.bonus_objectives[i].script_team == teamRole && (available == 1))
			return level.bonus_objectives[i];
	}
	//no current objective, return nil
	return undefined;
}

setObjectiveTextAll() 
{
    printDebug ("setObjectiveTextAll()  was called.");
	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
		setObjectiveText (players[i]);
  
}

setObjectiveText( player ) 
{
  	printDebug ("setObjectiveText( player )  was called.");
	nextObj = getNextObjective(player.pers["team"]);

	if (isdefined(nextObj)) 
	{
   		printDebug ("nextObj is defined.");
		if (isdefined (nextObj.script_objective_name))
		{
			objectiveName = nextObj.script_objective_name;
			printDebug ("nextObj.script_objective_name is defined and is " + objectiveName);
		}
		else
			objectiveName = "the next objective";

		objText = toUpper(player.pers["team"]) + "^7 must take ^2" + objectiveName + "^7";
	} 
	else 
	{
		if(player.pers["team"] == game["attackers"])
			objText = game["rbcnq_attackers_obj_text"];
		else if (player.pers["team"] == game["defenders"])
			objText = game["rbcnq_defenders_obj_text"];
		else
			objText = game["rbcnq_neutral_obj_text"];
	}

	player setClientCvar("cg_objectiveText", objText); 
}

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);
	}
}

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 iprintln(&"MP_YOU_WILL_RESPAWN_WITH_AN", weaponname);
			else
				self iprintln(&"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"];
		}
	}
}

allied_ObjectiveSounds()
{
	if(level.roundended || level.mapended)
		return;
	
	if(self.pers["team"] == "allies")
	{
		
		level thread playSoundOnPlayers("ctf_enemy_touchcapture", "allies");
		level thread playSoundOnPlayers("mp_announcer_objective_captured");
		wait 1;
		level thread playSoundOnPlayers(game["allies_area_secured"], "allies");
	}
	else
		level thread playSoundOnPlayers(game["german_losing_ground"], "axis");
}

axis_ObjectiveSounds()
{
	if(level.roundended || level.mapended)
		return;


		if(self.pers["team"] == "axis")
		{
			level thread playSoundOnPlayers("ctf_enemy_touchcapture", "axis");
			level thread playSoundOnPlayers("mp_announcer_objective_captured");
			wait 1;
			level thread playSoundOnPlayers(game["german_area_secured"], "axis");
		}
		else
			level thread playSoundOnPlayers(game["allies_losing_ground"], "allies");
	
}

allied_BonusObjSounds()
{
	if(level.roundended || level.mapended)
		return;

		
	if(self.pers["team"] == "allies")
	{	
		level thread playSoundOnPlayers("ctf_touchcapture", "allies");
		wait 1.4;
		level thread playSoundOnPlayers(game["allies_ground_taken"], "allies");
	}
	else
		level thread playSoundOnPlayers(game["german_losing_ground"], "axis");
}

axis_BonusObjSounds()
{
	if(level.roundended || level.mapended)
		return;
	

	if(self.pers["team"] == "axis")
	{
		level thread playSoundOnPlayers("ctf_touchcapture", "axis");
		wait 1.4;
		level thread playSoundOnPlayers(game["german_ground_taken"], "axis");
	}
	else
		level thread playSoundOnPlayers(game["allies_losing_ground"], "allies");

}

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);
	}
}

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_cap_count()
{
	self endon("disconnect"); 

	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_cap_count()
{
	self endon("disconnect");

	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;
	}
}

allies_sub_cap_count()
{
	self endon("disconnect");
	
	if(level.allies_cap_count == 0) return;
	
	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;
	}
}

axis_sub_cap_count()
{
	self endon("disconnect");
	
	if(level.axis_cap_count == 0) return;
	
	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;
	}
}

toUpper( str ) 
{
	return ( mapChar( str, "L-U" ) );
}

toLower( str ) 
{
	return ( mapChar( str, "U-L" ) );
}

mapChar( str, conv )
{
	if ( !isdefined( str ) || ( str == "" ) )
		return ( "" );

	switch ( conv )
	{
	  case "U-L":	case "U-l":	case "u-L":	case "u-l":
		from = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		to   = "abcdefghijklmnopqrstuvwxyz";
		break;
	  case "L-U":	case "L-u":	case "l-U":	case "l-u":
		from = "abcdefghijklmnopqrstuvwxyz";
		to   = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		break;
	  default:
	  	return ( str );
	}

	s = "";
	for ( i = 0; i < str.size; i++ )
	{
		ch = str[ i ];

		for ( j = 0; j < from.size; j++ )
			if ( ch == from[ j ] )
			{
				ch = to[ j ];
				break;
			}

		s += ch;
	}

	return ( s );
}
