#include extreme\_ex_weapons;

spawnCrates()
{
	thread extreme\_ex_logfile::Log("spawnCrates");
	level endon("ex_gameover");

	// use tdm spawns to allow increase crate deployment area
	spallie = getentarray("mp_tdm_spawn", "classname");
	spaxis = getentarray("mp_tdm_spawn", "classname");

	// fall back to dm spawns, just in case
	if(!spallie.size) spallie = getentarray("mp_dm_spawn", "classname");
	if(!spaxis.size) spaxis = getentarray("mp_dm_spawn", "classname");

	// email the map maker and tell them to make a decent map - ! ABORT !
	if(!spallie.size || !spaxis.size) return;

	// check if teambased
	if(!level.ex_teamplay) level.ex_amc_perteam = level.ex_amc_perteam / 2;

	// crates per team,
	amc_alliesmax = level.ex_amc_perteam;
	amc_axismax = amc_alliesmax;

	// minimum distance apart (40ft)
	min_dist_apart = 480;

	// spawn logic variables
	spawnteam = "allies";
	allie_spawn_num = 0;
	axis_spawn_num = 0;

	// spawn logic comparison arrays
	allies_spawnpoints = [];
	axis_spawnpoints = [];

	// crate spawn logic
	for(;;)
	{
		// thats enough, split!
		if(allie_spawn_num >= amc_alliesmax && axis_spawn_num >= amc_alliesmax) break;

		if(spawnteam == "allies") spawnpos = spallie[randomInt(spallie.size)];
		else spawnpos = spaxis[randomInt(spaxis.size)];
	
		findanother = false;
	
		if(spawnteam == "allies" && allie_spawn_num <= amc_alliesmax)
		{
			// team is allies, check if any other allie crates are near
			for(j = 0; j < allies_spawnpoints.size; j++)
				if(distance(spawnpos.origin, allies_spawnpoints[j].origin) < min_dist_apart) findanother = true;

			// seems ok, but check axis spawnpoints just in case
			if(!findanother)
			{
				for(j = 0; j < axis_spawnpoints.size; j++)
					if(distance(spawnpos.origin, axis_spawnpoints[j].origin) < min_dist_apart) findanother = true;
			}
	
			if(!findanother)
			{
				allies_spawnpoints[allie_spawn_num] = spawnpos;
				spawnCrate(spawnpos, "allies", "xmodel/prop_crate_smallshipping_open1");
				allie_spawn_num++;
				spawnteam = "axis";
			}
		}
		else if(axis_spawn_num <= amc_axismax) // team is axis, check if any other axis crates are near
		{
			for(j = 0; j < axis_spawnpoints.size; j++)
				if(distance(spawnpos.origin, axis_spawnpoints[j].origin) < min_dist_apart) findanother = true;

			// seems ok, but check allies spawnpoints just in case
			if(!findanother)
			{
				for(j = 0; j < allies_spawnpoints.size; j++)
					if(distance(spawnpos.origin, allies_spawnpoints[j].origin) < min_dist_apart) findanother = true;
			}

			if(!findanother)
			{
				axis_spawnpoints[axis_spawn_num] = spawnpos;
				spawnCrate(spawnpos, "axis", "xmodel/prop_mortar_crate2");
				axis_spawn_num++;
				spawnteam = "allies";
			}
		}

		wait 0.05;
	}
}

spawnCrate(spawnpoint, team, modeltype)
{
	thread extreme\_ex_logfile::Log("spawnCrate");

	position = spawnpoint.origin - ( 15, 15, 0) + ( randomInt(31), randomInt(31), 0);
	trace = bulletTrace(position,position+(0,0,-1200),false,undefined);
	ground = trace["position"];
	crate = spawn("script_model", ground+(0,0,-10000));
	crate setmodel (modeltype);
	crate.team = team;
	crate.origin = ground + (0,0,0);
	crate show();
	crate thread ammoCrateThink();
}

ammoCrateThink()
{
	thread extreme\_ex_logfile::Log("ammoCrateThink");

	level endon("ex_gameover");
	level endon("intermission");
	level endon("round_ended");
	level endon("map_ended");
	
	wait 5;
	
	while(!level.ex_gameover)
	{
		wait 0.05;

		//look for any players near enough to the crate to rearm
		players = getentarray("player", "classname");
		for(i = 0; i < players.size; i++)
		{
			// clear the rearming messages if present and team checking or rearming!
			if(isPlayer(players[i]) && isDefined(players[i].ex_amc_msg) && !isDefined(players[i].ex_amc_rearm) && !isDefined(players[i].ex_amc_check)) players[i] thread clearAmmoMsg();
			
			// if sprinting, don't try to rearm the player
			if(isPlayer(players[i]) && isDefined(players[i].ex_sprinting) && players[i].ex_sprinting || players[i] [[level.ex_getstance]](false) == 2) continue;

			if(isPlayer(players[i]) && players[i].sessionstate == "playing" && players[i] isOnGround() && !isDefined(players[i].ex_amc_rearm))
			{
				dist = distance(players[i].origin, self.origin);
				if(dist < 36) players[i] thread ammoCrateTeamCheck(self);
			}
		}
	}
}

