Ejemplo n.º 1
0
//------------------------------------------------------------------------------
void CNPC_EnemyFinder::PrescheduleThink()
{
	BaseClass::PrescheduleThink();

	bool bHasEnemies = GetEnemies()->NumEnemies() > 0;
	
	if ( GetEnemies()->NumEnemies() > 0 )
	{
		//If I haven't seen my enemy in half a second then we'll assume he's gone.
		if ( gpGlobals->curtime - GetEnemyLastTimeSeen() >= 0.5f )
		{
			bHasEnemies = false;
		}
	}

	if ( m_bEnemyStatus != bHasEnemies )
	{
		if ( bHasEnemies )
		{
			m_OnAcquireEnemies.FireOutput( this, this );
		}
		else
		{
			m_OnLostEnemies.FireOutput( this, this );
		}
		
		m_bEnemyStatus = bHasEnemies;
	}

	if( ai_debug_enemyfinders.GetBool() )
	{
		m_debugOverlays |= OVERLAY_BBOX_BIT;

		if( IsInSquad() && GetSquad()->NumMembers() > 1 )
		{
			AISquadIter_t iter;
			CAI_BaseNPC *pSquadmate = m_pSquad ? m_pSquad->GetFirstMember( &iter ) : NULL;
			while ( pSquadmate )
			{
				NDebugOverlay::Line( WorldSpaceCenter(), pSquadmate->EyePosition(), 255, 255, 0, false, 0.1f );
				pSquadmate = m_pSquad->GetNextMember( &iter );
			}
		}
	}
}
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;
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------
// Purpose: Activate any nearby bugbait targets
//			Returns true if the bugbait target wants to suppress the call.
//-----------------------------------------------------------------------------
bool CGrenadeBugBait::ActivateBugbaitTargets( CBaseEntity *pOwner, Vector vecOrigin, bool bSqueezed )
{
	//Attempt to activate any spawners in a radius around the bugbait
	CBaseEntity*	pList[100];
	Vector			delta( bugbait_grenade_radius.GetFloat(), bugbait_grenade_radius.GetFloat(), bugbait_grenade_radius.GetFloat() );
	bool			suppressCall = false;

	int count = UTIL_EntitiesInBox( pList, 100, vecOrigin - delta, vecOrigin + delta, 0 );
	
	// If the bugbait's been thrown, look for nearby targets to affect
	if ( !bSqueezed )
	{
		for ( int i = 0; i < count; i++ )
		{
			// If close enough, make combine soldiers freak out when hit
			if ( UTIL_DistApprox( pList[i]->WorldSpaceCenter(), vecOrigin ) < bugbait_grenade_radius.GetFloat() )
			{
				// Must be a soldier
				if ( FClassnameIs( pList[i], "npc_combine_s") )
				{
					CAI_BaseNPC *pCombine = pList[i]->MyNPCPointer();

					if ( pCombine != NULL )
					{
						trace_t tr;
						UTIL_TraceLine( vecOrigin, pCombine->EyePosition(), MASK_ALL, pOwner, COLLISION_GROUP_NONE, &tr);

						if ( tr.fraction == 1.0 || tr.m_pEnt == pCombine )
						{
							// Randomize the start time a little so multiple combine hit by 
							// the same bugbait don't all dance in synch.
							g_EventQueue.AddEvent( pCombine, "HitByBugbait", RandomFloat(0, 0.5), pOwner, pOwner );
						}
					}
				}
			}
		}
	}
	// Iterate over all sensors to see if they detected this impact
	for ( CBugBaitSensor *pSensor = GetBugBaitSensorList(); pSensor != NULL; pSensor = pSensor->m_pNext )
	{
		if ( pSensor == NULL )
			continue;

		if ( pSensor->IsDisabled() )
			continue;

		if ( bSqueezed && pSensor->DetectsSqueeze() == false )
			continue;

		if ( !bSqueezed && pSensor->DetectsThrown() == false )
			continue;

		//Make sure we're within range of the sensor
		if ( pSensor->GetRadius() > ( pSensor->GetAbsOrigin() - vecOrigin ).Length() )
		{
			//Tell the sensor it's been hit
			if ( pSensor->Baited( pOwner ) )
			{
				//If we're suppressing the call to antlions, then don't make a bugbait sound
				if ( pSensor->SuppressCall() )
				{
					suppressCall = true;
				}
			}
		}
	}

	return suppressCall;
}
Ejemplo n.º 4
0
//---------------------------------------------------------
// Returns distance to the nearest BaseCombatCharacter.
//---------------------------------------------------------
float CBounceBomb::FindNearestNPC()
{
	float flNearest = (BOUNCEBOMB_WARN_RADIUS * BOUNCEBOMB_WARN_RADIUS) + 1.0;

	// Assume this search won't find anyone.
	SetNearestNPC( NULL );

	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->IsAlive() )
		{
			// ignore hidden objects
			if ( pNPC->IsEffectActive( EF_NODRAW ) )
				continue;

			// Don't bother with NPC's that are below me.
			if( pNPC->EyePosition().z < GetAbsOrigin().z )
				continue;

			// Disregard things that want to be disregarded
			if( pNPC->Classify() == CLASS_NONE )
				continue; 

			// Disregard bullseyes
			if( pNPC->Classify() == CLASS_BULLSEYE )
				continue;

			// Disregard turrets
			if( pNPC->m_iClassname == gm_iszFloorTurretClassname || pNPC->m_iClassname == gm_iszGroundTurretClassname )
				continue;


			float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();

			if( flDist < flNearest )
			{
				// Now do a visibility test.
				if( FVisible( pNPC, MASK_SOLID_BRUSHONLY ) )
				{
					flNearest = flDist;
					SetNearestNPC( pNPC );
				}
			}
		}
	}

	// finally, check the player.
	CBasePlayer *pPlayer = UTIL_GetLocalPlayer();

	if( pPlayer && !(pPlayer->GetFlags() & FL_NOTARGET) )
	{
		float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr();

		if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) )
		{
			flNearest = flDist;
			SetNearestNPC( pPlayer );
		}
	}

	if( m_hNearestNPC.Get() )
	{
		// If sprite is active, update its color to reflect who is nearest.
		if( IsFriend( m_hNearestNPC ) )
		{
			if( m_bFoeNearest )
			{
				// Changing state to where a friend is nearest.

				if( IsFriend( m_hNearestNPC ) )
				{
					// Friend
					UpdateLight( true, 0, 255, 0, 190 );
					m_bFoeNearest = false;
				}
			}
		}
		else // it's a foe
		{
			if( !m_bFoeNearest )
			{
				// Changing state to where a foe is nearest.
				UpdateLight( true, 255, 0, 0, 190 );
				m_bFoeNearest = true;
			}
		}
	}

	return sqrt( flNearest );
}