// * AdmiralMOD by Matthias Lorenz, http://www.cod2mod.com *




main()
{


	SetupVars();
	

  	// * AdmiralMOD *  
    maps\mp\gametypes\_admiral_mod_vars::GetAMVars();

	//** Hinzugefügt für HELLZone_AM **//
	
	level.random_maplist = maps\mp\gametypes\_admiral_mod_player::ForAllPlayersRandomMaps();
	
	//** ---Ende für HELLZone_AM--- **//


	// * Mission-Pack *
	maps\mp\gametypes\_admiral_mod_xmission_engine::MissionEngineInit();


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

	level.autoassign = ::menuAutoAssign;
	level.allies = ::menuAllies;
	level.axis = ::menuAxis;
	level.spectator = ::menuSpectator;
	level.weapon = ::menuWeapon;
	level.endgameconfirmed = ::endMap;


	level.checkScoreLimit = ::checkScoreLimit;
}



SetupVars() {


	level.highscore_text_allies = "";
	level.highscore_text_axis 	= "";



}



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

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

	// server cvar overrides
	if(getCvar("scr_allies") != "")
		game["allies"] = getCvar("scr_allies");
	if(getCvar("scr_axis") != "")
		game["axis"] = getCvar("scr_axis");


	if(game["am_enabled"] == 1) {

		game["allies"] 					= game["am_allies"];
		game["axis"] 					= game["am_axis"];
		game["american_soldiertype"] 	= game["am_american_soldiertype"];
		game["british_soldiertype"] 	= game["am_british_soldiertype"];
		game["russian_soldiertype"] 	= game["am_russian_soldiertype"];
		game["german_soldiertype"]		= game["am_german_soldiertype"];
	}

	precacheStatusIcon("hud_status_dead");
	precacheRumble("damage_heavy");
	precacheString(&"PLATFORM_PRESS_TO_SPAWN");
	
	

	// * Mission-Pack *
	maps\mp\gametypes\_admiral_mod_xmission_engine::MissionEnginePrecache();



	// * AdmiralMOD *  
	if(game["am_enabled"] == 1) maps\mp\gametypes\_admiral_mod_precache::Precache();



	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\_hearticons::init();
	thread maps\mp\gametypes\_tnticons::init();
	thread maps\mp\gametypes\_damagefeedback::init();
	thread maps\mp\gametypes\_healthoverlay::init();
	thread maps\mp\gametypes\_objpoints::init();
	thread maps\mp\gametypes\_friendicons::init();
	thread maps\mp\gametypes\_spectating::init();
	thread maps\mp\gametypes\_grenadeindicators::init();

	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] = "tdm";
	maps\mp\gametypes\_gameobjects::main(allowed);

	// Time limit per map
	if(getCvar("scr_tdm_timelimit") == "")
		setCvar("scr_tdm_timelimit", "30");
	else if(getCvarFloat("scr_tdm_timelimit") > 1440)
		setCvar("scr_tdm_timelimit", "1440");
	level.timelimit = getCvarFloat("scr_tdm_timelimit");
	setCvar("ui_tdm_timelimit", level.timelimit);
	makeCvarServerInfo("ui_tdm_timelimit", "30");

	// Score limit per map
	if(getCvar("scr_tdm_scorelimit") == "")
		setCvar("scr_tdm_scorelimit", "300");
	level.scorelimit = getCvarInt("scr_tdm_scorelimit");
	setCvar("ui_tdm_scorelimit", level.scorelimit);
	makeCvarServerInfo("ui_tdm_scorelimit", "300");

	// Force respawning
	if(getCvar("scr_forcerespawn") == "")
		setCvar("scr_forcerespawn", "0");

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

	level.mapended = false;
	
//** hinzugefügt für HELLZone_AM **//

	level.teamplay = 1;

//** ---Ende für HELLZone_AM--- **//

	level.team["allies"] = 0;
	level.team["axis"] = 0;


	thread startGame();
	//thread maps\mp\gametypes\_teams::addTestClients();

	

	// * Mission-Pack Start *
	thread maps\mp\gametypes\_admiral_mod_xmission_engine::MissionEngineStart();
	
}

