CBaseEntity *CAI_PlayerAlly::EnumFriends( CBaseEntity *pPrevious, int listNumber, bool bTrace ) { CBaseEntity *pFriend = pPrevious; char *pszFriend; trace_t tr; Vector vecCheck; pszFriend = m_szFriends[ FriendNumber(listNumber) ]; while (pFriend = gEntList.FindEntityByClassname( pFriend, pszFriend )) { if (pFriend == this || !pFriend->IsAlive()) // don't talk to self or dead people continue; if ( bTrace ) { vecCheck = pFriend->GetAbsOrigin(); vecCheck.z = pFriend->GetAbsMaxs().z; UTIL_TraceLine( GetAbsOrigin(), vecCheck, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); } else tr.fraction = 1.0; if (tr.fraction == 1.0) { return pFriend; } } return NULL; }
//========================================================= // FindNearestFriend // Scan for nearest, visible friend. If fPlayer is true, look for // nearest player //========================================================= CBaseEntity *CAI_PlayerAlly::FindNearestFriend(bool fPlayer) { CBaseEntity *pFriend = NULL; CBaseEntity *pNearest = NULL; float range = 10000000.0; trace_t tr; Vector vecStart = GetAbsOrigin(); Vector vecCheck; int i; const char *pszFriend; int cfriends; vecStart.z = GetAbsMaxs().z; if (fPlayer) cfriends = 1; else cfriends = TLK_CFRIENDS; // for each type of friend... for (i = cfriends-1; i > -1; i--) { if (fPlayer) { CBaseEntity *pPlayer = UTIL_PlayerByIndex(1); if ( pPlayer ) { pszFriend = STRING(pPlayer->m_iClassname); } else { pszFriend = "player"; } } else pszFriend = m_szFriends[FriendNumber(i)]; if (!pszFriend) continue; // for each friend in this bsp... while (pFriend = gEntList.FindEntityByClassname( pFriend, pszFriend )) { if (pFriend == this || !pFriend->IsAlive()) // don't talk to self or dead people continue; CAI_BaseNPC *pNPC = pFriend->MyNPCPointer(); // If not a NPC for some reason, or in a script. if ( pNPC && (pNPC->m_NPCState == NPC_STATE_SCRIPT || pNPC->m_NPCState == NPC_STATE_PRONE)) continue; if( pNPC && pNPC->IsSelected() ) { // Don't bother people that are awaiting orders. return false; } vecCheck = pFriend->GetLocalOrigin(); vecCheck.z = pFriend->GetAbsMaxs().z; // if closer than previous friend, and in range, see if he's visible if (range > (vecStart - vecCheck).Length()) { UTIL_TraceLine(vecStart, vecCheck, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); if (tr.fraction == 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; }