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



/*
	Night Of The Zombies
	Objective: 	Score points for your team by eliminating players on the opposing team
	Map ends:	When one team reaches the score limit, or time limit is reached
	Respawning:	No wait / Near teammates

	Level requirements
	------------------
		Spawnpoints:
			classname		mp_tdm_spawn
			All players spawn from these. The spawnpoint chosen is dependent on the current locations of teammates and enemies
			at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.

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

	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.

		If using minefields or exploders:
			maps\mp\_load::main();

	Optional level script settings
	------------------------------
		Soldier Type and Variation:
			game["american_soldiertype"] = "normandy";
			game["german_soldiertype"] = "normandy";
			This sets what character models are used for each nationality on a particular map.

			Valid settings:
				american_soldiertype	normandy
				british_soldiertype		normandy, africa
				russian_soldiertype		coats, padded
				german_soldiertype		normandy, africa, winterlight, winterdark
*/

/*QUAKED mp_tdm_spawn (0.0 0.0 1.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies and near their team at one of these positions.*/

main()
{
  	// * 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--- **//



	// * NOZ - Vars * 
	game["am_forced_autoassign"] = 1;
	game["am_use_player_class_system"] = 0;
	game["am_boats"] = 0;
	game["am_secondary_weapon"] = 0;
	game["am_weapon_arsenal"] = 0;
	game["am_enable_weapon_enfield_for_american"] = 0;
	game["am_enable_weapon_thompson_for_axis"] = 0;
	game["am_give_players_thompson_second_weapon"] = 0;
	game["am_battlechatter"] = 0;
	game["am_climbing"] = 0;
	game["am_arm_hit_drop_weapon"] = 0;
	game["am_bleeding"] = 0;
	game["am_player_spawn_protect"] = 0;
	game["am_switch_incative_player_to_spectator"] = 1;
	game["am_switch_incative_player_to_spectator_waittime"] = 60;
	game["am_anti_teamkill"] = 0;
	game["am_show_team_score"] = 1;
	game["am_player_life_board"] = 1;
	game["am_healthbar"] = 1;
	game["am_health_regen"] = 0;
	game["am_health_drop"] = 0;
	game["am_enable_player_rank"] = 0;
	game["am_squads"] = 0;
	game["am_player_artillerie"] = 0;
	game["am_mortar_attacks"] = 0;
	game["am_max_turrets"] = 0;
	game["am_parachute"] = 0;
	game["am_down_by_leg_shot"] = 0;
	game["am_show_campers"] = 0;
	game["am_ambient_flyby_sounds"] = 0;
	game["am_weapon_damage_modifiers"] = 0;
	game["am_weapon_drop"] = 0;
	
	setcvar("scr_friendlyfire",0);


	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.scorelimit = 99999999; // * für Teamscore, damit kein Error entsteht *
	
	if(!isDefined(game["roundsplayed"])) game["roundsplayed"] = 0;	
	
}

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(!isDefined(game["alliedscore"]))	game["alliedscore"] = 0;
	if(!isDefined(game["axisscore"]))	game["axisscore"] = 0;




	level.compassstation[0]	= "objectivea";	
	level.compassstation[1]	= "objectiveb";	
	level.compassstation[2]	= "objectivec";	
	level.compassstation[3]	= "objectived";	


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

	precacheString(&"AM_MP_HUNTERS");
	precacheString(&"AM_MP_ZOMBIES");
	precacheString(&"AM_MP_ELIMINATE_HUNTERS");
	precacheString(&"AM_MP_ELIMINATE_ZOMBIES");
	precacheString(&"AM");
	precacheString(&"PM");

	precacheShader(level.compassstation[0]);
	precacheShader(level.compassstation[1]);
	precacheShader(level.compassstation[2]);
	precacheShader(level.compassstation[3]);

	precacheShader("hudStopwatch");
	precacheShader("hudstopwatchneedle");
		

	precacheModel("xmodel/prop_market_stands1");



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



	// * Für die Support Stationen *
	spawnpointname = "mp_dm_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_noz_timelimit") == "")
		setCvar("scr_noz_timelimit", "30");
	else if(getCvarFloat("scr_noz_timelimit") > 1440)
		setCvar("scr_noz_timelimit", "1440");
	level.timelimit = getCvarFloat("scr_noz_timelimit");
	setCvar("ui_noz_timelimit", level.timelimit);
	makeCvarServerInfo("ui_noz_timelimit", "30");

	// Round limit per map
	if(getCvar("scr_noz_roundlimit") == "")
		setCvar("scr_noz_roundlimit", "3");
	level.roundlimit = getCvarInt("scr_noz_roundlimit");
	setCvar("ui_noz_roundlimit", level.roundlimit);
	makeCvarServerInfo("ui_noz_roundlimit", "3");

	// Time length of each round
	if(getCvar("scr_noz_roundlength") == "") setCvar("scr_noz_roundlength", "5");
	else if(getCvarFloat("scr_noz_roundlength") > 10) 	setCvar("scr_noz_roundlength", "10");
	else if(getCvarFloat("scr_noz_roundlength") < 1) 	setCvar("scr_noz_roundlength", "1");
	level.roundlength = getCvarFloat("scr_noz_roundlength");
	setCvar("ui_noz_roundlength", level.roundlength);
	makeCvarServerInfo("ui_noz_roundlength", "5");

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



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


	if(!isdefined(game["matchstarted"]))
		game["matchstarted"] = false;


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

	level.teamplay = 1;

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

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


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


	// * Nach jeder Runde und Neustart die aktuellen Teampunkte anzeigen *
	setTeamScore("allies", game["alliedscore"]);
	setTeamScore("axis", game["axisscore"]);
			
	level notify("update_teamscore_hud");
	level notify("update_allhud_score");	

	
}

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



	self.pers["player_status"] = undefined;


	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(!level.xenon)
		{
			if(!isdefined(self.pers["skipserverinfo"])) self openMenu(game["menu_serverinfo"]);
			else self openMenu(game["menu_team"]);
		}
		else
			self openMenu(game["menu_team"]);


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

		spawnSpectator();
	}

	self setClientCvar("g_scriptMainMenu", scriptMainMenu);
	
	self thread LimitNOZWeapons();
	
}


