//----------------------------------------------------------------------------- // 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; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CGrenadeBugBait::BugBaitTouch( CBaseEntity *pOther ) { Assert( pOther ); if ( !pOther->IsSolid() ) return; if ( m_pSporeTrail != NULL ) { m_pSporeTrail->m_bEmit = false; } //Do effect for the hit SporeExplosion *pSporeExplosion = SporeExplosion::CreateSporeExplosion(); if ( pSporeExplosion ) { Vector dir = -GetAbsVelocity(); VectorNormalize( dir ); QAngle angles; VectorAngles( dir, angles ); pSporeExplosion->SetLocalAngles( angles ); pSporeExplosion->SetLocalOrigin( GetAbsOrigin() ); pSporeExplosion->m_flSpawnRate = 1.0f; pSporeExplosion->m_flParticleLifetime = 2.0f; pSporeExplosion->SetRenderColor( 0.0f, 0.5f, 0.25f, 0.15f ); pSporeExplosion->m_flStartSize = 0.0f; pSporeExplosion->m_flEndSize = 32.0f; pSporeExplosion->m_flSpawnRadius = 2.0f; pSporeExplosion->SetLifetime( bugbait_distract_time.GetFloat() ); UTIL_Relink( pSporeExplosion ); } trace_t tr; Vector traceDir, tracePos; Vector directions[ NUM_SPLASHES ] = { Vector( 1, 0, 0 ), Vector( -1, 0, 0 ), Vector( 0, 1, 0 ), Vector( 0, -1, 0 ), Vector( 0, 0, 1 ), Vector( 0, 0, -1 ), }; //Splatter decals everywhere for ( int i = 0; i < NUM_SPLASHES; i++ ) { traceDir = directions[i]; tracePos = GetAbsOrigin() + ( traceDir * 64.0f ); UTIL_TraceLine( GetAbsOrigin(), tracePos, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0f ) { UTIL_DecalTrace( &tr, "BeerSplash" ); //TODO: Use real decal } } //Make a splat sound CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), CHAN_WEAPON, "weapons/bugbait/splat.wav", 1.0f, ATTN_NORM ); //Attempt to activate any spawners in a radius around the bugbait CBaseEntity* pList[100]; Vector delta( 256, 256, 256 ); bool suppressCall = false; int count = UTIL_EntitiesInBox( pList, 100, GetAbsOrigin() - delta, GetAbsOrigin() + delta, 0 ); //Iterate over all the possible targets for ( i = 0; i < count; i++ ) { //See if this is a bugbait sensor if ( FClassnameIs( pList[i], "point_bugbait" ) ) { CBugBaitSensor *pSensor = dynamic_cast<CBugBaitSensor *>(pList[i]); if ( pSensor == NULL ) continue; //Make sure we're within range of the sensor if ( pSensor->GetRadius() > ( pSensor->GetAbsOrigin() - GetAbsOrigin() ).Length() ) { //Tell the sensor it's been hit pSensor->Baited( GetOwner() ); //If we're suppressing the call to antlions, then don't make a bugbait sound if ( pSensor->SuppressCall() ) { suppressCall = true; } } } } //Make sure we want to call antlions if ( suppressCall == false ) { //Alert any antlions around CSoundEnt::InsertSound( SOUND_BUGBAIT, GetAbsOrigin(), bugbait_hear_radius.GetInt(), bugbait_distract_time.GetFloat(), GetOwner() ); } //Go away UTIL_Remove( this ); }