From 067d9e791f87fc033fb4e741a44d62a6f075a565 Mon Sep 17 00:00:00 2001 From: Shard <30301841+Shard-MW@users.noreply.github.com> Date: Sat, 28 Dec 2019 09:40:13 +0100 Subject: [PATCH] fix(Core/Battlegrounds) Rewrite RandomBG and enabling bg/arenas weights (#2516) --- src/common/Containers.h | 10 ++ src/common/Utilities/Util.cpp | 13 ++ src/common/Utilities/Util.h | 17 +++ .../game/Battlegrounds/Battleground.cpp | 8 +- src/server/game/Battlegrounds/Battleground.h | 52 ++++---- .../game/Battlegrounds/BattlegroundMgr.cpp | 125 ++++++++---------- .../game/Battlegrounds/BattlegroundMgr.h | 42 +++--- .../game/Battlegrounds/BattlegroundQueue.cpp | 76 +++-------- .../Battlegrounds/Zones/BattlegroundAB.cpp | 4 +- .../Battlegrounds/Zones/BattlegroundEY.cpp | 2 +- .../Battlegrounds/Zones/BattlegroundWS.cpp | 2 +- src/server/game/DataStores/DBCStores.cpp | 14 -- .../game/Entities/GameObject/GameObject.cpp | 6 +- src/server/game/Entities/Player/Player.cpp | 28 ++-- src/server/game/Groups/Group.cpp | 10 ++ src/server/game/Handlers/QuestHandler.cpp | 2 +- src/server/game/Spells/SpellEffects.cpp | 4 +- src/server/game/Spells/SpellMgr.cpp | 2 +- .../scripts/World/achievement_scripts.cpp | 14 +- 19 files changed, 210 insertions(+), 221 deletions(-) diff --git a/src/common/Containers.h b/src/common/Containers.h index 141079ef3..6de3e511d 100644 --- a/src/common/Containers.h +++ b/src/common/Containers.h @@ -13,9 +13,11 @@ #include #include #include +#include //! Because circular includes are bad extern uint32 urand(uint32 min, uint32 max); +extern uint32 urandweighted(size_t count, double const* chances); namespace acore { @@ -97,6 +99,14 @@ namespace acore std::advance(it, urand(0, container.size() - 1)); return *it; } + + /* Select a random element from a container where each element has a different chance to be selected. */ + template typename C::value_type const& SelectRandomWeightedContainerElement(C const& container, std::vector const& weights) + { + typename C::const_iterator it = container.begin(); + std::advance(it, urandweighted(weights.size(), weights.data())); + return *it; + } } //! namespace Containers } diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index d17218f00..6289d281d 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -18,9 +18,11 @@ #include #include #include +#include typedef ACE_TSS SFMTRandTSS; static SFMTRandTSS sfmtRand; +static SFMTEngine engine; int32 irand(int32 min, int32 max) { @@ -55,6 +57,17 @@ double rand_chance() return sfmtRand->Random() * 100.0; } +uint32 urandweighted(size_t count, double const* chances) +{ + std::discrete_distribution dd(chances, chances + count); + return dd(SFMTEngine::Instance()); +} + +SFMTEngine& SFMTEngine::Instance() +{ + return engine; +} + Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve) { m_str = new char[src.length() + 1]; diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index 831083d27..0a9e4579e 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -82,6 +82,8 @@ double rand_norm(); /* Return a random double from 0.0 to 100.0 (exclusive). */ double rand_chance(); +uint32 urandweighted(size_t count, double const* chances); + /* Return true if a random roll fits in the specified chance (range 0-100). */ inline bool roll_chance_f(float chance) { @@ -555,6 +557,21 @@ bool CompareValues(ComparisionType type, T val1, T val2) } } +/* +* SFMT wrapper satisfying UniformRandomNumberGenerator concept for use in algorithms +*/ +class SFMTEngine +{ +public: + typedef uint32 result_type; + + static constexpr result_type min() { return std::numeric_limits::min(); } + static constexpr result_type max() { return std::numeric_limits::max(); } + result_type operator()() const { return rand32(); } + + static SFMTEngine& Instance(); +}; + class EventMap { typedef std::multimap EventStore; diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 64ee67215..cc3036038 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -112,6 +112,7 @@ void Battleground::BroadcastWorker(Do& _do) Battleground::Battleground() { m_RealTypeID = BATTLEGROUND_TYPE_NONE; + m_RandomTypeID = BATTLEGROUND_TYPE_NONE; m_InstanceID = 0; m_Status = STATUS_NONE; m_ClientInstanceID = 0; @@ -127,6 +128,7 @@ Battleground::Battleground() m_StartDelayTime = 0; m_IsRated = false; m_BuffChange = false; + m_IsRandom = false; m_Name = ""; m_LevelMin = 0; m_LevelMax = 0; @@ -785,7 +787,7 @@ void Battleground::EndBattleground(TeamId winnerTeamId) stmt->setUInt64(0, battlegroundId); stmt->setUInt8(1, GetWinner()); stmt->setUInt8(2, GetUniqueBracketId()); - stmt->setUInt8(3, GetBgTypeID()); + stmt->setUInt8(3, GetBgTypeID(true)); CharacterDatabase.Execute(stmt); } @@ -984,7 +986,7 @@ void Battleground::EndBattleground(TeamId winnerTeamId) // Reward winner team if (bgTeamId == winnerTeamId) { - if (player->IsCurrentBattlegroundRandom() || BattlegroundMgr::IsBGWeekend(GetBgTypeID())) + if (IsRandom() || BattlegroundMgr::IsBGWeekend(GetBgTypeID(true))) { UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(winner_kills)); @@ -1000,7 +1002,7 @@ void Battleground::EndBattleground(TeamId winnerTeamId) } else { - if (player->IsCurrentBattlegroundRandom() || BattlegroundMgr::IsBGWeekend(GetBgTypeID())) + if (IsRandom() || BattlegroundMgr::IsBGWeekend(GetBgTypeID(true))) UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(loser_kills)); } diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 187345ab4..eac35f6d2 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -354,7 +354,7 @@ class Battleground /* Battleground */ // Get methods: char const* GetName() const { return m_Name; } - BattlegroundTypeId GetBgTypeID() const { return m_RealTypeID; } + BattlegroundTypeId GetBgTypeID(bool GetRandom = false) const { return GetRandom ? m_RandomTypeID : m_RealTypeID; } uint32 GetInstanceID() const { return m_InstanceID; } BattlegroundStatus GetStatus() const { return m_Status; } uint32 GetClientInstanceID() const { return m_ClientInstanceID; } @@ -374,9 +374,12 @@ class Battleground uint32 GetScriptId() const { return ScriptId; } uint32 GetBonusHonorFromKill(uint32 kills) const; + bool IsRandom() { return m_IsRandom; } + // Set methods: void SetName(char const* Name) { m_Name = Name; } void SetBgTypeID(BattlegroundTypeId TypeID) { m_RealTypeID = TypeID; } + void SetRandomTypeID(BattlegroundTypeId TypeID) { m_RandomTypeID = TypeID; } void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; } void SetStatus(BattlegroundStatus Status) { m_Status = Status; } void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; } @@ -389,6 +392,7 @@ class Battleground void SetArenaorBGType(bool _isArena) { m_IsArena = _isArena; } void SetWinner(TeamId winner) { m_WinnerId = winner; } void SetScriptId(uint32 scriptId) { ScriptId = scriptId; } + void SetRandom(bool isRandom) { m_IsRandom = isRandom; } void ModifyStartDelayTime(int32 diff) { m_StartDelayTime -= diff; } void SetStartDelayTime(int32 Time) { m_StartDelayTime = Time; } @@ -591,38 +595,38 @@ class Battleground // because BattleGrounds with different types and same level range has different m_BracketId uint8 GetUniqueBracketId() const; - BattlegroundAV* ToBattlegroundAV() { if (GetBgTypeID() == BATTLEGROUND_AV) return reinterpret_cast(this); else return NULL; } - BattlegroundAV const* ToBattlegroundAV() const { if (GetBgTypeID() == BATTLEGROUND_AV) return reinterpret_cast(this); else return NULL; } + BattlegroundAV* ToBattlegroundAV() { if (GetBgTypeID(true) == BATTLEGROUND_AV) return reinterpret_cast(this); else return NULL; } + BattlegroundAV const* ToBattlegroundAV() const { if (GetBgTypeID(true) == BATTLEGROUND_AV) return reinterpret_cast(this); else return NULL; } - BattlegroundWS* ToBattlegroundWS() { if (GetBgTypeID() == BATTLEGROUND_WS) return reinterpret_cast(this); else return NULL; } - BattlegroundWS const* ToBattlegroundWS() const { if (GetBgTypeID() == BATTLEGROUND_WS) return reinterpret_cast(this); else return NULL; } + BattlegroundWS* ToBattlegroundWS() { if (GetBgTypeID(true) == BATTLEGROUND_WS) return reinterpret_cast(this); else return NULL; } + BattlegroundWS const* ToBattlegroundWS() const { if (GetBgTypeID(true) == BATTLEGROUND_WS) return reinterpret_cast(this); else return NULL; } - BattlegroundAB* ToBattlegroundAB() { if (GetBgTypeID() == BATTLEGROUND_AB) return reinterpret_cast(this); else return NULL; } - BattlegroundAB const* ToBattlegroundAB() const { if (GetBgTypeID() == BATTLEGROUND_AB) return reinterpret_cast(this); else return NULL; } + BattlegroundAB* ToBattlegroundAB() { if (GetBgTypeID(true) == BATTLEGROUND_AB) return reinterpret_cast(this); else return NULL; } + BattlegroundAB const* ToBattlegroundAB() const { if (GetBgTypeID(true) == BATTLEGROUND_AB) return reinterpret_cast(this); else return NULL; } - BattlegroundNA* ToBattlegroundNA() { if (GetBgTypeID() == BATTLEGROUND_NA) return reinterpret_cast(this); else return NULL; } - BattlegroundNA const* ToBattlegroundNA() const { if (GetBgTypeID() == BATTLEGROUND_NA) return reinterpret_cast(this); else return NULL; } + BattlegroundNA* ToBattlegroundNA() { if (GetBgTypeID(true) == BATTLEGROUND_NA) return reinterpret_cast(this); else return NULL; } + BattlegroundNA const* ToBattlegroundNA() const { if (GetBgTypeID(true) == BATTLEGROUND_NA) return reinterpret_cast(this); else return NULL; } - BattlegroundBE* ToBattlegroundBE() { if (GetBgTypeID() == BATTLEGROUND_BE) return reinterpret_cast(this); else return NULL; } - BattlegroundBE const* ToBattlegroundBE() const { if (GetBgTypeID() == BATTLEGROUND_BE) return reinterpret_cast(this); else return NULL; } + BattlegroundBE* ToBattlegroundBE() { if (GetBgTypeID(true) == BATTLEGROUND_BE) return reinterpret_cast(this); else return NULL; } + BattlegroundBE const* ToBattlegroundBE() const { if (GetBgTypeID(true) == BATTLEGROUND_BE) return reinterpret_cast(this); else return NULL; } - BattlegroundEY* ToBattlegroundEY() { if (GetBgTypeID() == BATTLEGROUND_EY) return reinterpret_cast(this); else return NULL; } - BattlegroundEY const* ToBattlegroundEY() const { if (GetBgTypeID() == BATTLEGROUND_EY) return reinterpret_cast(this); else return NULL; } + BattlegroundEY* ToBattlegroundEY() { if (GetBgTypeID(true) == BATTLEGROUND_EY) return reinterpret_cast(this); else return NULL; } + BattlegroundEY const* ToBattlegroundEY() const { if (GetBgTypeID(true) == BATTLEGROUND_EY) return reinterpret_cast(this); else return NULL; } - BattlegroundRL* ToBattlegroundRL() { if (GetBgTypeID() == BATTLEGROUND_RL) return reinterpret_cast(this); else return NULL; } - BattlegroundRL const* ToBattlegroundRL() const { if (GetBgTypeID() == BATTLEGROUND_RL) return reinterpret_cast(this); else return NULL; } + BattlegroundRL* ToBattlegroundRL() { if (GetBgTypeID(true) == BATTLEGROUND_RL) return reinterpret_cast(this); else return NULL; } + BattlegroundRL const* ToBattlegroundRL() const { if (GetBgTypeID(true) == BATTLEGROUND_RL) return reinterpret_cast(this); else return NULL; } - BattlegroundSA* ToBattlegroundSA() { if (GetBgTypeID() == BATTLEGROUND_SA) return reinterpret_cast(this); else return NULL; } - BattlegroundSA const* ToBattlegroundSA() const { if (GetBgTypeID() == BATTLEGROUND_SA) return reinterpret_cast(this); else return NULL; } + BattlegroundSA* ToBattlegroundSA() { if (GetBgTypeID(true) == BATTLEGROUND_SA) return reinterpret_cast(this); else return NULL; } + BattlegroundSA const* ToBattlegroundSA() const { if (GetBgTypeID(true) == BATTLEGROUND_SA) return reinterpret_cast(this); else return NULL; } - BattlegroundDS* ToBattlegroundDS() { if (GetBgTypeID() == BATTLEGROUND_DS) return reinterpret_cast(this); else return NULL; } - BattlegroundDS const* ToBattlegroundDS() const { if (GetBgTypeID() == BATTLEGROUND_DS) return reinterpret_cast(this); else return NULL; } + BattlegroundDS* ToBattlegroundDS() { if (GetBgTypeID(true) == BATTLEGROUND_DS) return reinterpret_cast(this); else return NULL; } + BattlegroundDS const* ToBattlegroundDS() const { if (GetBgTypeID(true) == BATTLEGROUND_DS) return reinterpret_cast(this); else return NULL; } - BattlegroundRV* ToBattlegroundRV() { if (GetBgTypeID() == BATTLEGROUND_RV) return reinterpret_cast(this); else return NULL; } - BattlegroundRV const* ToBattlegroundRV() const { if (GetBgTypeID() == BATTLEGROUND_RV) return reinterpret_cast(this); else return NULL; } + BattlegroundRV* ToBattlegroundRV() { if (GetBgTypeID(true) == BATTLEGROUND_RV) return reinterpret_cast(this); else return NULL; } + BattlegroundRV const* ToBattlegroundRV() const { if (GetBgTypeID(true) == BATTLEGROUND_RV) return reinterpret_cast(this); else return NULL; } - BattlegroundIC* ToBattlegroundIC() { if (GetBgTypeID() == BATTLEGROUND_IC) return reinterpret_cast(this); else return NULL; } - BattlegroundIC const* ToBattlegroundIC() const { if (GetBgTypeID() == BATTLEGROUND_IC) return reinterpret_cast(this); else return NULL; } + BattlegroundIC* ToBattlegroundIC() { if (GetBgTypeID(true) == BATTLEGROUND_IC) return reinterpret_cast(this); else return NULL; } + BattlegroundIC const* ToBattlegroundIC() const { if (GetBgTypeID(true) == BATTLEGROUND_IC) return reinterpret_cast(this); else return NULL; } protected: // this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends Battleground @@ -652,6 +656,7 @@ class Battleground uint32 StartMessageIds[BG_STARTING_EVENT_COUNT]; bool m_BuffChange; + bool m_IsRandom; BGHonorMode m_HonorMode; int32 m_TeamScores[BG_TEAMS_COUNT]; @@ -661,6 +666,7 @@ class Battleground private: // Battleground BattlegroundTypeId m_RealTypeID; + BattlegroundTypeId m_RandomTypeID; // TypeID created from Random Battleground list uint32 m_InstanceID; // Battleground Instance's GUID! BattlegroundStatus m_Status; uint32 m_ClientInstanceID; // the instance-id which is sent to the client and without any other internal use diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index a259240de..f72bc262f 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -46,7 +46,7 @@ /*** BATTLEGROUND MANAGER ***/ /*********************************************************/ -BattlegroundMgr::BattlegroundMgr() : randomBgDifficultyEntry(999, 0, 80, 80, 0), m_ArenaTesting(false), m_Testing(false), +BattlegroundMgr::BattlegroundMgr() : m_ArenaTesting(false), m_Testing(false), m_lastClientVisibleInstanceId(0), m_NextAutoDistributionTime(0), m_AutoDistributionTimeChecker(0), m_NextPeriodicQueueUpdateTime(5*IN_MILLISECONDS) { for (uint32 qtype = BATTLEGROUND_QUEUE_NONE; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype) @@ -92,9 +92,6 @@ void BattlegroundMgr::Update(uint32 diff) } } - // update to change current bg type the random system is trying to create - RandomSystem.Update(diff); - // update events for (int qtype = BATTLEGROUND_QUEUE_NONE; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype) m_BattlegroundQueues[qtype].UpdateEvents(diff); @@ -427,14 +424,12 @@ uint32 BattlegroundMgr::GetNextClientVisibleInstanceId() } // create a new battleground that will really be used to play -Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId bgTypeId, uint32 minLevel, uint32 maxLevel, uint8 arenaType, bool isRated) +Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId originalBgTypeId, uint32 minLevel, uint32 maxLevel, uint8 arenaType, bool isRated) { - // pussywizard: random battleground is chosen before calling this function! - ASSERT(bgTypeId != BATTLEGROUND_RB); + BattlegroundTypeId bgTypeId = GetRandomBG(originalBgTypeId); - // pussywizard: randomize for all arena - if (bgTypeId == BATTLEGROUND_AA) - bgTypeId = RAND(BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL, BATTLEGROUND_DS, BATTLEGROUND_RV); + if (originalBgTypeId == BATTLEGROUND_AA) + originalBgTypeId = bgTypeId; // get the template BG Battleground* bg_template = GetBattlegroundTemplate(bgTypeId); @@ -449,14 +444,18 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId bgTypeId bg = BattlegroundMgr::bgTypeToTemplate[bgTypeId](bg_template); + bool isRandom = bgTypeId != originalBgTypeId && !bg->isArena(); + bg->SetLevelRange(minLevel, maxLevel); bg->SetInstanceID(sMapMgr->GenerateInstanceId()); - bg->SetClientInstanceID(IsArenaType(bgTypeId) ? 0 : GetNextClientVisibleInstanceId()); + bg->SetClientInstanceID(IsArenaType(originalBgTypeId) ? 0 : GetNextClientVisibleInstanceId()); bg->Init(); bg->SetStatus(STATUS_WAIT_JOIN); // start the joining of the bg bg->SetArenaType(arenaType); - bg->SetBgTypeID(bgTypeId); + bg->SetBgTypeID(originalBgTypeId); + bg->SetRandomTypeID(bgTypeId); bg->SetRated(isRated); + bg->SetRandom(isRandom); // Set up correct min/max player counts for scoreboards if (bg->isArena()) @@ -491,7 +490,10 @@ bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data) if (bg == NULL) return false; - bg->SetMapId(data.bgTypeId == BATTLEGROUND_RB ? randomBgDifficultyEntry.mapId : data.MapID); + if (data.bgTypeId == BATTLEGROUND_RB) + bg->SetRandom(true); + + bg->SetMapId(data.MapID); bg->SetBgTypeID(data.bgTypeId); bg->SetInstanceID(0); bg->SetArenaorBGType(data.IsArena); @@ -512,6 +514,10 @@ bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data) void BattlegroundMgr::CreateInitialBattlegrounds() { uint32 oldMSTime = getMSTime(); + + _battlegroundMapTemplates.clear(); + _battlegroundTemplates.clear(); + // 0 1 2 3 4 5 6 7 8 9 10 11 QueryResult result = WorldDatabase.Query("SELECT ID, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, AllianceStartLoc, AllianceStartO, HordeStartLoc, HordeStartO, StartMaxDist, Weight, ScriptName FROM battleground_template"); @@ -549,6 +555,7 @@ void BattlegroundMgr::CreateInitialBattlegrounds() data.LevelMax = fields[4].GetUInt8(); float dist = fields[9].GetFloat(); data.StartMaxDist = dist * dist; + data.Weight = fields[10].GetUInt8(); data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString()); data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()]; @@ -613,6 +620,11 @@ void BattlegroundMgr::CreateInitialBattlegrounds() if (!CreateBattleground(data)) continue; + _battlegroundTemplates[BattlegroundTypeId(bgTypeId)] = data; + + if (bl->mapid[1] == -1) // in this case we have only one mapId + _battlegroundMapTemplates[bl->mapid[0]] = &_battlegroundTemplates[BattlegroundTypeId(bgTypeId)]; + ++count; } while (result->NextRow()); @@ -910,6 +922,34 @@ bool BattlegroundMgr::IsBGWeekend(BattlegroundTypeId bgTypeId) return IsHolidayActive(BGTypeToWeekendHolidayId(bgTypeId)); } +BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId) +{ + if (CreateBattlegroundData const* bgTemplate = GetBattlegroundTemplateByTypeId(bgTypeId)) + { + std::vector ids; + ids.reserve(16); + std::vector weights; + weights.reserve(16); + BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId); + + for (int32 mapId : bl->mapid) + { + if (mapId == -1) + break; + + if (CreateBattlegroundData const* bg = GetBattlegroundTemplateByMapId(mapId)) + { + ids.push_back(bg->bgTypeId); + weights.push_back(bg->Weight); + } + } + + return acore::Containers::SelectRandomWeightedContainerElement(ids, weights); + } + + return BATTLEGROUND_TYPE_NONE; +} + void BattlegroundMgr::AddBattleground(Battleground* bg) { if (bg->GetInstanceID() == 0) @@ -986,65 +1026,6 @@ void BattlegroundMgr::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, T } } -RandomBattlegroundSystem::RandomBattlegroundSystem() : m_CurrentRandomBg(BATTLEGROUND_TYPE_NONE), m_SwitchTimer(0) -{ -} - -void RandomBattlegroundSystem::Update(uint32 diff) -{ - if (m_SwitchTimer <= diff) - { - if (m_BgOrder.empty()) - { - // order it like: big, small, big, small, small, small (stored backwards, actually) - - std::vector big, small; - big.push_back(BATTLEGROUND_AV); - big.push_back(BATTLEGROUND_IC); - small.push_back(BATTLEGROUND_WS); - small.push_back(BATTLEGROUND_EY); - small.push_back(BATTLEGROUND_AB); - small.push_back(BATTLEGROUND_SA); - - std::random_device rd; - auto rng = std::default_random_engine{rd()}; - - std::shuffle(big.begin(), big.end(), rng); - std::shuffle(small.begin(), small.end(), rng); - - m_BgOrder.push_back(small.back()); small.pop_back(); - m_BgOrder.push_back(small.back()); small.pop_back(); - m_BgOrder.push_back(small.back()); small.pop_back(); - m_BgOrder.push_back(big.back()); big.pop_back(); - m_BgOrder.push_back(small.back()); small.pop_back(); - m_BgOrder.push_back(big.back()); big.pop_back(); - } - - m_CurrentRandomBg = m_BgOrder.back(); - m_BgOrder.pop_back(); - - switch (m_CurrentRandomBg) - { - case BATTLEGROUND_AV: m_SwitchTimer = 180*IN_MILLISECONDS; break; // max 40 per team - case BATTLEGROUND_WS: m_SwitchTimer = 30*IN_MILLISECONDS; break; // max 10 per team - case BATTLEGROUND_IC: m_SwitchTimer = 180*IN_MILLISECONDS; break; // max 40 per team - case BATTLEGROUND_EY: m_SwitchTimer = 40*IN_MILLISECONDS; break; // max 15 per team - case BATTLEGROUND_AB: m_SwitchTimer = 40*IN_MILLISECONDS; break; // max 15 per team - case BATTLEGROUND_SA: m_SwitchTimer = 40*IN_MILLISECONDS; break; // max 15 per team - default: ABORT(); break; - } - } - else - m_SwitchTimer -= diff; -} - -void RandomBattlegroundSystem::BattlegroundCreated(BattlegroundTypeId bgTypeId) -{ - // if created current random bg, set current to another one - if (bgTypeId == m_CurrentRandomBg) - Update(0xffffffff); -} - // init/update unordered_map // Battlegrounds std::unordered_map BattlegroundMgr::bgToQueue = { diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index f93044bf1..30435802e 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -40,24 +40,11 @@ struct CreateBattlegroundData float Team2StartLocO; float StartMaxDist; uint32 scriptId; + uint8 Weight; }; struct GroupQueueInfo; -// pussywizard -class RandomBattlegroundSystem -{ - public: - RandomBattlegroundSystem(); - void Update(uint32 diff); - BattlegroundTypeId GetCurrentRandomBg() const { return m_CurrentRandomBg; } - void BattlegroundCreated(BattlegroundTypeId bgTypeId); - private: - BattlegroundTypeId m_CurrentRandomBg; - uint32 m_SwitchTimer; - std::vector m_BgOrder; -}; - class BattlegroundMgr { private: @@ -117,8 +104,6 @@ class BattlegroundMgr static BattlegroundTypeId WeekendHolidayIdToBGType(HolidayIds holiday); static bool IsBGWeekend(BattlegroundTypeId bgTypeId); - PvPDifficultyEntry randomBgDifficultyEntry; - uint32 GetRatingDiscardTimer() const; void InitAutomaticArenaPointDistribution(); void LoadBattleMastersEntry(); @@ -132,7 +117,6 @@ class BattlegroundMgr } const BattlegroundContainer& GetBattlegroundList() { return m_Battlegrounds; } // pussywizard - RandomBattlegroundSystem RandomSystem; // pussywizard static std::unordered_map bgToQueue; // BattlegroundTypeId -> BattlegroundQueueTypeId static std::unordered_map queueToBg; // BattlegroundQueueTypeId -> BattlegroundTypeId @@ -142,6 +126,7 @@ class BattlegroundMgr private: bool CreateBattleground(CreateBattlegroundData& data); uint32 GetNextClientVisibleInstanceId(); + BattlegroundTypeId GetRandomBG(BattlegroundTypeId id); typedef std::map BattlegroundTemplateContainer; BattlegroundTemplateContainer m_BattlegroundTemplates; @@ -157,6 +142,29 @@ class BattlegroundMgr uint32 m_AutoDistributionTimeChecker; uint32 m_NextPeriodicQueueUpdateTime; BattleMastersMap mBattleMastersMap; + + CreateBattlegroundData const* GetBattlegroundTemplateByTypeId(BattlegroundTypeId id) + { + BattlegroundTemplateMap::const_iterator itr = _battlegroundTemplates.find(id); + if (itr != _battlegroundTemplates.end()) + return &itr->second; + return nullptr; + } + + CreateBattlegroundData const* GetBattlegroundTemplateByMapId(uint32 mapId) + { + BattlegroundMapTemplateContainer::const_iterator itr = _battlegroundMapTemplates.find(mapId); + if (itr != _battlegroundMapTemplates.end()) + return itr->second; + return nullptr; + } + + typedef std::map BattlegroundSelectionWeightMap; + + typedef std::map BattlegroundTemplateMap; + typedef std::map BattlegroundMapTemplateContainer; + BattlegroundTemplateMap _battlegroundTemplates; + BattlegroundMapTemplateContainer _battlegroundMapTemplates; }; #define sBattlegroundMgr BattlegroundMgr::instance() diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 63a729ca6..9b0c9f634 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -590,53 +590,25 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground * bgTemplate, Battleground minPlayers = minPlayers * Coef; - // if current queue is BATTLEGROUND_QUEUE_RB, then we are trying to create bg using players from 2 queues - if (bgTemplate->GetBgTypeID() == BATTLEGROUND_RB) + FillPlayersToBG(bgTemplate, maxPlayers, maxPlayers, bracket_id); + + //allow 1v0 if debug bg + if (sBattlegroundMgr->isTesting() && bgTemplate->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) + return true; + + switch (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE)) { - // specific template - Battleground* specificTemplate = sBattlegroundMgr->GetBattlegroundTemplate(sBattlegroundMgr->RandomSystem.GetCurrentRandomBg()); - if (!specificTemplate) - return false; + 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; - // specific bracket id - PvPDifficultyEntry const* specificBracket = GetBattlegroundBracketByLevel(specificTemplate->GetMapId(), sBattlegroundMgr->randomBgDifficultyEntry.minLevel); - if (!specificBracket || specificBracket->maxLevel < sBattlegroundMgr->randomBgDifficultyEntry.maxLevel) - return false; + 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; - // specific queue - BattlegroundQueue& specificQueue = sBattlegroundMgr->GetBattlegroundQueue(BattlegroundMgr::BGQueueTypeId(sBattlegroundMgr->RandomSystem.GetCurrentRandomBg(), 0)); + 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; - FillPlayersToBGWithSpecific(specificTemplate, specificTemplate->GetMaxPlayersPerTeam(), specificTemplate->GetMaxPlayersPerTeam(), bracket_id, &specificQueue, BattlegroundBracketId(specificBracket->bracketId)); - - //allow 1v0 if debug bg - if (sBattlegroundMgr->isTesting() && bgTemplate->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) - return true; - - 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); - - //allow 1v0 if debug bg - if (sBattlegroundMgr->isTesting() && bgTemplate->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) - return true; - - 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; - } + default: // same as unbalanced (in case wrong setting is entered...) + return m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers; } } @@ -722,7 +694,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id for (BattlegroundContainer::const_iterator itr = bgList.begin(); itr != bgList.end(); ++itr) { Battleground* bg = itr->second; - if (!BattlegroundMgr::IsArenaType(bg->GetBgTypeID()) && (bg->GetBgTypeID() == m_bgTypeId || m_bgTypeId == BATTLEGROUND_RB) && + if (!BattlegroundMgr::IsArenaType(bg->GetBgTypeID()) && (bg->GetBgTypeID(true) == m_bgTypeId || m_bgTypeId == BATTLEGROUND_RB) && bg->HasFreeSlots() && bg->GetMinLevel() <= bracketEntry->minLevel && bg->GetMaxLevel() >= bracketEntry->maxLevel) bgsToCheck.insert(bg); } @@ -795,22 +767,6 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id uint32 minLvl = bracketEntry->minLevel; uint32 maxLvl = bracketEntry->maxLevel; - // for random bg use values from specific - if (m_bgTypeId == BATTLEGROUND_RB) - { - newBgTypeId = sBattlegroundMgr->RandomSystem.GetCurrentRandomBg(); - Battleground* specificTemplate = sBattlegroundMgr->GetBattlegroundTemplate(newBgTypeId); - if (!specificTemplate) - return; - PvPDifficultyEntry const* specificBracket = GetBattlegroundBracketByLevel(specificTemplate->GetMapId(), sBattlegroundMgr->randomBgDifficultyEntry.minLevel); - if (!specificBracket) - return; - minLvl = specificBracket->minLevel; - maxLvl = specificBracket->maxLevel; - - sBattlegroundMgr->RandomSystem.BattlegroundCreated(newBgTypeId); - } - // create new battleground Battleground* bg = sBattlegroundMgr->CreateNewBattleground(newBgTypeId, minLvl, maxLvl, m_arenaType, false); if (!bg) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 76eb3d135..d07d03199 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -401,8 +401,8 @@ void BattlegroundAB::Init() _bgEvents.Reset(); - _honorTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID()) ? BG_AB_HONOR_TICK_WEEKEND : BG_AB_HONOR_TICK_NORMAL; - _reputationTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID()) ? BG_AB_REP_TICK_WEEKEND : BG_AB_REP_TICK_NORMAL; + _honorTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID(true)) ? BG_AB_HONOR_TICK_WEEKEND : BG_AB_HONOR_TICK_NORMAL; + _reputationTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID(true)) ? BG_AB_REP_TICK_WEEKEND : BG_AB_REP_TICK_NORMAL; _capturePointInfo[BG_AB_NODE_STABLES]._iconNone = BG_AB_OP_STABLE_ICON; _capturePointInfo[BG_AB_NODE_FARM]._iconNone = BG_AB_OP_FARM_ICON; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index 812c68d3d..01cf8ebcf 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -340,7 +340,7 @@ void BattlegroundEY::Init() Battleground::Init(); _bgEvents.Reset(); - _honorTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID()) ? BG_EY_HONOR_TICK_WEEKEND : BG_EY_HONOR_TICK_NORMAL; + _honorTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID(true)) ? BG_EY_HONOR_TICK_WEEKEND : BG_EY_HONOR_TICK_NORMAL; _ownedPointsCount[TEAM_ALLIANCE] = 0; _ownedPointsCount[TEAM_HORDE] = 0; _flagKeeperGUID = 0; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 6322e693f..3408b5122 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -443,7 +443,7 @@ void BattlegroundWS::Init() _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE; _lastFlagCaptureTeam = TEAM_NEUTRAL; - if (sBattlegroundMgr->IsBGWeekend(GetBgTypeID())) + if (sBattlegroundMgr->IsBGWeekend(GetBgTypeID(true))) { _reputationCapture = 45; _honorWinKills = 3; diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 4eada1a69..f5da15447 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -752,13 +752,6 @@ MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &di PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level) { - if (mapid == sBattlegroundMgr->randomBgDifficultyEntry.mapId) - { - if (level < sBattlegroundMgr->randomBgDifficultyEntry.minLevel) - return NULL; - return &sBattlegroundMgr->randomBgDifficultyEntry; - } - PvPDifficultyEntry const* maxEntry = NULL; // used for level > max listed level case for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) { @@ -783,13 +776,6 @@ PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 lev PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id) { - if (mapid == sBattlegroundMgr->randomBgDifficultyEntry.mapId) - { - if (id != sBattlegroundMgr->randomBgDifficultyEntry.bracketId) - return NULL; - return &sBattlegroundMgr->randomBgDifficultyEntry; - } - for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->mapId == mapid && entry->GetBracketId() == id) diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index eb472998c..d3e10cd3d 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1120,7 +1120,7 @@ bool GameObject::ActivateToQuest(Player* target) const //look for battlegroundAV for some objects which are only activated after mine gots captured by own team if (GetEntry() == BG_AV_OBJECTID_MINE_N || GetEntry() == BG_AV_OBJECTID_MINE_S) if (Battleground* bg = target->GetBattleground()) - if (bg->GetBgTypeID() == BATTLEGROUND_AV && !bg->ToBattlegroundAV()->PlayerCanDoMineQuest(GetEntry(), target->GetTeamId())) + if (bg->GetBgTypeID(true) == BATTLEGROUND_AV && !bg->ToBattlegroundAV()->PlayerCanDoMineQuest(GetEntry(), target->GetTeamId())) return false; return true; } @@ -1784,11 +1784,11 @@ void GameObject::Use(Unit* user) { case 179785: // Silverwing Flag case 179786: // Warsong Flag - if (bg->GetBgTypeID() == BATTLEGROUND_WS) + if (bg->GetBgTypeID(true) == BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag(player, this); break; case 184142: // Netherstorm Flag - if (bg->GetBgTypeID() == BATTLEGROUND_EY) + if (bg->GetBgTypeID(true) == BATTLEGROUND_EY) bg->EventPlayerClickedOnFlag(player, this); break; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 179bbbb5e..89021b385 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9034,7 +9034,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type) //TODO: fix this big hack if ((go->GetEntry() == BG_AV_OBJECTID_MINE_N || go->GetEntry() == BG_AV_OBJECTID_MINE_S)) if (Battleground* bg = GetBattleground()) - if (bg->GetBgTypeID() == BATTLEGROUND_AV) + if (bg->GetBgTypeID(true) == BATTLEGROUND_AV) if (!bg->ToBattlegroundAV()->PlayerCanDoMineQuest(go->GetEntry(), GetTeamId())) { go->ForceValuesUpdateAtIndex(GAMEOBJECT_BYTES_1); @@ -9182,7 +9182,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type) // Xinef: For AV Achievement if (Battleground* bg = GetBattleground()) { - if (bg->GetBgTypeID() == BATTLEGROUND_AV) + if (bg->GetBgTypeID(true) == BATTLEGROUND_AV) loot->FillLoot(1, LootTemplates_Creature, this, true); } // Xinef: For wintergrasp Quests @@ -9508,7 +9508,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) data << uint32(2325) << uint32(0x0); // 13 sandworm E break; case 2597: // Alterac Valley - if (bg && bg->GetBgTypeID() == BATTLEGROUND_AV) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_AV) bg->FillInitialWorldStates(data); else { @@ -9590,7 +9590,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 3277: // Warsong Gulch - if (bg && bg->GetBgTypeID() == BATTLEGROUND_WS) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_WS) bg->FillInitialWorldStates(data); else { @@ -9605,7 +9605,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 3358: // Arathi Basin - if (bg && bg->GetBgTypeID() == BATTLEGROUND_AB) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_AB) bg->FillInitialWorldStates(data); else { @@ -9644,7 +9644,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 3820: // Eye of the Storm - if (bg && bg->GetBgTypeID() == BATTLEGROUND_EY) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_EY) bg->FillInitialWorldStates(data); else { @@ -9817,7 +9817,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 3698: // Nagrand Arena - if (bg && bg->GetBgTypeID() == BATTLEGROUND_NA) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_NA) bg->FillInitialWorldStates(data); else { @@ -9827,7 +9827,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 3702: // Blade's Edge Arena - if (bg && bg->GetBgTypeID() == BATTLEGROUND_BE) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_BE) bg->FillInitialWorldStates(data); else { @@ -9837,7 +9837,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 3968: // Ruins of Lordaeron - if (bg && bg->GetBgTypeID() == BATTLEGROUND_RL) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_RL) bg->FillInitialWorldStates(data); else { @@ -9847,7 +9847,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 4378: // Dalaran Sewers - if (bg && bg->GetBgTypeID() == BATTLEGROUND_DS) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_DS) bg->FillInitialWorldStates(data); else { @@ -9857,7 +9857,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 4384: // Strand of the Ancients - if (bg && bg->GetBgTypeID() == BATTLEGROUND_SA) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_SA) bg->FillInitialWorldStates(data); else { @@ -9892,7 +9892,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) } break; case 4406: // Ring of Valor - if (bg && bg->GetBgTypeID() == BATTLEGROUND_RV) + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_RV) bg->FillInitialWorldStates(data); else { @@ -9901,8 +9901,8 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) data << uint32(0xe1a) << uint32(0x0); // 9 show } break; - case 4710: - if (bg && bg->GetBgTypeID() == BATTLEGROUND_IC) + case 4710: // Isle of Conquest + if (bg && bg->GetBgTypeID(true) == BATTLEGROUND_IC) bg->FillInitialWorldStates(data); else { diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 2ae9af475..93f33a941 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1827,6 +1827,8 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot); TeamId teamId = reference->GetTeamId(); + BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); + // check every member of the group to be able to join uint32 memberscount = 0; for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next(), ++memberscount) @@ -1865,6 +1867,14 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* // pussywizard: check for free slot, this is actually ensured before calling this function, but just in case if (!member->HasFreeBattlegroundQueueId()) return ERR_BATTLEGROUND_TOO_MANY_QUEUES; + + // don't let join if someone from the group is in bg queue random + if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) + return ERR_IN_RANDOM_BG; + + // don't let join to bg queue random if someone from the group is already in bg queue + if (bgTemplate->GetBgTypeID() == BATTLEGROUND_RB && member->InBattlegroundQueue()) + return ERR_IN_NON_RANDOM_BG; } // for arenas: check party size is proper diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 862b636b2..e76541525 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -512,7 +512,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) } if (Battleground* bg = _player->GetBattleground()) - if (bg->GetBgTypeID() == BATTLEGROUND_AV) + if (bg->GetBgTypeID(true) == BATTLEGROUND_AV) bg->ToBattlegroundAV()->HandleQuestComplete(questId, _player); if (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 4fe439938..82acb4714 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2119,7 +2119,7 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) // in battleground check if (Battleground* bg = player->GetBattleground()) { - if (bg->GetBgTypeID() == BATTLEGROUND_EY) + if (bg->GetBgTypeID(true) == BATTLEGROUND_EY) bg->EventPlayerClickedOnFlag(player, gameObjTarget); return; } @@ -3868,7 +3868,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) case 54640: { if (Player* player = unitTarget->ToPlayer()) - if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID() == BATTLEGROUND_SA) + if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA) { if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f)) { diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 83366a88c..5a08c3f7c 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1131,7 +1131,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 return false; Battleground* bg = player->GetBattleground(); - if (!bg || bg->GetBgTypeID() != BATTLEGROUND_IC) + if (!bg || bg->GetBgTypeID(true) != BATTLEGROUND_IC) return false; uint8 nodeType = spellId == 68719 ? NODE_TYPE_REFINERY : NODE_TYPE_QUARRY; diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp index fe145edc0..54cec637b 100644 --- a/src/server/scripts/World/achievement_scripts.cpp +++ b/src/server/scripts/World/achievement_scripts.cpp @@ -23,7 +23,7 @@ class achievement_resilient_victory : public AchievementCriteriaScript bool OnCheck(Player* source, Unit* /*target*/) { Battleground* bg = source->GetBattleground(); - return bg && bg->GetBgTypeID() == BATTLEGROUND_AB && bg->ToBattlegroundAB()->IsTeamScores500Disadvantage(source->GetTeamId()); + return bg && bg->GetBgTypeID(true) == BATTLEGROUND_AB && bg->ToBattlegroundAB()->IsTeamScores500Disadvantage(source->GetTeamId()); } }; @@ -52,7 +52,7 @@ class achievement_save_the_day : public AchievementCriteriaScript if (Player const* player = target->ToPlayer()) { Battleground* bg = source->GetBattleground(); - return bg && bg->GetBgTypeID() == BATTLEGROUND_WS && bg->ToBattlegroundWS()->GetFlagState(player->GetTeamId()) == BG_WS_FLAG_STATE_ON_BASE; + return bg && bg->GetBgTypeID(true) == BATTLEGROUND_WS && bg->ToBattlegroundWS()->GetFlagState(player->GetTeamId()) == BG_WS_FLAG_STATE_ON_BASE; } return false; } @@ -66,7 +66,7 @@ class achievement_bg_ic_resource_glut : public AchievementCriteriaScript bool OnCheck(Player* source, Unit* /*target*/) { Battleground* bg = source->GetBattleground(); - return bg && bg->GetBgTypeID() == BATTLEGROUND_IC && bg->ToBattlegroundIC()->IsResourceGlutAllowed(source->GetTeamId()); + return bg && bg->GetBgTypeID(true) == BATTLEGROUND_IC && bg->ToBattlegroundIC()->IsResourceGlutAllowed(source->GetTeamId()); } }; @@ -155,7 +155,7 @@ class achievement_everything_counts : public AchievementCriteriaScript bool OnCheck(Player* source, Unit* /*target*/) { Battleground* bg = source->GetBattleground(); - return bg && bg->GetBgTypeID() == BATTLEGROUND_AV && bg->ToBattlegroundAV()->IsBothMinesControlledByTeam(source->GetTeamId()); + return bg && bg->GetBgTypeID(true) == BATTLEGROUND_AV && bg->ToBattlegroundAV()->IsBothMinesControlledByTeam(source->GetTeamId()); } }; @@ -167,7 +167,7 @@ class achievement_bg_av_perfection : public AchievementCriteriaScript bool OnCheck(Player* source, Unit* /*target*/) { Battleground* bg = source->GetBattleground(); - return bg && bg->GetBgTypeID() == BATTLEGROUND_AV && bg->ToBattlegroundAV()->IsAllTowersControlledAndCaptainAlive(source->GetTeamId()); + return bg && bg->GetBgTypeID(true) == BATTLEGROUND_AV && bg->ToBattlegroundAV()->IsAllTowersControlledAndCaptainAlive(source->GetTeamId()); } }; @@ -179,7 +179,7 @@ class achievement_sa_defense_of_the_ancients : public AchievementCriteriaScript bool OnCheck(Player* source, Unit* /*target*/) { Battleground* bg = source->GetBattleground(); - return bg && bg->GetBgTypeID() == BATTLEGROUND_SA && bg->ToBattlegroundSA()->AllowDefenseOfTheAncients(source); + return bg && bg->GetBgTypeID(true) == BATTLEGROUND_SA && bg->ToBattlegroundSA()->AllowDefenseOfTheAncients(source); } }; @@ -226,7 +226,7 @@ class achievement_not_even_a_scratch : public AchievementCriteriaScript return false; Battleground* battleground = source->GetBattleground(); - return battleground && battleground->GetBgTypeID() == BATTLEGROUND_SA && battleground->ToBattlegroundSA()->notEvenAScratch(source->GetTeamId()); + return battleground && battleground->GetBgTypeID(true) == BATTLEGROUND_SA && battleground->ToBattlegroundSA()->notEvenAScratch(source->GetTeamId()); } };