Пример #1
0
int CWeaponCrowbar::WeaponMeleeAttack1Condition( float flDot, float flDist )
{
    // Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
    CAI_BaseNPC *pNPC	= GetOwner()->MyNPCPointer();
    CBaseEntity *pEnemy = pNPC->GetEnemy();
    if (!pEnemy)
        return COND_NONE;

    Vector vecVelocity;
    vecVelocity = pEnemy->GetSmoothedVelocity( );

    // Project where the enemy will be in a little while
    float dt = sk_crowbar_lead_time.GetFloat();
    dt += SharedRandomFloat( "crowbarmelee1", -0.3f, 0.2f );
    if ( dt < 0.0f )
        dt = 0.0f;

    Vector vecExtrapolatedPos;
    VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos );

    Vector vecDelta;
    VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta );

    if ( fabs( vecDelta.z ) > 70 )
    {
        return COND_TOO_FAR_TO_ATTACK;
    }

    Vector vecForward = pNPC->BodyDirection2D( );
    vecDelta.z = 0.0f;
    float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() );
    if ((flDist > 64) && (flExtrapolatedDist > 64))
    {
        return COND_TOO_FAR_TO_ATTACK;
    }

    float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() );
    if ((flDot < 0.7) && (flExtrapolatedDot < 0.7))
    {
        return COND_NOT_FACING_ATTACK;
    }

    return COND_CAN_MELEE_ATTACK1;
}
	void InputSetAggressiveness( inputdata_t &inputdata )
	{
		int newVal = inputdata.value.Int();
		
		m_aggressiveness = (Aggressiveness_t)newVal;
		ValidateAggression();
		
		UpdateActors();

		const CUtlVector<AIHANDLE> &actors = AccessActors();
		for ( int i = 0; i < actors.Count(); i++ )
		{
			CAI_BaseNPC *pAI = actors[i];
			CAI_StandoffBehavior *pBehavior;
			if ( !pAI->GetBehavior( &pBehavior ) )
				continue;
			SetBehaviorParams( pBehavior);
		}
	}