LimitNOZWeapons() {

	self endon("disconnect");

	wait 1;


	if(game["am_night_of_zombies_more_weapons"] == 0) {
	
		// * NOZ Weapons *
		self setClientCvar("ui_allow_enfieldsniper", "0");
		self setClientCvar("ui_allow_kar98ksniper", "0");
		self setClientCvar("ui_allow_nagantsniper", "0");
		self setClientCvar("ui_allow_springfield", "0");
		self setClientCvar("ui_allow_svt40", "0");

		// Rifles
		self setClientCvar("ui_allow_enfield", "0");
		self setClientCvar("ui_allow_kar98k", "0");
		self setClientCvar("ui_allow_m1carbine", "0");
		self setClientCvar("ui_allow_m1garand", "0");
		self setClientCvar("ui_allow_nagant", "0");
		self setClientCvar("ui_allow_g43", "0");

		// MGs
		self setClientCvar("ui_allow_bar", "0");
		self setClientCvar("ui_allow_bren", "0");
		self setClientCvar("ui_allow_mp44", "0");
		self setClientCvar("ui_allow_ppsh", "0");

		//SMGs
		self setClientCvar("ui_allow_sten", "0");
		self setClientCvar("ui_allow_mp40", "0");
		self setClientCvar("ui_allow_thompson", "0");
		self setClientCvar("ui_allow_pps42", "0");
		self setClientCvar("ui_allow_greasegun", "0");

		// Shotgun
		self setClientCvar("ui_allow_shotgun", "1");

		// Grenades
		self setClientCvar("ui_allow_smokegrenades", "0");
		self setClientCvar("ui_allow_fraggrenades", "0");

		// Added Weapons
		self setClientCvar("ui_allow_panzerschreck", "0");
		self setClientCvar("ui_allow_30cal", "0");
		self setClientCvar("ui_allow_mg42", "0");		
	}
	else {
	
		// * NOZ Weapons *
		self setClientCvar("ui_allow_enfieldsniper", "1");
		self setClientCvar("ui_allow_kar98ksniper", "1");
		self setClientCvar("ui_allow_nagantsniper", "1");
		self setClientCvar("ui_allow_springfield", "1");
		self setClientCvar("ui_allow_svt40", "1");

		// Rifles
		self setClientCvar("ui_allow_enfield", "1");
		self setClientCvar("ui_allow_kar98k", "1");
		self setClientCvar("ui_allow_m1carbine", "1");
		self setClientCvar("ui_allow_m1garand", "1");
		self setClientCvar("ui_allow_nagant", "1");
		self setClientCvar("ui_allow_g43", "1");

		// MGs
		self setClientCvar("ui_allow_bar", "0");
		self setClientCvar("ui_allow_bren", "0");
		self setClientCvar("ui_allow_mp44", "0");
		self setClientCvar("ui_allow_ppsh", "0");

		//SMGs
		self setClientCvar("ui_allow_sten", "0");
		self setClientCvar("ui_allow_mp40", "0");
		self setClientCvar("ui_allow_thompson", "0");
		self setClientCvar("ui_allow_pps42", "0");
		self setClientCvar("ui_allow_greasegun", "0");

		// Shotgun
		self setClientCvar("ui_allow_shotgun", "1");

		// Grenades
		self setClientCvar("ui_allow_smokegrenades", "0");
		self setClientCvar("ui_allow_fraggrenades", "0");

		// Added Weapons
		self setClientCvar("ui_allow_panzerschreck", "0");
		self setClientCvar("ui_allow_30cal", "0");
		self setClientCvar("ui_allow_mg42", "0");			
	}

}


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;



	if(self.pers["team"] == "axis") iDamage = int(iDamage/5);



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


	// * Für Zombie Re-Alive *
	if(self.pers["team"] == "allies") 	self.pers["player_status"] = "zombie";
	if(self.pers["team"] == "axis") 	{
	
		self.pers["player_status"] = "dead_zombie";
		
		// * Zeitstempel anlegen für möglichen Respawn *
		self.pers["death_time"] = getTime();
	}



	// 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
	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");
	level notify("update_allhud_score");


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


	// * Wenn Hunter... dann toten Zombie wiederbeleben, aber nur wenn nicht der letzte war, sonst Round Ende *
	if(self.pers["team"] == "allies" && CheckHuntersAlive()) {
		
		// * Wenn ein Hunter getötet, dann ein Spectate-Zombie reaktivieren *
		level thread ReAliveZombie();
		
		// * Wenn Nachts, dann noch einen Spectate-Zombie reaktivieren  *
		if(isDefined(level.allow_two_zombies)) level thread ReAliveZombie();
	}




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

	

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

	if(doKillcam && level.killcam)
		self maps\mp\gametypes\_killcam::killcam(attackerNum, delay, psOffsetTime, true);


	// * Wenn Hunter... dann Zombie *
	if(self.pers["team"] != "axis") {

		self thread menuAxis();
	}
	else { // * Wenn Zombie... dann Spectate *
		
		place = self GetRespawnPosition();				
		if(place > -1 && CheckZombiesAlive() && CheckHuntersAlive()) self iprintlnbold(&"AM_MP_ZOMBIE_RESPAWN_INFORMATION", place);

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




ReAliveZombie() {

	// * Zombie der am längsten tod ist respawnen *
	
	while(isDefined(level.realive)) wait 0.1;
	level.realive = true;
	
	
	death_time = 1000000;
	zombie = undefined;

	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{
	
		if(players[i].sessionstate == "spectator" && isDefined(players[i].pers["player_status"]) && players[i].pers["player_status"] == "dead_zombie" && isDefined(players[i].pers["death_time"]) && players[i].pers["death_time"] < death_time) {
				
			death_time = players[i].pers["death_time"];
			zombie = players[i];				
		}
	}
	
	if(isDefined(zombie)) {
		
		zombie.pers["death_time"] = undefined;
		zombie thread respawn();
	}


	level.realive = undefined;
}



GetRespawnPosition() {

	self endon("disconnect");

	// * Wieviele vor dem Spieler noch respawnen *
	
	if(!isDefined(self.pers["death_time"])) return -1;
	
	death_time = self.pers["death_time"];
	
	
	place = 1;
	

	players = getentarray("player", "classname");
	for(i = 0; i < players.size; i++)
	{	
		if(players[i] != self && players[i].sessionstate == "spectator" && isDefined(players[i].pers["player_status"]) && players[i].pers["player_status"] == "dead_zombie" && isDefined(players[i].pers["death_time"]) && players[i].pers["death_time"] < death_time) {
				
			place++;			
		}
	}
	
	return place;
}







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


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


	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(!isdefined(self))
		return;


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

	if(self.pers["team"] == "allies")
	{
		self setClientCvar("cg_objectiveText", &"AM_MP_ELIMINATE_ZOMBIES");
	}
	else
		self setClientCvar("cg_objectiveText", &"AM_MP_ELIMINATE_HUNTERS");



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


	// * Wenn Spieler ein Hunter ist *
	if(self.pers["team"] == "allies") self thread StartLoseHealth(self.clientid, self.pers["team"]);


	// * Zombies haben keine Munition *
	if(self.pers["team"] == "axis") {
	
		self setWeaponSlotAmmo("primary", 0);
		self setWeaponSlotClipAmmo("primary", 0);		
		self setWeaponSlotAmmo("primaryb", 0);
		self setWeaponSlotClipAmmo("primaryb", 0);		
	}
	

}

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", "");
	
	
	// * 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");

	
}

