| 4666 | } |
| 4667 | |
| 4668 | void CGameContext::UpdatePlayerMaps() |
| 4669 | { |
| 4670 | const auto DistCompare = [](std::pair<float, int> a, std::pair<float, int> b) -> bool { |
| 4671 | return (a.first < b.first); |
| 4672 | }; |
| 4673 | |
| 4674 | if(Server()->Tick() % g_Config.m_SvMapUpdateRate != 0) |
| 4675 | return; |
| 4676 | |
| 4677 | std::pair<float, int> Dist[MAX_CLIENTS]; |
| 4678 | for(int i = 0; i < MAX_CLIENTS; i++) |
| 4679 | { |
| 4680 | if(!Server()->ClientIngame(i)) |
| 4681 | continue; |
| 4682 | if(Server()->GetClientVersion(i) >= VERSION_DDNET_OLD) |
| 4683 | continue; |
| 4684 | int *pMap = Server()->GetIdMap(i); |
| 4685 | |
| 4686 | // compute distances |
| 4687 | for(int j = 0; j < MAX_CLIENTS; j++) |
| 4688 | { |
| 4689 | Dist[j].second = j; |
| 4690 | if(j == i) |
| 4691 | continue; |
| 4692 | if(!Server()->ClientIngame(j) || !m_apPlayers[j]) |
| 4693 | { |
| 4694 | Dist[j].first = 1e10; |
| 4695 | continue; |
| 4696 | } |
| 4697 | CCharacter *pChr = m_apPlayers[j]->GetCharacter(); |
| 4698 | if(!pChr) |
| 4699 | { |
| 4700 | Dist[j].first = 1e9; |
| 4701 | continue; |
| 4702 | } |
| 4703 | if(!pChr->CanSnapCharacter(i)) |
| 4704 | Dist[j].first = 1e8; |
| 4705 | else |
| 4706 | Dist[j].first = length_squared(m_apPlayers[i]->m_ViewPos - pChr->GetPos()); |
| 4707 | } |
| 4708 | |
| 4709 | // always send the player themselves, even if all in same position |
| 4710 | Dist[i].first = -1; |
| 4711 | |
| 4712 | std::nth_element(&Dist[0], &Dist[VANILLA_MAX_CLIENTS - 1], &Dist[MAX_CLIENTS], DistCompare); |
| 4713 | |
| 4714 | int Index = 1; // exclude self client id |
| 4715 | for(int j = 0; j < VANILLA_MAX_CLIENTS - 1; j++) |
| 4716 | { |
| 4717 | pMap[j + 1] = -1; // also fill player with empty name to say chat msgs |
| 4718 | if(Dist[j].second == i || Dist[j].first > 5e9f) |
| 4719 | continue; |
| 4720 | pMap[Index++] = Dist[j].second; |
| 4721 | } |
| 4722 | |
| 4723 | // sort by real client ids, guarantee order on distance changes, O(Nlog(N)) worst case |
| 4724 | // sort just clients in game always except first (self client id) and last (fake client id) indexes |
| 4725 | std::sort(&pMap[1], &pMap[minimum(Index, VANILLA_MAX_CLIENTS - 1)]); |
nothing calls this directly
no test coverage detected