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