dummy()
{
	waittillframeend;

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





Callback_PlayerConnect()
{


	thread dummy();

	self.statusicon = "";
	self waittill("begin");
	self.statusicon = "";

	level notify("connected", self);

	//if(!level.splitscreen)	iprintln(&"MP_CONNECTED", self.name);
	
	

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


	// * AdmiralMOD *  
	if(game["am_enabled"] == 1){
	
		self maps\mp\gametypes\_admiral_mod_player::PlayerConnect(level.random_maplist);
	}



	if(game["state"] == "intermission")
	{
		spawnIntermission();
		return;
	}

	level endon("intermission");

	if(level.splitscreen)
		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(self.pers["team"] == "allies")
			self.sessionteam = "allies";
		else
			self.sessionteam = "axis";

		if(isDefined(self.pers["weapon"]))
			spawnPlayer();
		else
		{
			spawnSpectator();

			scriptMainMenu = self maps\mp\gametypes\_menus::am_menuSelection();

		}
	}
	else
	{
		self setClientCvar("ui_allow_weaponchange", "0");

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

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

		spawnSpectator();
	}

	self setClientCvar("g_scriptMainMenu", scriptMainMenu);




	self closeMenu(); 
	self closeInGameMenu();	

	self.pers["team"] = "spectator";
	self.sessionteam = "spectator";
	
	self allowSpectateTeam("allies", true);
	self allowSpectateTeam("axis", true);
	self allowSpectateTeam("freelook", false);	
	

	//spawnSpectator();		
	//spawnPlayer();


	
	// * Automatic-Bots nicht sofort spawnen *
	if(isDefined(self.pers["imabot_automatic"])) return;


	self maps\mp\gametypes\_admiral_mod_xmission_engine::GetSavedMissionDatas();



	if(!isDefined(self.pers["team"]) || (self.pers["team"] != "allies" && self.pers["team"] != "axis")) self menuAutoAssign();
	else {
	
		self notify("joined_team");
		self notify("end_respawn");
	}
	
	
	self maps\mp\gametypes\_weapons::givePistol();
	self maps\mp\gametypes\_weapons::giveGrenades();
	
	self.pers["weapon"] = "none";


	
	self spawnPlayer();
	
	
}

