예제 #1
0
CBaseMonster *CScriptedSentence::FindEntity( void )
{
	CBaseEntity* pTargetEnt = nullptr;

	CBaseMonster* pMonster = nullptr;

	while( (pTargetEnt = UTIL_FindEntityByTargetname( pTargetEnt, STRING( m_iszEntity ) )) )
	{
		if( (pMonster = pTargetEnt->MyMonsterPointer()) )
		{
			if( AcceptableSpeaker( pMonster ) )
				return pMonster;

			//ALERT( at_console, "%s (%s), not acceptable\n", pMonster->GetClassname(), pMonster->GetTargetname() );
		}
	}

	pTargetEnt = nullptr;

	while( (pTargetEnt = UTIL_FindEntityInSphere( pTargetEnt, GetAbsOrigin(), m_flRadius )) )
	{
		if( pTargetEnt->ClassnameIs( m_iszEntity ) )
		{
			if( pTargetEnt->GetFlags().Any( FL_MONSTER ) )
			{
				pMonster = pTargetEnt->MyMonsterPointer();

				if( AcceptableSpeaker( pMonster ) )
					return pMonster;
			}
		}
	}

	return nullptr;
}
예제 #2
0
파일: bmodels.cpp 프로젝트: XashDev/XashXT
void CFuncClock :: Activate( void )
{
	if( m_fInit ) return;

	if( m_iClockType == SECODNS_PER_DAY && m_vecCurtime != g_vecZero )
	{
		// try to find minutes and seconds entity
		CBaseEntity *pEntity = NULL;
		while( pEntity = UTIL_FindEntityInSphere( pEntity, GetLocalOrigin(), pev->size.z ))
		{
			if( FClassnameIs( pEntity, "func_clock" ))
			{
				CFuncClock *pClock = (CFuncClock *)pEntity;
				// write start hours, minutes and seconds
				switch( pClock->m_iClockType )
				{
				case SECODNS_PER_DAY:
					// NOTE: here we set time for himself through FindEntityInSphere
					pClock->m_flCurTime = m_vecFinaltime.x;
					break;
				case SECONDS_PER_HOUR:
					pClock->m_flCurTime = m_vecFinaltime.y;
					break;
				default:
					pClock->m_flCurTime = m_vecFinaltime.z;
					break;
				}
			}
		}
	}

	// clock start	
	SetNextThink( 0 );
	m_fInit = 1;
}
예제 #3
0
void CFlame::Fly( void )
{
	if ( pev->frags <= 0 || UTIL_PointContents(pev->origin) == CONTENT_WATER )
	{
		FX_Trail( pev->origin, entindex(), PROJ_REMOVE );
		UTIL_Remove( this );
		return;
	}
	pev->frags--;

	entvars_t *pevOwner = VARS(pev->owner);
	CBaseEntity *pOther = NULL;

	while ((pOther = UTIL_FindEntityInSphere( pOther, pev->origin, 50 )) != NULL)
	{
		if (pOther->edict() != pev->owner && pOther->pev->takedamage && pOther->Classify() != CLASS_MACHINE )
		{
			TraceResult tr;
			UTIL_TraceLine( pev->origin, pOther->pev->origin, dont_ignore_monsters, ENT(pev), &tr );
			CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);

			ClearMultiDamage( );
			pEntity->TraceAttack( pevOwner, pev->dmg/3, pev->velocity, &tr, DMG_IGNITE | DMG_NEVERGIB);
			ApplyMultiDamage( pev, pevOwner );
		}
	}
	pev->nextthink = gpGlobals->time + 0.1;
}
//=========================================================
// Leader boid calls this to form a flock from surrounding boids
//=========================================================
void CFlockingFlyer :: FormFlock( void )
{
	if ( !InSquad() )
	{
		// I am my own leader
		m_pSquadLeader = this;
		m_pSquadNext = NULL;
		int squadCount = 1;

		CBaseEntity *pEntity = NULL;
		
		while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, AFLOCK_MAX_RECRUIT_RADIUS )) != NULL)
		{
			CBaseMonster *pRecruit = pEntity->MyMonsterPointer( );

			if ( pRecruit && pRecruit != this && pRecruit->IsAlive() && !pRecruit->m_pCine )
			{
				// Can we recruit this guy?
				if ( FClassnameIs ( pRecruit->pev, "monster_flyer" ) )
				{
					squadCount++;
					SquadAdd( (CFlockingFlyer *)pRecruit );
				}
			}
		}
	}

	SetThink( &CFlockingFlyer::IdleThink );// now that flock is formed, go to idle and wait for a player to come along.
	pev->nextthink = gpGlobals->time;
}
예제 #5
0
// Quake Radius damage
void Q_RadiusDamage(CBaseEntity *pInflictor, CBaseEntity *pAttacker, float flDamage, CBaseEntity *pIgnore)
{
	CBaseEntity *pEnt = NULL;

	while((pEnt = UTIL_FindEntityInSphere(pEnt, pInflictor->pev->origin, flDamage + 40)) != NULL)
	{
		if(pEnt != pIgnore)
		{
			if(pEnt->pev->takedamage)
			{
				Vector vecOrg   = pEnt->pev->origin + ((pEnt->pev->mins + pEnt->pev->maxs) * 0.5);
				float  flPoints = 0.5 * (pInflictor->pev->origin - vecOrg).Length();
				if(flPoints < 0)
					flPoints = 0;
				flPoints     = flDamage - flPoints;

				if(pEnt == pAttacker)
					flPoints = flPoints * 0.5;
				if(flPoints > 0)
				{
					if(Q_CanDamage(pEnt, pInflictor))
						pEnt->TakeDamage(pInflictor->pev, pAttacker->pev, flPoints, DMG_GENERIC);
				}
			}
		}
	}
}
예제 #6
0
파일: AvHMine.cpp 프로젝트: Arkshine/NS
bool AvHMine::GetDropLocation(Vector& outLocation, Vector* outAngles) const
{
	bool theSuccess = false;

	UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle );
	Vector vecSrc	 = m_pPlayer->GetGunPosition( );
	Vector vecAiming = gpGlobals->v_forward;
	
	TraceResult tr;
	
	UTIL_TraceLine( vecSrc, vecSrc + vecAiming*this->mRange, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr );

	if (tr.flFraction < 1.0)
	{
		CBaseEntity* theEntity = CBaseEntity::Instance( tr.pHit );
		
		// puzl: 981
		// Mines can't be planted on players or buildings
        if (!dynamic_cast<AvHDeployedMine*>(theEntity) && !dynamic_cast<AvHPlayer *>(theEntity) && !dynamic_cast<AvHBaseBuildable *>(theEntity))
        {
    
            int kOffset = 8;
            Vector thePotentialOrigin = tr.vecEndPos + tr.vecPlaneNormal * kOffset;

		    BaseEntityListType theEntityList;
		    theEntityList.push_back(theEntity);

		    // Make sure there isn't an entity nearby that this would block
		    theEntity = NULL;
		    const int kMineSearchRadius = 15;
		    while((theEntity = UTIL_FindEntityInSphere(theEntity, thePotentialOrigin, kMineSearchRadius)) != NULL)
		    {
			    theEntityList.push_back(theEntity);
		    }
		    
		    // For the mine placement to be valid, the entity it hit, and all the entities nearby must be valid and non-blocking
		    theSuccess = true;
		    for(BaseEntityListType::iterator theIter = theEntityList.begin(); theIter != theEntityList.end(); theIter++)
		    {
				// puzl: 225 make sure there are no mines within kMineSearchRadius of each other ( 15 units )
			    CBaseEntity* theCurrentEntity = *theIter;
			    if(!theCurrentEntity || (theCurrentEntity->pev->flags & FL_CONVEYOR) || AvHSUGetIsExternalClassName(STRING(theCurrentEntity->pev->classname)) || dynamic_cast<CBaseDoor*>(theCurrentEntity) || dynamic_cast<CRotDoor*>(theCurrentEntity)
					|| dynamic_cast<AvHDeployedMine*>(theCurrentEntity) )
			    {
				    theSuccess = false;
				    break;
			    }
		    }

		    if(theSuccess)
		    {
			    VectorCopy(thePotentialOrigin, outLocation);
			    if(outAngles)
			    {
				    VectorCopy(UTIL_VecToAngles( tr.vecPlaneNormal ), *outAngles)
			    }
		    }

        }
예제 #7
0
void CBlackHole::RadiusDamage( )
{
	CBaseEntity *pEntity = NULL;
	TraceResult	tr;
	float		flAdjustedDamage;
	Vector		vecSpot;

	entvars_t *pevOwner = VARS( pev->owner );
	Vector vecSrc = pev->origin + Vector(0,0,1);

	if ( !pevOwner )
		pevOwner = pev;

	CBaseEntity *pPlayer = CBaseEntity::Instance (pevOwner);

	// iterate on all entities in the vicinity.
	while ((pEntity = UTIL_FindEntityInSphere( pEntity, vecSrc, (dmg_chrono_radius.value * (mp_wpn_power.value/100)) )) != NULL)
	{
		if ( pEntity->pev->movetype != MOVETYPE_PUSH && pEntity->pev->movetype != MOVETYPE_NONE && pEntity->pev->movetype != MOVETYPE_FOLLOW && pEntity->pev->movetype != MOVETYPE_NOCLIP )
		{
			if (pEntity == this) continue;

			if (CVAR_GET_FLOAT("mp_noselfdamage")==1 && pEntity->pev == pevOwner )
			continue;

			if (CVAR_GET_FLOAT("mp_noteamdamage")==1 && g_pGameRules->PlayerRelationship(pPlayer, pEntity) == GR_TEAMMATE && pEntity->pev != pevOwner)
			continue;

			vecSpot = pEntity->BodyTarget( vecSrc );
			
			UTIL_TraceLine ( vecSrc, vecSpot, ignore_monsters, ENT(pev), &tr );

			if ( tr.flFraction == 1.0 || tr.pHit == pEntity->edict() )
			{
				flAdjustedDamage = ( vecSrc - tr.vecEndPos ).Length();
			
				if ( flAdjustedDamage <	1 )
					flAdjustedDamage = 1;
			
				Vector m_vel = ( vecSrc - tr.vecEndPos ).Normalize() * ((500 * (dmg_chrono_radius.value * (mp_wpn_power.value/100)) / flAdjustedDamage) + 150);

				if (m_vel.Length() > 1000) m_vel = m_vel.Normalize() * 1000;

				pEntity->pev->velocity = m_vel;

				if (flAdjustedDamage < 200)
				{
					if (!(pEntity->Classify() == CLASS_MACHINE || pEntity->IsBot() || pEntity->IsPlayer() || FClassnameIs(pEntity->pev, "laser_dot") || FClassnameIs(pEntity->pev, "laser_spot")))
					{
						pEntity->Killed ( pevOwner, 0 );
						return;
					}
				}
				
			}
		}
	}
}
void CSatchel::WeaponIdle(void)
{
	if (m_flTimeUpdate < UTIL_GlobalTimeBase() && m_iChargeLevel)
	{
		edict_t *pPlayer = m_pPlayer->edict();
		CBaseEntity *pSatchel = NULL;
		while ((pSatchel = UTIL_FindEntityInSphere(pSatchel, m_pPlayer->pev->origin, 4096)) != NULL)
		{
			if (FClassnameIs(pSatchel->pev, "monster_satchel"))
			{
				if (pSatchel->pev->owner == pPlayer)
				{
					pSatchel->Use(m_pPlayer, m_pPlayer, USE_ON, 0);
					m_chargeReady = 2;
				}
			}
		}
		SendWeaponAnim(SATCHEL_RADIO_HOLSTER);
		m_iChargeLevel = 0;
	}

	if (m_flTimeWeaponIdle > UTIL_GlobalTimeBase()) return;
	switch (m_chargeReady)
	{
	case 0:
		SendWeaponAnim(SATCHEL_FIDGET1);
		// use tripmine animations
		strcpy(m_pPlayer->m_szAnimExtention, "trip");
		break;
	case 1:
		SendWeaponAnim(SATCHEL_RADIO_FIDGET1);
		// use hivehand animations
		strcpy(m_pPlayer->m_szAnimExtention, "hive");
		break;
	case 2:
		if (!m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
		{
			m_chargeReady = 0;
			RetireWeapon();
			return;
		}

		m_pPlayer->pev->viewmodel = MAKE_STRING("models/v_satchel.mdl");
		m_pPlayer->pev->weaponmodel = MAKE_STRING("models/p_satchel.mdl");
		SendWeaponAnim(SATCHEL_DRAW);

		// use tripmine animations
		strcpy(m_pPlayer->m_szAnimExtention, "trip");

		m_flNextPrimaryAttack = UTIL_GlobalTimeBase() + 0.5;
		m_flNextSecondaryAttack = UTIL_GlobalTimeBase() + 0.5;
		m_chargeReady = 0;
		break;
	}
	m_flTimeWeaponIdle = UTIL_GlobalTimeBase() + RANDOM_LONG(10, 15);// how long till we do this again.
}
예제 #9
0
//=========================================================
// Look - overriden for the roach, which can virtually see 
// 360 degrees.
//=========================================================
void CRoach :: Look ( int iDistance )
{
	CBaseEntity	*pSightEnt = NULL;// the current visible entity that we're dealing with
	CBaseEntity	*pPreviousEnt;// the last entity added to the link list 
	int			iSighted = 0;

	// DON'T let visibility information from last frame sit around!
	ClearConditions( bits_COND_SEE_HATE |bits_COND_SEE_DISLIKE | bits_COND_SEE_ENEMY | bits_COND_SEE_FEAR );

	// don't let monsters outside of the player's PVS act up, or most of the interesting
	// things will happen before the player gets there!
	if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
	{
		return;
	}

	m_pLink = NULL;
	pPreviousEnt = this;

	// Does sphere also limit itself to PVS?
	// Examine all entities within a reasonable radius
	// !!!PERFORMANCE - let's trivially reject the ent list before radius searching!
	while ((pSightEnt = UTIL_FindEntityInSphere( pSightEnt, pev->origin, iDistance )) != NULL)
	{
		// only consider ents that can be damaged. !!!temporarily only considering other monsters and clients
		if (  pSightEnt->IsPlayer() || FBitSet ( pSightEnt->pev->flags, FL_MONSTER ) )
		{
			if ( /*FVisible( pSightEnt ) &&*/ !FBitSet( pSightEnt->pev->flags, FL_NOTARGET ) && pSightEnt->pev->health > 0 )
			{
				// NULL the Link pointer for each ent added to the link list. If other ents follow, the will overwrite
				// this value. If this ent happens to be the last, the list will be properly terminated.
				pPreviousEnt->m_pLink = pSightEnt;
				pSightEnt->m_pLink = NULL;
				pPreviousEnt = pSightEnt;

				// don't add the Enemy's relationship to the conditions. We only want to worry about conditions when
				// we see monsters other than the Enemy.
				switch ( IRelationship ( pSightEnt ) )
				{
				case	R_FR:		
					iSighted |= bits_COND_SEE_FEAR;	
					break;
				case	R_NO:
					break;
				default:
					ALERT ( at_console, "%s can't asses %s\n", STRING(pev->classname), STRING(pSightEnt->pev->classname ) );
					break;
				}
			}
		}
	}
	SetConditions( iSighted );
}
예제 #10
0
void CFuncMachinegun::CheckSpawn( void )
{
	CBaseEntity *pFound = NULL;
	while ((pFound = UTIL_FindEntityInSphere(pFound, pev->oldorigin, 50)) != NULL)
	{
		if (pFound->IsPlayer() && pFound->IsAlive())
		{
			pev->nextthink = gpGlobals->time + 1;
			return;
		}
	ReSpawn();
	}
}
예제 #11
0
void CFuncVehicle::NearestPath()
{
	CPathTrack *pTrack = nullptr;
	CPathTrack *pNearest = nullptr;
	real_t dist;
	float closest = 1024.0f;

	while ((pTrack = UTIL_FindEntityInSphere(pTrack, pev->origin, 1024.0f)))
	{
		// filter out non-tracks
		if (!(pTrack->pev->flags & (FL_CLIENT | FL_MONSTER)) && FClassnameIs(pTrack->pev, "path_track"))
		{
			dist = (pev->origin - pTrack->pev->origin).Length();

			if (dist < closest)
			{
				closest = dist;
				pNearest = pTrack;
			}
		}
	}

	if (!pNearest)
	{
		ALERT(at_console, "Can't find a nearby track !!!\n");
		SetThink(nullptr);
		return;
	}

	ALERT(at_aiconsole, "TRAIN: %s, Nearest track is %s\n", STRING(pev->targetname), STRING(pNearest->pev->targetname));

	// If I'm closer to the next path_track on this path, then it's my real path
	pTrack = pNearest->GetNext();

	if (pTrack)
	{
		if ((pev->origin - pTrack->pev->origin).Length() < (pev->origin - pNearest->pev->origin).Length())
		{
			pNearest = pTrack;
		}
	}

	m_ppath = pNearest;

	if (pev->speed != 0)
	{
		NextThink(pev->ltime + 0.1f, FALSE);
		SetThink(&CFuncVehicle::Next);
	}
}
예제 #12
0
bool CServerOP4CTF::ClientIsImportant(CClient *pClient)
{
   // see if this player has the flag...
   CEntity *pEntity = NULL;
   while (pEntity = UTIL_FindEntityInSphere(pEntity, pClient->GetOrigin(), 10)) {
      if (!pEntity->GetOwner())
         continue; // reliability check
      if (*pEntity->GetOwner() == *pClient &&
         pEntity->GetOrigin() == pClient->GetOrigin() &&
         strcmp(pEntity->GetClassname(), "item_ctfflag") == 0)
         return true; // this player has the flag
   }
   return false; // this player doesn't have the flag
}
예제 #13
0
void AvHMovementChamber::EnergyAliensThink()
{
	// Don't teleport until it's "warmed up"
	SetUse(&AvHMovementChamber::TeleportUse);

	// Loop through all players
	CBaseEntity* theBaseEntity = NULL;
	int theNumEntsProcessed = 0;
	
	while(((theBaseEntity = UTIL_FindEntityInSphere(theBaseEntity, this->pev->origin, BALANCE_VAR(kMovementChamberEnergyRange))) != NULL) && (theNumEntsProcessed < BALANCE_VAR(kAlienChamberMaxPlayers)))
	{
		if(theBaseEntity->pev->team == this->pev->team)
		{
			float theEnergizeAmount = BALANCE_VAR(kMovementChamberEnergyAmount);
			AvHBaseBuildable* theBuildable = dynamic_cast<AvHBaseBuildable*>(theBaseEntity);
			AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theBaseEntity);
			if(thePlayer && thePlayer->IsAlive())
			{
				if(thePlayer->Energize(theEnergizeAmount))
				{
					theNumEntsProcessed++;
				}
			}
			// Energize alien buildables
//			else if(theBuildable)
//			{
//				if(theBuildable->Energize(theEnergizeAmount))
//				{
//					theNumEntsProcessed++;
//				}
//			}
		}
	}

	// Play an animation (spin the arms if energizing)
	int theIdle = this->GetIdle2Animation();

	// Play sound
	if(theNumEntsProcessed > 0)
	{
		EMIT_SOUND(this->edict(), CHAN_AUTO, kAlienEnergySound, 1.0f, ATTN_NORM);

		theIdle = this->GetIdle1Animation();
	}

	this->PlayAnimationAtIndex(theIdle);
	
	// Set next think
	this->pev->nextthink = gpGlobals->time + BALANCE_VAR(kMovementChamberThinkInterval);
}
예제 #14
0
// find a viable entity
int CCineMonster::FindEntity(void)
{
	edict_t *pentTarget;

	pentTarget            = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszEntity));
	m_hTargetEnt          = NULL;
	CBaseMonster *pTarget = NULL;

	while(!FNullEnt(pentTarget))
	{
		if(FBitSet(VARS(pentTarget)->flags, FL_MONSTER))
		{
			pTarget = GetMonsterPointer(pentTarget);
			if(pTarget && pTarget->CanPlaySequence(FCanOverrideState(), SS_INTERRUPT_BY_NAME))
			{
				m_hTargetEnt = pTarget;
				return TRUE;
			}
			ALERT(at_console, "Found %s, but can't play!\n", STRING(m_iszEntity));
		}
		pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(m_iszEntity));
		pTarget    = NULL;
	}

	if(!pTarget)
	{
		CBaseEntity *pEntity = NULL;
		while((pEntity = UTIL_FindEntityInSphere(pEntity, pev->origin, m_flRadius)) != NULL)
		{
			if(FClassnameIs(pEntity->pev, STRING(m_iszEntity)))
			{
				if(FBitSet(pEntity->pev->flags, FL_MONSTER))
				{
					pTarget = pEntity->MyMonsterPointer();
					if(pTarget && pTarget->CanPlaySequence(FCanOverrideState(), SS_INTERRUPT_IDLE))
					{
						m_hTargetEnt = pTarget;
						return TRUE;
					}
				}
			}
		}
	}
	pTarget      = NULL;
	m_hTargetEnt = NULL;
	return FALSE;
}
예제 #15
0
// find a viable entity
bool CCineMonster::FindEntity()
{
	m_hTargetEnt = nullptr;

	CBaseEntity* pTargetEnt = nullptr;
	CBaseMonster* pTarget = nullptr;

	while( ( pTargetEnt = UTIL_FindEntityByTargetname( pTargetEnt, STRING( m_iszEntity ) ) ) != nullptr )
	{
		if( pTargetEnt->GetFlags().Any( FL_MONSTER ) )
		{
			pTarget = pTargetEnt->MyMonsterPointer();

			if( pTarget && pTarget->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_BY_NAME ) )
			{
				m_hTargetEnt = pTarget;
				return true;
			}

			ALERT( at_console, "Found %s, but can't play!\n", STRING( m_iszEntity ) );
		}

		pTarget = nullptr;
	}

	if( !pTarget )
	{
		pTargetEnt = nullptr;
		while( ( pTargetEnt = UTIL_FindEntityInSphere( pTargetEnt, GetAbsOrigin(), m_flRadius ) ) != nullptr )
		{
			if( pTargetEnt->ClassnameIs( STRING( m_iszEntity ) ) )
			{
				if( pTargetEnt->GetFlags().Any( FL_MONSTER ) )
				{
					pTarget = pTargetEnt->MyMonsterPointer();
					if( pTarget && pTarget->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_IDLE ) )
					{
						m_hTargetEnt = pTarget;
						return true;
					}
				}
			}
		}
	}
	m_hTargetEnt = nullptr;
	return false;
}
예제 #16
0
/* <1bb840> ../cstrike/dlls/vehicle.cpp:878 */
void CFuncVehicle::NearestPath()
{
    CBaseEntity *pTrack = NULL;
    CBaseEntity *pNearest = NULL;
    float_precision dist;
    float closest = 1024;

    while ((pTrack = UTIL_FindEntityInSphere(pTrack, pev->origin, 1024)) != NULL)
    {
        if (!(pTrack->pev->flags & (FL_CLIENT | FL_MONSTER)) && FClassnameIs(pTrack->pev, "path_track"))
        {
            dist = (pev->origin - pTrack->pev->origin).Length();

            if (dist < closest)
            {
                closest = dist;
                pNearest = pTrack;
            }
        }
    }

    if (!pNearest)
    {
        ALERT(at_console, "Can't find a nearby track !!!\n");
        SetThink(NULL);
        return;
    }

    ALERT(at_aiconsole, "TRAIN: %s, Nearest track is %s\n", STRING(pev->targetname), STRING(pNearest->pev->targetname));
    pTrack = ((CPathTrack *)pNearest)->GetNext();

    if (pTrack != NULL)
    {
        if ((pev->origin - pTrack->pev->origin).Length() < (pev->origin - pNearest->pev->origin).Length())
        {
            pNearest = pTrack;
        }
    }

    m_ppath = static_cast<CPathTrack *>(pNearest);
    if (pev->speed != 0)
    {
        NextThink(pev->ltime + 0.1, FALSE);
        SetThink(&CFuncVehicle::Next);
    }
}
예제 #17
0
void CBiorifle::SecondaryAttack( void )
{
	edict_t *pPlayer = m_pPlayer->edict( );
	CBaseEntity *pBioCharge = NULL;

	while ((pBioCharge = UTIL_FindEntityInSphere( pBioCharge, m_pPlayer->pev->origin, 16384)) != NULL)
	{
		if (FClassnameIs( pBioCharge->pev, "biomass"))
		{
			if (pBioCharge->pev->owner == pPlayer)
			{
				pBioCharge->Use( m_pPlayer, m_pPlayer, USE_ON, 0 );
			}
		}
	}
	m_pPlayer->m_flNextAttack = gpGlobals->time + 0.1;
}
예제 #18
0
void AvHDefenseChamber::RegenAliensThink()
{
	// Loop through all players
	CBaseEntity* theBaseEntity = NULL;
	int theNumEntsHealed = 0;
	
	while(((theBaseEntity = UTIL_FindEntityInSphere(theBaseEntity, this->pev->origin, BALANCE_VAR(kDefensiveChamberHealRange))) != NULL) && (theNumEntsHealed < BALANCE_VAR(kAlienChamberMaxPlayers)))
	{
		if(theBaseEntity->pev->team == this->pev->team)
		{
			AvHBaseBuildable* theBuildable = dynamic_cast<AvHBaseBuildable*>(theBaseEntity);
			AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theBaseEntity);
			float thePercent=BALANCE_VAR(kDefensiveChamberRegenPercent)/100.0f;
			float amount=BALANCE_VAR(kDefensiveChamberRegenAmount) + (theBaseEntity->pev->max_health*thePercent);
			if(thePlayer && thePlayer->IsAlive())
			{
				if(thePlayer->Heal(amount, true, true))
				{
					theNumEntsHealed++;
				}
			}
			else if(theBuildable && theBuildable->GetIsBuilt() && (theBuildable != this))
			{
				if(theBuildable->Regenerate(amount, true, true))
				{
					theNumEntsHealed++;
				}
			}
		}
	}
	
	// Set next think
	this->pev->nextthink = gpGlobals->time + BALANCE_VAR(kDefenseChamberThinkInterval);
	
	// Play a random idle animation
	int theIdle = this->GetIdle1Animation();
	
	if(RANDOM_LONG(0, 1))
	{
		theIdle = this->GetIdle2Animation();
	}
	
	this->PlayAnimationAtIndex(theIdle);
}
예제 #19
0
void CHostageImprov::UpdateGrenadeReactions()
{
	if (m_coughTimer.IsElapsed())
	{
		if (TheBots->IsInsideSmokeCloud(&GetCentroid()))
		{
			m_coughTimer.Start(RANDOM_FLOAT(1, 3));
			Chatter(HOSTAGE_CHATTER_COUGH);
			Frighten(SCARED);
		}
	}

	if (m_grenadeTimer.IsElapsed())
	{
		CBaseEntity *entity = NULL;
		const float watchGrenadeRadius = 500.0f;

		m_grenadeTimer.Start(RANDOM_FLOAT(0.4f, 0.6f));

		while ((entity = UTIL_FindEntityInSphere(entity, GetCentroid(), watchGrenadeRadius)) != NULL)
		{
			CGrenade *grenade = static_cast<CGrenade *>(entity);

			if (!FClassnameIs(grenade->pev, "grenade") || grenade->m_SGSmoke > 1)
				continue;

			if (IsVisible(grenade->Center()))
			{
				Chatter(HOSTAGE_CHATTER_SAW_HE_GRENADE);

				if (grenade->pev->dmg > 50.0f)
				{
					m_idleState.OnInjury();
					Frighten(TERRIFIED);
				}
				else
					Frighten(SCARED);

				m_grenadeTimer.Start(10);
				break;
			}
		}
	}
}
예제 #20
0
CBasePlayer *CCSBot::FindNearbyPlayer()
{
	CBaseEntity *pEntity = NULL;
	Vector vecSrc = pev->origin;
	const float flRadius = 800.0f;

	while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecSrc, flRadius)) != NULL)
	{
		if (!pEntity->IsPlayer())
			continue;

		if (!(pEntity->pev->flags & FL_FAKECLIENT))
			continue;

		return static_cast<CBasePlayer *>(pEntity); 
	}

	return NULL;
}
예제 #21
0
void CSatchel::PrimaryAttack()
{
	switch (m_chargeReady)
	{
	case 0:
		{
		Throw( );
		}
		break;
	case 1:
		{
		SendWeaponAnim( SATCHEL_RADIO_FIRE );

		edict_t *pPlayer = m_pPlayer->edict( );

		CBaseEntity *pSatchel = NULL;

		while ((pSatchel = UTIL_FindEntityInSphere( pSatchel, m_pPlayer->pev->origin, 4096 )) != NULL)
		{
			if (FClassnameIs( pSatchel->pev, "monster_satchel"))
			{
				if (pSatchel->pev->owner == pPlayer)
				{
					pSatchel->Use( m_pPlayer, m_pPlayer, USE_ON, 0 );
					m_chargeReady = 2;
				}
			}
		}

		m_chargeReady = 2;
		m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
		m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5;
		m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
		break;
		}

	case 2:
		// we're reloading, don't allow fire
		{
		}
		break;
	}
}
예제 #22
0
CBasePlayer *CCSBot::FindNearbyPlayer()
{
	CBasePlayer *pPlayer = nullptr;
	Vector vecSrc = pev->origin;
	const float flRadius = 800.0f;

	while ((pPlayer = UTIL_FindEntityInSphere(pPlayer, vecSrc, flRadius)))
	{
		if (!pPlayer->IsPlayer())
			continue;

		if (!(pPlayer->pev->flags & FL_FAKECLIENT))
			continue;

		return pPlayer;
	}

	return nullptr;
}
예제 #23
0
파일: AvHHive.cpp 프로젝트: Arkshine/NS
void AvHHive::ProcessHealing()
{
	// Regenerate nearby friendly aliens
	CBaseEntity* theEntity = NULL;
	const int theHiveHealRadius = BALANCE_VAR(kHiveHealRadius);

	while((theEntity = UTIL_FindEntityInSphere(theEntity, this->pev->origin, theHiveHealRadius)) != NULL)
	{
		AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity);
		if(thePlayer)
		{
			if(thePlayer->GetIsRelevant() && (thePlayer->GetTeam() == this->GetTeamNumber()) && !thePlayer->GetIsBeingDigested())
			{
                // Hive heals percentage of player health
                float theRegenPercentage = BALANCE_VAR(kHiveRegenerationPercentage);
                int theMaxHealth = AvHPlayerUpgrade::GetMaxHealth(thePlayer->pev->iuser4, (AvHUser3)thePlayer->pev->iuser3, thePlayer->GetExperienceLevel());
                float theRegenAmount = (theRegenPercentage*theMaxHealth);
                thePlayer->Heal(theRegenAmount, true);
			}
		}
	}
	
	// Regenerate self
	bool theDidHeal = false;
	
	// If we aren't at full health, heal health
	if(this->pev->health < this->mMaxHitPoints)
	{
        float theHiveRegenAmount = BALANCE_VAR(kHiveRegenerationAmount);
        float theCombatModeScalar = /*GetGameRules()->GetIsCombatMode() ? (1.0f/BALANCE_VAR(kCombatModeTimeScalar)) :*/ 1.0f;

		this->pev->health = min((float)this->mMaxHitPoints, this->pev->health + theHiveRegenAmount*theCombatModeScalar);
		theDidHeal = true;
	}
	
	// Play regen event
	if(theDidHeal)
	{
		// Play regeneration event
		PLAYBACK_EVENT_FULL(0, this->edict(), gRegenerationEventID, 0, this->pev->origin, (float *)&g_vecZero, 1.0f, 0.0, /*theWeaponIndex*/ 0, 0, 0, 0 );
	}
}
예제 #24
0
파일: AvHCombat.cpp 프로젝트: Arkshine/NS
void AvHGamerules::AwardExperience(AvHPlayer* inPlayer, int inTargetLevel, bool inAwardFriendliesInRange)
{
	PlayerListType thePlayerList;
	thePlayerList.push_back(inPlayer);

	if(inAwardFriendliesInRange)
	{
		// Award experience to player, and any other players nearby
		int theExperienceRadius = BALANCE_IVAR(kCombatFriendlyNearbyRange);

		// Make list of players to split it between.  If a player is at full experience, extra is wasted.
		CBaseEntity* theEntity = NULL;
		while ((theEntity = UTIL_FindEntityInSphere(theEntity, inPlayer->pev->origin, theExperienceRadius)) != NULL)
		{
			const char* theClassName = STRING(theEntity->pev->classname);
			if(!AvHSUGetIsExternalClassName(theClassName))
			{
				AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity);
				if(thePlayer && (thePlayer != inPlayer) && (thePlayer->pev->team == inPlayer->pev->team) && thePlayer->GetIsRelevant() && !thePlayer->GetIsBeingDigested())
				{
					thePlayerList.push_back(thePlayer);
				}
			}
		}
	}
	
	ASSERT(thePlayerList.size() > 0);

	float theExperienceFactor = GetGameRules()->GetIsIronMan() ? BALANCE_FVAR(kCombatIronManExperienceScalar) : 1.0f;

	int theExperienceToAward = BALANCE_IVAR(kCombatExperienceBaseAward) + inTargetLevel*BALANCE_IVAR(kCombatExperienceLevelAward);

	float theExperienceForEach = (theExperienceToAward/(float)thePlayerList.size() + BALANCE_IVAR(kCombatExperienceCrowdAward))*theExperienceFactor;

	for(PlayerListType::iterator thePlayerIter = thePlayerList.begin(); thePlayerIter != thePlayerList.end(); thePlayerIter++)
	{
		AvHPlayer* theCurrentPlayer = (*thePlayerIter);
		theCurrentPlayer->SetExperience(theCurrentPlayer->GetExperience() + theExperienceForEach);
	}
}
예제 #25
0
void CFuncWallDetail::Think( void )
{
	//MAKE FAKE Level Of Detail
	CBaseEntity *pEntity = NULL;

    while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, 9999 )) != NULL) 
	{
		if ( pEntity->IsPlayer() ) 
		{
			float flDist = (pEntity->Center() - pev->origin).Length();
							
			ALERT ( at_console, "flDist is: %f\n",flDist );

			if ( flDist >= 800)
			{
				//ALERT ( at_console, "m_iszWallNormal\n" );
				FireTargets( STRING(m_iszWallLow), this, this, USE_ON, 0 );//LOW
				FireTargets( STRING(m_iszWallNormal), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallDetail), this, this, USE_OFF, 0 );
			}
			else if ( flDist >= 400)
			{
				//ALERT ( at_console, "m_iszWallLow\n" );
				FireTargets( STRING(m_iszWallLow), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallNormal), this, this, USE_ON, 0 );//NORMAL
				FireTargets( STRING(m_iszWallDetail), this, this, USE_OFF, 0 );
			}
			else//detallado
			{
				//ALERT ( at_console, "m_iszWallDetail\n" );
				FireTargets( STRING(m_iszWallLow), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallNormal), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallDetail), this, this, USE_ON, 0 );//DETAILED
			}	
		}
	}

	pev->nextthink = gpGlobals->time + 0.1;
}
예제 #26
0
void CZombie :: RunTask ( Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_CHECK_FOR_NOBODY_AROUND:
		{
			CBaseEntity *pEnt = NULL;

			while (pEnt = UTIL_FindEntityInSphere(pEnt, pev->origin + Vector(0, 0, 20), 18))
			{
				if (pEnt->edict() == edict()) continue;

				if (!pEnt->IsAlive()) continue;

				if (pEnt->pev->solid == SOLID_NOT || pEnt->pev->solid == SOLID_TRIGGER) continue;

				return;
			}

			TaskComplete();
		}
		break;

	case TASK_AWAKE_FROM_DEAD:
		{
			if ( pev->frame >= 255 )
			{
				ReSpawn();
				TaskComplete();
			}
		}
		break;

	default:
		CBaseMonster::RunTask(pTask);
		break;
	}
}
예제 #27
0
void CMGargantua :: FlameDamage( Vector vecStart, Vector vecEnd, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType )
{
	edict_t *pEntity = NULL;
	TraceResult	tr;
	float		flAdjustedDamage;
	Vector		vecSpot;

	Vector vecMid = (vecStart + vecEnd) * 0.5;

	float searchRadius = (vecStart - vecMid).Length();

	Vector vecAim = (vecEnd - vecStart).Normalize( );

	// iterate on all entities in the vicinity.
	while ((pEntity = UTIL_FindEntityInSphere( pEntity, vecMid, searchRadius )) != NULL)
	{
		if ( pEntity->v.takedamage != DAMAGE_NO )
		{
			// UNDONE: this should check a damage mask, not an ignore
		
			vecSpot = UTIL_BodyTarget( pEntity,vecMid );
		
			float dist = DotProduct( vecAim, vecSpot - vecMid );
			if (dist > searchRadius)
				dist = searchRadius;
			else if (dist < -searchRadius)
				dist = searchRadius;
			
			Vector vecSrc = vecMid + dist * vecAim;

			UTIL_TraceLine ( vecSrc, vecSpot, dont_ignore_monsters, ENT(pev), &tr );

			dist = ( vecSrc - tr.vecEndPos ).Length();

				if (dist > 64)
				{
					flAdjustedDamage = flDamage - (dist - 64) * 0.4;
					if (flAdjustedDamage <= 0)
						continue;
				}
				else
				{
					flAdjustedDamage = flDamage;
				}

				// ALERT( at_console, "hit %s\n", STRING( pEntity->pev->classname ) );
				if (tr.flFraction != 1.0)
				{
					if (UTIL_IsPlayer (pEntity))
					{
						ClearMultiDamage( );
						UTIL_TraceAttack( pEntity,pevInflictor, flAdjustedDamage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, bitsDamageType );
						ApplyMultiDamage( pevInflictor, pevAttacker );
					}
					else if (pEntity->v.euser4 != NULL)
					{
						CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pEntity));
						ClearMultiDamage( );
						pMonster->TraceAttack( pevInflictor, flAdjustedDamage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, bitsDamageType );
						ApplyMultiDamage( pevInflictor, pevAttacker );
					}
				}
				else
				{
					if (UTIL_IsPlayer (pEntity))
					{
						UTIL_TakeDamage ( pEntity,pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType );
					}
					else if (pEntity->v.euser4 != NULL)
					{
						CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pEntity));
						pMonster->TakeDamage(pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType );
					}
			}
		}
	}
	
}
예제 #28
0
//=========================================================
//
// SquadRecruit(), get some monsters of my classification and
// link them as a group.  returns the group size
//
//=========================================================
int CSquadMonster :: SquadRecruit( int searchRadius, int maxMembers )
{
    int squadCount;
    int iMyClass = Classify();// cache this monster's class


    // Don't recruit if I'm already in a group
    if ( InSquad() )
        return 0;

    if ( maxMembers < 2 )
        return 0;

    // I am my own leader
    m_hSquadLeader = this;
    squadCount = 1;

    CBaseEntity *pEntity = NULL;

    if ( !FStringNull( pev->netname ) )
    {
        // I have a netname, so unconditionally recruit everyone else with that name.
        pEntity = UTIL_FindEntityByString( pEntity, "netname", STRING( pev->netname ) );
        while ( pEntity )
        {
            CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer();

            if ( pRecruit )
            {
                if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass && pRecruit != this )
                {
                    // minimum protection here against user error.in worldcraft.
                    if (!SquadAdd( pRecruit ))
                        break;
                    squadCount++;
                }
            }

            pEntity = UTIL_FindEntityByString( pEntity, "netname", STRING( pev->netname ) );
        }
    }
    else
    {
        while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, searchRadius )) != NULL)
        {
            CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer( );

            if ( pRecruit && pRecruit != this && pRecruit->IsAlive() && !pRecruit->m_pCine )
            {
                // Can we recruit this guy?
                if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass &&
                        ( (iMyClass != CLASS_ALIEN_MONSTER) || FStrEq(STRING(pev->classname), STRING(pRecruit->pev->classname))) &&
                        FStringNull( pRecruit->pev->netname ) )
                {
                    TraceResult tr;
                    UTIL_TraceLine( pev->origin + pev->view_ofs, pRecruit->pev->origin + pev->view_ofs, ignore_monsters, pRecruit->edict(), &tr );// try to hit recruit with a traceline.
                    if ( tr.flFraction == 1.0 )
                    {
                        if (!SquadAdd( pRecruit ))
                            break;

                        squadCount++;
                    }
                }
            }
        }
    }

    // no single member squads
    if (squadCount == 1)
    {
        m_hSquadLeader = NULL;
    }

    return squadCount;
}
예제 #29
0
파일: combat.cpp 프로젝트: 6779660/halflife
void RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType )
{
	CBaseEntity *pEntity = NULL;
	TraceResult	tr;
	float		flAdjustedDamage, falloff;
	Vector		vecSpot;

	if ( flRadius )
		falloff = flDamage / flRadius;
	else
		falloff = 1.0;

	int bInWater = (UTIL_PointContents ( vecSrc ) == CONTENTS_WATER);

	vecSrc.z += 1;// in case grenade is lying on the ground

	if ( !pevAttacker )
		pevAttacker = pevInflictor;

	// iterate on all entities in the vicinity.
	while ((pEntity = UTIL_FindEntityInSphere( pEntity, vecSrc, flRadius )) != NULL)
	{
		if ( pEntity->pev->takedamage != DAMAGE_NO )
		{
			// UNDONE: this should check a damage mask, not an ignore
			if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
			{// houndeyes don't hurt other houndeyes with their attack
				continue;
			}

			// blast's don't tavel into or out of water
			if (bInWater && pEntity->pev->waterlevel == 0)
				continue;
			if (!bInWater && pEntity->pev->waterlevel == 3)
				continue;

			vecSpot = pEntity->BodyTarget( vecSrc );
			
			UTIL_TraceLine ( vecSrc, vecSpot, dont_ignore_monsters, ENT(pevInflictor), &tr );

			if ( tr.flFraction == 1.0 || tr.pHit == pEntity->edict() )
			{// the explosion can 'see' this entity, so hurt them!
				if (tr.fStartSolid)
				{
					// if we're stuck inside them, fixup the position and distance
					tr.vecEndPos = vecSrc;
					tr.flFraction = 0.0;
				}
				
				// decrease damage for an ent that's farther from the bomb.
				flAdjustedDamage = ( vecSrc - tr.vecEndPos ).Length() * falloff;
				flAdjustedDamage = flDamage - flAdjustedDamage;
			
				if ( flAdjustedDamage < 0 )
				{
					flAdjustedDamage = 0;
				}
			
				// ALERT( at_console, "hit %s\n", STRING( pEntity->pev->classname ) );
				if (tr.flFraction != 1.0)
				{
					ClearMultiDamage( );
					pEntity->TraceAttack( pevInflictor, flAdjustedDamage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, bitsDamageType );
					ApplyMultiDamage( pevInflictor, pevAttacker );
				}
				else
				{
					pEntity->TakeDamage ( pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType );
				}
			}
		}
	}
}
예제 #30
0
//=========================================================
// SonicAttack
//=========================================================
void CHoundeye :: SonicAttack ( void )
{
	float		flAdjustedDamage;
	float		flDist;

	switch ( RANDOM_LONG( 0, 2 ) )
	{
	case 0:	EMIT_SOUND(ENT(pev), CHAN_WEAPON, "houndeye/he_blast1.wav", 1, ATTN_NORM);	break;
	case 1:	EMIT_SOUND(ENT(pev), CHAN_WEAPON, "houndeye/he_blast2.wav", 1, ATTN_NORM);	break;
	case 2:	EMIT_SOUND(ENT(pev), CHAN_WEAPON, "houndeye/he_blast3.wav", 1, ATTN_NORM);	break;
	}

	// blast circles
	MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
		WRITE_BYTE( TE_BEAMCYLINDER );
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16);
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16 + HOUNDEYE_MAX_ATTACK_RADIUS / .2); // reach damage radius over .3 seconds
		WRITE_SHORT( m_iSpriteTexture );
		WRITE_BYTE( 0 ); // startframe
		WRITE_BYTE( 0 ); // framerate
		WRITE_BYTE( 2 ); // life
		WRITE_BYTE( 16 );  // width
		WRITE_BYTE( 0 );   // noise

		WriteBeamColor();

		WRITE_BYTE( 255 ); //brightness
		WRITE_BYTE( 0 );		// speed
	MESSAGE_END();

	MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
		WRITE_BYTE( TE_BEAMCYLINDER );
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16);
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16 + ( HOUNDEYE_MAX_ATTACK_RADIUS / 2 ) / .2); // reach damage radius over .3 seconds
		WRITE_SHORT( m_iSpriteTexture );
		WRITE_BYTE( 0 ); // startframe
		WRITE_BYTE( 0 ); // framerate
		WRITE_BYTE( 2 ); // life
		WRITE_BYTE( 16 );  // width
		WRITE_BYTE( 0 );   // noise

		WriteBeamColor();
		
		WRITE_BYTE( 255 ); //brightness
		WRITE_BYTE( 0 );		// speed
	MESSAGE_END();


	CBaseEntity *pEntity = NULL;
	// iterate on all entities in the vicinity.
	while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, HOUNDEYE_MAX_ATTACK_RADIUS )) != NULL)
	{
		if ( pEntity->pev->takedamage != DAMAGE_NO )
		{
			if ( !FClassnameIs(pEntity->pev, "monster_houndeye") )
			{// houndeyes don't hurt other houndeyes with their attack

				// houndeyes do FULL damage if the ent in question is visible. Half damage otherwise.
				// This means that you must get out of the houndeye's attack range entirely to avoid damage.
				// Calculate full damage first

				if ( SquadCount() > 1 )
				{
					// squad gets attack bonus.
					flAdjustedDamage = gSkillData.houndeyeDmgBlast + gSkillData.houndeyeDmgBlast * ( HOUNDEYE_SQUAD_BONUS * ( SquadCount() - 1 ) );
				}
				else
				{
					// solo
					flAdjustedDamage = gSkillData.houndeyeDmgBlast;
				}

				flDist = (pEntity->Center() - pev->origin).Length();

				flAdjustedDamage -= ( flDist / HOUNDEYE_MAX_ATTACK_RADIUS ) * flAdjustedDamage;

				if ( !FVisible( pEntity ) )
				{
					if ( pEntity->IsPlayer() )
					{
						// if this entity is a client, and is not in full view, inflict half damage. We do this so that players still 
						// take the residual damage if they don't totally leave the houndeye's effective radius. We restrict it to clients
						// so that monsters in other parts of the level don't take the damage and get pissed.
						flAdjustedDamage *= 0.5;
					}
					else if ( !FClassnameIs( pEntity->pev, "func_breakable" ) && !FClassnameIs( pEntity->pev, "func_pushable" ) ) 
					{
						// do not hurt nonclients through walls, but allow damage to be done to breakables
						flAdjustedDamage = 0;
					}
				}

				//ALERT ( at_aiconsole, "Damage: %f\n", flAdjustedDamage );

				if (flAdjustedDamage > 0 )
				{
					pEntity->TakeDamage ( pev, pev, flAdjustedDamage, DMG_SONIC | DMG_ALWAYSGIB );
				}
			}
		}
	}
}