CBaseEntity *CTalkMonster::EnumFriends( CBaseEntity *pPrevious, int listNumber, const bool bTrace ) { CBaseEntity *pFriend = pPrevious; const char* pszFriend; TraceResult tr; Vector vecCheck; pszFriend = m_szFriends[ FriendNumber(listNumber) ]; while( ( pFriend = UTIL_FindEntityByClassname( pFriend, pszFriend ) ) != nullptr ) { if (pFriend == this || !pFriend->IsAlive()) // don't talk to self or dead people continue; if ( bTrace ) { vecCheck = pFriend->GetAbsOrigin(); vecCheck.z = pFriend->GetAbsMax().z; UTIL_TraceLine( GetAbsOrigin(), vecCheck, ignore_monsters, ENT(pev), &tr); } else tr.flFraction = 1.0; if (tr.flFraction == 1.0) { return pFriend; } } return NULL; }
//========================================================= // FindNearestFriend // Scan for nearest, visible friend. If fPlayer is true, look for // nearest player //========================================================= CBaseEntity* CTalkMonster::FindNearestFriend( const bool fPlayer ) const { CBaseEntity *pFriend = NULL; CBaseEntity *pNearest = NULL; float range = 10000000.0; TraceResult tr; Vector vecStart = GetAbsOrigin(); Vector vecCheck; int i; const char* pszFriend; int cfriends; vecStart.z = GetAbsMax().z; if (fPlayer) cfriends = 1; else cfriends = TLK_CFRIENDS; // for each type of friend... for (i = cfriends-1; i > -1; i--) { if (fPlayer) pszFriend = "player"; else pszFriend = m_szFriends[FriendNumber(i)]; if (!pszFriend) continue; // for each friend in this bsp... while( ( pFriend = UTIL_FindEntityByClassname( pFriend, pszFriend ) ) != nullptr ) { if (pFriend == this || !pFriend->IsAlive()) // don't talk to self or dead people continue; CBaseMonster *pMonster = pFriend->MyMonsterPointer(); // If not a monster for some reason, or in a script, or prone if ( !pMonster || pMonster->m_MonsterState == MONSTERSTATE_SCRIPT || pMonster->m_MonsterState == MONSTERSTATE_PRONE ) continue; vecCheck = pFriend->GetAbsOrigin(); vecCheck.z = pFriend->GetAbsMax().z; // if closer than previous friend, and in range, see if he's visible if (range > (vecStart - vecCheck).Length()) { UTIL_TraceLine(vecStart, vecCheck, ignore_monsters, ENT(pev), &tr); if (tr.flFraction == 1.0) { // visible and in range, this is the new nearest scientist if ((vecStart - vecCheck).Length() < TALKRANGE_MIN) { pNearest = pFriend; range = (vecStart - vecCheck).Length(); } } } } } return pNearest; }