From b1d102e04b480ff2791d6167ca7891a314dbbcdd Mon Sep 17 00:00:00 2001 From: Kargatum Date: Wed, 21 Aug 2019 03:58:15 +0600 Subject: [PATCH] feat(Core/BG): rewrite invite in bg (#2137) Co-authored-by: mik1893 --- .../game/Battlegrounds/Battleground.cpp | 46 +++++++++++- .../game/Battlegrounds/BattlegroundQueue.cpp | 75 +++++++++++++++---- src/server/game/World/World.cpp | 2 + src/server/game/World/World.h | 1 + src/server/worldserver/worldserver.conf.dist | 11 +++ 5 files changed, 120 insertions(+), 15 deletions(-) diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index b6c4da73a..59263a2a9 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1308,7 +1308,51 @@ void Battleground::AddOrSetPlayerToCorrectBgGroup(Player* player, TeamId teamId) uint32 Battleground::GetFreeSlotsForTeam(TeamId teamId) const { - return GetInvitedCount(teamId) < GetMaxPlayersPerTeam() ? GetMaxPlayersPerTeam() - GetInvitedCount(teamId) : 0; + // if BG is starting and CONFIG_BATTLEGROUND_INVITATION_TYPE == BG_QUEUE_INVITATION_TYPE_NO_BALANCE, invite anyone + if (GetStatus() == STATUS_WAIT_JOIN && sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_NO_BALANCE) + return (GetInvitedCount(teamId) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(teamId) : 0; + + // if BG is already started or CONFIG_BATTLEGROUND_INVITATION_TYPE != BG_QUEUE_INVITATION_TYPE_NO_BALANCE, do not allow to join too many players of one faction + uint32 thisTeamInvitedCount = teamId == TEAM_ALLIANCE ? GetInvitedCount(TEAM_ALLIANCE) : GetInvitedCount(TEAM_HORDE); + uint32 thisTeamPlayersCount = teamId == TEAM_ALLIANCE ? GetPlayersCountByTeam(TEAM_ALLIANCE) : GetPlayersCountByTeam(TEAM_HORDE); + uint32 otherTeamInvitedCount = teamId == TEAM_ALLIANCE ? GetInvitedCount(TEAM_HORDE) : GetInvitedCount(TEAM_ALLIANCE); + uint32 otherTeamPlayersCount = teamId == TEAM_ALLIANCE ? GetPlayersCountByTeam(TEAM_HORDE) : GetPlayersCountByTeam(TEAM_ALLIANCE); + + if (GetStatus() == STATUS_IN_PROGRESS || GetStatus() == STATUS_WAIT_JOIN) + { + // difference based on ppl invited (not necessarily entered battle) + // default: allow 0 + uint32 diff = 0; + uint32 maxPlayersPerTeam = GetMaxPlayersPerTeam(); + uint32 minPlayersPerTeam = GetMinPlayersPerTeam(); + + // allow join one person if the sides are equal (to fill up bg to minPlayerPerTeam) + if (otherTeamInvitedCount == thisTeamInvitedCount) + diff = 1; + else if (otherTeamInvitedCount > thisTeamInvitedCount) // allow join more ppl if the other side has more players + diff = otherTeamInvitedCount - thisTeamInvitedCount; + + // difference based on max players per team (don't allow inviting more) + uint32 diff2 = (thisTeamInvitedCount < maxPlayersPerTeam) ? maxPlayersPerTeam - thisTeamInvitedCount : 0; + + // difference based on players who already entered + // default: allow 0 + uint32 diff3 = 0; + + // allow join one person if the sides are equal (to fill up bg minPlayerPerTeam) + if (otherTeamPlayersCount == thisTeamPlayersCount) + diff3 = 1; + else if (otherTeamPlayersCount > thisTeamPlayersCount) // allow join more ppl if the other side has more players + diff3 = otherTeamPlayersCount - thisTeamPlayersCount; + else if (thisTeamInvitedCount <= minPlayersPerTeam) // or other side has less than minPlayersPerTeam + diff3 = minPlayersPerTeam - thisTeamInvitedCount + 1; + + // return the minimum of the 3 differences + // min of diff, diff2 and diff3 + return std::min({ diff, diff2, diff3 }); + } + + return 0; } uint32 Battleground::GetMaxFreeSlots() const diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 5fdbe7550..1ec75c957 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -400,8 +400,25 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, const int32 aliFree, c int32 aliDiff = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); int32 hordeDiff = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); - // if free space differs too much, ballance - while (abs(aliDiff - hordeDiff) > 1 && (m_SelectionPools[TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() > 0)) + int32 invType = sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE); + int32 invDiff = 0; + + // check balance configuration and set the max difference between teams + switch (invType) + { + case BG_QUEUE_INVITATION_TYPE_NO_BALANCE: + return; + case BG_QUEUE_INVITATION_TYPE_BALANCED: + invDiff = 1; + break; + case BG_QUEUE_INVITATION_TYPE_EVEN: + break; + default: + return; + } + + // balance the teams based on the difference allowed + while (abs(aliDiff - hordeDiff) > invDiff && (m_SelectionPools[TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() > 0)) { // if results in more alliance players than horde: if (aliDiff < hordeDiff) @@ -427,8 +444,8 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, const int32 aliFree, c } // recalculate free space after adding - aliDiff = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); - hordeDiff = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); + aliDiff = aliFree - static_cast(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); + hordeDiff = hordeFree - static_cast(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); } } @@ -466,8 +483,25 @@ void BattlegroundQueue::FillPlayersToBGWithSpecific(Battleground* bg, const int3 int32 aliDiff = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); int32 hordeDiff = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); + int32 invType = sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE); + int32 invDiff = 0; + + // check balance configuration and set the max difference between teams + switch (invType) + { + case BG_QUEUE_INVITATION_TYPE_NO_BALANCE: + return; + case BG_QUEUE_INVITATION_TYPE_BALANCED: + invDiff = 1; + break; + case BG_QUEUE_INVITATION_TYPE_EVEN: + break; + default: + return; + } + // if free space differs too much, ballance - while (abs(aliDiff - hordeDiff) > 1 && (m_SelectionPools[TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() > 0)) + while (abs(aliDiff - hordeDiff) > invDiff && (m_SelectionPools[TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() > 0)) { // if results in more alliance players than horde: if (aliDiff < hordeDiff) @@ -479,9 +513,8 @@ void BattlegroundQueue::FillPlayersToBGWithSpecific(Battleground* bg, const int3 // kick alliance, returns true if kicked more than needed, so then try to fill up if (m_SelectionPools[TEAM_ALLIANCE].KickGroup(hordeDiff - aliDiff)) for (; Ali_itr != m_QueuedBoth[TEAM_ALLIANCE].end() && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree >= hordeDiff ? aliFree - hordeDiff : 0); ++Ali_itr); - } - // if results in more horde players than alliance: - else + } + else // if results in more horde players than alliance: { // no more horde in pool, invite whatever we can from alliance if (!m_SelectionPools[TEAM_HORDE].GetPlayerCount()) @@ -493,8 +526,8 @@ void BattlegroundQueue::FillPlayersToBGWithSpecific(Battleground* bg, const int3 } // recalculate free space after adding - aliDiff = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); - hordeDiff = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); + aliDiff = aliFree - static_cast(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()); + hordeDiff = hordeFree - static_cast(m_SelectionPools[TEAM_HORDE].GetPlayerCount()); } } @@ -584,9 +617,10 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground * bgTemplate, Battleground if (sBattlegroundMgr->isTesting() && bgTemplate->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) return true; - return m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= std::min(specificTemplate->GetMinPlayersPerTeam() * Coef, 15) && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= std::min(specificTemplate->GetMinPlayersPerTeam() * Coef, 15); - } - else // if this is not random bg queue - use players only from this queue + return (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() + m_SelectionPools[TEAM_HORDE].GetPlayerCount()) >= 2 * (std::min(specificTemplate->GetMinPlayersPerTeam(), 15)); + } + // if this is not random bg queue - use players only from this queue + else { FillPlayersToBG(bgTemplate, maxPlayers, maxPlayers, bracket_id); @@ -594,7 +628,20 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground * bgTemplate, Battleground if (sBattlegroundMgr->isTesting() && bgTemplate->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) return true; - return m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers; + switch (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE)) + { + case BG_QUEUE_INVITATION_TYPE_NO_BALANCE: // in this case, as soon as both teams have > mincount, start + return m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers; + + case BG_QUEUE_INVITATION_TYPE_BALANCED: // check difference between selection pools - if = 1 or less start. + return abs(static_cast(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount()) - static_cast(m_SelectionPools[TEAM_HORDE].GetPlayerCount())) <= 1 && m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers; + + case BG_QUEUE_INVITATION_TYPE_EVEN: // if both counts are same then it's an even match + return (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() == m_SelectionPools[TEAM_HORDE].GetPlayerCount()) && m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers; + + default: // same as unbalanced (in case wrong setting is entered...) + return m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers; + } } } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index da62ad302..05186efaf 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -78,6 +78,7 @@ #include "ServerMotd.h" #include "GameGraveyard.h" #include + #ifdef ELUNA #include "LuaEngine.h" #endif @@ -1105,6 +1106,7 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_BATTLEGROUND_STORE_STATISTICS_ENABLE] = sConfigMgr->GetBoolDefault("Battleground.StoreStatistics.Enable", false); m_bool_configs[CONFIG_BATTLEGROUND_TRACK_DESERTERS] = sConfigMgr->GetBoolDefault("Battleground.TrackDeserters.Enable", false); m_int_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfigMgr->GetIntDefault ("Battleground.PrematureFinishTimer", 5 * MINUTE * IN_MILLISECONDS); + m_int_configs[CONFIG_BATTLEGROUND_INVITATION_TYPE] = sConfigMgr->GetIntDefault("Battleground.InvitationType", 0); m_int_configs[CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH] = sConfigMgr->GetIntDefault ("Battleground.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILLISECONDS); m_bool_configs[CONFIG_BG_XP_FOR_KILL] = sConfigMgr->GetBoolDefault("Battleground.GiveXPForKills", false); m_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfigMgr->GetIntDefault ("Arena.MaxRatingDifference", 150); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 0b8269d4e..c530005a0 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -286,6 +286,7 @@ enum WorldIntConfigs CONFIG_DISABLE_BREATHING, CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER, CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH, + CONFIG_BATTLEGROUND_INVITATION_TYPE, CONFIG_ARENA_MAX_RATING_DIFFERENCE, CONFIG_ARENA_RATING_DISCARD_TIMER, CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS, diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 869a46d49..57a39f133 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2628,6 +2628,17 @@ Battleground.StoreStatistics.Enable = 1 Battleground.TrackDeserters.Enable = 1 +# +# Battleground.InvitationType +# Description: Set Battleground invitation type. +# Default: 0 - (Normal, Invite as much players to battlegrounds as queued, +# Don't bother with balance) +# 1 - (Experimental, Don't allow to invite much more players +# of one faction) +# 2 - (Experimental, Try to have even teams) + +Battleground.InvitationType = 0 + # ###################################################################################################