Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions conf/CFBG.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,11 @@
#
# CFBG.BalanceTeamsOnEntry.Enabled
# Description: When a solo player enters a battleground while the teams are
# uneven, move them to the smaller team according to the live
# in-BG head counts at that moment. If the teams are already
# even they keep the team chosen at invite time, and grouped
# players are never moved.
# uneven, move them to the smaller team according to the
# invited counts at that moment (players inside plus accepted
# or pending invitees still on their way). If the teams are
# already even they keep the team chosen at invite time, and
# grouped players are never moved.
# Default: 1 - (Enabled)
# 0 - (Disabled)

Expand Down
24 changes: 20 additions & 4 deletions src/CFBG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,19 @@ void CFBG::BalanceTeamsOnEntry(Battleground* bg, Player* player)

TeamId provisional = player->GetBgTeamId();

// Live head counts correctly EXCLUDE the entering player (counted later in
// Battleground::AddPlayer).
int32 countA = bg->GetPlayersCountByTeam(TEAM_ALLIANCE);
int32 countH = bg->GetPlayersCountByTeam(TEAM_HORDE);
// The invited ledger (entered + accepted-in-flight + pending-invited) sees
// reservations that live head counts miss while invitees are still porting
// (issue #172: a solo flipped onto a porting premade's side -> 1v3).
int32 countA = bg->GetInvitedCount(TEAM_ALLIANCE);
int32 countH = bg->GetInvitedCount(TEAM_HORDE);

// Accept does not release the reservation (RemovePlayer with
// decreaseInvitedCount=false), so the entrant is still ledgered on the
// provisional side: exclude them from the comparison.
if (provisional == TEAM_ALLIANCE)
--countA;
else
--countH;

// Sides already balanced: keep the provisional team, no morph / count churn.
if (countA == countH)
Expand Down Expand Up @@ -735,6 +744,13 @@ std::array<uint32, 2> CFBG::GetProjectedBaseCounts(Battleground* bg, Battlegroun
if (gInfo->IsInvitedToBGInstanceGUID == bg->GetInstanceID())
counts[gInfo->teamId] += gInfo->Players.size();

// A player between accept and worldport ack is in neither term above (the
// accept deleted their ginfo; AddPlayer has not run yet). The BG's invited
// ledger still holds every reservation, so clamp up to it; max() degrades
// gracefully if either register is skewed.
counts[TEAM_ALLIANCE] = std::max(counts[TEAM_ALLIANCE], bg->GetInvitedCount(TEAM_ALLIANCE));
counts[TEAM_HORDE] = std::max(counts[TEAM_HORDE], bg->GetInvitedCount(TEAM_HORDE));

return counts;
}

Expand Down
Loading