Callback_PlayerDisconnect()
{
	if(!level.splitscreen)
		iprintln(&"MP_DISCONNECTED", self.name);

	if(isdefined(self.pers["team"]))
	{
		if(self.pers["team"] == "allies")
			setplayerteamrank(self, 0, 0);
		else if(self.pers["team"] == "axis")
			setplayerteamrank(self, 1, 0);
		else if(self.pers["team"] == "spectator")
			setplayerteamrank(self, 2, 0);
	}
	
	lpselfnum = self getEntityNumber();
	lpGuid = self getGuid();
	logPrint("Q;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n");
	
	// * AdmiralMOD *  
	if(game["am_enabled"] == 1) self maps\mp\gametypes\_admiral_mod_player::PlayerDisconnect();
	
}

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

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


	// * Wenn Vote, dann kein Damage mehr *
	if(isDefined(level.vote_starting)) return;



	// * Wenn keine Submission läuft, dann kein kill möglich * 
	if(!isDefined(level.submission_is_runnning)) return;



	// * Weapon Damage Modifier *
	if(game["am_weapon_damage_modifiers"] == 1) {
	
		if(isDefined(sWeapon) && isDefined(sMeansOfDeath) && sMeansOfDeath != "MOD_MELEE") {
		
			iDamage = maps\mp\gametypes\_admiral_mod_weapons::ModifyWeaponDamage(iDamage,sWeapon);			
		}
	}


	// * Spawn Protection *
	if(game["am_enabled"] == 1 && game["am_player_spawn_protect"] == 1) {
	
		// * Spawn Protect hier nur wenn nicht Gas/Fire *
		if(!isDefined(sWeapon) || (isDefined(sWeapon) && sWeapon != "gas_grenade_mp" && sWeapon != "fire_grenade_mp")) {
	
			// * Gegner anzeigen das Spawn Protected *
			if(isPlayer(eAttacker) && isDefined(self.spawnProtection)) {

				self thread maps\mp\gametypes\_admiral_mod_player::PlayerSpawnProtection();	
			}

			// * Wenn getroffener Spieler Spawn Prodtected, dann kein Damage *
			if(isDefined(self.spawnProtection)) return;		
		}
	}

	if(sMeansOfDeath == "MOD_FALLING" && game["am_fall_damage_modifier"] > -1) iDamage = game["am_fall_damage_modifier"];



	// * AdmiralMOD *  
	if(game["am_enabled"] == 1) {
			
		if(isPlayer(eAttacker) && (self != eAttacker) && (self.pers["team"] == eAttacker.pers["team"]) ) {
			
			if(level.friendlyfire == "2")	eAttacker maps\mp\gametypes\_admiral_mod_player::PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);
			else							self maps\mp\gametypes\_admiral_mod_player::PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);	

		}
		else self maps\mp\gametypes\_admiral_mod_player::PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime);
	}



	if(isDefined(sWeapon) && (sWeapon == "gas_grenade_mp" || sWeapon == "fire_grenade_mp")) return;


	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(getCvarInt("g_debugDamage"))
	{
		println("client:" + self getEntityNumber() + " health:" + self.health +
			" damage:" + iDamage + " hitLoc:" + sHitLoc);
	}

	if(self.sessionstate != "dead")
	{
		lpselfnum = self getEntityNumber();
		lpselfname = self.name;
		lpselfteam = self.pers["team"];
		lpselfGuid = self getGuid();
		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;

	// 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";

	// * Bei Squads und wenn keine Submission läuft, keine Obituary's anzeigen * 
	if(game["am_squads"] != 1 && isDefined(level.submission_is_runnning)) obituary(self, attacker, sWeapon, sMeansOfDeath);


	// * AdmiralMOD *
	if(game["am_weapon_drop"] == 1) {
	
		self maps\mp\gametypes\_weapons::dropWeapon();
		self maps\mp\gametypes\_weapons::dropOffhand();
	}

	self.sessionstate = "dead";
	self.statusicon = "hud_status_dead";


	// * AdmiralMOD *
	if(game["am_enabled"] == 1) self maps\mp\gametypes\_admiral_mod_player::PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration);



	if(!isdefined(self.switching_teams))
		self.deaths++;

	lpselfnum = self getEntityNumber();
	lpselfname = self.name;
	lpselfguid = self getGuid();
	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.score--;
				}
			}

			if(isdefined(attacker.friendlydamage))
				attacker iprintln(&"MP_FRIENDLY_FIRE_WILL_NOT");
		}
		else
		{
			attackerNum = attacker getEntityNumber();
			doKillcam = true;

			if(self.pers["team"] == attacker.pers["team"]) // killed by a friendly
				attacker.score--;
			else
			{
				attacker.score++;						
			}
		}

		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.score--;

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

	level notify("update_teamscore_hud");

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

	// Stop thread if map ended on this death
	if(level.mapended)
		return;

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

	body = self cloneplayer(deathAnimDuration);


	// * AdmiralMOD *
	if(game["am_deathicons"] == 1) thread maps\mp\gametypes\_deathicons::addDeathicon(body, self.clientid, self.pers["team"], 5);



	delay = 2;	// Delay the player becoming a spectator till after he's done dying


	// * AdmiralMOD *
	if(game["am_squads"] == 1) {

		self thread maps\mp\gametypes\_admiral_mod_squad::SquadRespawnTimer();
	}	
	

	wait delay;	// ?? Also required for Callback_PlayerKilled to complete before respawn/killcam can execute

	if(!isDefined(self.pers["imabot_automatic"])) {
	
		if(doKillcam && level.killcam)
		self maps\mp\gametypes\_killcam::killcam(attackerNum, delay, psOffsetTime, true);
	}
	else {
	
		wait randomint(5) + 1;
		if(isDefined(body)) body delete();
	}
	
	

	// * Wenn Submission noch nicht läuft... sofortiger Respawn (Bots sofort Respawnen) *
	if(!isDefined(level.submission_is_runnning) || isDefined(self.pers["imabot_automatic"])) {
		
		self thread respawn();
	}
	else {

		// * Ansonsten Team-Spectate-Modus *
	
		wait 0.2;


		if(self.pers["team"] == "allies") {

			self allowSpectateTeam("allies", true);
			self allowSpectateTeam("axis", false);
		}
		if(self.pers["team"] == "axis") {

			self allowSpectateTeam("allies", false);
			self allowSpectateTeam("axis", true);
		}
		self allowSpectateTeam("freelook", false);
		self allowSpectateTeam("none", false);	

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

		currentorigin = self.origin;
		currentangles = self.angles;
		self thread spawnSpectator(currentorigin + (0, 0, 60), currentangles);
	}


}

