//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CGrenadeHopwire::KillStriders( void ) { CBaseEntity *pEnts[128]; Vector mins, maxs; ClearBounds( mins, maxs ); AddPointToBounds( -Vector( MAX_STRIDER_STUN_DISTANCE_HORZ, MAX_STRIDER_STUN_DISTANCE_HORZ, MAX_STRIDER_STUN_DISTANCE_HORZ ), mins, maxs ); AddPointToBounds( Vector( MAX_STRIDER_STUN_DISTANCE_HORZ, MAX_STRIDER_STUN_DISTANCE_HORZ, MAX_STRIDER_STUN_DISTANCE_HORZ ), mins, maxs ); AddPointToBounds( -Vector( MAX_STRIDER_STUN_DISTANCE_VERT, MAX_STRIDER_STUN_DISTANCE_VERT, MAX_STRIDER_STUN_DISTANCE_VERT ), mins, maxs ); AddPointToBounds( Vector( MAX_STRIDER_STUN_DISTANCE_VERT, MAX_STRIDER_STUN_DISTANCE_VERT, MAX_STRIDER_STUN_DISTANCE_VERT ), mins, maxs ); // FIXME: It's probably much faster to simply iterate over the striders in the map, rather than any entity in the radius - jdw // Find any striders in range of us int numTargets = UTIL_EntitiesInBox( pEnts, ARRAYSIZE( pEnts ), GetAbsOrigin()+mins, GetAbsOrigin()+maxs, FL_NPC ); float targetDistHorz, targetDistVert; for ( int i = 0; i < numTargets; i++ ) { // Only affect striders if ( FClassnameIs( pEnts[i], "npc_strider" ) == false ) continue; // We categorize our spatial relation to the strider in horizontal and vertical terms, so that we can specify both parameters separately targetDistHorz = UTIL_DistApprox2D( pEnts[i]->GetAbsOrigin(), GetAbsOrigin() ); targetDistVert = fabs( pEnts[i]->GetAbsOrigin()[2] - GetAbsOrigin()[2] ); if ( targetDistHorz < MAX_STRIDER_KILL_DISTANCE_HORZ && targetDistHorz < MAX_STRIDER_KILL_DISTANCE_VERT ) { // Kill the strider float fracDamage = ( pEnts[i]->GetMaxHealth() / hopwire_strider_hits.GetFloat() ) + 1.0f; CTakeDamageInfo killInfo( this, this, fracDamage, DMG_GENERIC ); Vector killDir = pEnts[i]->GetAbsOrigin() - GetAbsOrigin(); VectorNormalize( killDir ); killInfo.SetDamageForce( killDir * -1000.0f ); killInfo.SetDamagePosition( GetAbsOrigin() ); pEnts[i]->TakeDamage( killInfo ); } else if ( targetDistHorz < MAX_STRIDER_STUN_DISTANCE_HORZ && targetDistHorz < MAX_STRIDER_STUN_DISTANCE_VERT ) { // Stun the strider CTakeDamageInfo killInfo( this, this, 200.0f, DMG_GENERIC ); pEnts[i]->TakeDamage( killInfo ); } } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pTask - //----------------------------------------------------------------------------- void CAI_PolicingBehavior::StartTask( const Task_t *pTask ) { switch (pTask->iTask) { case TASK_POLICE_GET_PATH_TO_HARASS_GOAL: { Vector harassDir = ( m_hPoliceGoal->GetTarget()->WorldSpaceCenter() - WorldSpaceCenter() ); float flDist = VectorNormalize( harassDir ); // See if we're already close enough if ( flDist < pTask->flTaskData ) { TaskComplete(); break; } float flInter1, flInter2; Vector harassPos = GetAbsOrigin() + ( harassDir * ( flDist - pTask->flTaskData ) ); // Find a point on our policing radius to stand on if ( IntersectInfiniteRayWithSphere( GetAbsOrigin(), harassDir, m_hPoliceGoal->GetAbsOrigin(), m_hPoliceGoal->GetRadius(), &flInter1, &flInter2 ) ) { Vector vPos = m_hPoliceGoal->GetAbsOrigin() + harassDir * ( MAX( flInter1, flInter2 ) ); // See how far away the default one is float testDist = UTIL_DistApprox2D( m_hPoliceGoal->GetAbsOrigin(), harassPos ); // If our other goal is closer, choose it if ( testDist > UTIL_DistApprox2D( m_hPoliceGoal->GetAbsOrigin(), vPos ) ) { harassPos = vPos; } } if ( GetNavigator()->SetGoal( harassPos, (int)pTask->flTaskData ) ) { GetNavigator()->SetMovementActivity( (Activity) ACT_WALK_ANGRY ); GetNavigator()->SetArrivalDirection( m_hPoliceGoal->GetTarget() ); TaskComplete(); } else { TaskFail( FAIL_NO_ROUTE ); } } break; case TASK_POLICE_GET_PATH_TO_POLICE_GOAL: { if ( GetNavigator()->SetGoal( m_hPoliceGoal->GetAbsOrigin(), (int)pTask->flTaskData ) ) { GetNavigator()->SetArrivalDirection( m_hPoliceGoal->GetAbsAngles() ); TaskComplete(); } else { TaskFail( FAIL_NO_ROUTE ); } } break; case TASK_POLICE_ANNOUNCE_HARASS: { AnnouncePolicing(); // Randomly say this again in the future m_flNextHarassTime = gpGlobals->curtime + random->RandomInt( 4, 6 ); // Scatter rubber-neckers CSoundEnt::InsertSound( SOUND_MOVE_AWAY, GetAbsOrigin(), 256, 2.0f, GetOuter() ); } TaskComplete(); break; case TASK_POLICE_FACE_ALONG_GOAL: { // We may have lost our police goal in the 2 seconds we wait before this task if ( m_hPoliceGoal ) { GetMotor()->SetIdealYaw( m_hPoliceGoal->GetAbsAngles().y ); GetOuter()->SetTurnActivity(); } } break; default: BaseClass::StartTask( pTask ); break; } }
bool CNPC_Dog::FindPhysicsObject( const char *pPickupName, CBaseEntity *pIgnore ) { CBaseEntity *pEnt = NULL; CBaseEntity *pNearest = NULL; float flDist; IPhysicsObject *pPhysObj = NULL; float flNearestDist = 99999; if ( pPickupName != NULL && strlen( pPickupName ) > 0 ) { pEnt = gEntList.FindEntityByName( NULL, pPickupName ); if ( m_hUnreachableObjects.Find( pEnt ) == -1 ) { m_bHasObject = false; m_hPhysicsEnt = pEnt; return true; } } while ( ( pEnt = gEntList.FindEntityByClassname( pEnt, "prop_physics" ) ) != NULL ) { //We don't want this one. if ( pEnt == pIgnore ) continue; if ( m_hUnreachableObjects.Find( pEnt ) != -1 ) continue; pPhysObj = pEnt->VPhysicsGetObject(); if( pPhysObj == NULL ) continue; if ( pPhysObj->GetMass() > DOG_MAX_THROW_MASS ) continue; Vector center = pEnt->WorldSpaceCenter(); flDist = UTIL_DistApprox2D( GetAbsOrigin(), center ); vcollide_t *pCollide = modelinfo->GetVCollide( pEnt->GetModelIndex() ); if ( pCollide == NULL ) continue; if ( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) continue; if ( pPhysObj->IsMoveable() == false ) continue; if ( pEnt->GetCollisionGroup() == COLLISION_GROUP_DEBRIS || pEnt->GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS ) continue; if ( center.z > EyePosition().z ) continue; if ( flDist >= flNearestDist ) continue; if ( FVisible( pEnt ) == false ) continue; pNearest = pEnt; flNearestDist = flDist; } m_bHasObject = false; m_hPhysicsEnt = pNearest; if ( dog_debug.GetBool() == true ) { if ( pNearest ) NDebugOverlay::Box( pNearest->WorldSpaceCenter(), pNearest->CollisionProp()->OBBMins(), pNearest->CollisionProp()->OBBMaxs(), 255, 0, 255, true, 3 ); } if( m_hPhysicsEnt == NULL ) { return false; } else { return true; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CAI_BehaviorAlyxInjured::GatherConditions( void ) { BaseClass::GatherConditions(); // Always stomp over this ClearCondition( COND_INJURED_TOO_FAR_FROM_PLAYER ); ClearCondition( COND_INJURED_OVERWHELMED ); // See if we're overwhelmed by foes if ( NumKnownEnemiesInRadius( GetOuter()->GetAbsOrigin(), COVER_DISTANCE ) >= MIN_ENEMY_MOB ) { SetCondition( COND_INJURED_OVERWHELMED ); } // Determines whether we consider ourselves in danger bool bInDanger = ( HasCondition( COND_LIGHT_DAMAGE ) || HasCondition( COND_HEAVY_DAMAGE ) || HasCondition( COND_INJURED_OVERWHELMED ) ); // See if we're too far away from the player and in danger if ( AI_IsSinglePlayer() && bInDanger ) { bool bWarnPlayer = false; // This only works in single-player CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); if ( pPlayer != NULL ) { // FIXME: This distance may need to be the length of the shortest walked path between the follower and the target // Get our approximate distance to the player float flDistToPlayer = UTIL_DistApprox2D( GetOuter()->GetAbsOrigin(), pPlayer->GetAbsOrigin() ); if ( flDistToPlayer > injured_help_plee_range.GetFloat() ) { bWarnPlayer = true; } else if ( flDistToPlayer > (injured_help_plee_range.GetFloat()*0.5f) && HasCondition( COND_SEE_PLAYER ) == false ) { // Cut our distance in half if we can't see the player bWarnPlayer = true; } } // Yell for help! if ( bWarnPlayer ) { // FIXME: This should be routed through the normal speaking code with a system to emit from the player's suit. CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); //float flPlayerDistSqr = ( GetOuter()->GetAbsOrigin() - pPlayer->GetAbsOrigin() ).LengthSqr(); // If the player is too far away or we can't see him //if ( HasCondition( COND_SEE_PLAYER ) == false || flPlayerDistSqr > Square( 128 ) ) { if ( m_flNextWarnTime < gpGlobals->curtime ) { pPlayer->EmitSound( "npc_alyx.injured_too_far" ); m_flNextWarnTime = gpGlobals->curtime + random->RandomFloat( 3.0f, 5.0f ); } } /* else { SpeakIfAllowed( TLK_INJURED_FOLLOW_TOO_FAR ); m_flNextWarnTime = gpGlobals->curtime + random->RandomFloat( 3.0f, 5.0f ); } */ SetCondition( COND_INJURED_TOO_FAR_FROM_PLAYER ); } } }