#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
#include maps\mp\agents\_agent_utility;
#include maps\mp\gametypes\_damage;
#include maps\mp\bots\_bots_util;
#include maps\mp\bots\_bots_strategy;

//===========================================
// 				constants
//===========================================
CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_GAME		= 5;
CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_PLAYER 	= 2;


//===========================================
// 					init
//===========================================
init()
{
	level.killStreakFuncs["agent"] 			= ::tryUseSquadmate;
	level.killStreakFuncs["recon_agent"] 	= ::tryUseReconSquadmate;
}


//===========================================
// 				setup_callbacks
//===========================================
setup_callbacks()
{
	level.agent_funcs["squadmate"] = level.agent_funcs["player"];
	
	level.agent_funcs["squadmate"]["think"] 		= ::squadmate_agent_think;
	level.agent_funcs["squadmate"]["on_killed"]		= ::on_agent_squadmate_killed;
	level.agent_funcs["squadmate"]["on_damaged"]	= maps\mp\agents\_agents::on_agent_player_damaged;
	level.agent_funcs["squadmate"]["gametype_update"]= ::no_gametype_update;
}

no_gametype_update()
{
	return false;
}

//===========================================
// 				tryUseSquadmate
//===========================================
tryUseSquadmate( lifeId, streakName )
{
	return useSquadmate( "agent" );
}


//===========================================
// 			tryUseReconSquadmate
//===========================================
tryUseReconSquadmate( lifeId, streakName )
{
	return useSquadmate( "reconAgent" );
}


//===========================================
// 				useSquadmate
//===========================================
useSquadmate( killStreakType )
{
	// limit the number of active "squadmate" agents allowed per game
	if( getNumActiveAgents( "squadmate" ) >= CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_GAME )
	{
		self iPrintLnBold( &"KILLSTREAKS_AGENT_MAX" );
		return false;
	}
	
	// limit the number of active agents allowed per player
	if( getNumOwnedActiveAgents( self ) >= CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_PLAYER )
	{
		self iPrintLnBold( &"KILLSTREAKS_AGENT_MAX" );
		return false;
	}
		
	// try to spawn the agent on a path node near the player
	nearestPathNode = self getValidSpawnPathNodeNearPlayer( false, true );
	
	if( !IsDefined(nearestPathNode) )
	{
		return false;
	}

	// make sure the player is still alive before the agent trys to spawn on the player
	if( !isReallyAlive(self) )
	{
		return false;
	}
	
	spawnOrigin = nearestPathNode.origin;
	spawnAngles = VectorToAngles( self.origin - nearestPathNode.origin );
	
	agent = maps\mp\agents\_agents::add_humanoid_agent( "squadmate", self.team, undefined, spawnOrigin, spawnAngles, self, false, false, "veteran" );
	if( !IsDefined( agent ) )
	{
		self iPrintLnBold( &"KILLSTREAKS_AGENT_MAX" );
		return false;
	}
	
	agent.killStreakType = killStreakType;	
	
	if ( agent.killStreakType == "reconAgent" )
	{
		// 2013-06-26 wallace
		// At the time of this comment, giveLoadout runs and finishes execution immediately
		// We run sendAgentWeaponNotify and finishReconAgentLoadout since they block until giveLoadout sends its notify
		agent thread sendAgentWeaponNotify( "iw6_riotshield_mp" );
		agent thread finishReconAgentLoadout();
		agent thread maps\mp\gametypes\_class::giveAndApplyLoadout( self.pers["team"], "reconAgent", false );
		agent maps\mp\agents\_agent_common::set_agent_health( 250 ); 
		agent maps\mp\perks\_perkfunctions::setLightArmor();
	}
	else
	{
		agent maps\mp\perks\_perkfunctions::setLightArmor();
	}

	agent _setNameplateMaterial( "player_name_bg_green_agent", "player_name_bg_red_agent" );
	
	return true;
}

finishReconAgentLoadout()
{
	self  endon( "death" );
	self  endon( "disconnect" );
	level endon( "game_ended" );
	
	self waittill( "applyLoadout" );
	
	self maps\mp\perks\_perkfunctions::setLightArmor();
	self givePerk( "specialty_quickswap", false );
	self givePerk( "specialty_regenfaster", false );
}


//===========================================
// 			sendAgentWeaponNotify
//===========================================
sendAgentWeaponNotify( weaponName )
{
	self  endon( "death" );
	self  endon( "disconnect" );
	level endon( "game_ended" );
	
	self waittill( "applyLoadout" );
	
	if( !IsDefined(weaponName) )
		weaponName = "iw6_riotshield_mp";
	
	self notify( "weapon_change", weaponName );
}


//=======================================================
//				squadmate_agent_think
//=======================================================
squadmate_agent_think()
{
	self endon( "death" );
	self endon( "disconnect" );
	self endon( "owner_disconnect" );
	
	level endon( "game_ended" );
		
	while(1)
	{	
		// Squad mate agent prefers to have shield out when not in combat and guarding player
		self BotSetFlag( "prefer_shield_out", true );

		handled_by_gametype = self [[ self agentFunc("gametype_update") ]]();
		if ( !handled_by_gametype )
		{
			if ( !self bot_is_guarding_player( self.owner ) )
				self bot_guard_player( self.owner, 350 );
		}
		
		wait(0.05);
	}
}


//=======================================================
//				on_agent_squadmate_killed
//=======================================================
on_agent_squadmate_killed(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
{
	self maps\mp\agents\_agents::on_humanoid_agent_killed_common(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration, false);
		
	// award XP for killing agents
	if( IsPlayer( eAttacker ) && IsDefined(self.owner) && eAttacker != self.owner )
	{
		self.owner leaderDialogOnPlayer( "squad_killed" );
		self maps\mp\gametypes\_damage::onKillstreakKilled( eAttacker, sWeapon, sMeansOfDeath, iDamage, "destroyed_squad_mate" );
	}

	self maps\mp\agents\_agent_utility::deactivateAgent();
}