ammoCrateTeamCheck(crate)
{
	thread extreme\_ex_logfile::Log("ammoCrateTeamCheck");

	level endon("ex_gameover");
	level endon("intermission");
	level endon("map_ended");

	self endon("disconnect");
	self endon("spawned");
	
	if(isDefined(self.ex_amc_check) || isDefined(self.ex_amc_rearm)) return;
	self.ex_amc_check = true;
	
	msg = undefined;
	
	while(isPlayer(self) && self.sessionstate == "playing"  && distance(self.origin, crate.origin) < 36 && self [[level.ex_getstance]](true) != 2)
	{
		if(crate.team != self.pers["team"] && level.ex_teamplay)
		{
			//display the message
			if(!isDefined(self.ex_amc_deny_displayed))
			{
				self.ex_amc_deny_displayed = true;

				if(crate.team == "allies")
				{
					switch(game["allies"])
					{
						case "american":	msg = &"AMMOCRATE_DENY_AMERICAN";	break;
						case "british":		msg = &"AMMOCRATE_DENY_BRITISH";		break;
						default:					msg = &"AMMOCRATE_DENY_RUSSIAN";		break;
					}
				}
				else msg = &"AMMOCRATE_DENY_GERMAN";

				self ammoCrateMessage(msg);
			}
		}
		else self thread ammoCratePlayerRearm(crate);

		wait 0.05;
	}

	self thread clearAmmoMsg();
	self.ex_amc_deny_displayed = undefined;
	self.ex_amc_check = undefined;
}

ammoCratePlayerRearm(crate)
{
	thread extreme\_ex_logfile::Log("ammoCratePlayerRearm");

	level endon("ex_gameover");
	level endon("intermission");
	level endon("map_ended");

	self endon("disconnect");
	self endon("spawned");
	
	if(isDefined(self.ex_amc_rearm)) return;
	self.ex_amc_rearm = true;
	
	monitor = true;

	// set the progress limit, check firstaid system on or off
	prog_limit = 5;
	if(level.ex_callformedic) prog_limit = 8;

	while(monitor && isPlayer(self) && self.sessionstate == "playing"  && distance(self.origin, crate.origin) < 36 && self [[level.ex_getstance]](true) != 2)
	{
		//display the message
		if(!isDefined(self.ex_amc_msg_displayed))
		{
			self.ex_amc_msg_displayed = true;
			self ammoCrateMessage(&"AMMOCRATE_ACTIVATE");
		}

		wait 0.05;

		// if sprinting, wait till the real weapon is put pack
		if(self getWeaponSlotWeapon("primary") == "sprint_mp") continue;

		// while there not pressing the USE key, wait!
		if(!self useButtonPressed()) continue;

		// make sure they want to rearm, and have not just stopped sprinting over one
		count = 0;
		while(self useButtonPressed() && count < 10)
		{
			wait 0.05;
			count++;
		}

		// they didn't want to rearm
		if(count < 10) continue;
		
		// ok, they're still holding so lets rearm them
		if(self useButtonPressed())
		{
			// if the bar graphic is not displayed, better had display it!
			if(!isDefined(self.pbgrd)) self thread extreme\_ex_utils::createBarGraphic(288, prog_limit);

			self linkTo(crate);

			progresstime = 0;
			count = 0;

			weaponsdone = undefined;
			grenadesdone = undefined;
			firstaiddone = undefined;
			self ammoCrateMessage(&"AMMOCRATE_REARMING_WEAPONS");

			while(isPlayer(self) && self useButtonPressed() && progresstime <= prog_limit)
			{
				wait 0.05;
				count++;

				if(count >= 20)
				{
					count = 0;
					progresstime++;
					continue;
				}

				if(progresstime == 2 && !isDefined(weaponsdone))
				{
					self thread replenishWeapons();
					self thread ammoCrateMessage(&"AMMOCRATE_REARMING_GRENADES");
					weaponsdone = true;
				}
				else if(progresstime == 5 && !isDefined(grenadesdone))
				{
					self thread replenishGrenades();
					if(level.ex_callformedic) self ammoCrateMessage(&"AMMOCRATE_REARMING_FIRSTAID");
					grenadesdone = true;
				}
				else if(progresstime == 8 && !isDefined(firstaiddone))
				{
					self thread replenishFirstaid();
					firstaiddone = true;
				}
			}

			// clear the bar graphic and reset the variables
			self unlink();
			self enableWeapon();
			self thread clearAmmoMsg();
			self thread extreme\_ex_utils::cleanBarGraphic();
			self.ex_amc_msg_displayed = undefined;
			self.ex_amc_rearm = undefined;
			monitor = false;
		}
	}

	// clear the bar graphic and reset the variables
	self unlink();
	self enableWeapon();
	self thread clearAmmoMsg();
	self thread extreme\_ex_utils::cleanBarGraphic();
	self.ex_amc_msg_displayed = undefined;
	self.ex_amc_rearm = undefined;
}

ammoCrateMessage(msg)
{
	level endon("ex_gameover");
	self endon("disconnect");
	self endon("ex_dead");

	switch(level.ex_amc_msg)
	{
		case 0:		self iprintln(msg); break;
		case 1:		self iprintlnbold(msg); break;
		case 2:		self thread extreme\_ex_utils::ex_hud_announce(msg, 0); break;
		default:		self thread ammoCrateOnScreenMsg(msg); break;
	}
}

ammoCrateOnScreenMsg(msg)
{
	self endon("disconnect");
	self endon("ex_dead");

	if(!isDefined(msg)) return;

	if(!isDefined(self.ex_amc_msg))
	{
		self.ex_amc_msg = newClientHudElem(self);
		self.ex_amc_msg.alignX = "center";
		self.ex_amc_msg.alignY = "middle";
		self.ex_amc_msg.x = 320;
		self.ex_amc_msg.y = 408;
		self.ex_amc_msg.alpha = 1;
		self.ex_amc_msg.sort = 1;
		self.ex_amc_msg.fontScale = 0.80;
	}

	self.ex_amc_msg setText(msg);
}

clearAmmoMsg()
{
	self endon("disconnect");
	self endon("ex_dead");

	if(isDefined(self.ex_amc_msg)) self.ex_amc_msg destroy();
	self.ex_amc_msg = undefined;
	self.ex_amc_msg_displayed = undefined;
}