bool BattlegroundQueue::CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg) { if (!sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) || bg->isArena()) return false; // Only do this if crossbg's are enabled. // Here we will add all players to selectionpool, later we check if there are enough and launch a bg. FillXPlayersToBG(bracket_id, bg, true); if (sBattlegroundMgr->isTesting() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) return true; uint8 MPT = bg->GetMinPlayersPerTeam(); if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() < MPT || m_SelectionPools[TEAM_HORDE].GetPlayerCount() < MPT) return false; return true; }
/* This function is inviting players to already running battlegrounds Invitation type is based on config file large groups are disadvantageous, because they will be kicked first if invitation type = 1 */ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id) { int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE); int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); if (FillXPlayersToBG(bracket_id, aliFree, hordeFree)) return; //iterator for iterating through bg queue GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); //count of groups in queue - used to stop cycles uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size(); //index to queue which group is current uint32 aliIndex = 0; for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++) ++Ali_itr; //the same thing for horde GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin(); uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size(); uint32 hordeIndex = 0; for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++) ++Horde_itr; //if ofc like BG queue invitation is set in config, then we are happy if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == 0) return; /* if we reached this code, then we have to solve NP - complete problem called Subset sum problem So one solution is to check all possible invitation subgroups, or we can use these conditions: 1. Last time when BattlegroundQueue::Update was executed we invited all possible players - so there is only small possibility that we will invite now whole queue, because only 1 change has been made to queues from the last BattlegroundQueue::Update call 2. Other thing we should consider is group order in queue */ // At first we need to compare free space in bg and our selection pool int32 diffAli = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); int32 diffHorde = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); while (abs(diffAli - diffHorde) > 1 && (m_SelectionPools[TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() > 0)) { //each cycle execution we need to kick at least 1 group if (diffAli < diffHorde) { //kick alliance group, add to pool new group if needed if (m_SelectionPools[TEAM_ALLIANCE].KickGroup(diffHorde - diffAli)) { for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0); aliIndex++) ++Ali_itr; } //if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break; if (!m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()) { if (aliFree <= diffHorde + 1) break; m_SelectionPools[TEAM_HORDE].KickGroup(diffHorde - diffAli); } } else { //kick horde group, add to pool new group if needed if (m_SelectionPools[TEAM_HORDE].KickGroup(diffAli - diffHorde)) { for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0); hordeIndex++) ++Horde_itr; } if (!m_SelectionPools[TEAM_HORDE].GetPlayerCount()) { if (hordeFree <= diffAli + 1) break; m_SelectionPools[TEAM_ALLIANCE].KickGroup(diffAli - diffHorde); } } //count diffs after small update diffAli = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); diffHorde = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); } }