spawnPlayer()
{

	
	// * Respawn vor Anfang der neuen Submission verhindern *
	
	
	
	if(game["am_gametype"] == "mm") {
	
		if(!isDefined(self.pers["imabot_automatic"]) && (isDefined(level.submission_is_runnning) || !isDefined(level.submission_spawn_allow))) {
		
			self.sessionteam = self.pers["team"]; // * Damit der teamwechsel sofort sichtbar wird *
			self iprintln(&"AM_MP_YOU_WILL_RESPAWN_NEXT_SUBMISSION");
			
			return;
		}		
		else {			
						
		}
	}
	
	

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


	resettimeout();

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


	// * AdmiralMOD *
	if(isDefined(self.pers["teamkiller"])) return;
	if(game["am_enabled"] == 1) self maps\mp\gametypes\_admiral_mod_player::SpawnPlayerPre();


	if(self.pers["team"] == "allies") 	self setClientCvar("cg_objectiveText", &"AM_MP_MMISSION_OBJECTIVE_TEXT",level.highscore_text_allies);
	if(self.pers["team"] == "axis") 	self setClientCvar("cg_objectiveText", &"AM_MP_MMISSION_OBJECTIVE_TEXT",level.highscore_text_axis);

	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;

	spawnpointname = "mp_tdm_spawn";
	spawnpoints = getentarray(spawnpointname, "classname");
	
	
	if(self.pers["team"] == "allies" && isDefined(level.spawnpoint_allies)) {
	
		spawnpoint = maps\mp\gametypes\_spawnlogic::NearestSpawnpoint(spawnpoints,level.spawnpoint_allies);
	}
	else if(self.pers["team"] == "axis" && isDefined(level.spawnpoint_axis)) {
	
		spawnpoint = maps\mp\gametypes\_spawnlogic::NearestSpawnpoint(spawnpoints,level.spawnpoint_axis);
	}
	else {
	
		spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(spawnpoints);
	}
	


	if(isDefined(self.pers["automatic_spawn_position"])) {
	
		self spawn(self.pers["automatic_spawn_position"] + (0,0,5), (0,0,0));
	}
	else 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"]);

	
	self maps\mp\gametypes\_weapons::clearWeaponSlots();

	self maps\mp\gametypes\_weapons::givePistol();
	self maps\mp\gametypes\_weapons::giveGrenades();
	self maps\mp\gametypes\_weapons::giveBinoculars();

	if(maps\mp\gametypes\_weapons::checkFreeSlotA() && isDefined(self.pers["weapon"]) && self.pers["weapon"] != "" && self.pers["weapon"] != "none") {
	
	 	self setWeaponSlotWeapon("primary", self.pers["weapon"]);
		self setWeaponSlotAmmo("primary", 999);
		self setWeaponSlotClipAmmo("primary", 999);		
		self setSpawnWeapon(self.pers["weapon"]);
	}
	else {
	
		second = self getweaponslotweapon("primaryb");
	
		if(isDefined(second) && second != "" && second != "none") {
	
			wait 0.1;
			self switchToWeapon(second);
		}
	}


	// * AdmiralMOD *
	self thread maps\mp\gametypes\_admiral_mod_squad::SquadRespawnTimerUpdate();


	waittillframeend;
	self notify("spawned_player");
	
	
	// * AdmiralMOD *
	if(game["am_enabled"] == 1) self maps\mp\gametypes\_admiral_mod_player::SpawnPlayerPost();


	// * Automatic Bot Positionieren *
	if(isDefined(self.pers["imabot_automatic"])) {

		
		if(!isDefined(self.pers["link"])) {
		
			self.pers["link"] = spawn("script_model", (0,0,0));	
			wait 0.1;			
		}
		
		self.pers["link"].origin = self.origin;
		
		self linkto(self.pers["link"]);

		self.pers["link"] moveto(self.pers["automatic_spawn_position"] + (0,0,2),0.1);
		wait 0.15;
	
	}		
}