respawn()
{

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

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



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

	setExpFog(0.005, 0.2, 0.2, 0.2, 1);	
	

	thread StartRound();

		
		
	if(game["matchstarted"]) {
	
	
		// * NOZ - Fog * 
		level thread Fogging();
		
	//** 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--- **//


		// 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"]))
				player.statusicon = "hud_status_dead";
		}


		level thread CheckWin();


		wait((level.roundlength * 60));

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

		
		// * Prüfen ob Maptime überschritten *
		checkTimeLimit();
		
		// * Ansonsten Rundenende *
		iprintln(&"MP_TIMEHASEXPIRED");
		level thread endMap();
	}
}



StartRound() {


	// * Beim Rundenstart kein Spawn mehr zulassen *
	if(game["matchstarted"] && CheckPlayerCountEachTeam()) 	level.roundended = false;

	
	if(!game["matchstarted"]) {
	
		// * Beim warten auf Spieler Spawn zulassen *
		level.roundended = true;
		
	
		// * Warten bis in jedem Team mind. 1 Spieler *
		while(!CheckPlayerCountEachTeam()) wait 1;
	}

	level.starttime = getTime();


	if(level.timelimit > 0)	{
	
		if(isDefined(level.clock)) level.clock destroy();
	
		level.clock = newHudElem();
		level.clock.horzAlign = "left";
		level.clock.vertAlign = "top";
		level.clock.x = 8;
		level.clock.y = 2;
		level.clock.font = "default";
		level.clock.fontscale = 2;
		level.clock setTimer(level.roundlength * 60);
		level.clock.color = (.98, .827, .58);

		if((isDefined(game["am_show_time"]) && game["am_show_time"] == 0) || !game["matchstarted"]) level.clock.alpha = 0;


		// * AdmiralMOD *
		level.clock.sort = 50;
	}



	if(!game["matchstarted"]) {
		

		zeit = 20; // * 20 Sekunden *
		

		// * Auf alle Spieler warten *
		waittimer = newHudElem();
		waittimer.x = 288;
		waittimer.y = 208;
		waittimer.horzAlign = "left";
		waittimer.vertAlign = "top";
		waittimer setClock(zeit, 60, "hudStopwatch", 64, 64);

		iprintln(&"MP_MATCHSTARTING");
		
		wait zeit;

		if(isDefined(waittimer)) waittimer destroy();


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


		game["matchstarted"] = true;
		
		level.mapended = false;
				
		game["state"] = "playing";
		level notify("restarting");
		
							
		map_restart(true);		
	}



}









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


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


	// * Damit connected Players während noch nicht alle Runden gespielt auch spawnen können *
	if(game["roundsplayed"] < level.roundlimit) {
	
		level.mapended = false;
		game["state"] = "playing";
		level notify("restarting");
	}
	


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


	if(isDefined(level.clock)) level.clock destroy();


	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"]]++;
	}

	winningteam = "tie";
	
	if(level.exist["allies"] > 0 && level.exist["axis"] > 0) 	winningteam = "tie";
	else if(level.exist["allies"] > 0) 							winningteam = "allies";
	else if(level.exist["axis"] > 0) 							winningteam = "axis";
	

	
	
	if(winningteam == "allies")
	{
		game["alliedscore"]++;
		setTeamScore("allies", game["alliedscore"]);

		winningteam = "allies";
		losingteam = "axis";
		text = &"AM_MP_HUNTERS_WIN";
	}
	else if(winningteam == "axis")
	{
		game["axisscore"]++;
		setTeamScore("axis", game["axisscore"]);

		winningteam = "axis";
		losingteam = "allies";
		text = &"AM_MP_ZOMBIES_WIN";
	}
	else
	{
		winningteam = "tie";
		losingteam = "tie";
		text = &"AM_MP_NOBODY_WIN";
	}
	
	
	level notify("update_teamscore_hud");
	level notify("update_allhud_score");
	
	
	iprintlnbold(text);
	wait 8;
	
	// * AdmiralMOD *
	if(game["am_enabled"] == 1) maps\mp\gametypes\_admiral_mod::EndMapPre();
	
		

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

	// * Time AND Rounds Check * 
	if(timepassed < level.timelimit && game["roundsplayed"] < level.roundlimit) {


		// * Alle Spieler Spectator *
		players = getentarray("player", "classname");
		for(i = 0; i < players.size; i++) {
			
			players[i].pers["team"] = "spectator";
			players[i].sessionteam = "spectator";
			
			players[i] spawnSpectator();
		}


		if(!CheckPlayerCountEachTeam()) iprintlnbold(&"AM_MP_WAITING_FOR_PLAYERS");
		
		// * Warten bis in jedem Team mind. 1 Spieler *
		while(!CheckPlayerCountEachTeam()) wait 1;


		iprintlnbold(&"AM_MP_START_NEXT_ROUND");


		zeit = 15;		

		// * Auf alle Spieler warten *
		waittimer = newHudElem();
		waittimer.x = 288;
		waittimer.y = 208;
		waittimer.horzAlign = "left";
		waittimer.vertAlign = "top";
		waittimer setClock(zeit, 60, "hudStopwatch", 64, 64);
		
		wait zeit;

		if(isDefined(waittimer)) waittimer destroy();


		level.mapended = false;

		game["state"] = "playing";
		level notify("restarting");


		map_restart(true);

	}
	else {

		// * Time * 
		if(timepassed > level.timelimit) {

			iprintlnbold(&"MP_TIME_LIMIT_REACHED");
			
			wait 5;
		}



	
		winners = "";
		losers = "";


		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;

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


		exitLevel(false);
		
	}
}

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

	timepassed = (getTime() - level.starttime) / 1000;
	timepassed = timepassed / 60.0;

	if(timepassed < level.timelimit)
		return;

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

	iprintln(&"MP_TIME_LIMIT_REACHED");
		
		
	level thread endMap();
}


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

			level.timelimit = timelimit;
			setCvar("ui_noz_timelimit", level.timelimit);
			level.starttime = getTime();

			if(level.timelimit > 0)
			{
				if(!isDefined(level.clock))
				{
					level.clock = newHudElem();
					level.clock.horzAlign = "left";
					level.clock.vertAlign = "top";
					level.clock.x = 8;
					level.clock.y = 2;
					level.clock.font = "default";
					level.clock.fontscale = 2;
				}
				level.clock setTimer(level.timelimit * 60);
			}
			else
			{
				if(isDefined(level.clock))
					level.clock destroy();
			}

			checkTimeLimit();
		}

		roundlimit = getCvarInt("scr_noz_roundlimit");
		if(level.roundlimit != roundlimit)
		{
			level.roundlimit = roundlimit;
			setCvar("ui_noz_roundlimit", level.roundlimit);			
		}

		roundlength = getCvarInt("scr_noz_roundlength");
		if(level.roundlength != roundlength)
		{
			level.roundlength = roundlength;
			setCvar("ui_noz_roundlength", level.roundlength);			
		}

		
		wait 1;
	}
}

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

