void CDplusProtocol::HandleKeepalives(void) { // send keepalives CBuffer keepalive; EncodeKeepAlivePacket(&keepalive); // iterate on clients CClients *clients = g_Reflector.GetClients(); int index = -1; CClient *client = NULL; while ( (client = clients->FindNextClient(PROTOCOL_DPLUS, &index)) != NULL ) { // send keepalive //std::cout << "Sending DPlus packet @ " << client->GetIp() << std::endl; m_Socket.Send(keepalive, client->GetIp()); // is this client busy ? if ( client->IsAMaster() ) { // yes, just tickle it client->Alive(); } // check it's still with us else if ( !client->IsAlive() ) { // no, disconnect CBuffer disconnect; EncodeDisconnectPacket(&disconnect); m_Socket.Send(disconnect, client->GetIp()); // and remove it std::cout << "DPlus client " << client->GetCallsign() << " keepalive timeout" << std::endl; clients->RemoveClient(client); } } g_Reflector.ReleaseClients(); }
bool CBaseBot::FindEnemy() { // check if the health is decreased bool fHealthDecreased = m_iPrevHealth > GetHealth(); m_iPrevHealth = GetHealth(); // store away the current health value float cur_dist; if (m_pEnemy && (!m_pEnemy->IsValid() || !m_pEnemy->IsAlive())) m_pEnemy = NULL; // null out the enemy pointer as it's no longer valid Vector vecHisPos; unsigned char cHit; // see if we can still see the current enemy... if (m_pEnemy) { if (FBoxVisible(m_pEnemy, &vecHisPos, &cHit)) { m_vecEnemy = vecHisPos; m_ucVisibility = cHit; } else { m_pEnemy = NULL; // we can no longer see this enemy } } // if we already have an enemy... if (m_pEnemy) { // don't discard important enemies (bomb/flag/hostage carrier, VIP, etc) if (g_pServer->ClientIsImportant(EnemyClient())) return false; // calculate the distance to the enemy cur_dist = (m_pEnemy->GetOrigin() - GetOrigin()).Length(); } else { cur_dist = FLT_MAX; // just some crazy value } // loop through all the clients... for (int i = 0; i < g_pServer->GetMaxClients(); i++) { if (i == entindex() - 1 || (m_pEnemy && i == m_pEnemy->entindex() - 1)) continue; // skip myself and the current enemy CClient *pClient = g_pServer->m_rgpClients[i]; if (!pClient || !pClient->IsValid() || !pClient->IsAlive()) continue; float dist = (pClient->GetOrigin() - GetOrigin()).Length(); // if this enemy is further away than the current one... if (dist > cur_dist && !g_pServer->ClientIsImportant(pClient)) continue; // skip it if (dist > 900 + 4000 * ((GetDifficulty() - 1) / 4.0)) continue; // enemy is too far if (g_pServer->IsTeamplay() && GetTeam() == g_pServer->GetTeam(pClient)) continue; // skip our teammates float fov; // if the bot's health decreased or the enemy is shooting if (!m_pEnemy && (fHealthDecreased || pClient->IsShooting())) fov = 360; else fov = GetFov() * 2 - (GetFov() - (dist > GetFov() * 9 ? GetFov() * 9 : dist) / 9); // check if enemy is in the view cone if (!FInViewCone(pClient, fov)) continue; // enemy isn't in bot's view cone // check if enemy is visible if (!FBoxVisible(pClient, &vecHisPos, &cHit)) { continue; // skip this enemy } // if the enemy is quite far away, not shooting and the bot is not damaged if (!m_pEnemy && dist > 200 && !fHealthDecreased && !pClient->IsShooting()) { // if the bot isn't in the fov of the enemy and the bot doesn't really want to fight if (!pClient->FInViewCone(this, 120) /*&& BotWantsToRetreat()*/) continue; // skip this enemy } m_pEnemy = pClient; // found a new enemy m_vecEnemy = vecHisPos; m_ucVisibility = cHit; DebugMsg(DEBUG_BOTCOMBAT, "Found new enemy: %s", m_pEnemy->GetNetName()); return true; } return false; // no new enemy is found }