spawnSpectator(origin, angles)
{
	self notify("spawned");
	self notify("end_respawn");

	resettimeout();

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


	// * AdmiralMOD *
	if(isDefined(self.pers["teamkiller"])) return;
	if(game["am_enabled"] == 1) self maps\mp\gametypes\_admiral_mod_player::SpawnSpectatorPre();


	self.sessionstate = "spectator";
	self.spectatorclient = -1;
	self.archivetime = 0;
	self.psoffsettime = 0;
	self.friendlydamage = undefined;

	if(self.pers["team"] == "spectator")
		self.statusicon = "";

	maps\mp\gametypes\_spectating::setSpectatePermissions();

	if(isDefined(origin) && isDefined(angles))
		self spawn(origin, angles);
	else
	{
		spawnpointname = "mp_global_intermission";
		spawnpoints = getentarray(spawnpointname, "classname");
		spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(spawnpoints);

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

	self setClientCvar("cg_objectiveText", level.highscore_text);
	
	
	// * AdmiralMOD *
	if(game["am_enabled"] == 1) self maps\mp\gametypes\_admiral_mod_player::SpawnSpectatorPost();
		
}

spawnIntermission()
{
	self notify("spawned");
	self notify("end_respawn");

	resettimeout();

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

	self.sessionstate = "intermission";
	self.spectatorclient = -1;
	self.archivetime = 0;
	self.psoffsettime = 0;
	self.friendlydamage = undefined;

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

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

	
	// * AdmiralMOD *
	self thread maps\mp\gametypes\_admiral_mod_squad::SquadRespawnTimerUpdate();

	self setClientCvar("cg_objectiveText", level.highscore_text);

}

respawn()
{

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

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


	// * AdmiralMOD *
	if(game["am_squads"] == 1) {

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

		
		
		// * AdmiralMOD *
		// * Wenn Waiting Timer bei Squad noch läuft, dann anzeigen *
		if(game["am_squads"] == 1 && isDefined(self.WaitingToSpawn)) {

			// * Respawn Timer Update *
			self thread maps\mp\gametypes\_admiral_mod_squad::SquadRespawnTimerUpdate();
		}
		
		
		
		while(isdefined(self.WaitingToSpawn)) wait .05;	

	}



	if(getCvarInt("scr_forcerespawn") <= 0)
	{
		self thread waitRespawnButton();
		self waittill("respawn");
	}

	self thread spawnPlayer();
}

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()
{
//** hinzugefügt für HELLZone_AM **//

	level.firstblood = 0;	//** Variabel für ersten Kill -FIRST BLOOD- **//

//	thread maps\mp\gametypes\_myaddon::Timeannouncer();
//	level.clock.color = (0,0,1); //** Farbe Clock **//
	
//** ---Ende für HELLZone_AM--- **//
}

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

	alliedscore = getTeamScore("allies");
	axisscore = getTeamScore("axis");


	if(alliedscore == axisscore)
	{
		winningteam = "tie";
		losingteam = "tie";
		text = &"MP_THE_GAME_IS_A_TIE";
	}
	else if(alliedscore > axisscore)
	{
		winningteam = "allies";
		losingteam = "axis";
		text = &"MP_ALLIES_WIN";
	}
	else
	{
		winningteam = "axis";
		losingteam = "allies";
		text = &"MP_AXIS_WIN";
	}


	// * AdmiralMOD *
	if(game["am_enabled"] == 1) maps\mp\gametypes\_admiral_mod::EndMapPre();



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

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

	if((winningteam == "allies") || (winningteam == "axis"))
	{
		logPrint("W;" + winningteam + winners + "\n");
		logPrint("L;" + losingteam + losers + "\n");
	}

	// set everyone's rank on xenon
	if(level.xenon)
	{
		players = getentarray("player", "classname");
		highscore = undefined;

		for(i = 0; i < players.size; i++)
		{
			player = players[i];
	
			if(!isdefined(player.score))
				continue;
	
			if(!isdefined(highscore) || player.score > highscore)
				highscore = player.score;
		}

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

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

			if(highscore <= 0)
				rank = 0;
			else
			{
				rank = int(player.score * 10 / highscore);
				if(rank < 0)
					rank = 0;
			}

			if(player.pers["team"] == "allies")
				setplayerteamrank(player, 0, rank);
			else if(player.pers["team"] == "axis")
				setplayerteamrank(player, 1, rank);
			else if(player.pers["team"] == "spectator")
				setplayerteamrank(player, 2, rank);
		}
		sendranks();
	}


	wait 10;
		
}


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