menuAutoAssign()
{

	if(!level.xenon && isdefined(self.pers["team"]) && (self.pers["team"] == "allies" || self.pers["team"] == "axis"))
	{
		self openMenu(game["menu_team"]);
		return;
	}



	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(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(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")
	{	
		scriptMainMenu = self maps\mp\gametypes\_menus::am_menuSelection();
		//self openMenu(game["menu_weapon_allies"]);
		//self setClientCvar("g_scriptMainMenu", game["menu_weapon_allies"]);
	}
	else
	{	
		scriptMainMenu = self maps\mp\gametypes\_menus::am_menuSelection();
		//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(!level.xenon && !maps\mp\gametypes\_teams::getJoinTeamPermissions("allies"))
		{
			self openMenu(game["menu_team"]);
			return;
		}


		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(!level.xenon && !maps\mp\gametypes\_teams::getJoinTeamPermissions("axis"))
		{
			self openMenu(game["menu_team"]);
			return;
		}


		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;	

		
		
		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;

	
	// * Wenn zu den Allies gewechselt (über Spectator), dann Zombie-EIntrag löschen *
	if(self.pers["team"] == "allies") self.pers["player_status"] = undefined;
	

	// * Nur Spawnen, wenn Runde zuende, oder ein Hunter gerade getötet und zu den Axis gewechselt => Autospawn *
	if(!isDefined(self.pers["weapon"]) && (level.roundended || (isDefined(self.pers["player_status"]) && self.pers["player_status"] == "zombie" && self.pers["team"] == "axis") ))	{
		
		self.pers["weapon"] = weapon;

		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(self.pers["team"] == "allies") {
		
			self iprintln(&"AM_MP_YOU_WILL_SPAWN_NEXT_ROUND_AS_HUNTER");			
		}
		else if(self.pers["team"] == "axis") {
					
			self iprintln(&"AM_MP_YOU_WILL_SPAWN_NEXT_ROUND_AS_ZOMBIE");
		}
	}
	

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


Fogging() {


	self notify("Fogging");
	self endon("Fogging");

	nebel_start			= 0.002;
	nebel_ziel 			= 0.005;
	nebel_schritt 		= 0.00002;
	
	nacht_start			= 0.5;
	nacht_ziel 			= 0.0;
	nacht_schritt 		= 0.005;
	stunden_step 		= 24/((nacht_start/nacht_schritt)*2);
	
	
	nebel = nebel_start;
	nacht = nacht_start;
	

	modus = 1;
	stunde = 0;
	k = "am";

	
	font_size 	= 1.2;
	font_color	= (1,.2,.2);


	level maps\mp\gametypes\_admiral_mod_hud::deleteLevelHudElementByName("noz_day_clock");
	level maps\mp\gametypes\_admiral_mod_hud::createLevelTextHudElement("noz_day_clock", 310, 25,"center","middle","fullscreen","fullscreen",false, undefined, 0,font_size,0,1,1,1,1);
	level maps\mp\gametypes\_admiral_mod_hud::deleteLevelHudElementByName("noz_day_clock_am");
	level maps\mp\gametypes\_admiral_mod_hud::createLevelTextHudElement("noz_day_clock_am", 330, 25,"center","middle","fullscreen","fullscreen",false, &"AM", undefined,font_size,0,1,1,1,1);

	
	while(1) {

		wait 0.5;
		
		
		stunde += stunden_step;
		
		uhrzeit = int(stunde);
		if(uhrzeit > 23) uhrzeit = 0;

		if(uhrzeit < 4 && uhrzeit > 20) level.allow_two_zombies = true;
		else							level.allow_two_zombies = undefined;

			
		if(uhrzeit > 11) 					k = "am";			
		if(uhrzeit >= 0 && uhrzeit <= 11) 	k = "pm";
				
		if(uhrzeit > 11) uhrzeit = uhrzeit - 12;
		
		
		
		
		level maps\mp\gametypes\_admiral_mod_hud::changeLevelTextHudElementByName("noz_day_clock", undefined, uhrzeit,1.4,1,font_color);
		
		if(k == "am") 	level maps\mp\gametypes\_admiral_mod_hud::changeLevelTextHudElementByName("noz_day_clock_am", &"AM", undefined,font_size,1,font_color);
		else			level maps\mp\gametypes\_admiral_mod_hud::changeLevelTextHudElementByName("noz_day_clock_am", &"PM", undefined,font_size,1,font_color);
			
	
		if(modus == 1) {
					
			nacht = nacht - nacht_schritt;
			nebel = nebel + nebel_schritt;
		}
		else {
					
			nacht = nacht + nacht_schritt;
			nebel = nebel - nebel_schritt;
		}


		if(nacht <= nacht_ziel) {
			
			
			modus = 2;
			
			continue;
		}
		if(nacht >= nacht_start) {
						
			modus = 1;	
			stunde = 0;
			
			continue;
		}

				

		setExpFog(nebel, nacht, nacht, nacht, 1);		
	}
	
}



initStations() {

	
	stations = [];
	
	
	spawnpoints = getentarray("mp_dm_spawn", "classname");
	
	j = randomInt(spawnpoints.size);
	
	stations[0] = spawnpoints[j];	
	//logprint("station "+stations.size+ " : " + spawnpoints[j].origin + "\n");
	
	
	trys = 0;
	while(stations.size < 4) {
	
		trys++;
		if(trys > 100) break;
	
		j = randomInt(spawnpoints.size);
	
		
		near = false;
		for(i=0;i<stations.size;i++) {
	
			if(distance(spawnpoints[j].origin,stations[i].origin) < 1000) {
			
				near = true;
				break;
			}
		}	
		if(near == true) continue;
		
		stations[stations.size] = spawnpoints[j];			
		//logprint("station "+stations.size+ " : " + spawnpoints[j].origin + "\n");		
	}
	
	//logprint("Trys: " + trys + "\n");		



	for(i=0;i<stations.size;i++) {
	
	
		team 							= "none";			
			
		stations[i].home_origin 		= stations[i].origin;
		stations[i].home_angles 		= stations[i].angles;
		
		stations[i].stationmodel 	= spawn("script_model", stations[i].home_origin);
		stations[i].stationmodel.angles 		= stations[i].home_angles;
		stations[i].stationmodel setmodel("xmodel/prop_market_stands1");
	
		stations[i].team 				= team;
		stations[i].objective 			= i;
		stations[i].compassstation 		= level.compassstation[i];

		objective_add(stations[i].objective, "current", stations[i].origin, stations[i].compassstation);

			
		stations[i] thread StationThink();		

	}	
	
	level.stations = stations;	

}



StationThink() {


	while(level.mapended == false) {
	
		// * Auf einen Spieler warten *
	
		other = maps\mp\gametypes\_admiral_mod_player::WaitForRadius(self.origin, 80, 50);

		if(other.sessionstate == "playing" && isDefined(other.pers["team"]) && other.pers["team"] == "allies") {

			other thread PlayerRefresh();
		}
		
				
		wait 10;
	}
}



PlayerRefresh() {


	self endon("disconnect");
	self endon("killed_player");
	
		
			
	self.health = self.maxhealth;
		

	healthBarData = self maps\mp\gametypes\_admiral_mod_hud::getPlayerHudElementDataByName("healthbar_health");

	// * Wenn Healthbar des Players nicht mehr vorhanden, dann raus hier! *
	if(!isDefined(healthBarData)) return;


	if(healthBarData["width"] < 1) 	width = 1;
	else 							width = healthBarData["width"];

	newWidth = int((width/100) * self.health);

	gruen 	= ((1.0/width)*newWidth) * 0.8;
	rot 	= 1 - gruen;

	newcolor = (rot,gruen,healthBarData["color"][2]);

	self maps\mp\gametypes\_admiral_mod_hud::changePlayerHudElementByName("healthbar_health",healthBarData["shader"],newWidth,healthBarData["height"],0.7,newcolor);


	// * Wenn Gesundheitszustand wieder ok, dann Sprinten möglich *
	if(self.health > game["am_deny_sprinting_health"]) {

		self.pers["deny_sprinting_health"] = undefined;			
	}


	self.show_heart_icon = undefined;	
	
	self playSound("health_pickup_large");  	
	wait 0.2;
	
	
	
	self giveMaxAmmo(self maps\mp\gametypes\_weapons::getPistolType());
		
	self setWeaponSlotAmmo("primary", 999);
	self setWeaponSlotAmmo("primaryb", 999);	
	
	
	self playsound("weap_pickup",self.origin);
	wait 0.5;

	
	
	
	self setClientCvar("am_ui_player_info_text", "@AM_MP_LNG_PLAYER_REFRESH");
	self.pers["am_ui_player_info_text"] = "AM_MP_LNG_PLAYER_REFRESH";
	wait 2;
	self setClientCvar("am_ui_player_info_text", " ");
	self.pers["am_ui_player_info_text"] = " ";
		
}




CheckWin() {


	wait 1;



	while(!level.mapended && !level.roundended) {
			

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

		level.inTeam["allies"] = 0;
		level.inTeam["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"]]++;
		}

		// * Wenn in jedem Team Spieler bei einem Team alle Spieler down ... *
		if(level.exist["allies"] == 0 || level.exist["axis"] == 0 && (!level.mapended && !level.roundended)) {

			level.mapended = true;
			level thread endMap();
			break;
		}
		
		
		wait 1;
	}
}




StartLoseHealth(client_id, client_team) {


	self endon("spawned");
	self endon("disconnect");
	self endon("killed_player");


	if(!isDefined(client_id) || !isDefined(client_team)) return;

 	

	if(game["am_error_logfile"] == 1) logPrint("StartLoseHealth\n");


	wait 0.1;
	self maps\mp\gametypes\_admiral_mod_hud::updateHealthBar("healthbar",self.health);


	wait 1;


	
	while(1) {

		wait 1;


		self.health = self.health - 1;		
		if(self.health < 1) {
		
			self suicide();
			break;
		}
		self maps\mp\gametypes\_admiral_mod_hud::updateHealthBar("healthbar",self.health);
		
	}
}



CheckPlayerCountEachTeam() {

	if(game["am_error_logfile"] == 1) logPrint("CheckPlayerCountEachTeam\n");

	
	allies 	= 0;
	axis 	= 0;
	
	
	mind_one_player = false;
		
	players = getentarray("player", "classname");
	
	for(i=0;i<players.size;i++) {
		
		
		if(isDefined(players[i].pers["imabot"])) {
		
		}
		else mind_one_player = true;
		
		
		if(isDefined(players[i].pers["team"])) {

			if(players[i].pers["team"] == "allies") allies++;
			if(players[i].pers["team"] == "axis") 	axis++;
		}
	}
	 
	
	if(allies > 0 && axis > 0 && mind_one_player == true) return true;
	
	return false;

}


CheckHuntersAlive() {

	if(game["am_error_logfile"] == 1) logPrint("CheckHuntersAlive\n");

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

			if(players[i].pers["team"] == "allies" && players[i].sessionstate == "playing") allies++;			
		}
	}
	 
	
	if(allies > 0) return true;
	
	return false;
}


CheckZombiesAlive() {

	if(game["am_error_logfile"] == 1) logPrint("CheckZombiesAlive\n");

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

			if(players[i].pers["team"] == "axis" && players[i].sessionstate == "playing") axis++;			
		}
	}
	 
	
	if(axis > 0) return true;
	
	return false;
}