//=========================================================
// Crea un Zombi sin colisiones.
//=========================================================
CAI_BaseNPC *CDirectorSpawn::MakeNoCollisionNPC(bool Horde, bool disclosePlayer)
{
	// Desactivado
	if ( Disabled )
		return NULL;

	// Creamos el NPC normalmente.
	CAI_BaseNPC *pNPC = MakeNPC(Horde, disclosePlayer, false);

	// Emm... ¿puso todas las clases en "no crear"? :genius:
	if ( !pNPC )
	{
		Warning("[DIRECTOR NPC] Ha ocurrido un problema al intentar crear un zombie. \r\n");
		return NULL;
	}

	// Lugar de creación.
	pNPC->SetAbsOrigin(GetAbsOrigin());
	// No colisiona con otros NPC's.
	pNPC->SetCollisionGroup(COLLISION_GROUP_SPECIAL_NPC);

	return pNPC;
}
//=========================================================
// Crea un hijo en la ubicación especificada.
//=========================================================
bool CDirector_Manager::AddChild(const Vector &vecPosition, int flag)
{
	// No se ha podido acceder al Director.
	if ( !Director() )
		return false;

	// No es posible crear un hijo aquí.
	if ( !CanMake(vecPosition) )
		return false;

	// Creamos un hijo de la lista.
	const char *pChildName	= GetChildClass();
	CAI_BaseNPC *pChild		= (CAI_BaseNPC *)CreateEntityByName(pChildName);

	QAngle angles = RandomAngle(0, 360);
	angles.x = 0.0;
	angles.z = 0.0;	
	pChild->SetAbsAngles(angles);

	// Establecemos la ubicación de creación.
	pChild->SetAbsOrigin(vecPosition);

	// Debe caer al suelo y desaparecer.
	pChild->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);
	pChild->AddSpawnFlags(SF_NPC_FADE_CORPSE);

	UTIL_DropToFloor(pChild, MASK_SOLID);

	ConVarRef director_debug("director_debug");

	DispatchSpawn(pChild);
	pChild->SetOwnerEntity(Director());
	DispatchActivate(pChild);

	// ¡¡NO CAMBIAR!!
	pChild->SetName(MAKE_STRING(CHILD_NAME));

	// Sin colisiones.
	if ( flag == SPAWN_NO_COLLISION || flag == SPAWN_NO_COLLISION_AND_POWERFUL )
	{
		pChild->SetCollisionGroup(COLLISION_GROUP_SPECIAL_NPC);
		Vector vecOriginRadius;

		if ( Director()->Status == PANIC && RandomInt(0, 4) == 2 )
			pChild->SetCollisionGroup(COLLISION_GROUP_NPC);

		// Intentamos crearlo en un radio de 100
		if ( CAI_BaseNPC::FindSpotForNPCInRadius(&vecOriginRadius, vecPosition, pChild, 150, false) )
		{
			// Evitamos que se mueva por debajo del suelo.
			vecOriginRadius.z = vecPosition.z;

			// Movemos hacia esta ubicación.
			pChild->SetAbsOrigin(vecOriginRadius);

			// Marcamos al nodo afortunado. (Naranja)
			if ( director_debug.GetBool() )
				NDebugOverlay::Box(vecOriginRadius, -Vector(10, 10, 10), Vector(10, 10, 10), 255, 128, 0, 10, 20.0f);
		}
	}

	// Poderoso.
	if ( flag == SPAWN_POWERFUL || flag == SPAWN_NO_COLLISION_AND_POWERFUL )
	{
		int moreHealth = 3;

		// Normal: 5 más de salud.
		if ( InGameRules()->IsSkillLevel(SKILL_MEDIUM) ) 
			moreHealth = 5;

		// Dificil: 8 más de salud.
		if ( InGameRules()->IsSkillLevel(SKILL_HARD) )
			moreHealth = 8;

		// Más rápido.
		pChild->SetAddAccel(40);

		// Establecemos la nueva salud.
		pChild->SetMaxHealth(pChild->GetMaxHealth() + moreHealth);
		pChild->SetHealth(pChild->GetMaxHealth());

		// Seleccionamos al jugador más cercano.
		float flDistance = 0.0f;
		CIN_Player *pPlayer = UTIL_GetNearestInPlayer(pChild->GetAbsOrigin(), flDistance);

		if ( pPlayer )
		{
			// Le decimos que su nuevo enemigo es el jugador y le damos la ubicación de este.
			pChild->SetEnemy(pPlayer);
			pChild->UpdateEnemyMemory(pPlayer, pPlayer->GetAbsOrigin());
		}
	}

	// Al parecer se atoro en una pared.
	if ( !PostSpawn(pChild) )
	{
		// Marcamos al nodo desafortunado. (Negro)
		if ( director_debug.GetBool() )
			NDebugOverlay::Box(vecPosition, -Vector(10, 10, 10), Vector(10, 10, 10), 0, 0, 0, 10, 3.0f);

		return false;
	}

	// Marcamos al nodo afortunado. (Rojo)
	if ( director_debug.GetBool() )
		NDebugOverlay::Box(vecPosition, -Vector(10, 10, 10), Vector(10, 10, 10), 223, 1, 1, 10, 3.0f);

	DevMsg("[MANAGER] Se ha creado <%s> (faltan %i) \r\n", pChildName, Director()->SpawnQueue);
	++Director()->ChildsSpawned;

	return true;
}
//=========================================================
// Crea un Zombi.
//=========================================================
CAI_BaseNPC *CSurvivalZombieSpawn::MakeNPC()
{
	// Desactivado
	if ( Disabled || !sv_spawn_zombies.GetBool() )
		return NULL;

	// Seleccionamos una clase de zombi para crear.
	const char *pZombieClass	= SelectRandomZombie();

	// El elegido es un Grunt.
	if ( pZombieClass == "npc_grunt" )
		return MakeGrunt();

	// Creamos al zombi.
	CAI_BaseNPC *pZombie = (CAI_BaseNPC *)CreateEntityByName(pZombieClass);

	// Emm... ¿puso todas las clases en "no crear"? :genius:
	if ( !pZombie )
	{
		Warning("[SURVIVAL ZOMBIE MAKER] Ha ocurrido un problema al intentar crear un zombie. \r\n");
		return NULL;
	}

	Vector origin;

	if ( !CanMakeNPC(pZombie, &origin) )
		return NULL;

	// Lugar de creación.
	pZombie->SetAbsOrigin(origin);

	// Nombre del zombie.
	// [¡NO CAMBIAR!] Es utilizado por otras entidades para referirse a los zombis creados por esta entidad.
	pZombie->SetName(MAKE_STRING("survival_zombie"));

	QAngle angles	= GetAbsAngles();
	angles.x		= 0.0;
	angles.z		= 0.0;

	pZombie->SetAbsAngles(angles);

	// Tiene que caer al suelo.
	pZombie->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);
	// Su cuerpo tiene que desaparecer al morir.
	pZombie->AddSpawnFlags(SF_NPC_FADE_CORPSE);

	// No colisionan con otros NPC's. (Zombis)
	if ( random->RandomInt(1, 3) == 2 )
		pZombie->SetCollisionGroup(COLLISION_GROUP_SPECIAL_NPC);

	// Creamos al zombi, le decimos quien es su dios (creador) y lo activamos.
	DispatchSpawn(pZombie);
	pZombie->SetOwnerEntity(this);
	DispatchActivate(pZombie);

	// Skin al azar.
	pZombie->m_nSkin = random->RandomInt(1, 4);

	Childs++;
	ChildsAlive++;
	LastSpawn = gpGlobals->curtime;

	OnSpawnZombie.FireOutput(pZombie, this);
	return pZombie;
}
//=========================================================
// Crea un Zombi.
//=========================================================
CAI_BaseNPC *CDirectorSpawn::MakeNPC(bool Horde, bool disclosePlayer, bool checkRadius)
{
	// Desactivado
	// Esta entidad no funciona en Multiplayer.
	if ( Disabled )
		return NULL;

	// Seleccionamos una clase de NPC para crear.
	const char *pClass	= SelectRandom();
	CAI_BaseNPC *pNPC	= VerifyClass(pClass);

	// Emm... ¿puso todas las clases en "no crear"? :genius:
	if ( !pNPC )
	{
		Warning("[DIRECTOR SPAWN] Ha ocurrido un problema al intentar crear un NPC. \r\n");
		return NULL;
	}

	Vector origin;

	// Verificamos si podemos crear un zombi en el radio.
	if ( checkRadius )
	{
		if ( !CanMakeNPC(pNPC, &origin) )
			return NULL;
	}

	// Lugar de creación.
	pNPC->SetAbsOrigin(origin);

	QAngle angles	= GetAbsAngles();
	angles.x		= 0.0;
	angles.z		= 0.0;

	pNPC->SetAbsAngles(angles);

	// Tiene que caer al suelo.
	pNPC->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);
	// Su cuerpo tiene que desaparecer al morir.
	pNPC->AddSpawnFlags(SF_NPC_FADE_CORPSE);

	// Creamos al NPC, le decimos quien es su dios (creador) y lo activamos.
	DispatchSpawn(pNPC);
	pNPC->SetOwnerEntity(this);
	DispatchActivate(pNPC);

	// Al parecer se atoro en una pared.
	if ( !PostSpawn(pNPC) )
		return NULL;

	// Nombre del NPC.
	pNPC->SetName(MAKE_STRING(CHILD_NAME));

#ifdef APOCALYPSE
	// Skin al azar.
	if ( pNPC->GetClassname() == "npc_zombie" )	
		pNPC->m_nSkin = random->RandomInt(1, 4);
#endif

	// Es un NPC para la horda ¡woot!
	if ( Horde )
	{
		AddHealth(pNPC);

#ifdef APOCALYPSE
		// Más rápido.
		pNPC->SetAddAccel(40);

		// No colisiona con otros NPC's. (Zombis)
		if ( random->RandomInt(1, 4) == 2 )
			pNPC->SetCollisionGroup(COLLISION_GROUP_SPECIAL_NPC);
#endif
	}

	// Debe conocer la ubicación del jugador (Su enemigo)
	if ( disclosePlayer )
	{
		CIN_Player *pPlayer = UTIL_GetRandomInPlayer();

		if ( pPlayer )
			pNPC->UpdateEnemyMemory(pPlayer, pPlayer->GetAbsOrigin());
	}

	Childs++;
	ChildsAlive++;
	LastSpawn = gpGlobals->curtime;

	OnSpawnNPC.FireOutput(pNPC, this);
	return pNPC;
}