menuAutoAssign()
{
	numonteam["allies"] = 0;
	numonteam["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 == self)
			continue;

		numonteam[player.pers["team"]]++;
	}

	// if teams are equal return the team with the lowest score
	if(numonteam["allies"] == numonteam["axis"])
	{
		if(getTeamScore("allies") == getTeamScore("axis"))
		{
			teams[0] = "allies";
			teams[1] = "axis";
			assignment = teams[randomInt(2)];
		}
		else if(getTeamScore("allies") < getTeamScore("axis"))
			assignment = "allies";
		else
			assignment = "axis";
	}
	else {
	
		if(numonteam["allies"] < numonteam["axis"])	assignment = "allies";
		else										assignment = "axis";
	}


	
	if(isDefined(self.pers["team"]) && (self.pers["team"] == "allies" || self.pers["team"] == "axis") ) {
	
		assignment = self.pers["team"];
	}


	if(isDefined(self.pers["team"]) && assignment == self.pers["team"] && (self.sessionstate == "playing" || self.sessionstate == "dead"))
	{
	    if(!isdefined(self.pers["weapon"]))
	    {
		    if(self.pers["team"] == "allies")
			    self openMenu(game["menu_weapon_allies"]);
		    else
			    self openMenu(game["menu_weapon_axis"]);
	    }

		return;
	}

	if(!isDefined(self.pers["imabot_automatic"]) && isDefined(self.pers["team"]) && assignment != self.pers["team"] && (self.sessionstate == "playing" || self.sessionstate == "dead"))
	{
		self.switching_teams = true;
		self.joining_team = assignment;
		self.leaving_team = self.pers["team"];
		self suicide();
	}


	self.pers["team"] = assignment;
	self.pers["weapon"] = undefined;
	self.pers["savedmodel"] = undefined;


	self.pers["remember_player_class"] 		= -1;
	self.pers["preselected_player_class"] 	= -1;
	self.pers["player_class"] 				= -1;	

	self setClientCvar("ui_allow_weaponchange", "1");

	/*
	
	if(self.pers["team"] == "allies")
	{	
		self openMenu(game["menu_weapon_allies"]);
		self setClientCvar("g_scriptMainMenu", game["menu_weapon_allies"]);
	}
	else
	{	
		self openMenu(game["menu_weapon_axis"]);
		self setClientCvar("g_scriptMainMenu", game["menu_weapon_axis"]);
	}

	*/

	self notify("joined_team");
	self notify("end_respawn");
}

