コード例 #1
0
//=========================================================
// Crea un Jefe.
//=========================================================
CAI_BaseNPC *CDirectorSpawn::MakeBoss()
{
	// Desactivado
	if ( Disabled )
		return NULL;

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

	// Ocurrio algún problema.
	if ( !pNPC )
	{
		Warning("[DIRECTOR SPAWN] Ha ocurrido un problema al intentar crear un Jefe. \r\n");
		return NULL;
	}

	Vector origin;

	// Verificamos si podemos crear el Grunt en el radio.
	if ( !CanMakeNPC(pNPC, &origin) )
		return NULL;

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

	// Nombre del Jefe.
	pNPC->SetName(MAKE_STRING(BOSS_NAME));

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

	// Creamos al Jefe, 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;

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

	if ( pPlayer )
	{
		// Ataca al jugador YA
		pNPC->SetEnemy(pPlayer);
		pNPC->UpdateEnemyMemory(pPlayer, pPlayer->GetAbsOrigin());
	}

	return pNPC;
}
コード例 #2
0
//=========================================================
// Crea un NPC Grunt.
//=========================================================
CAI_BaseNPC *CSurvivalZombieSpawn::MakeGrunt()
{
	// Desactivado
	if ( Disabled || !sv_spawn_zombies.GetBool() )
		return NULL;

	CAI_BaseNPC *pGrunt = (CAI_BaseNPC *)CreateEntityByName("npc_grunt");

	// Ocurrio algún problema.
	if ( !pGrunt )
	{
		Warning("[SURVIVAL ZOMBIE MAKER] Ha ocurrido un problema al intentar crear un grunt. \r\n");
		return NULL;
	}

	Vector origin;

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

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

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

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

	pGrunt->SetAbsAngles(angles);

	// Tiene que caer al suelo.
	pGrunt->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);

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

	// Ahora creamos la música.
	pGruntMusic = (CEnvSound *)CreateEntityByName("env_sound");
	pGruntMusic->SetSourceEntityName(MAKE_STRING("survival_grunt"));
	pGruntMusic->SetSoundName(MAKE_STRING("NPC_Grunt.BackgroundMusic"));
	pGruntMusic->SetRadius(8000.0);
	
	pGruntMusic->SetAbsOrigin(origin);
	DispatchSpawn(pGruntMusic);
	pGruntMusic->SetOwnerEntity(this);
	DispatchActivate(pGruntMusic);

	pGruntMusic->SetPitch(100);
	pGruntMusic->SetVolume(1);
	pGruntMusic->PlayManual(1, 100);

	return pGrunt;
}
コード例 #3
0
//-----------------------------------------------------------------------------
// Purpose: Place NPC somewhere on the perimeter of my radius.
//-----------------------------------------------------------------------------
void CTemplateNPCMaker::MakeNPCInRadius( void )
{
	if ( !CanMakeNPC(true))
		return;

	CAI_BaseNPC	*pent = NULL;
	CBaseEntity *pEntity = NULL;
	MapEntity_ParseEntity( pEntity, STRING(m_iszTemplateData), NULL );
	if ( pEntity != NULL )
	{
		pent = (CAI_BaseNPC *)pEntity;
	}

	if ( !pent )
	{
		Warning("NULL Ent in NPCMaker!\n" );
		return;
	}
	
	if ( !PlaceNPCInRadius( pent ) )
	{
		// Failed to place the NPC. Abort
		UTIL_RemoveImmediate( pent );
		return;
	}

	m_OnSpawnNPC.Set( pEntity, pEntity, this );

	pent->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );

	pent->RemoveSpawnFlags( SF_NPC_TEMPLATE );
	ChildPreSpawn( pent );

	DispatchSpawn( pent );

	pent->SetOwnerEntity( this );
	DispatchActivate( pent );

	ChildPostSpawn( pent );

	m_nLiveChildren++;// count this NPC

	if (!(m_spawnflags & SF_NPCMAKER_INF_CHILD))
	{
		m_nMaxNumNPCs--;

		if ( IsDepleted() )
		{
			m_OnAllSpawned.FireOutput( this, this );

			// Disable this forever.  Don't kill it because it still gets death notices
			SetThink( NULL );
			SetUse( NULL );
		}
	}
}
コード例 #4
0
bool CDirector_Manager::AddBoss(const Vector &vecPosition)
{
	// No se ha podido acceder al Director.
	if ( !Director() )
		return false;

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

	// Creamos un jefe de la lista.
	const char *pBossName	= GetBossClass();
	CAI_BaseNPC *pBoss		= (CAI_BaseNPC *)CreateEntityByName(pBossName);

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

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

	// Debe caer al suelo y desaparecer.
	pBoss->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);
	UTIL_DropToFloor(pBoss, MASK_SOLID);

	ConVarRef director_debug("director_debug");

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

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

	// ¡¡NO CAMBIAR!!
	pBoss->SetName(MAKE_STRING(BOSS_NAME));

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

	DevMsg("[MANAGER] Se ha creado un JEFE. \r\n");

	++Director()->BossSpawned;
	Director()->BossPendient = false;
	Director()->ChildsKilled = 0;

	return true;
}
コード例 #5
0
ファイル: asw_harvester.cpp プロジェクト: Au-heppa/swarm-sdk
CAI_BaseNPC* CASW_Harvester::SpawnAlien()
{
	if (asw_harverter_suppress_children.GetBool())
		return NULL;

	CBaseEntity	*pEntity = CreateEntityByName( "asw_parasite_defanged" );
	CAI_BaseNPC	*pNPC = dynamic_cast<CAI_BaseNPC*>(pEntity);

	if ( !pNPC )
	{
		Warning("NULL Ent in CASW_Harvester!\n");
		return NULL;
	}

	pNPC->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );
	
	pNPC->SetAbsOrigin( GetAbsOrigin() + Vector( 0, 0, asw_harvester_spawn_height.GetFloat() ) );

	// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
	QAngle angles = GetAbsAngles();
	angles.x = 0.0;
	angles.z = 0.0;
	pNPC->SetAbsAngles( angles );

	IASW_Spawnable_NPC* pSpawnable = dynamic_cast<IASW_Spawnable_NPC*>(pNPC);
	ASSERT(pSpawnable);	
	if ( !pSpawnable )
	{
		Warning("NULL Spawnable Ent in CASW_Harvester!\n");
		UTIL_Remove(pNPC);
		return NULL;
	}

	DispatchSpawn( pNPC );
	pNPC->SetOwnerEntity( this );
	pNPC->Activate();

	CASW_Parasite *pParasite = dynamic_cast<CASW_Parasite*>(pNPC);
	if (pParasite)
	{
		m_iCrittersAlive++;
		pParasite->SetMother(this);
	}

	return pNPC;
}
コード例 #6
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTemplateNPCMaker::MakeNPC( void )
{
	// If we should be using the radius spawn method instead, do so
	if ( m_flRadius && HasSpawnFlags(SF_NPCMAKER_ALWAYSUSERADIUS) )
	{
		MakeNPCInRadius();
		return;
	}

	if (!CanMakeNPC( ( m_iszDestinationGroup != NULL_STRING ) ))
		return;

	CNPCSpawnDestination *pDestination = NULL;
	if ( m_iszDestinationGroup != NULL_STRING )
	{
		pDestination = FindSpawnDestination();
		if ( !pDestination )
		{
			DevMsg( 2, "%s '%s' failed to find a valid spawnpoint in destination group: '%s'\n", GetClassname(), STRING(GetEntityName()), STRING(m_iszDestinationGroup) );
			return;
		}
	}

	CAI_BaseNPC	*pent = NULL;
	CBaseEntity *pEntity = NULL;
	MapEntity_ParseEntity( pEntity, STRING(m_iszTemplateData), NULL );
	if ( pEntity != NULL )
	{
		pent = (CAI_BaseNPC *)pEntity;
	}

	if ( !pent )
	{
		Warning("NULL Ent in NPCMaker!\n" );
		return;
	}
	
	if ( pDestination )
	{
		pent->SetAbsOrigin( pDestination->GetAbsOrigin() );

		// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
		QAngle angles = pDestination->GetAbsAngles();
		angles.x = 0.0;
		angles.z = 0.0;
		pent->SetAbsAngles( angles );

		pDestination->OnSpawnedNPC( pent );
	}
	else
	{
		pent->SetAbsOrigin( GetAbsOrigin() );

		// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
		QAngle angles = GetAbsAngles();
		angles.x = 0.0;
		angles.z = 0.0;
		pent->SetAbsAngles( angles );
	}

	m_OnSpawnNPC.Set( pEntity, pEntity, this );

	if ( m_spawnflags & SF_NPCMAKER_FADE )
	{
		pent->AddSpawnFlags( SF_NPC_FADE_CORPSE );
	}

	pent->RemoveSpawnFlags( SF_NPC_TEMPLATE );

	if ( ( m_spawnflags & SF_NPCMAKER_NO_DROP ) == false )
	{
		pent->RemoveSpawnFlags( SF_NPC_FALL_TO_GROUND ); // don't fall, slam
	}

	ChildPreSpawn( pent );

	DispatchSpawn( pent );
	pent->SetOwnerEntity( this );
	DispatchActivate( pent );

	ChildPostSpawn( pent );

	m_nLiveChildren++;// count this NPC

	if (!(m_spawnflags & SF_NPCMAKER_INF_CHILD))
	{
		m_nMaxNumNPCs--;

		if ( IsDepleted() )
		{
			m_OnAllSpawned.FireOutput( this, this );

			// Disable this forever.  Don't kill it because it still gets death notices
			SetThink( NULL );
			SetUse( NULL );
		}
	}
}
コード例 #7
0
//-----------------------------------------------------------------------------
// Purpose: Creates the NPC.
//-----------------------------------------------------------------------------
void CNPCMaker::MakeNPC( void )
{
	if (!CanMakeNPC())
		return;

	CAI_BaseNPC	*pent = (CAI_BaseNPC*)CreateEntityByName( STRING(m_iszNPCClassname) );

	if ( !pent )
	{
		Warning("NULL Ent in NPCMaker!\n" );
		return;
	}
	
	// ------------------------------------------------
	//  Intialize spawned NPC's relationships
	// ------------------------------------------------
	pent->SetRelationshipString( m_RelationshipString );

	m_OnSpawnNPC.Set( pent, pent, this );

	pent->SetAbsOrigin( GetAbsOrigin() );

	// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
	QAngle angles = GetAbsAngles();
	angles.x = 0.0;
	angles.z = 0.0;
	pent->SetAbsAngles( angles );

	pent->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );

	if ( m_spawnflags & SF_NPCMAKER_FADE )
	{
		pent->AddSpawnFlags( SF_NPC_FADE_CORPSE );
	}

	pent->m_spawnEquipment	= m_spawnEquipment;
	pent->SetSquadName( m_SquadName );
	pent->SetHintGroup( m_strHintGroup );

	ChildPreSpawn( pent );

	DispatchSpawn( pent );
	pent->SetOwnerEntity( this );
	DispatchActivate( pent );

	if ( m_ChildTargetName != NULL_STRING )
	{
		// if I have a netname (overloaded), give the child NPC that name as a targetname
		pent->SetName( m_ChildTargetName );
	}

	ChildPostSpawn( pent );

	m_nLiveChildren++;// count this NPC

	if (!(m_spawnflags & SF_NPCMAKER_INF_CHILD))
	{
		m_nMaxNumNPCs--;

		if ( IsDepleted() )
		{
			m_OnAllSpawned.FireOutput( this, this );

			// Disable this forever.  Don't kill it because it still gets death notices
			SetThink( NULL );
			SetUse( NULL );
		}
	}
}
コード例 #8
0
//=========================================================
// 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;
}
コード例 #9
0
//=========================================================
// 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;
}
コード例 #10
0
//=========================================================
// 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;
}
コード例 #11
0
void CNPC_CombineDropship::SpawnTroops( void )
{
	int				i;
//	char			szAttachmentName[ 32 ];
	Vector			vecLocation;
	QAngle			vecAngles;
	QAngle			vecSpawnAngles;

//	memset( szAttachmentName, 0, 32 );

	vecSpawnAngles = GetLocalAngles();
	vecSpawnAngles.y = UTIL_AngleMod( vecSpawnAngles.y - 180 );
	vecSpawnAngles.x = 0;
	vecSpawnAngles.z = 0;

	for( i = 1 ; i <= m_soldiersToDrop ; i++ )
	{

//		Q_snprintf( szAttachmentName,sizeof(szAttachmentName), "spot%d", i );
//		GetAttachment( szAttachmentName, vecLocation, vecAngles );

		vecLocation = GetAbsOrigin();
		vecAngles = GetAbsAngles();

		// troops spawn behind vehicle at all times
		Vector shipDir, shipLeft;
		AngleVectors( vecAngles, &shipDir, &shipLeft, NULL );
		vecLocation -= shipDir * 250;

		// set spawn position for spawning in formation
		switch( i )
		{
		case 1:
			vecLocation -= shipLeft * DROPSHIP_TROOP_GRID;
			break;
		case 3:
			vecLocation += shipLeft * DROPSHIP_TROOP_GRID;
			break;
		case 4:
			vecLocation -= shipDir * DROPSHIP_TROOP_GRID - shipLeft * DROPSHIP_TROOP_GRID;
			break;
		case 5:
			vecLocation -= shipDir * DROPSHIP_TROOP_GRID;
			break;
		case 6:
			vecLocation -= shipDir * DROPSHIP_TROOP_GRID + shipLeft * DROPSHIP_TROOP_GRID;
		}

		// spawn based upon template
		CAI_BaseNPC	*pEnt = NULL;
		CBaseEntity *pEntity = NULL;
		MapEntity_ParseEntity( pEntity, STRING(m_sNPCTemplateData), NULL );
		if ( pEntity != NULL )
		{
			pEnt = (CAI_BaseNPC *)pEntity;
		}
		else
		{
			Warning("Dropship could not create template NPC\n" );
			return;
		}

		pEnt->SetLocalOrigin( vecLocation );
		pEnt->SetLocalAngles( vecSpawnAngles );
		DispatchSpawn( pEnt );

		pEnt->m_NPCState = NPC_STATE_IDLE;
		pEnt->SetOwnerEntity( this );
		pEnt->Activate();
	}
}
//-----------------------------------------------------------------------------
// Purpose: Creates the NPC.
//-----------------------------------------------------------------------------
void CNPCMakerXenInvasion::MakeNPC(void)
{
	if (!CanMakeNPC())
		return;
	
	if (g_pGameRules->bHasRandomized)
	{
		if (g_pGameRules->iRandomGamemode == FIREFIGHT_PRIMARY_XENINVASION)
		{
			int nNPCs = ARRAYSIZE(g_charNPCSXenInvasionSupport);
			int randomChoice = rand() % nNPCs;
			const char *pRandomName = g_charNPCSXenInvasionSupport[randomChoice];

			CAI_BaseNPC	*pent = (CAI_BaseNPC*)CreateEntityByName(pRandomName);

			if (!pent)
			{
				Warning("npc_maker_firefight: Entity classname does not exist in database.\n");
				return;
			}

			// ------------------------------------------------
			//  Intialize spawned NPC's relationships
			// ------------------------------------------------
			pent->SetRelationshipString(m_RelationshipString);

			m_OnSpawnNPC.Set(pent, pent, this);

			pent->SetAbsOrigin(GetAbsOrigin());

			// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
			QAngle angles = GetAbsAngles();
			angles.x = 0.0;
			angles.z = 0.0;
			pent->SetAbsAngles(angles);

			pent->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);

			if (m_spawnflags & SF_NPCMAKER_FADE)
			{
				pent->AddSpawnFlags(SF_NPC_FADE_CORPSE);
			}

			pent->m_isRareEntity = false;
			pent->SetSquadName(m_SquadName);
			pent->SetHintGroup(m_strHintGroup);

			ChildPreSpawn(pent);

			DispatchSpawn(pent);
			pent->SetOwnerEntity(this);
			DispatchActivate(pent);

			if (m_ChildTargetName != NULL_STRING)
			{
				// if I have a netname (overloaded), give the child NPC that name as a targetname
				pent->SetName(m_ChildTargetName);
			}

			ChildPostSpawn(pent);
		}
		else
		{
			CAI_BaseNPC	*pent = (CAI_BaseNPC*)CreateEntityByName(STRING(m_iszNPCClassname));

			if (!pent)
			{
				Warning("npc_maker_firefight: Entity classname does not exist in database.\n");
				return;
			}

			// ------------------------------------------------
			//  Intialize spawned NPC's relationships
			// ------------------------------------------------
			pent->SetRelationshipString(m_RelationshipString);

			m_OnSpawnNPC.Set(pent, pent, this);

			pent->SetAbsOrigin(GetAbsOrigin());

			// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
			QAngle angles = GetAbsAngles();
			angles.x = 0.0;
			angles.z = 0.0;
			pent->SetAbsAngles(angles);

			pent->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);

			if (m_spawnflags & SF_NPCMAKER_FADE)
			{
				pent->AddSpawnFlags(SF_NPC_FADE_CORPSE);
			}

			pent->m_spawnEquipment = m_spawnEquipment;
			pent->m_isRareEntity = false;
			pent->SetSquadName(m_SquadName);
			pent->SetHintGroup(m_strHintGroup);

			ChildPreSpawn(pent);

			DispatchSpawn(pent);
			pent->SetOwnerEntity(this);
			DispatchActivate(pent);

			if (m_ChildTargetName != NULL_STRING)
			{
				// if I have a netname (overloaded), give the child NPC that name as a targetname
				pent->SetName(m_ChildTargetName);
			}

			ChildPostSpawn(pent);
		}
	}
	else
	{
		if (g_pGameRules->GetGamemode() == FIREFIGHT_PRIMARY_XENINVASION)
		{
			int nNPCs = ARRAYSIZE(g_charNPCSXenInvasionSupport);
			int randomChoice = rand() % nNPCs;
			const char *pRandomName = g_charNPCSXenInvasionSupport[randomChoice];

			CAI_BaseNPC	*pent = (CAI_BaseNPC*)CreateEntityByName(pRandomName);

			if (!pent)
			{
				Warning("npc_maker_firefight: Entity classname does not exist in database.\n");
				return;
			}

			// ------------------------------------------------
			//  Intialize spawned NPC's relationships
			// ------------------------------------------------
			pent->SetRelationshipString(m_RelationshipString);

			m_OnSpawnNPC.Set(pent, pent, this);

			pent->SetAbsOrigin(GetAbsOrigin());

			// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
			QAngle angles = GetAbsAngles();
			angles.x = 0.0;
			angles.z = 0.0;
			pent->SetAbsAngles(angles);

			pent->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);

			if (m_spawnflags & SF_NPCMAKER_FADE)
			{
				pent->AddSpawnFlags(SF_NPC_FADE_CORPSE);
			}

			pent->m_isRareEntity = false;
			pent->SetSquadName(m_SquadName);
			pent->SetHintGroup(m_strHintGroup);

			ChildPreSpawn(pent);

			DispatchSpawn(pent);
			pent->SetOwnerEntity(this);
			DispatchActivate(pent);

			if (m_ChildTargetName != NULL_STRING)
			{
				// if I have a netname (overloaded), give the child NPC that name as a targetname
				pent->SetName(m_ChildTargetName);
			}

			ChildPostSpawn(pent);
		}
		else
		{
			CAI_BaseNPC	*pent = (CAI_BaseNPC*)CreateEntityByName(STRING(m_iszNPCClassname));

			if (!pent)
			{
				Warning("npc_maker_firefight: Entity classname does not exist in database.\n");
				return;
			}

			// ------------------------------------------------
			//  Intialize spawned NPC's relationships
			// ------------------------------------------------
			pent->SetRelationshipString(m_RelationshipString);

			m_OnSpawnNPC.Set(pent, pent, this);

			pent->SetAbsOrigin(GetAbsOrigin());

			// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
			QAngle angles = GetAbsAngles();
			angles.x = 0.0;
			angles.z = 0.0;
			pent->SetAbsAngles(angles);

			pent->AddSpawnFlags(SF_NPC_FALL_TO_GROUND);

			if (m_spawnflags & SF_NPCMAKER_FADE)
			{
				pent->AddSpawnFlags(SF_NPC_FADE_CORPSE);
			}

			pent->m_spawnEquipment = m_spawnEquipment;
			pent->m_isRareEntity = false;
			pent->SetSquadName(m_SquadName);
			pent->SetHintGroup(m_strHintGroup);

			ChildPreSpawn(pent);

			DispatchSpawn(pent);
			pent->SetOwnerEntity(this);
			DispatchActivate(pent);

			if (m_ChildTargetName != NULL_STRING)
			{
				// if I have a netname (overloaded), give the child NPC that name as a targetname
				pent->SetName(m_ChildTargetName);
			}

			ChildPostSpawn(pent);
		}
	}

	m_nLiveChildren++;// count this NPC
}