@@ -857,21 +857,20 @@ bool BfCapturePoint::HandlePlayerEnter(Player* player)
857857 player->SendUpdateWorldState (go->GetGOInfo ()->capturePoint .worldstate2 , uint32 (std::ceil ((Value + MaxValue) / (2 * MaxValue) * 100 .0f )));
858858 player->SendUpdateWorldState (go->GetGOInfo ()->capturePoint .worldstate3 , NeutralValuePct);
859859 }
860- return ActivePlayers[player-> GetTeamId ()] .insert (player->GetGUID ()).second ;
860+ return ActivePlayers.insert (player->GetGUID ()).second ;
861861}
862862
863863GuidUnorderedSet::iterator BfCapturePoint::HandlePlayerLeave (Player* player)
864864{
865865 if (GameObject* go = GetCapturePointGo (player))
866866 player->SendUpdateWorldState (go->GetGOInfo ()->capturePoint .worldState1 , 0 );
867867
868- GuidUnorderedSet::iterator current = ActivePlayers[player-> GetTeamId ()] .find (player->GetGUID ());
868+ GuidUnorderedSet::iterator current = ActivePlayers.find (player->GetGUID ());
869869
870- if (current == ActivePlayers[player-> GetTeamId ()] .end ())
870+ if (current == ActivePlayers.end ())
871871 return current; // return end()
872872
873- current = ActivePlayers[player->GetTeamId ()].erase (current);
874- return current;
873+ return ActivePlayers.erase (current);
875874}
876875
877876void BfCapturePoint::SendChangePhase ()
@@ -880,17 +879,16 @@ void BfCapturePoint::SendChangePhase()
880879 if (!capturePoint)
881880 return ;
882881
883- for (uint8 team = 0 ; team < 2 ; ++team)
884- for (ObjectGuid const & guid : ActivePlayers[team]) // send to all players present in the area
885- if (Player* player = ObjectAccessor::FindPlayer (guid))
886- {
887- // send this too, sometimes the slider disappears, dunno why :(
888- player->SendUpdateWorldState (capturePoint->GetGOInfo ()->capturePoint .worldState1 , 1 );
889- // send these updates to only the ones in this objective
890- player->SendUpdateWorldState (capturePoint->GetGOInfo ()->capturePoint .worldstate2 , (uint32) std::ceil ((Value + MaxValue) / (2 * MaxValue) * 100 .0f ));
891- // send this too, sometimes it resets :S
892- player->SendUpdateWorldState (capturePoint->GetGOInfo ()->capturePoint .worldstate3 , NeutralValuePct);
893- }
882+ for (ObjectGuid const & guid : ActivePlayers) // send to all players present in the area
883+ if (Player* player = ObjectAccessor::FindPlayer (guid))
884+ {
885+ // send this too, sometimes the slider disappears, dunno why :(
886+ player->SendUpdateWorldState (capturePoint->GetGOInfo ()->capturePoint .worldState1 , 1 );
887+ // send these updates to only the ones in this objective
888+ player->SendUpdateWorldState (capturePoint->GetGOInfo ()->capturePoint .worldstate2 , (uint32) std::ceil ((Value + MaxValue) / (2 * MaxValue) * 100 .0f ));
889+ // send this too, sometimes it resets :S
890+ player->SendUpdateWorldState (capturePoint->GetGOInfo ()->capturePoint .worldstate3 , NeutralValuePct);
891+ }
894892}
895893
896894bool BfCapturePoint::SetCapturePointData (GameObject* capturePoint, TeamId team)
@@ -962,19 +960,19 @@ bool BfCapturePoint::Update(uint32 diff)
962960
963961 float radius = capturePoint->GetGOInfo ()->capturePoint .radius ;
964962
965- for (uint8 team = 0 ; team < 2 ; ++team)
963+ // Single pass over the existing set: drop leavers, count survivors per team.
964+ uint32 counts[PVP_TEAMS_COUNT] = { 0 , 0 };
965+ for (auto itr = ActivePlayers.begin (); itr != ActivePlayers.end ();)
966966 {
967- for (auto itr = ActivePlayers[team].begin (); itr != ActivePlayers[team].end ();)
967+ Player* player = ObjectAccessor::FindPlayer (*itr);
968+ if (player && capturePoint->IsWithinDistInMap (player, radius) && player->IsOutdoorPvPActive ())
968969 {
969- if (Player* player = ObjectAccessor::FindPlayer (*itr))
970- if (!capturePoint->IsWithinDistInMap (player, radius) || !player->IsOutdoorPvPActive ())
971- {
972- itr = HandlePlayerLeave (player);
973- continue ;
974- }
975-
970+ ++counts[player->GetTeamId ()];
976971 ++itr;
972+ continue ;
977973 }
974+
975+ itr = (player ? HandlePlayerLeave (player) : ActivePlayers.erase (itr));
978976 }
979977
980978 std::list<Player*> players;
@@ -984,11 +982,14 @@ bool BfCapturePoint::Update(uint32 diff)
984982
985983 for (Player* player : players)
986984 if (player->IsOutdoorPvPActive ())
987- if (ActivePlayers[player->GetTeamId ()].insert (player->GetGUID ()).second )
985+ if (ActivePlayers.insert (player->GetGUID ()).second )
986+ {
988987 HandlePlayerEnter (player);
988+ ++counts[player->GetTeamId ()];
989+ }
989990
990991 // get the difference of numbers
991- float factDiff = ((float ) ActivePlayers[ 0 ]. size () - (float ) ActivePlayers[ 1 ]. size () ) * diff / BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL ;
992+ float factDiff = ((float )counts[TEAM_ALLIANCE] - (float )counts[TEAM_HORDE] ) * diff / BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL;
992993 if (G3D::fuzzyEq (factDiff, 0 .0f ))
993994 return false ;
994995
@@ -1074,34 +1075,36 @@ bool BfCapturePoint::Update(uint32 diff)
10741075
10751076void BfCapturePoint::SendUpdateWorldState (uint32 field, uint32 value)
10761077{
1077- for (uint8 team = 0 ; team < 2 ; ++team)
1078- for (ObjectGuid const & guid : ActivePlayers[team]) // send to all players present in the area
1079- if (Player* player = ObjectAccessor::FindPlayer (guid))
1080- player->SendUpdateWorldState (field, value);
1078+ for (ObjectGuid const & guid : ActivePlayers) // send to all players present in the area
1079+ if (Player* player = ObjectAccessor::FindPlayer (guid))
1080+ player->SendUpdateWorldState (field, value);
10811081}
10821082
10831083void BfCapturePoint::SendObjectiveComplete (uint32 id, ObjectGuid guid)
10841084{
1085- uint8 team ;
1085+ TeamId winner ;
10861086 switch (State)
10871087 {
10881088 case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE:
1089- team = 0 ;
1089+ winner = TEAM_ALLIANCE ;
10901090 break ;
10911091 case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE:
1092- team = 1 ;
1092+ winner = TEAM_HORDE ;
10931093 break ;
10941094 default :
10951095 return ;
10961096 }
10971097
1098- // send to all players present in the area
1099- for (ObjectGuid const & playerGuid : ActivePlayers[team])
1098+ // Credit only players on the controlling team. Team is read from the
1099+ // player at iteration time, not at insert time, so players whose
1100+ // GetTeamId() changed mid-stay get credit on their current side.
1101+ for (ObjectGuid const & playerGuid : ActivePlayers)
11001102 if (Player* player = ObjectAccessor::FindPlayer (playerGuid))
1101- player->KilledMonsterCredit (id, guid);
1103+ if (player->GetTeamId () == winner)
1104+ player->KilledMonsterCredit (id, guid);
11021105}
11031106
11041107bool BfCapturePoint::IsInsideObjective (Player* player) const
11051108{
1106- return ActivePlayers[player-> GetTeamId ()] .find (player->GetGUID ()) != ActivePlayers[player-> GetTeamId ()] .end ();
1109+ return ActivePlayers.find (player->GetGUID ()) != ActivePlayers.end ();
11071110}
0 commit comments