menuAllies()
{
	if(self.pers["team"] != "allies")
	{
		if(self.sessionstate == "playing")
		{
			self.switching_teams = true;
			self.joining_team = "allies";
			self.leaving_team = self.pers["team"];
			self suicide();
		}

		self.pers["team"] = "allies";
		self.pers["weapon"] = undefined;
		self.pers["savedmodel"] = undefined;


		self.pers["remember_player_class"] 		= -1;
		self.pers["preselected_player_class"] 	= -1;
		self.pers["player_class"] 				= -1;	

		self setClientCvar("ui_allow_weaponchange", "1");
		scriptMainMenu = self maps\mp\gametypes\_menus::am_menuSelection();
		//self setClientCvar("g_scriptMainMenu", scriptMainMenu);

		self notify("joined_team");
		self notify("end_respawn");
	}

	if(!isdefined(self.pers["weapon"])) {
	
		scriptMainMenu = self maps\mp\gametypes\_menus::am_menuSelection();
	}
}

menuAxis()
{
	if(self.pers["team"] != "axis")
	{
		if(self.sessionstate == "playing")
		{
			self.switching_teams = true;
			self.joining_team = "axis";
			self.leaving_team = self.pers["team"];
			self suicide();
		}

		self.pers["team"] = "axis";
		self.pers["weapon"] = undefined;
		self.pers["savedmodel"] = undefined;


		self.pers["remember_player_class"] 		= -1;
		self.pers["preselected_player_class"] 	= -1;
		self.pers["player_class"] 				= -1;	

		self setClientCvar("ui_allow_weaponchange", "1");
		scriptMainMenu = self maps\mp\gametypes\_menus::am_menuSelection();
		//self setClientCvar("g_scriptMainMenu", scriptMainMenu);

		self notify("joined_team");
		self notify("end_respawn");
	}

	if(!isdefined(self.pers["weapon"])) {
		
		scriptMainMenu = self maps\mp\gametypes\_menus::am_menuSelection();
	}
}

menuSpectator()
{
	if(self.pers["team"] != "spectator")
	{
		if(isAlive(self))
		{
			self.switching_teams = true;
			self.joining_team = "spectator";
			self.leaving_team = self.pers["team"];
			self suicide();
		}

		self.pers["team"] = "spectator";
		self.pers["weapon"] = undefined;
		self.pers["savedmodel"] = undefined;

		self.sessionteam = "spectator";
		self setClientCvar("ui_allow_weaponchange", "0");


		self.pers["remember_player_class"] 		= -1;
		self.pers["preselected_player_class"] 	= -1;
		self.pers["player_class"] 				= -1;	
		
		// * AdmiralMOD *
		self thread maps\mp\gametypes\_admiral_mod_squad::SquadRespawnTimerUpdate();
		
		spawnSpectator();

		if(level.splitscreen)
			self setClientCvar("g_scriptMainMenu", game["menu_ingame_spectator"]);
		else
			self setClientCvar("g_scriptMainMenu", game["menu_ingame"]);

		self notify("joined_spectators");
	}
}

menuWeapon(response)
{
	self endon("disconnect");


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

	if(level.splitscreen)
		self setClientCvar("g_scriptMainMenu", game["menu_ingame_onteam"]);
	else
		self setClientCvar("g_scriptMainMenu", game["menu_ingame"]);

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

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

		// * AdmiralMOD *
		if(isdefined(self.WaitingToSpawn))
		{
			self thread respawn();	
			self thread maps\mp\gametypes\_admiral_mod_squad::SquadRespawnTimerUpdate();		
		}
		else spawnPlayer();
			
		// **
		

		self thread printJoinedTeam(self.pers["team"]);
	}
	else
	{
		self.pers["next_spawn_weapon"] = weapon;
		
		self.pers["weapon"] = weapon;

		weaponname = maps\mp\gametypes\_weapons::getWeaponName(self.pers["weapon"]);


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

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


checkScoreLimit()
{
	waittillframeend;

	
}