Пример #3
0
void CAI_PlayerAlly::AlertFriends( CBaseEntity *pKiller )
{
	CBaseEntity *pFriend = NULL;
	int i;

	// for each friend in this bsp...
	for ( i = 0; i < TLK_CFRIENDS; i++ )
	{
		while (pFriend = EnumFriends( pFriend, i, true ))
		{
			CAI_BaseNPC *pNPC = pFriend->MyNPCPointer();
			if ( pNPC->IsAlive() )
			{
				// If a client killed me, make everyone else mad/afraid of him
				if ( pKiller->GetFlags() & FL_CLIENT )
				{
					pNPC->SetSchedule( SCHED_TALKER_BETRAYED );
#ifdef ALLIES_CAN_BE_PROVOKED
					pNPC->Remember( bits_MEMORY_PROVOKED );

					if( IsSelected() )
					{
						PlayerSelect( false );
					}
#endif
				}
				else
				{
					if( IRelationType(pKiller) == D_HT)
					{
						// Killed by an enemy!!!
						CAI_PlayerAlly *pAlly = (CAI_PlayerAlly *)pNPC;
						
						if( pAlly && pAlly->GetExpresser()->CanSpeakConcept( TLK_ALLY_KILLED ) )
						{
							pAlly->Speak( TLK_ALLY_KILLED );
						}
					}
				}
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeapon357::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
	switch( pEvent->event )
	{
		case EVENT_WEAPON_PISTOL_FIRE:
		{
			Vector vecShootOrigin, vecShootDir;
			vecShootOrigin = pOperator->Weapon_ShootPosition();

			CAI_BaseNPC *npc = pOperator->MyNPCPointer();
			ASSERT(npc != NULL);

			vecShootDir = npc->GetActualShootTrajectory(vecShootOrigin);

			CSoundEnt::InsertSound(SOUND_COMBAT | SOUND_CONTEXT_GUNFIRE, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, pOperator, SOUNDENT_CHANNEL_WEAPON, pOperator->GetEnemy());

			WeaponSound(SINGLE_NPC);
			pOperator->FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2);
			pOperator->DoMuzzleFlash();
			m_iClip1 = m_iClip1 - 1;
		}
		case EVENT_WEAPON_RELOAD:
		{
			CBasePlayer *pOwner = ToBasePlayer(GetOwner());
			CEffectData data;

			// Emit six spent shells
			for (int i = 0; i < 6; i++)
			{
				data.m_vOrigin = pOwner->WorldSpaceCenter() + RandomVector(-4, 4);
				data.m_vAngles = QAngle(90, random->RandomInt(0, 360), 0);
				data.m_nEntIndex = entindex();

				DispatchEffect("ShellEject", data);
			}
		}
		break;
		default:
			BaseClass::Operator_HandleAnimEvent(pEvent, pOperator);
			break;
	}
}
Пример #5
0
void CNPC_Vortigaunt::CallForHelp( char *szClassname, float flDist, CBaseEntity * pEnemy, Vector &vecLocation )
{
    // ALERT( at_aiconsole, "help " );

    // skip ones not on my netname
    if ( !m_pSquad )
        return;

    AISquadIter_t iter;
    for (CAI_BaseNPC *pSquadMember = m_pSquad->GetFirstMember( &iter ); pSquadMember; pSquadMember = m_pSquad->GetNextMember( &iter ) )
    {
        float d = ( GetAbsOrigin() - pSquadMember->GetAbsOrigin() ).Length();

        if ( d < flDist )
        {
            pSquadMember->Remember( bits_MEMORY_PROVOKED );
            pSquadMember->UpdateEnemyMemory( pEnemy, vecLocation );
        }
    }
}
Пример #6
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pKiller - 
//-----------------------------------------------------------------------------
void CNPCSimpleTalker::AlertFriends( CBaseEntity *pKiller )
{
	CBaseEntity *pFriend = NULL;
	int i;

	// for each friend in this bsp...
	for ( i = 0; i < TLK_CFRIENDS; i++ )
	{
		while ((pFriend = EnumFriends( pFriend, i, true )) != NULL )
		{
			CAI_BaseNPC *pNPC = pFriend->MyNPCPointer();
			if ( pNPC->IsAlive() )
			{
				// If a client killed me, make everyone else mad/afraid of him
				if ( pKiller->GetFlags() & FL_CLIENT )
				{
					CNPCSimpleTalker*pTalkNPC = (CNPCSimpleTalker *)pFriend;

					if (pTalkNPC && pTalkNPC->IsOkToCombatSpeak())
					{
						// FIXME: need to check CanSpeakConcept?
						pTalkNPC->Speak( TLK_BETRAYED );
					}
				}
				else
				{
					if( IRelationType(pKiller) == D_HT)
					{
						// Killed by an enemy!!!
						CNPCSimpleTalker *pAlly = (CNPCSimpleTalker *)pNPC;
						
						if( pAlly && pAlly->GetExpresser()->CanSpeakConcept( TLK_ALLY_KILLED ) )
						{
							pAlly->Speak( TLK_ALLY_KILLED );
						}
					}
				}
			}
		}
	}
}
Пример #7
0
int	CAI_Squad::BroadcastInteraction( int interactionType, void *data, CBaseCombatCharacter *sender )
{
	//Must have a squad
	if ( m_SquadMembers.Count() == 0 )
		return false;

	//Broadcast to all members of the squad
	for ( int i = 0; i < m_SquadMembers.Count(); i++ )
	{
		CAI_BaseNPC *pMember = m_SquadMembers[i]->MyNPCPointer();
		
		//Validate and don't send again to the sender
		if ( ( pMember != NULL) && ( pMember != sender ) )
		{
			//Send it
			pMember->DispatchInteraction( interactionType, data, sender );
		}
	}

	return true;
}
Пример #8
0
//-----------------------------------------------------------------------------
// Purpose: ENTITY I/O method for telling the assault behavior to cue assault
// Input  : &inputdata - 
//-----------------------------------------------------------------------------
void CAI_AssaultGoal::InputBeginAssault( inputdata_t &inputdata )
{
	int i;

	for( i = 0 ; i < NumActors() ; i++ )
	{
		CAI_BaseNPC *pActor = GetActor( i );

		if( pActor )
		{
			// Now use this actor to lookup the Behavior
			CAI_AssaultBehavior *pBehavior;

			if( pActor->GetBehavior( &pBehavior ) )
			{
				// GOT IT! Now tell the behavior that entity i/o wants to cue the assault.
				pBehavior->ReceiveAssaultCue( CUE_ENTITY_INPUT );
			}
		}
	}
}
//=========================================================
// Revela la posición de los jugadores.
//=========================================================
void CDirector_Manager::Disclose()
{
	CAI_BaseNPC *pNPC = NULL;

	do
	{
		// Buscamos a todos los hijos en el mapa.
		pNPC = (CAI_BaseNPC *)gEntList.FindEntityByName(pNPC, CHILD_NAME);

		// No existe o esta muerto.
		if ( !pNPC || !pNPC->IsAlive() )
			continue;

		// Ya tiene a un jugador como enemigo.
		if ( pNPC->GetEnemy() && pNPC->GetEnemy()->IsPlayer() )
			continue;

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

		if ( !pPlayer )
			continue;

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

	}
	while ( pNPC );
}
Пример #10
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pInflictor - 
//			pAttacker - 
//			flDamage - 
//			bitsDamageType - 
//-----------------------------------------------------------------------------
void CNPC_Stalker::Event_Killed( const CTakeDamageInfo &info )
{
	if( IsInSquad() && info.GetAttacker()->IsPlayer() )
	{
		AISquadIter_t iter;
		for ( CAI_BaseNPC *pSquadMember = GetSquad()->GetFirstMember( &iter ); pSquadMember; pSquadMember = GetSquad()->GetNextMember( &iter ) )
		{
			if ( pSquadMember->IsAlive() && pSquadMember != this )
			{
				CNPC_Stalker *pStalker = dynamic_cast <CNPC_Stalker*>(pSquadMember);

				if( pStalker && pStalker->FVisible(info.GetAttacker()) )
				{
					pStalker->m_iPlayerAggression++;
				}
			}
		}
	}

	KillAttackBeam();
	BaseClass::Event_Killed( info );
}
bool CAI_OperatorBehavior::CanSeePositionEntity()
{
    CAI_BaseNPC *pOuter = GetOuter();

    Assert( m_hPositionEnt.Get() != NULL );

    // early out here.
    if( !pOuter->QuerySeeEntity(m_hPositionEnt) )
    {
        m_WatchSeeEntity.Stop();
        return false;
    }

    bool bSpotted = (pOuter->EyePosition().DistToSqr(m_hPositionEnt->GetAbsOrigin()) <= POSITION_ENT_ALWAYS_SEE_DIST);
    if ( !bSpotted )
    {
        bSpotted = ( pOuter->FInViewCone(m_hPositionEnt) && pOuter->FVisible(m_hPositionEnt) );
    }

    if (bSpotted )
    {
        // If we haven't seen it up until now, start a timer. If we have seen it, wait for the
        // timer to finish. This prevents edge cases where turning on the flashlight makes
        // NPC spot the position entity a frame before she spots an enemy.
        if ( !m_WatchSeeEntity.IsRunning() )
        {
            m_WatchSeeEntity.Start( 0.3,0.31 );
            return false;
        }

        if ( !m_WatchSeeEntity.Expired() )
            return false;

        return true;
    }

    m_WatchSeeEntity.Stop();
    return false;
}
Пример #12
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pAttacker - 
//			flDamage - 
//			&vecDir - 
//			*ptr - 
//			bitsDamageType - 
//-----------------------------------------------------------------------------
void CNPC_Bullseye::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr )
{
	//If specified, we must be the enemy of the target
	if ( m_spawnflags & SF_BULLSEYE_ENEMYDAMAGEONLY )
	{
		CAI_BaseNPC *pInstigator = info.GetAttacker()->MyNPCPointer();

		if ( pInstigator == NULL )
			return;

		if ( pInstigator->GetEnemy() != this )
			return;
	}

	//We can bleed if we want to, we can leave decals behind...
	if ( ( m_spawnflags & SF_BULLSEYE_BLEED ) && ( m_takedamage == DAMAGE_NO ) )
	{
		TraceBleed( info.GetDamage(), vecDir, ptr, info.GetDamageType() );
	}

	BaseClass::TraceAttack( info, vecDir, ptr );
}
Пример #13
0
//-------------------------------------
// Purpose: Addes the given NPC to the squad
//-------------------------------------
void CAI_Squad::AddToSquad(CAI_BaseNPC *pNPC)
{
	if ( !pNPC || !pNPC->IsAlive() )
	{
		Assert(0);
		return;
	}

	if ( pNPC->GetSquad() == this )
		return;

	if ( pNPC->GetSquad() )
	{
		pNPC->GetSquad()->RemoveFromSquad(pNPC);
	}

	if (m_SquadMembers.Count() == MAX_SQUAD_MEMBERS)
	{
		DevMsg("Error!! Squad %s is too big!!! Replacing last member\n",this->m_Name);
		m_SquadMembers.Remove(m_SquadMembers.Count()-1);
	}
	m_SquadMembers.AddToTail(pNPC);
	pNPC->SetSquad( this );
	pNPC->SetSquadName( m_Name );

	if ( m_SquadMembers.Count() > 1 )
	{
		CAI_BaseNPC *pCopyFrom = m_SquadMembers[0];
		CAI_Enemies *pEnemies = pCopyFrom->GetEnemies();
		AIEnemiesIter_t iter;
		AI_EnemyInfo_t *pInfo = pEnemies->GetFirst( &iter );
		while ( pInfo )
		{
			pNPC->UpdateEnemyMemory( pInfo->hEnemy, pInfo->vLastKnownLocation, pCopyFrom );
			pInfo = pEnemies->GetNext( &iter );
		}
	}

}
//=========================================================
// 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;
}
Пример #15
0
void CWeaponOICW::Operator_HandleAnimEvent(animevent_t *pEvent, CBaseCombatCharacter *pOperator)
{
	switch (pEvent->event)
	{
	case EVENT_WEAPON_AR2:
	{
		Vector vecShootOrigin, vecShootDir;
		vecShootOrigin = pOperator->Weapon_ShootPosition();

		CAI_BaseNPC *npc = pOperator->MyNPCPointer();
		ASSERT(npc != NULL);
		vecShootDir = npc->GetActualShootTrajectory(vecShootOrigin);
		WeaponSound(SINGLE_NPC);
		pOperator->FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2);
		pOperator->DoMuzzleFlash();
		m_iClip1 = m_iClip1 - 1;
	}
	break;
	default:
		CBaseCombatWeapon::Operator_HandleAnimEvent(pEvent, pOperator);
		break;
	}
}
Пример #16
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pOperator - 
//-----------------------------------------------------------------------------
void CWeaponShotgun::FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, bool bUseWeaponAngles )
{
	Vector vecShootOrigin, vecShootDir;
	CAI_BaseNPC *npc = pOperator->MyNPCPointer();
	ASSERT( npc != NULL );
	WeaponSound( SINGLE_NPC );
	pOperator->DoMuzzleFlash();
	m_iClip1 = m_iClip1 - 1;

	if ( bUseWeaponAngles )
	{
		QAngle	angShootDir;
		GetAttachment( LookupAttachment( "muzzle" ), vecShootOrigin, angShootDir );
		AngleVectors( angShootDir, &vecShootDir );
	}
	else 
	{
		vecShootOrigin = pOperator->Weapon_ShootPosition();
		vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );
	}

	pOperator->FireBullets( 8, vecShootOrigin, vecShootDir, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );
}
//=========================================================
// 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;
}
Пример #18
0
void CAI_GoalEntity::ResolveNames()
{
	m_actors.SetCount( 0 );
	
	CBaseEntity *pEntity = NULL;
	for (;;)
	{
		switch ( m_SearchType )
		{
			case ST_ENTNAME:
			{
				pEntity = gEntList.FindEntityByName( pEntity, m_iszActor, NULL );
				break;
			}
			
			case ST_CLASSNAME:
			{
				pEntity = gEntList.FindEntityByClassname( pEntity, STRING( m_iszActor ) );
				break;
			}
		}
		
		if ( !pEntity )
			break;
			
		CAI_BaseNPC *pActor = pEntity->MyNPCPointer();
		
		if ( pActor  && pActor->GetState() != NPC_STATE_DEAD )
		{
			AIHANDLE temp;
			temp = pActor;
			m_actors.AddToTail( temp );
		}
	}
		
	m_hGoalEntity = gEntList.FindEntityByName( NULL, m_iszGoal, NULL );
}
Пример #19
0
bool CAI_Enemies::ShouldDiscardMemory( AI_EnemyInfo_t *pMemory )
{
	CBaseEntity *pEnemy = pMemory->hEnemy;

	if ( pEnemy )
	{
		CAI_BaseNPC *pEnemyNPC = pEnemy->MyNPCPointer();
		if ( pEnemyNPC && pEnemyNPC->GetState() == NPC_STATE_DEAD )
			return true;
	}
	else
	{
		if ( !pMemory->bDangerMemory )
			return true;
	}

	if ( !pMemory->bUnforgettable &&
		 gpGlobals->curtime > pMemory->timeLastSeen + m_flEnemyDiscardTime )
	{
		return true;
	}

	return false;
}
Пример #20
0
void CWeaponShotgun::FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, bool bUseWeaponAngles )
{
	Vector vecShootOrigin, vecShootDir;
	CAI_BaseNPC *npc = pOperator->MyNPCPointer();
	ASSERT( npc != NULL );

	WeaponSound( SINGLE_NPC );
	pOperator->DoMuzzleFlash();
	m_iClip1 -= 1;

	if ( bUseWeaponAngles )
	{
		QAngle	angShootDir;
		GetAttachment( LookupAttachment( "muzzle" ), vecShootOrigin, angShootDir );
		AngleVectors( angShootDir, &vecShootDir );
	}
	else 
	{
		vecShootOrigin = pOperator->Weapon_ShootPosition();
		vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );
	}

	PrepareFireBullets(5, pOperator, vecShootOrigin, vecShootDir, false);
}
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;
}
//-----------------------------------------------------------------------------
// Purpose: Gets event from anim stream and throws the object
// Input  :
// Output :
//-----------------------------------------------------------------------------
void CWeaponBrickbat::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
	switch( pEvent->event )
	{
		case EVENT_WEAPON_THROW:
		{
			CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();

			if (!pNPC)
			{
				return;
			}

			Vector vec_target = pNPC->GetEnemyLKP();

			// -----------------------------------------------------
			//  Get position of throw
			// -----------------------------------------------------
			// If owner has a hand, set position to the hand bone position
			Vector launchPos;
			int iBIndex = pNPC->LookupBone("Bip01 R Hand");
			if (iBIndex != -1) {
				Vector origin;
				QAngle angles;
				pNPC->GetBonePosition( iBIndex, launchPos, angles);
			}
			// Otherwise just set to in front of the owner
			else {
				Vector vFacingDir = pNPC->BodyDirection2D( );
				vFacingDir = vFacingDir * 60.0; 
				launchPos = pNPC->GetLocalOrigin()+vFacingDir;
			}

			ThrowBrickbat( launchPos, m_vecTossVelocity, sk_npc_dmg_brickbat.GetFloat());

			// Drop the weapon and remove as no more ammo
			pNPC->Weapon_Drop( this );
			UTIL_Remove( this );
		}
		break;
		default:
			BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
			break;
	}
}
void asw_drone_cycle_f()
{
	CBaseEntity* pEntity = NULL;
	while ((pEntity = gEntList.FindEntityByClassname( pEntity, "asw_drone" )) != NULL)
	{
		CAI_BaseNPC* pAI = dynamic_cast<CAI_BaseNPC*>(pEntity);			
		if (pAI)
		{
			Msg("[%d:%s] Cycle=%f", pAI->entindex(),
							pAI->GetClassname(),
							pAI->GetCycle());
			int iLayers = pAI->GetNumAnimOverlays();
			for (int i=0;i<iLayers;i++)
			{
				Msg("  L%d: Cycle=%f Weight=%f\n", i, pAI->GetLayerCycle(i), pAI->GetLayerWeight(i));
			}
				
		}
	}
}
Пример #24
0
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;
}
void CLagCompensationManager::UpdateAIIndexes()
{
	CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
	int nAIs = g_AI_Manager.NumAIs();

	for ( int i = 0; i < nAIs; i++ )
	{
		CAI_BaseNPC *pNPC = ppAIs[i];
		if ( pNPC && pNPC->GetAIIndex() != i ) // index of NPC has changed
		{// move their data to their new index, probably wanting to delete the old track record
			int oldIndex = pNPC->GetAIIndex();
			int newIndex = i;

			//Msg("Lag compensation record adjusting, moving from index %i to %i\n",oldIndex,newIndex);

			CUtlFixedLinkedList< LagRecord > *track = &m_EntityTrack[ oldIndex ];
			CUtlFixedLinkedList< LagRecord > *oldTrack = &m_EntityTrack[ newIndex ];

			m_EntityTrack[oldIndex] = *oldTrack;
			m_EntityTrack[newIndex] = *track;
			if ( oldTrack->Count() > 0 ) // there's data in the auld yin, probably from someone newly dead,
			{// but if not we'll swap them round so that the old one can then fix their AI index
				//Msg("Index %i already contains data!\n",newIndex);
				for ( int j=0; j<nAIs; j++ )
				{
					CAI_BaseNPC *pConflictingNPC = ppAIs[j];
					if ( pConflictingNPC && pConflictingNPC->GetAIIndex() == newIndex )
					{// found the conflicting NPC, swap them into the old index
						pConflictingNPC->SetAIIndex(oldIndex); // presumably they'll fix themselves further down the loop
						Warning("Lag compensation adjusting entity index, swapping with an existing entity! (%i & %i)\n",oldIndex,newIndex);
						break;
					}
				}
			}

			pNPC->SetAIIndex(newIndex);
		}
	}
//========= End Of AI Patch =======
}
bool CPhysicsNPCSolver::IsIntersecting()
{
	CAI_BaseNPC *pNPC = m_hNPC.Get();
	CBaseEntity *pPhysics = m_hEntity.Get();
	if ( pNPC && pPhysics )
	{
		Ray_t ray;
		// bloated bounds to force slight separation
		Vector mins = pNPC->WorldAlignMins() - Vector(1,1,1);
		Vector maxs = pNPC->WorldAlignMaxs() + Vector(1,1,1);

		ray.Init( pNPC->GetAbsOrigin(), pNPC->GetAbsOrigin(), mins, maxs );
		trace_t tr;
		enginetrace->ClipRayToEntity( ray, pNPC->PhysicsSolidMaskForEntity(), pPhysics, &tr );
		if ( tr.startsolid )
			return true;
	}
	return false;
}
Пример #27
0
//-----------------------------------------------------------------------------
// Purpose: Check the weapon LOS for an owner at an arbitrary position
//			If bSetConditions is true, LOS related conditions will also be set
//-----------------------------------------------------------------------------
bool CASW_Weapon::WeaponLOSCondition( const Vector &ownerPos, const Vector &targetPos, bool bSetConditions )
{
	bool bHasLOS = BaseClass::WeaponLOSCondition(ownerPos, targetPos, bSetConditions);

	// if the weapon has LOS, then do another wider trace to check we don't hit any friendlies
	//   this is to stop the AI marines shooting way too close to other marines, which stops the player thinking about positioning so much
	if (bHasLOS && GetOwner() && asw_weapon_safety_hull.GetFloat() > 0)
	{
		CAI_BaseNPC* npcOwner = GetOwner()->MyNPCPointer();	
		Vector vecRelativeShootPosition;
		VectorSubtract( npcOwner->Weapon_ShootPosition(), npcOwner->GetAbsOrigin(), vecRelativeShootPosition );	// Find its relative shoot position
		Vector barrelPos = ownerPos + vecRelativeShootPosition;	
		CASWWeaponLOSFilter traceFilter( GetOwner(), npcOwner->GetEnemy(), COLLISION_GROUP_BREAKABLE_GLASS );	// Use the custom LOS trace filter
		trace_t tr;
		UTIL_TraceHull( barrelPos, targetPos, Vector(-asw_weapon_safety_hull.GetFloat(), -asw_weapon_safety_hull.GetFloat(), -asw_weapon_safety_hull.GetFloat()),
						Vector(asw_weapon_safety_hull.GetFloat(), asw_weapon_safety_hull.GetFloat(), asw_weapon_safety_hull.GetFloat()),	MASK_SHOT, &traceFilter, &tr );

		if ( tr.fraction == 1.0 || tr.m_pEnt == npcOwner->GetEnemy() )	
			return true;

		// if a friendly is in the way, then we report failure
		CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( tr.m_pEnt );
		if ( pBCC ) 
		{
			if ( npcOwner->IRelationType( pBCC ) == D_HT )
				return true;

			if ( bSetConditions )
			{
				npcOwner->SetCondition( COND_WEAPON_BLOCKED_BY_FRIEND );
			}
			return false;
		}
	}

	return bHasLOS;
}
Пример #28
0
bool CAI_MoveAndShootOverlay::CanAimAtEnemy()
{
	CAI_BaseNPC *pOuter = GetOuter();
	bool result = false;
	bool resetConditions = false;
	CAI_ScheduleBits savedConditions;

	if ( !GetOuter()->ConditionsGathered() )
	{
		savedConditions = GetOuter()->AccessConditionBits();
		GetOuter()->GatherEnemyConditions( GetOuter()->GetEnemy() );
	}
	
	if ( pOuter->HasCondition( COND_CAN_RANGE_ATTACK1 ) )
	{
		result = true;
	}
	else if ( !pOuter->HasCondition( COND_ENEMY_DEAD ) &&
			  !pOuter->HasCondition( COND_TOO_FAR_TO_ATTACK ) &&
			  !pOuter->HasCondition( COND_ENEMY_TOO_FAR ) &&
			  !pOuter->HasCondition( COND_ENEMY_OCCLUDED ) )
	{
		result = true;
	}

	// If we don't have a weapon, stop
	// This catches NPCs who holster their weapons while running
	if ( !HasAvailableRangeAttack() )
	{
		result = false;
	}

	if ( resetConditions )
	{
		GetOuter()->AccessConditionBits() = savedConditions;
	}
		
	return result;
}
Пример #29
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 );
		}
	}
}
Пример #30
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 );
		}
	}
}