void Director::AnalysePlayer(int playerNum) { int secondTarget = 0; float rank = RandomFloat(0.0f, 0.01f) + 1; float targetRank, bestTargetRank = 0; worldHistory_t *now = &m_history[m_currentSeqnr % m_historyLength]; playerData_t *player = &now->players[playerNum]; if (player->active) { if (m_WorldModel->IsValid()) { m_WorldModel->SetPVS(player->origin); for (int i = 0; i < MAX_CLIENTS; i++) { playerData_t *target = &now->players[i]; if (!target->active || !m_WorldModel->InPVS(target->origin)) { continue; } vec3_t offset; VectorSubtract(target->origin, player->origin, offset); float distance = Length(offset); if (distance >= 1.0f) { targetRank = WeightedAngle(target->angles, offset) + 1 / distance; // inverted VectorScale(offset, -1.0f, offset); targetRank = WeightedAngle(target->angles, offset) * targetRank; rank += targetRank; // remember closest player if (targetRank > bestTargetRank) { bestTargetRank = targetRank; secondTarget = i + 1; } } } } } else { rank = 0; } player->target = secondTarget; player->rank = player->rank + rank; SmoothRank(playerNum, rank); }
void CHLTVDirector::AnalyzeCameras() { InitRandomOrder( m_nNumFixedCameras ); for ( int i = 0; i<m_nNumFixedCameras; i++ ) { int iCameraIndex = s_RndOrder[i]; CBaseEntity *pCamera = m_pFixedCameras[ iCameraIndex ]; float flRank = 0.0f; int iClosestPlayer = 0; float flClosestPlayerDist = 100000.0f; int nCount = 0; // Number of visible targets Vector vDistribution; vDistribution.Init(); // distribution of targets Vector vCamPos = pCamera->GetAbsOrigin(); for ( int j=0; j<m_nNumActivePlayers; j++ ) { CBasePlayer *pPlayer = m_pActivePlayers[j]; Vector vPlayerPos = pPlayer->GetAbsOrigin(); float dist = VectorLength( vPlayerPos - vCamPos ); if ( dist > 1024.0f || dist < 4.0f ) continue; // too colse or far away // check visibility trace_t tr; UTIL_TraceLine( vCamPos, pPlayer->GetAbsOrigin(), MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0 ) continue; // not visible for camera nCount++; // remember closest player if ( dist < flClosestPlayerDist ) { iClosestPlayer = pPlayer->entindex(); flClosestPlayerDist = dist; } Vector v1; AngleVectors( pPlayer->EyeAngles(), &v1 ); // check players orientation towards camera Vector v2 = vCamPos - vPlayerPos; VectorNormalize( v2 ); // player/camera cost function: flRank += ( 1.0f/sqrt(dist) ) * WeightedAngle( v1, v2 ); vDistribution += v2; } if ( nCount > 0 ) { // normalize distribution flRank *= VectorLength( vDistribution ) / nCount; } IGameEvent *event = gameeventmanager->CreateEvent("hltv_rank_camera"); if ( event ) { event->SetFloat("rank", flRank ); event->SetInt("index", iCameraIndex ); // index in m_pFixedCameras event->SetInt("target", iClosestPlayer ); // ent index gameeventmanager->FireEvent( event ); } } }
void CHLTVDirector::AnalyzePlayers() { // build list of current active players BuildActivePlayerList(); // analyzes every active player InitRandomOrder( m_nNumActivePlayers ); for ( int i = 0; i<m_nNumActivePlayers; i++ ) { int iPlayerIndex = s_RndOrder[i]; CBasePlayer *pPlayer = m_pActivePlayers[ iPlayerIndex ]; float flRank = 0.0f; int iBestFacingPlayer = 0; float flBestFacingPlayer = 0.0f; int nCount = 0; // Number of visible targets Vector vDistribution; vDistribution.Init(); // distribution of targets Vector vCamPos = pPlayer->GetAbsOrigin(); Vector v1; AngleVectors( pPlayer->EyeAngles(), &v1 ); v1 *= -1; // inverted for ( int j=0; j<m_nNumActivePlayers; j++ ) { if ( iPlayerIndex == j ) continue; // don't check against itself CBasePlayer *pOtherPlayer = m_pActivePlayers[j]; Vector vPlayerPos = pOtherPlayer->GetAbsOrigin(); float dist = VectorLength( vPlayerPos - vCamPos ); if ( dist > 1024.0f || dist < 4.0f ) continue; // too close or far away // check visibility trace_t tr; UTIL_TraceLine( vCamPos, pOtherPlayer->GetAbsOrigin(), MASK_SOLID, pOtherPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0 ) continue; // not visible for camera nCount++; // check players orientation towards camera Vector v2; AngleVectors( pOtherPlayer->EyeAngles(), &v2 ); float facing = WeightedAngle( v1, v2 ); // remember closest player if ( facing > flBestFacingPlayer ) { iBestFacingPlayer = pOtherPlayer->entindex(); flBestFacingPlayer = facing; } // player/camera cost function: flRank += ( 1.0f/sqrt(dist) ) * facing; vDistribution += v2; } if ( nCount > 0 ) { float flDistribution = VectorLength( vDistribution ) / nCount; // normalize distribution flRank *= flDistribution; } IGameEvent *event = gameeventmanager->CreateEvent("hltv_rank_entity"); if ( event ) { event->SetInt("index", pPlayer->entindex() ); event->SetFloat("rank", flRank ); event->SetInt("target", iBestFacingPlayer ); // ent index gameeventmanager->FireEvent( event ); } } }