-
-
Save irancore/10913800 to your computer and use it in GitHub Desktop.
| From 4c18aba9cad7ed7120d3ddc2573de93eb653c73e Mon Sep 17 00:00:00 2001 | |
| From: irancore <[email protected]> | |
| Date: Tue, 12 May 2020 02:39:52 +0400 | |
| Subject: [PATCH] crossfaction battleground | |
| --- | |
| src/server/game/Battlegrounds/Arena.cpp | 4 +- | |
| .../game/Battlegrounds/Battleground.cpp | 50 ++- | |
| src/server/game/Battlegrounds/Battleground.h | 2 +- | |
| .../game/Battlegrounds/BattlegroundMgr.cpp | 2 +- | |
| .../game/Battlegrounds/BattlegroundQueue.cpp | 89 +++-- | |
| .../game/Battlegrounds/BattlegroundQueue.h | 13 +- | |
| .../Battlegrounds/Zones/BattlegroundAB.cpp | 2 +- | |
| .../Battlegrounds/Zones/BattlegroundAV.cpp | 20 +- | |
| .../Battlegrounds/Zones/BattlegroundWS.cpp | 4 +- | |
| src/server/game/Custom/Custom.cpp | 322 ++++++++++++++++++ | |
| src/server/game/Custom/Custom.h | 36 ++ | |
| src/server/game/Entities/Player/Player.cpp | 103 ++++-- | |
| src/server/game/Entities/Player/Player.h | 42 ++- | |
| src/server/game/Entities/Unit/Unit.cpp | 3 +- | |
| src/server/game/Entities/Unit/Unit.h | 6 +- | |
| .../game/Handlers/BattleGroundHandler.cpp | 13 +- | |
| src/server/game/Handlers/CharacterHandler.cpp | 5 +- | |
| src/server/game/Handlers/ChatHandler.cpp | 4 +- | |
| src/server/game/Handlers/MovementHandler.cpp | 14 + | |
| src/server/game/Handlers/QueryHandler.cpp | 2 +- | |
| src/server/game/World/World.cpp | 1 + | |
| src/server/game/World/World.h | 1 + | |
| src/server/worldserver/worldserver.conf.dist | 10 + | |
| 23 files changed, 643 insertions(+), 105 deletions(-) | |
| create mode 100644 src/server/game/Custom/Custom.cpp | |
| create mode 100644 src/server/game/Custom/Custom.h | |
| diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp | |
| index 1a40c12797..b095959079 100644 | |
| --- a/src/server/game/Battlegrounds/Arena.cpp | |
| +++ b/src/server/game/Battlegrounds/Arena.cpp | |
| @@ -74,9 +74,9 @@ Arena::Arena() | |
| void Arena::AddPlayer(Player* player) | |
| { | |
| Battleground::AddPlayer(player); | |
| - PlayerScores[player->GetGUID().GetCounter()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); | |
| + PlayerScores[player->GetGUID().GetCounter()] = new ArenaScore(player->GetGUID(), player->GetTeam()); | |
| - if (player->GetBGTeam() == ALLIANCE) // gold | |
| + if (player->GetTeam() == ALLIANCE) // gold | |
| { | |
| if (player->GetTeam() == HORDE) | |
| player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true); | |
| diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp | |
| index 6ff4e1c6ea..397d3f5478 100644 | |
| --- a/src/server/game/Battlegrounds/Battleground.cpp | |
| +++ b/src/server/game/Battlegrounds/Battleground.cpp | |
| @@ -244,7 +244,7 @@ inline void Battleground::_CheckSafePositions(uint32 diff) | |
| continue; | |
| Position pos = player->GetPosition(); | |
| - Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetBGTeam())); | |
| + Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetTeam())); | |
| if (pos.GetExactDistSq(startPos) > maxDist) | |
| { | |
| TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId()); | |
| @@ -464,7 +464,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) | |
| WorldPacket status; | |
| BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); | |
| uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); | |
| - sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam()); | |
| + sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetTeam()); | |
| player->SendDirectMessage(&status); | |
| player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION); | |
| @@ -637,22 +637,36 @@ void Battleground::RewardHonorToTeam(uint32 Honor, uint32 TeamID) | |
| UpdatePlayerScore(player, SCORE_BONUS_HONOR, Honor); | |
| } | |
| -void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID) | |
| +void Battleground::RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamID) | |
| { | |
| - FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); | |
| - if (!factionEntry) | |
| - return; | |
| + FactionEntry const* a_factionEntry = sFactionStore.LookupEntry(a_faction_id); | |
| + FactionEntry const* h_factionEntry = sFactionStore.LookupEntry(h_faction_id); | |
| for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) | |
| { | |
| Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam"); | |
| - if (!player) | |
| - continue; | |
| + if (!a_factionEntry || !h_factionEntry) | |
| + return; | |
| - uint32 repGain = Reputation; | |
| - AddPct(repGain, player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN)); | |
| - AddPct(repGain, player->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction_id)); | |
| - player->GetReputationMgr().ModifyReputation(factionEntry, repGain); | |
| + for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) | |
| + { | |
| + if (itr->second.OfflineRemoveTime) | |
| + continue; | |
| + | |
| + Player* player = ObjectAccessor::FindPlayer(itr->first); | |
| + | |
| + if (!player) | |
| + { | |
| + TC_LOG_ERROR("bg.battleground", "BattleGround:RewardReputationToTeam: %u not found!", itr->first); | |
| + continue; | |
| + } | |
| + uint32 team = player->GetTeam(); | |
| + if (team == TeamID) | |
| + if (Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam")) | |
| + { | |
| + player->GetReputationMgr().ModifyReputation(player->GetCFSTeam() == ALLIANCE ? a_factionEntry : h_factionEntry, Reputation); | |
| + } | |
| + } | |
| } | |
| } | |
| @@ -797,7 +811,7 @@ void Battleground::EndBattleground(uint32 winner) | |
| player->SendDirectMessage(&pvpLogData); | |
| WorldPacket data; | |
| - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam()); | |
| + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetTeam()); | |
| player->SendDirectMessage(&data); | |
| player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, player->GetMapId()); | |
| } | |
| @@ -914,6 +928,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen | |
| if (player) | |
| { | |
| + player->FitPlayerInTeam(false, this); | |
| // Do next only if found in battleground | |
| player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG. | |
| // reset destination bg team | |
| @@ -985,7 +1000,7 @@ void Battleground::AddPlayer(Player* player) | |
| // score struct must be created in inherited class | |
| - uint32 team = player->GetBGTeam(); | |
| + uint32 team = player->GetTeam(); | |
| BattlegroundPlayer bp; | |
| bp.OfflineRemoveTime = 0; | |
| @@ -1027,6 +1042,7 @@ void Battleground::AddPlayer(Player* player) | |
| // setup BG group membership | |
| PlayerAddedToBGCheckIfBGIsRunning(player); | |
| AddOrSetPlayerToCorrectBgGroup(player, team); | |
| + player->FitPlayerInTeam(true, this); | |
| } | |
| // this method adds player to his team's bg group, or sets his correct group if player is already in bg group | |
| @@ -1096,8 +1112,8 @@ void Battleground::EventPlayerLoggedOut(Player* player) | |
| // 1 player is logging out, if it is the last, then end arena! | |
| if (isArena()) | |
| - if (GetAlivePlayersCountByTeam(player->GetBGTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetBGTeam()))) | |
| - EndBattleground(GetOtherTeam(player->GetBGTeam())); | |
| + if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam()))) | |
| + EndBattleground(GetOtherTeam(player->GetTeam())); | |
| } | |
| } | |
| @@ -1714,7 +1730,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) | |
| BuildPvPLogDataPacket(data); | |
| player->SendDirectMessage(&data); | |
| - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam()); | |
| + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetTeam()); | |
| player->SendDirectMessage(&data); | |
| } | |
| diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h | |
| index a4af193dc4..9b75dfbf14 100644 | |
| --- a/src/server/game/Battlegrounds/Battleground.h | |
| +++ b/src/server/game/Battlegrounds/Battleground.h | |
| @@ -384,7 +384,7 @@ class TC_GAME_API Battleground | |
| void CastSpellOnTeam(uint32 SpellID, uint32 TeamID); | |
| void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID); | |
| void RewardHonorToTeam(uint32 Honor, uint32 TeamID); | |
| - void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID); | |
| + void RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamID); | |
| void UpdateWorldState(uint32 variable, uint32 value); | |
| virtual void EndBattleground(uint32 winner); | |
| void BlockMovement(Player* player); | |
| diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
| index 5b8e99f66f..049e2b6a9a 100644 | |
| --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
| +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
| @@ -702,7 +702,7 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt | |
| if (Battleground* bg = GetBattleground(instanceId, bgTypeId)) | |
| { | |
| uint32 mapid = bg->GetMapId(); | |
| - uint32 team = player->GetBGTeam(); | |
| + uint32 team = player->GetTeam(); | |
| if (team == 0) | |
| team = player->GetTeam(); | |
| diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
| index 633226f5ca..913ea3193f 100644 | |
| --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
| +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
| @@ -158,8 +158,12 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr | |
| index += PVP_TEAMS_COUNT; | |
| if (ginfo->Team == HORDE) | |
| index++; | |
| + | |
| + if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && ArenaType == 0) | |
| + index = BG_QUEUE_CROSSFACTION; | |
| + | |
| TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index); | |
| - | |
| + | |
| uint32 lastOnlineTime = GameTime::GetGameTimeMS(); | |
| //announce world (this don't need mutex) | |
| @@ -202,31 +206,59 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr | |
| { | |
| if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId)) | |
| { | |
| - uint32 MinPlayers = bg->GetMinPlayersPerTeam(); | |
| - uint32 qHorde = 0; | |
| - uint32 qAlliance = 0; | |
| - uint32 q_min_level = bracketEntry->minLevel; | |
| - uint32 q_max_level = bracketEntry->maxLevel; | |
| - GroupsQueueType::const_iterator itr; | |
| - for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) | |
| - if (!(*itr)->IsInvitedToBGInstanceGUID) | |
| - qAlliance += (*itr)->Players.size(); | |
| - for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr) | |
| - if (!(*itr)->IsInvitedToBGInstanceGUID) | |
| - qHorde += (*itr)->Players.size(); | |
| - | |
| - // Show queue status to player only (when joining queue) | |
| - if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) | |
| + if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED)) | |
| { | |
| - ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bg->GetName().c_str(), q_min_level, q_max_level, | |
| - qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
| - } | |
| + char const* bgName = bg->GetName().c_str(); | |
| + uint32 MinPlayers = bg->GetMinPlayersPerTeam() * 2; | |
| + uint32 qPlayers = 0; | |
| + uint32 q_min_level = bracketEntry->minLevel; | |
| + uint32 q_max_level = bracketEntry->maxLevel; | |
| + for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracketId][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_CROSSFACTION].end(); ++itr) | |
| + if (!(*itr)->IsInvitedToBGInstanceGUID) | |
| + qPlayers += (*itr)->Players.size(); | |
| + | |
| + if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) | |
| + { | |
| + ChatHandler(leader->GetSession()).PSendSysMessage("Queue status for %s (Lvl: %u to %u) Queued players: %u (Need at least %u more)", bgName, q_min_level, q_max_level, qPlayers, MinPlayers - qPlayers); | |
| + } | |
| + else | |
| + { | |
| + std::ostringstream ss; | |
| + ss << "|cffff0000[BG Queue Announcer]:|r " << bgName << " -- [" << q_min_level << "-" << q_max_level << "] " << qPlayers << "/" << MinPlayers; | |
| + sWorld->SendGlobalText(ss.str().c_str(), NULL); | |
| + } | |
| + } | |
| // System message | |
| else | |
| { | |
| - sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bg->GetName().c_str(), q_min_level, q_max_level, | |
| - qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
| - } | |
| + // std::string bgName = bg->GetName().c_str(); | |
| + char const* bgName = bg->GetName().c_str(); | |
| + uint32 MinPlayers = bg->GetMinPlayersPerTeam(); | |
| + uint32 qHorde = 0; | |
| + uint32 qAlliance = 0; | |
| + uint32 q_min_level = bracketEntry->minLevel; | |
| + uint32 q_max_level = bracketEntry->maxLevel; | |
| + GroupsQueueType::const_iterator itr; | |
| + for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) | |
| + if (!(*itr)->IsInvitedToBGInstanceGUID) | |
| + qAlliance += (*itr)->Players.size(); | |
| + for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr) | |
| + if (!(*itr)->IsInvitedToBGInstanceGUID) | |
| + qHorde += (*itr)->Players.size(); | |
| + | |
| + // Show queue status to player only (when joining queue) | |
| + if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) | |
| + { | |
| + ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, //****** | |
| + qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
| + } | |
| + // System message | |
| + else | |
| + { | |
| + sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level, //******* | |
| + qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
| + } | |
| + } | |
| } | |
| } | |
| //release mutex | |
| @@ -313,7 +345,8 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) | |
| { | |
| //we must check premade and normal team's queue - because when players from premade are joining bg, | |
| //they leave groupinfo so we can't use its players size to find out index | |
| - for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += PVP_TEAMS_COUNT) | |
| + //for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += PVP_TEAMS_COUNT) | |
| + for (uint8 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j) | |
| { | |
| GroupsQueueType::iterator k = m_QueuedGroups[bracket_id_tmp][j].begin(); | |
| for (; k != m_QueuedGroups[bracket_id_tmp][j].end(); ++k) | |
| @@ -503,7 +536,9 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId | |
| int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); | |
| uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size(); | |
| uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size(); | |
| - | |
| + if (!bg->isArena()) | |
| + if (FillXPlayersToBG(bracket_id, bg, false)) | |
| + return; | |
| // try to get even teams | |
| if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_EVEN) | |
| { | |
| @@ -777,7 +812,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp | |
| if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && | |
| m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() && | |
| m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() && | |
| - m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty()) | |
| + m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty() && | |
| + m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].empty()) | |
| return; | |
| // battleground with free slot for player should be always in the beggining of the queue | |
| @@ -868,7 +904,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp | |
| { | |
| // if there are enough players in pools, start new battleground or non rated arena | |
| if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam) | |
| - || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam))) | |
| + || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)) | |
| + || CheckCrossFactionMatch(bracket_id, bg_template)) | |
| { | |
| // we successfully created a pool | |
| Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false); | |
| diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h | |
| index b7cad6f5d4..166863eac7 100644 | |
| --- a/src/server/game/Battlegrounds/BattlegroundQueue.h | |
| +++ b/src/server/game/Battlegrounds/BattlegroundQueue.h | |
| @@ -41,6 +41,8 @@ struct GroupQueueInfo // stores informatio | |
| { | |
| std::map<ObjectGuid, PlayerQueueInfo*> Players; // player queue info map | |
| uint32 Team; // Player team (ALLIANCE/HORDE) | |
| + uint32 CFSTeam; | |
| + | |
| BattlegroundTypeId BgTypeId; // battleground type id | |
| bool IsRated; // rated | |
| uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG | |
| @@ -60,9 +62,10 @@ enum BattlegroundQueueGroupTypes | |
| BG_QUEUE_PREMADE_ALLIANCE = 0, | |
| BG_QUEUE_PREMADE_HORDE = 1, | |
| BG_QUEUE_NORMAL_ALLIANCE = 2, | |
| - BG_QUEUE_NORMAL_HORDE = 3 | |
| + BG_QUEUE_NORMAL_HORDE = 3, | |
| + BG_QUEUE_CROSSFACTION = 4 | |
| }; | |
| -#define BG_QUEUE_GROUP_TYPES_COUNT 4 | |
| +#define BG_QUEUE_GROUP_TYPES_COUNT 5 | |
| enum BattlegroundQueueInvitationType | |
| { | |
| @@ -80,7 +83,11 @@ class TC_GAME_API BattlegroundQueue | |
| void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0); | |
| void UpdateEvents(uint32 diff); | |
| - | |
| + bool FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start = false); | |
| + typedef std::multimap<int32, GroupQueueInfo*> QueuedGroupMap; | |
| + int32 PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam); | |
| + bool CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg); | |
| + | |
| void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id); | |
| bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); | |
| bool CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers); | |
| diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
| index 1b3d927840..93a98f919b 100644 | |
| --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
| +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
| @@ -143,7 +143,7 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff) | |
| if (m_ReputationScoreTics[team] >= m_ReputationTics) | |
| { | |
| - (team == TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE); | |
| + RewardReputationToTeam(509, 510, 10, team == ALLIANCE ? ALLIANCE : HORDE); | |
| m_ReputationScoreTics[team] -= m_ReputationTics; | |
| } | |
| diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
| index 5d3fbc4858..a3af506170 100644 | |
| --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
| +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
| @@ -96,7 +96,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
| if (entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS]) | |
| { | |
| CastSpellOnTeam(23658, HORDE); //this is a spell which finishes a quest where a player has to kill the boss | |
| - RewardReputationToTeam(729, BG_AV_REP_BOSS, HORDE); | |
| + RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
| RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), HORDE); | |
| EndBattleground(HORDE); | |
| DelCreature(AV_CPLACE_TRIGGER17); | |
| @@ -104,7 +104,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
| else if (entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS]) | |
| { | |
| CastSpellOnTeam(23658, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss | |
| - RewardReputationToTeam(730, BG_AV_REP_BOSS, ALLIANCE); | |
| + RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
| RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), ALLIANCE); | |
| EndBattleground(ALLIANCE); | |
| DelCreature(AV_CPLACE_TRIGGER19); | |
| @@ -117,7 +117,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
| return; | |
| } | |
| m_CaptainAlive[0]=false; | |
| - RewardReputationToTeam(729, BG_AV_REP_CAPTAIN, HORDE); | |
| + RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
| RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE); | |
| UpdateScore(ALLIANCE, (-1)*BG_AV_RES_CAPTAIN); | |
| //spawn destroyed aura | |
| @@ -136,7 +136,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
| return; | |
| } | |
| m_CaptainAlive[1]=false; | |
| - RewardReputationToTeam(730, BG_AV_REP_CAPTAIN, ALLIANCE); | |
| + RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
| RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE); | |
| UpdateScore(HORDE, (-1)*BG_AV_RES_CAPTAIN); | |
| //spawn destroyed aura | |
| @@ -158,6 +158,8 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player) | |
| if (GetStatus() != STATUS_IN_PROGRESS) | |
| return;//maybe we should log this, cause this must be a cheater or a big bug | |
| uint8 team = GetTeamIndexByTeamId(player->GetTeam()); | |
| + uint8 CFSteam = GetTeamIndexByTeamId(GetOtherTeam(player->GetTeam())); | |
| + | |
| /// @todo add reputation, events (including quest not available anymore, next quest available, go/npc de/spawning)and maybe honor | |
| TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed", questid); | |
| switch (questid) | |
| @@ -182,21 +184,21 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player) | |
| case AV_QUEST_A_COMMANDER1: | |
| case AV_QUEST_H_COMMANDER1: | |
| m_Team_QuestStatus[team][1]++; | |
| - RewardReputationToTeam(team, 1, player->GetTeam()); | |
| + RewardReputationToTeam(team, CFSteam, 1, player->GetTeam()); | |
| if (m_Team_QuestStatus[team][1] == 30) | |
| TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid); | |
| break; | |
| case AV_QUEST_A_COMMANDER2: | |
| case AV_QUEST_H_COMMANDER2: | |
| m_Team_QuestStatus[team][2]++; | |
| - RewardReputationToTeam(team, 1, player->GetTeam()); | |
| + RewardReputationToTeam(team, CFSteam, 1, player->GetTeam()); | |
| if (m_Team_QuestStatus[team][2] == 60) | |
| TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid); | |
| break; | |
| case AV_QUEST_A_COMMANDER3: | |
| case AV_QUEST_H_COMMANDER3: | |
| m_Team_QuestStatus[team][3]++; | |
| - RewardReputationToTeam(team, 1, player->GetTeam()); | |
| + RewardReputationToTeam(team, CFSteam, 1, player->GetTeam()); | |
| if (m_Team_QuestStatus[team][3] == 120) | |
| TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid); | |
| break; | |
| @@ -481,7 +483,7 @@ void BattlegroundAV::EndBattleground(uint32 winner) | |
| rep[i] += BG_AV_REP_SURVIVING_CAPTAIN; | |
| } | |
| if (rep[i] != 0) | |
| - RewardReputationToTeam(i == 0 ? 730 : 729, rep[i], i == 0 ? ALLIANCE : HORDE); | |
| + RewardReputationToTeam(729, 730, 10, i == ALLIANCE ? ALLIANCE : HORDE); | |
| if (kills[i] != 0) | |
| RewardHonorToTeam(GetBonusHonorFromKill(kills[i]), i == 0 ? ALLIANCE : HORDE); | |
| } | |
| @@ -586,7 +588,7 @@ void BattlegroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node) | |
| SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10), RESPAWN_IMMEDIATELY); | |
| UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, -1 * BG_AV_RES_TOWER); | |
| - RewardReputationToTeam(owner == ALLIANCE ? 730 : 729, BG_AV_REP_TOWER, owner); | |
| + RewardReputationToTeam(729, 730, BG_AV_REP_TOWER, owner); | |
| RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), owner); | |
| SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp), RESPAWN_ONE_DAY); | |
| diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
| index 8b24aa1bc0..9c3a770821 100644 | |
| --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
| +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
| @@ -311,7 +311,6 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player) | |
| if (GetTeamScore(TEAM_ALLIANCE) < BG_WS_MAX_TEAM_SCORE) | |
| AddPoint(ALLIANCE, 1); | |
| PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE); | |
| - RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE); | |
| } | |
| else | |
| { | |
| @@ -330,8 +329,9 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player) | |
| if (GetTeamScore(TEAM_HORDE) < BG_WS_MAX_TEAM_SCORE) | |
| AddPoint(HORDE, 1); | |
| PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE); | |
| - RewardReputationToTeam(889, m_ReputationCapture, HORDE); | |
| } | |
| + RewardReputationToTeam(890, 889, m_ReputationCapture, player->GetTeam()); | |
| + | |
| //for flag capture is reward 2 honorable kills | |
| RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeam()); | |
| diff --git a/src/server/game/Custom/Custom.cpp b/src/server/game/Custom/Custom.cpp | |
| new file mode 100644 | |
| index 0000000000..1937dd6f29 | |
| --- /dev/null | |
| +++ b/src/server/game/Custom/Custom.cpp | |
| @@ -0,0 +1,322 @@ | |
| +#include "Custom.h" | |
| +#include "Battleground.h" | |
| +#include "BattlegroundMgr.h" | |
| +#include "Player.h" | |
| +#include "Chat.h" | |
| +#include "BattlegroundQueue.h" | |
| +#include "World.h" | |
| +#include <cstdarg> | |
| + | |
| +uint8 Unit::GetRace(bool forceoriginal) const | |
| +{ | |
| + if (GetTypeId() == TYPEID_PLAYER) | |
| + { | |
| + Player* pPlayer = ((Player*)this); | |
| + | |
| + if (forceoriginal) | |
| + return pPlayer->getCFSRace(); | |
| + | |
| + if (pPlayer->InArena()) | |
| + return GetByteValue(UNIT_FIELD_BYTES_0, 0); | |
| + | |
| + if (!pPlayer->IsPlayingNative()) | |
| + return pPlayer->getFRace(); | |
| + } | |
| + | |
| + return GetByteValue(UNIT_FIELD_BYTES_0, 0); | |
| +} | |
| + | |
| +bool Player::SendRealNameQuery() | |
| +{ | |
| + if (IsPlayingNative()) | |
| + return false; | |
| + | |
| + WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10)); | |
| + data.appendPackGUID(GetGUID()); // player guid | |
| + data << uint8(0); // added in 3.1; if > 1, then end of packet | |
| + data << GetName(); // played name | |
| + data << uint8(0); // realm name for cross realm BG usage | |
| + data << uint8(getCFSRace()); | |
| + data << uint8(GetGender()); | |
| + data << uint8(GetClass()); | |
| + data << uint8(0); // is not declined | |
| + | |
| + return true; | |
| +} | |
| + | |
| +void Player::SetFakeRace() | |
| +{ | |
| + m_FakeRace = GetCFSTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN; | |
| +} | |
| + | |
| +bool Player::SendBattleGroundChat(uint32 msgtype, std::string message) | |
| +{ | |
| + // Select distance to broadcast to. | |
| + float distance = msgtype == CHAT_MSG_SAY ? sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY) : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL); | |
| + | |
| + if (Battleground* pBattleGround = GetBattleground()) | |
| + { | |
| + if (pBattleGround->isArena()) // Only fake chat in BG's. CFBG should not interfere with arenas. | |
| + return false; | |
| + | |
| + for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr) | |
| + { | |
| + if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first)) | |
| + { | |
| + if (GetDistance2d(pPlayer->GetPositionX(), pPlayer->GetPositionY()) <= distance) | |
| + { | |
| + WorldPacket data(SMSG_MESSAGECHAT, 200); | |
| + | |
| + if (GetTeam() == pPlayer->GetTeam()) | |
| + BuildPlayerChat(&data, msgtype, message, LANG_UNIVERSAL); | |
| + else if (msgtype != CHAT_MSG_EMOTE) | |
| + BuildPlayerChat(&data, msgtype, message, pPlayer->GetTeam() == ALLIANCE ? LANG_ORCISH : LANG_COMMON); | |
| + | |
| + pPlayer->GetSession()->SendPacket(&data); | |
| + } | |
| + } | |
| + } | |
| + return true; | |
| + } | |
| + else | |
| + return false; | |
| +} | |
| + | |
| +void Player::MorphFit(bool value) | |
| +{ | |
| + if (!IsPlayingNative() && value) | |
| + { | |
| + if (GetCFSTeam() == HORDE) | |
| + { | |
| + if (GetGender() == GENDER_MALE) | |
| + { | |
| + SetDisplayId(19723); | |
| + SetNativeDisplayId(19723); | |
| + } | |
| + else | |
| + { | |
| + SetDisplayId(19724); | |
| + SetNativeDisplayId(19724); | |
| + } | |
| + } | |
| + else | |
| + { | |
| + if (GetGender() == GENDER_MALE) | |
| + { | |
| + SetDisplayId(20578); | |
| + SetNativeDisplayId(20578); | |
| + } | |
| + else | |
| + { | |
| + SetDisplayId(20579); | |
| + SetNativeDisplayId(20579); | |
| + } | |
| + } | |
| + } | |
| + else | |
| + InitDisplayIds(); | |
| +} | |
| + | |
| +void Player::FitPlayerInTeam(bool action, Battleground* pBattleGround) | |
| +{ | |
| + if (!pBattleGround) | |
| + pBattleGround = GetBattleground(); | |
| + | |
| + if ((!pBattleGround || pBattleGround->isArena()) && action) | |
| + return; | |
| + | |
| + if(!IsPlayingNative() && action) | |
| + SetFactionForRace(GetRace()); | |
| + else | |
| + SetFactionForRace(getCFSRace()); | |
| + | |
| + if (action) | |
| + SetForgetBGPlayers(true); | |
| + else | |
| + SetForgetInListPlayers(true); | |
| + | |
| + MorphFit(action); | |
| + | |
| + if (pBattleGround && action) | |
| + SendChatMessage("%sYou are playing for the %s%s in this %s", MSG_COLOR_WHITE, GetTeam() == ALLIANCE ? MSG_COLOR_DARKBLUE"alliance" : MSG_COLOR_RED"horde", MSG_COLOR_WHITE, pBattleGround->GetName().c_str()); | |
| +} | |
| + | |
| +void Player::DoForgetPlayersInList() | |
| +{ | |
| + // m_FakePlayers is filled from a vector within the battleground | |
| + // they were in previously so all players that have been in that BG will be invalidated. | |
| + for (FakePlayers::const_iterator itr = m_FakePlayers.begin(); itr != m_FakePlayers.end(); ++itr) | |
| + { | |
| + WorldPacket data(SMSG_INVALIDATE_PLAYER, 8); | |
| + data << *itr; | |
| + GetSession()->SendPacket(&data); | |
| + if (Player* pPlayer = ObjectAccessor::FindPlayer(ObjectGuid(*itr))) | |
| + GetSession()->SendNameQueryOpcode(pPlayer->GetGUID()); | |
| + } | |
| + m_FakePlayers.clear(); | |
| +} | |
| + | |
| +void Player::DoForgetPlayersInBG(Battleground* pBattleGround) | |
| +{ | |
| + for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr) | |
| + { | |
| + // Here we invalidate players in the bg to the added player | |
| + WorldPacket data1(SMSG_INVALIDATE_PLAYER, 8); | |
| + data1 << itr->first; | |
| + GetSession()->SendPacket(&data1); | |
| + | |
| + if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first)) | |
| + { | |
| + GetSession()->SendNameQueryOpcode(pPlayer->GetGUID()); // Send namequery answer instantly if player is available | |
| + // Here we invalidate the player added to players in the bg | |
| + WorldPacket data2(SMSG_INVALIDATE_PLAYER, 8); | |
| + data2 << GetGUID(); | |
| + pPlayer->GetSession()->SendPacket(&data2); | |
| + pPlayer->GetSession()->SendNameQueryOpcode(GetGUID()); | |
| + } | |
| + } | |
| +} | |
| + | |
| +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 will invite players in the least populated faction, which makes battleground queues much faster. | |
| +// This function will return true if cross faction battlegrounds are enabled, otherwise return false, | |
| +// which is useful in FillPlayersToBG. Because then we can interrupt the regular invitation if cross faction bg's are enabled. | |
| +bool BattlegroundQueue::FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start) | |
| +{ | |
| + uint8 queuedPeople = 0; | |
| + for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr) | |
| + if (!(*itr)->IsInvitedToBGInstanceGUID) | |
| + queuedPeople += (*itr)->Players.size(); | |
| + | |
| + if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && (sBattlegroundMgr->isTesting() || queuedPeople >= bg->GetMinPlayersPerTeam()*2 || !start)) | |
| + { | |
| + int32 aliFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(ALLIANCE); | |
| + int32 hordeFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(HORDE); | |
| + // Empty selection pools. They will be refilled from queued groups. | |
| + m_SelectionPools[TEAM_ALLIANCE].Init(); | |
| + m_SelectionPools[TEAM_HORDE].Init(); | |
| + int32 valiFree = aliFree; | |
| + int32 vhordeFree = hordeFree; | |
| + int32 diff = 0; | |
| + | |
| + | |
| + // Add teams to their own factions as far as possible. | |
| + if (start) | |
| + { | |
| + QueuedGroupMap m_PreGroupMap_a, m_PreGroupMap_h; | |
| + int32 m_SmallestOfTeams = 0; | |
| + int32 queuedAlliance = 0; | |
| + int32 queuedHorde = 0; | |
| + | |
| + for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr) | |
| + { | |
| + if ((*itr)->IsInvitedToBGInstanceGUID) | |
| + continue; | |
| + | |
| + bool alliance = (*itr)->CFSTeam == ALLIANCE; | |
| + | |
| + if (alliance) | |
| + { | |
| + m_PreGroupMap_a.insert(std::make_pair((*itr)->Players.size(), *itr)); | |
| + queuedAlliance += (*itr)->Players.size(); | |
| + } | |
| + else | |
| + { | |
| + m_PreGroupMap_h.insert(std::make_pair((*itr)->Players.size(), *itr)); | |
| + queuedHorde += (*itr)->Players.size(); | |
| + } | |
| + } | |
| + | |
| + m_SmallestOfTeams = std::min(std::min(aliFree, queuedAlliance), std::min(hordeFree, queuedHorde)); | |
| + | |
| + valiFree -= PreAddPlayers(m_PreGroupMap_a, m_SmallestOfTeams, aliFree); | |
| + vhordeFree -= PreAddPlayers(m_PreGroupMap_h, m_SmallestOfTeams, hordeFree); | |
| + } | |
| + | |
| + QueuedGroupMap m_QueuedGroupMap; | |
| + | |
| + for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr) | |
| + m_QueuedGroupMap.insert(std::make_pair((*itr)->Players.size(), *itr)); | |
| + | |
| + for (QueuedGroupMap::reverse_iterator itr = m_QueuedGroupMap.rbegin(); itr != m_QueuedGroupMap.rend(); ++itr) | |
| + { | |
| + GroupsQueueType allypool = m_SelectionPools[TEAM_ALLIANCE].SelectedGroups; | |
| + GroupsQueueType hordepool = m_SelectionPools[TEAM_HORDE].SelectedGroups; | |
| + | |
| + GroupQueueInfo* ginfo = itr->second; | |
| + | |
| + // If player already was invited via pre adding (add to own team first) or he was already invited to a bg, skip. | |
| + if (ginfo->IsInvitedToBGInstanceGUID || | |
| + std::find(allypool.begin(), allypool.end(), ginfo) != allypool.end() || | |
| + std::find(hordepool.begin(), hordepool.end(), ginfo) != hordepool.end() || | |
| + (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= bg->GetMinPlayersPerTeam() && | |
| + m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= bg->GetMinPlayersPerTeam())) | |
| + continue; | |
| + | |
| + diff = abs(valiFree - vhordeFree); | |
| + bool moreAli = valiFree < vhordeFree; | |
| + | |
| + if (diff > 0) | |
| + ginfo->Team = moreAli ? HORDE : ALLIANCE; | |
| + | |
| + bool alliance = ginfo->Team == ALLIANCE; | |
| + | |
| + if (m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(ginfo, alliance ? aliFree : hordeFree)) | |
| + alliance ? valiFree -= ginfo->Players.size() : vhordeFree -= ginfo->Players.size(); | |
| + } | |
| + | |
| + return true; | |
| + } | |
| + return false; | |
| +} | |
| + | |
| +int32 BattlegroundQueue::PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam) | |
| +{ | |
| + int32 LeftToAdd = MaxAdd; | |
| + uint32 Added = 0; | |
| + | |
| + for (QueuedGroupMap::reverse_iterator itr = m_PreGroupMap.rbegin(); itr != m_PreGroupMap.rend(); ++itr) | |
| + { | |
| + int32 PlayerSize = itr->first; | |
| + bool alliance = itr->second->CFSTeam == ALLIANCE; | |
| + | |
| + if (PlayerSize <= LeftToAdd && m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(itr->second, MaxInTeam)) | |
| + LeftToAdd -= PlayerSize, Added -= PlayerSize; | |
| + } | |
| + | |
| + return LeftToAdd; | |
| +} | |
| + | |
| +void Player::SendChatMessage(const char *format, ...) | |
| +{ | |
| + if (!IsInWorld()) | |
| + return; | |
| + | |
| + if (format) | |
| + { | |
| + va_list ap; | |
| + char str [2048]; | |
| + va_start(ap, format); | |
| + vsnprintf(str, 2048, format, ap); | |
| + va_end(ap); | |
| + | |
| + ChatHandler(GetSession()).SendSysMessage(str); | |
| + } | |
| +} | |
| diff --git a/src/server/game/Custom/Custom.h b/src/server/game/Custom/Custom.h | |
| new file mode 100644 | |
| index 0000000000..885faa094b | |
| --- /dev/null | |
| +++ b/src/server/game/Custom/Custom.h | |
| @@ -0,0 +1,36 @@ | |
| +#ifndef _CUSTOM_H | |
| +#define _CUSTOM_H | |
| + | |
| +#define MSG_COLOR_LIGHTRED "|cffff6060" | |
| +#define MSG_COLOR_LIGHTBLUE "|cff00ccff" | |
| +#define MSG_COLOR_ANN_GREEN "|c1f40af20" | |
| +#define MSG_COLOR_RED "|cffff0000" | |
| +#define MSG_COLOR_GOLD "|cffffcc00" | |
| +#define MSG_COLOR_SUBWHITE "|cffbbbbbb" | |
| +#define MSG_COLOR_MAGENTA "|cffff00ff" | |
| +#define MSG_COLOR_YELLOW "|cffffff00" | |
| +#define MSG_COLOR_CYAN "|cff00ffff" | |
| +#define MSG_COLOR_DARKBLUE "|cff0000ff" | |
| + | |
| +#define MSG_COLOR_GREY "|cff9d9d9d" | |
| +#define MSG_COLOR_WHITE "|cffffffff" | |
| +#define MSG_COLOR_GREEN "|cff1eff00" | |
| +#define MSG_COLOR_BLUE "|cff0080ff" | |
| +#define MSG_COLOR_PURPLE "|cffb048f8" | |
| +#define MSG_COLOR_ORANGE "|cffff8000" | |
| + | |
| +#define MSG_COLOR_DRUID "|cffff7d0a" | |
| +#define MSG_COLOR_HUNTER "|cffabd473" | |
| +#define MSG_COLOR_MAGE "|cff69ccf0" | |
| +#define MSG_COLOR_PALADIN "|cfff58cba" | |
| +#define MSG_COLOR_PRIEST "|cffffffff" | |
| +#define MSG_COLOR_ROGUE "|cfffff569" | |
| +#define MSG_COLOR_SHAMAN "|cff0070de" | |
| +#define MSG_COLOR_WARLOCK "|cff9482c9" | |
| +#define MSG_COLOR_WARRIOR "|cffc79c6e" | |
| +#define MSG_COLOR_DEATH_KNIGHT "|cffc41f3b" | |
| +#define MSG_COLOR_MONK "|cff00ff96" | |
| + | |
| +#define LIMIT_UINT32 2147483647 | |
| + | |
| +#endif | |
| \ No newline at end of file | |
| diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp | |
| index 595614ce77..12b16da781 100644 | |
| --- a/src/server/game/Entities/Player/Player.cpp | |
| +++ b/src/server/game/Entities/Player/Player.cpp | |
| @@ -171,6 +171,11 @@ uint32 const MAX_MONEY_AMOUNT = static_cast<uint32>(std::numeric_limits<int32>:: | |
| Player::Player(WorldSession* session): Unit(true) | |
| { | |
| + m_FakeRace = 0; | |
| + m_RealRace = 0; | |
| + m_ForgetBGPlayers = false; | |
| + m_ForgetInListPlayers = false; | |
| + | |
| m_speakTime = 0; | |
| m_speakCount = 0; | |
| @@ -520,7 +525,11 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo | |
| SetClass(createInfo->Class); | |
| SetGender(createInfo->Gender); | |
| SetPowerType(Powers(powertype), false); | |
| - InitDisplayIds(); | |
| + SetCFSRace(); | |
| + m_team = TeamForRace(getCFSRace()); | |
| + SetFakeRace(); // m_team must be set before this can be used. | |
| + SetFactionForRace(getCFSRace()); | |
| + InitDisplayIds(); | |
| UpdatePositionData(); | |
| if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP) | |
| { | |
| @@ -2581,7 +2590,7 @@ void Player::GiveLevel(uint8 level) | |
| guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level); | |
| PlayerLevelInfo info; | |
| - sObjectMgr->GetPlayerLevelInfo(GetRace(), GetClass(), level, &info); | |
| + sObjectMgr->GetPlayerLevelInfo(getCFSRace(), GetClass(), level, &info); | |
| PlayerClassLevelInfo classInfo; | |
| sObjectMgr->GetPlayerClassLevelInfo(GetClass(), level, &classInfo); | |
| @@ -2716,7 +2725,7 @@ void Player::InitStatsForLevel(bool reapplyMods) | |
| sObjectMgr->GetPlayerClassLevelInfo(GetClass(), GetLevel(), &classInfo); | |
| PlayerLevelInfo info; | |
| - sObjectMgr->GetPlayerLevelInfo(GetRace(), GetClass(), GetLevel(), &info); | |
| + sObjectMgr->GetPlayerLevelInfo(getCFSRace(), GetClass(), GetLevel(), &info); | |
| SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)); | |
| SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(GetLevel())); | |
| @@ -4693,7 +4702,7 @@ Corpse* Player::CreateCorpse() | |
| // prevent the existence of 2 corpses for one player | |
| SpawnCorpseBones(); | |
| - uint32 _cfb1, _cfb2; | |
| + uint32 _cfb1, _cfb2,_uf; | |
| Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE); | |
| SetPvPDeath(false); | |
| @@ -4706,9 +4715,11 @@ Corpse* Player::CreateCorpse() | |
| _corpseLocation.WorldRelocate(*this); | |
| + _uf = getCFSRace(); | |
| _cfb1 = ((0x00) | (GetRace() << 8) | (GetNativeGender() << 16) | (GetSkinId() << 24)); | |
| _cfb2 = (GetFaceId() | (GetHairStyleId() << 8) | (GetHairColorId() << 16) | (GetFacialStyle() << 24)); | |
| + uint8 race = (uint8) (_uf); | |
| corpse->SetUInt32Value(CORPSE_FIELD_BYTES_1, _cfb1); | |
| corpse->SetUInt32Value(CORPSE_FIELD_BYTES_2, _cfb2); | |
| @@ -6508,10 +6519,10 @@ uint32 Player::TeamForRace(uint8 race) | |
| void Player::SetFactionForRace(uint8 race) | |
| { | |
| - m_team = TeamForRace(race); | |
| + SetBGTeam(TeamForRace(race)); | |
| ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race); | |
| - SetFaction(rEntry ? rEntry->FactionID : 0); | |
| + SetFaction(rEntry ? rEntry->FactionID : GetFaction()); | |
| } | |
| ReputationRank Player::GetReputationRank(uint32 faction) const | |
| @@ -6612,7 +6623,26 @@ void Player::RewardReputation(Unit* victim, float rate) | |
| ReputationOnKillEntry const* Rep = sObjectMgr->GetReputationOnKilEntry(victim->ToCreature()->GetCreatureTemplate()->Entry); | |
| if (!Rep) | |
| return; | |
| + uint32 repfaction1 = Rep->RepFaction1; | |
| + uint32 repfaction2 = Rep->RepFaction2; | |
| + if (!IsPlayingNative()) | |
| + { | |
| + if (GetCFSTeam() == ALLIANCE) | |
| + { | |
| + if (repfaction1 == 729) | |
| + repfaction1 = 730; | |
| + if (repfaction2 == 729) | |
| + repfaction2 = 730; | |
| + } | |
| + else | |
| + { | |
| + if (repfaction1 == 730) | |
| + repfaction1 = 729; | |
| + if (repfaction2 == 730) | |
| + repfaction2 = 729; | |
| + } | |
| + } | |
| uint32 ChampioningFaction = 0; | |
| if (GetChampioningFaction()) | |
| @@ -6627,23 +6657,23 @@ void Player::RewardReputation(Unit* victim, float rate) | |
| uint32 team = GetTeam(); | |
| - if (Rep->RepFaction1 && (!Rep->TeamDependent || team == ALLIANCE)) | |
| + if (repfaction1 && (!Rep->TeamDependent || team == ALLIANCE)) | |
| { | |
| - int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); | |
| - donerep1 = int32(donerep1 * rate); | |
| + int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : repfaction1); | |
| + donerep1 = int32(donerep1 * rate); | |
| - FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); | |
| + FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction1); | |
| uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1); | |
| if (factionEntry1) | |
| GetReputationMgr().ModifyReputation(factionEntry1, donerep1, current_reputation_rank1 > Rep->ReputationMaxCap1); | |
| } | |
| - if (Rep->RepFaction2 && (!Rep->TeamDependent || team == HORDE)) | |
| + if (repfaction2 && (!Rep->TeamDependent || team == HORDE)) | |
| { | |
| - int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); | |
| + int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : repfaction2); | |
| donerep2 = int32(donerep2 * rate); | |
| - FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); | |
| + FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction2); | |
| uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2); | |
| if (factionEntry2) | |
| GetReputationMgr().ModifyReputation(factionEntry2, donerep2, current_reputation_rank2 > Rep->ReputationMaxCap2); | |
| @@ -6743,7 +6773,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto | |
| if (!victim || victim == this || victim->GetTypeId() != TYPEID_PLAYER) | |
| return false; | |
| - if (GetBGTeam() == victim->ToPlayer()->GetBGTeam()) | |
| + if (GetTeam() == victim->ToPlayer()->GetTeam()) | |
| return false; | |
| return true; | |
| @@ -11766,11 +11796,11 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const | |
| if (!proto) | |
| return EQUIP_ERR_ITEM_NOT_FOUND; | |
| - if (((proto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && GetTeam() != HORDE) || | |
| - (((proto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && GetTeam() != ALLIANCE))) | |
| + if (((proto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && GetCFSTeam() != HORDE) || | |
| + (((proto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && GetCFSTeam() != ALLIANCE))) | |
| return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; | |
| - if ((proto->AllowableClass & GetClassMask()) == 0 || (proto->AllowableRace & GetRaceMask()) == 0) | |
| + if ((proto->AllowableClass & GetClassMask()) == 0 || (proto->AllowableRace & getCFSRaceMask()) == 0) | |
| return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; | |
| if (proto->RequiredSkill != 0) | |
| @@ -17240,6 +17270,11 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) | |
| SetClass(fields[4].GetUInt8()); | |
| SetGender(gender); | |
| + SetCFSRace(); | |
| + m_team = TeamForRace(getCFSRace()); | |
| + SetFakeRace(); // m_team must be set before this can be used. | |
| + SetFactionForRace(getCFSRace()); | |
| + | |
| // check if race/class combination is valid | |
| PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
| if (!info) | |
| @@ -17311,10 +17346,6 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) | |
| TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: Load Basic value of player '%s' is: ", m_name.c_str()); | |
| outDebugValues(); | |
| - //Need to call it to initialize m_team (m_team can be calculated from race) | |
| - //Other way is to saves m_team into characters table. | |
| - SetFactionForRace(GetRace()); | |
| - | |
| // load home bind and check in same time class/race pair, it used later for restore broken positions | |
| if (!_LoadHomeBind(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_HOME_BIND))) | |
| return false; | |
| @@ -19250,7 +19281,7 @@ void Player::AddInstanceEnterTime(uint32 instanceId, time_t enterTime) | |
| bool Player::_LoadHomeBind(PreparedQueryResult result) | |
| { | |
| - PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
| + PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), GetClass()); | |
| if (!info) | |
| { | |
| TC_LOG_ERROR("entities.player", "Player::_LoadHomeBind: Player '%s' (%s) has incorrect race/class (%u/%u) pair. Can't load.", | |
| @@ -19351,7 +19382,7 @@ void Player::SaveToDB(bool create /*=false*/) | |
| stmt->setUInt32(index++, GetGUID().GetCounter()); | |
| stmt->setUInt32(index++, GetSession()->GetAccountId()); | |
| stmt->setString(index++, GetName()); | |
| - stmt->setUInt8(index++, GetRace()); | |
| + stmt->setUInt8(index++, getCFSRace()); | |
| stmt->setUInt8(index++, GetClass()); | |
| stmt->setUInt8(index++, GetNativeGender()); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect | |
| stmt->setUInt8(index++, GetLevel()); | |
| @@ -19461,7 +19492,7 @@ void Player::SaveToDB(bool create /*=false*/) | |
| // Update query | |
| stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER); | |
| stmt->setString(index++, GetName()); | |
| - stmt->setUInt8(index++, GetRace()); | |
| + stmt->setUInt8(index++, getCFSRace()); | |
| stmt->setUInt8(index++, GetClass()); | |
| stmt->setUInt8(index++, GetNativeGender()); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect | |
| stmt->setUInt8(index++, GetLevel()); | |
| @@ -21587,22 +21618,25 @@ void Player::InitDataForForm(bool reapplyMods) | |
| void Player::InitDisplayIds() | |
| { | |
| - PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
| + PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), GetClass()); | |
| if (!info) | |
| { | |
| TC_LOG_ERROR("entities.player", "Player::InitDisplayIds: Player '%s' (%s) has incorrect race/class pair. Can't init display ids.", GetName().c_str(), GetGUID().ToString().c_str()); | |
| return; | |
| } | |
| + bool isMorphed = GetNativeDisplayId() != GetDisplayId(); | |
| uint8 gender = GetNativeGender(); | |
| switch (gender) | |
| { | |
| case GENDER_FEMALE: | |
| + if (!isMorphed) | |
| SetDisplayId(info->displayId_f); | |
| SetNativeDisplayId(info->displayId_f); | |
| break; | |
| case GENDER_MALE: | |
| - SetDisplayId(info->displayId_m); | |
| + if (!isMorphed) | |
| + SetDisplayId(info->displayId_m); | |
| SetNativeDisplayId(info->displayId_m); | |
| break; | |
| default: | |
| @@ -22222,10 +22256,10 @@ void Player::SetBGTeam(uint32 team) | |
| SetArenaFaction(uint8(team == ALLIANCE ? 1 : 0)); | |
| } | |
| -uint32 Player::GetBGTeam() const | |
| +/*uint32 Player::GetBGTeam() const | |
| { | |
| return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); | |
| -} | |
| +}*/ | |
| void Player::LeaveBattleground(bool teleportToEntryPoint) | |
| { | |
| @@ -22305,7 +22339,7 @@ void Player::ReportedAfkBy(Player* reporter) | |
| WorldLocation Player::GetStartPosition() const | |
| { | |
| - PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
| + PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), GetClass()); | |
| ASSERT(info); | |
| uint32 mapId = info->mapId; | |
| if (GetClass() == CLASS_DEATH_KNIGHT && HasSpell(50977)) | |
| @@ -26898,3 +26932,14 @@ std::string Player::GetDebugInfo() const | |
| sstr << Unit::GetDebugInfo(); | |
| return sstr.str(); | |
| } | |
| +void Player::BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language) const | |
| +{ | |
| + *data << uint8(msgtype); | |
| + *data << uint32(language); | |
| + *data << uint64(GetGUID()); | |
| + *data << uint32(0); // constant unknown time | |
| + *data << uint64(GetGUID()); | |
| + *data << uint32(text.length() + 1); | |
| + *data << text; | |
| + *data << uint8(GetChatTag()); | |
| +} | |
| diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h | |
| index 97835fb871..de484f5736 100644 | |
| --- a/src/server/game/Entities/Player/Player.h | |
| +++ b/src/server/game/Entities/Player/Player.h | |
| @@ -883,7 +883,35 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> | |
| public: | |
| explicit Player(WorldSession* session); | |
| ~Player(); | |
| - | |
| + private: | |
| + bool m_ForgetBGPlayers; | |
| + bool m_ForgetInListPlayers; | |
| + uint8 m_FakeRace; | |
| + uint8 m_RealRace; | |
| + uint32 m_FakeMorph; | |
| + public: | |
| + typedef std::vector<uint64> FakePlayers; | |
| + void SendChatMessage(const char *format, ...); | |
| + void FitPlayerInTeam(bool action, Battleground* pBattleGround = NULL); // void FitPlayerInTeam(bool action, Battleground* bg = NULL); | |
| + void DoForgetPlayersInList(); | |
| + void DoForgetPlayersInBG(Battleground* pBattleGround); // void DoForgetPlayersInBG(Battleground* bg); | |
| + uint8 getCFSRace() const { return m_RealRace; } | |
| + void SetCFSRace() { m_RealRace = GetByteValue(UNIT_FIELD_BYTES_0, 0); }; // SHOULD ONLY BE CALLED ON LOGIN | |
| + void SetFakeRace(); // SHOULD ONLY BE CALLED ON LOGIN | |
| + void SetFakeRaceAndMorph(); // SHOULD ONLY BE CALLED ON LOGIN | |
| + uint32 GetFakeMorph() { return m_FakeMorph; }; | |
| + uint8 getFRace() const { return m_FakeRace; } | |
| + void SetForgetBGPlayers(bool value) { m_ForgetBGPlayers = value; } | |
| + bool ShouldForgetBGPlayers() { return m_ForgetBGPlayers; } | |
| + void SetForgetInListPlayers(bool value) { m_ForgetInListPlayers = value; } | |
| + bool ShouldForgetInListPlayers() { return m_ForgetInListPlayers; } | |
| + bool SendBattleGroundChat(uint32 msgtype, std::string message); | |
| + void MorphFit(bool value); | |
| + bool IsPlayingNative() const { return GetTeam() == m_team; } | |
| + uint32 GetCFSTeam() const { return m_team; } | |
| + uint32 GetTeam() const { return m_bgData.bgTeam && GetBattleground() ? m_bgData.bgTeam : m_team; } | |
| + bool SendRealNameQuery(); | |
| + FakePlayers m_FakePlayers; | |
| PlayerAI* AI() const { return reinterpret_cast<PlayerAI*>(GetAI()); } | |
| void CleanupsBeforeDelete(bool finalCleanup = true) override; | |
| @@ -939,7 +967,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> | |
| void RemoveSocial(); | |
| PlayerTaxi m_taxi; | |
| - void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(GetRace(), GetClass(), GetLevel()); } | |
| + void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getCFSRace(), GetClass(), GetLevel()); } | |
| bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0); | |
| bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0); | |
| void FinishTaxiFlight(); | |
| @@ -1034,6 +1062,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> | |
| /// Handles whispers from Addons and players based on sender, receiver's guid and language. | |
| void Whisper(std::string const& text, Language language, Player* receiver, bool = false) override; | |
| void Whisper(uint32 textId, Player* target, bool isBossWhisper = false) override; | |
| + void BuildPlayerChat(WorldPacket* data, uint8 msgtype, std::string const& text, uint32 language) const; | |
| + | |
| /*********************************************************/ | |
| /*** STORAGE SYSTEM ***/ | |
| @@ -1752,8 +1782,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> | |
| void CheckAreaExploreAndOutdoor(void); | |
| static uint32 TeamForRace(uint8 race); | |
| - uint32 GetTeam() const { return m_team; } | |
| - TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; } | |
| + //uint32 GetTeam() const { return m_team; } | |
| + TeamId GetTeamId() const { return GetTeam() == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; } | |
| + | |
| void SetFactionForRace(uint8 race); | |
| void InitDisplayIds(); | |
| @@ -1924,8 +1955,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> | |
| void SetBattlegroundEntryPoint(); | |
| void SetBGTeam(uint32 team); | |
| - uint32 GetBGTeam() const; | |
| - | |
| + | |
| void LeaveBattleground(bool teleportToEntryPoint = true); | |
| bool CanJoinToBattleground(Battleground const* bg) const; | |
| bool CanReportAfkDueToLimit(); | |
| diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp | |
| index 31ca50eb70..3a5e44b449 100644 | |
| --- a/src/server/game/Entities/Unit/Unit.cpp | |
| +++ b/src/server/game/Entities/Unit/Unit.cpp | |
| @@ -11624,7 +11624,8 @@ void Unit::RemoveCharmedBy(Unit* charmer) | |
| void Unit::RestoreFaction() | |
| { | |
| if (GetTypeId() == TYPEID_PLAYER) | |
| - ToPlayer()->SetFactionForRace(GetRace()); | |
| + ToPlayer()->SetFactionForRace(ToPlayer()->GetRace()); | |
| + | |
| else | |
| { | |
| if (HasUnitTypeMask(UNIT_MASK_MINION)) | |
| diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h | |
| index a90145c139..25449c1805 100644 | |
| --- a/src/server/game/Entities/Unit/Unit.h | |
| +++ b/src/server/game/Entities/Unit/Unit.h | |
| @@ -845,9 +845,13 @@ class TC_GAME_API Unit : public WorldObject | |
| uint8 GetLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); } | |
| uint8 GetLevelForTarget(WorldObject const* /*target*/) const override { return GetLevel(); } | |
| void SetLevel(uint8 lvl, bool sendUpdate = true); | |
| - uint8 GetRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE); } | |
| + uint8 GetRace(bool forceoriginal = false) const; | |
| + uint8 getCFSRace() { return GetRace(true); } | |
| + | |
| + | |
| void SetRace(uint8 race) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, race); } | |
| uint32 GetRaceMask() const { return 1 << (GetRace() - 1); } | |
| + uint32 getCFSRaceMask() const { return 1 << (GetRace(true) - 1); } | |
| uint8 GetClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); } | |
| void SetClass(uint8 unitClass) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, unitClass); } | |
| uint32 GetClassMask() const { return 1 << (GetClass() - 1); } | |
| diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp | |
| index 9245c22ec6..69700e257b 100644 | |
| --- a/src/server/game/Handlers/BattleGroundHandler.cpp | |
| +++ b/src/server/game/Handlers/BattleGroundHandler.cpp | |
| @@ -37,6 +37,7 @@ | |
| #include "Player.h" | |
| #include "World.h" | |
| #include "WorldPacket.h" | |
| +#include "Custom/Custom.h" | |
| void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) | |
| { | |
| @@ -295,14 +296,20 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvDa | |
| data << flagCarrierCount; | |
| if (allianceFlagCarrier) | |
| { | |
| - data << uint64(allianceFlagCarrier->GetGUID()); | |
| + if (allianceFlagCarrier->SendRealNameQuery()) | |
| + data << uint64(allianceFlagCarrier->GetGUID() + LIMIT_UINT32); | |
| + else | |
| + data << uint64(allianceFlagCarrier->GetGUID()); | |
| data << float(allianceFlagCarrier->GetPositionX()); | |
| data << float(allianceFlagCarrier->GetPositionY()); | |
| } | |
| if (hordeFlagCarrier) | |
| { | |
| - data << uint64(hordeFlagCarrier->GetGUID()); | |
| + if (hordeFlagCarrier->SendRealNameQuery()) | |
| + data << uint64(hordeFlagCarrier->GetGUID() + LIMIT_UINT32); | |
| + else | |
| + data << uint64(hordeFlagCarrier->GetGUID()); | |
| data << float(hordeFlagCarrier->GetPositionX()); | |
| data << float(hordeFlagCarrier->GetPositionY()); | |
| } | |
| @@ -567,7 +574,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) | |
| { | |
| // this line is checked, i only don't know if GetStartTime is changing itself after bg end! | |
| // send status in Battleground | |
| - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); | |
| + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetTeam()); | |
| SendPacket(&data); | |
| continue; | |
| } | |
| diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp | |
| index ed3923ca97..5821077d58 100644 | |
| --- a/src/server/game/Handlers/CharacterHandler.cpp | |
| +++ b/src/server/game/Handlers/CharacterHandler.cpp | |
| @@ -51,6 +51,8 @@ | |
| #include "SystemPackets.h" | |
| #include "QueryHolder.h" | |
| #include "World.h" | |
| +#include "Battleground.h" | |
| +#include "ArenaTeamMgr.h" | |
| class LoginQueryHolder : public CharacterDatabaseQueryHolder | |
| { | |
| @@ -998,7 +1000,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) | |
| sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin); | |
| TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName()); | |
| - | |
| + if (pCurrChar->GetTeam() != pCurrChar->getCFSRace()) | |
| + pCurrChar->FitPlayerInTeam(pCurrChar->GetBattleground() && !pCurrChar->GetBattleground()->isArena() ? true : false, pCurrChar->GetBattleground()); | |
| delete holder; | |
| } | |
| diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp | |
| index 91475ebbd7..44d73cf7e1 100644 | |
| --- a/src/server/game/Handlers/ChatHandler.cpp | |
| +++ b/src/server/game/Handlers/ChatHandler.cpp | |
| @@ -269,7 +269,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) | |
| if (!ValidateHyperlinksAndMaybeKick(msg)) | |
| return; | |
| } | |
| - | |
| + if (!GetPlayer()->IsGameMaster()) | |
| + if (GetPlayer()->SendBattleGroundChat(type, msg)) | |
| + return; | |
| switch (type) | |
| { | |
| case CHAT_MSG_SAY: | |
| diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp | |
| index 28c7d88f62..4b256d3b84 100644 | |
| --- a/src/server/game/Handlers/MovementHandler.cpp | |
| +++ b/src/server/game/Handlers/MovementHandler.cpp | |
| @@ -656,6 +656,20 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData) | |
| void WorldSession::HandleTimeSyncResp(WorldPacket& recvData) | |
| { | |
| + Battleground* bg = _player->GetBattleground(); | |
| + if (bg) | |
| + { | |
| + if (_player->ShouldForgetBGPlayers() && bg) | |
| + { | |
| + _player->DoForgetPlayersInBG(bg); | |
| + _player->SetForgetBGPlayers(false); | |
| + } | |
| + } | |
| + else if (_player->ShouldForgetInListPlayers()) | |
| + { | |
| + _player->DoForgetPlayersInList(); | |
| + _player->SetForgetInListPlayers(false); | |
| + } | |
| TC_LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP"); | |
| uint32 counter, clientTimestamp; | |
| diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp | |
| index bbff42acbe..943b66c761 100644 | |
| --- a/src/server/game/Handlers/QueryHandler.cpp | |
| +++ b/src/server/game/Handlers/QueryHandler.cpp | |
| @@ -48,7 +48,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) | |
| data << uint8(0); // name known | |
| data << nameData->Name; // played name | |
| data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds) | |
| - data << uint8(nameData->Race); | |
| + data << uint8(player ? player->GetRace() : nameData->Race); | |
| data << uint8(nameData->Sex); | |
| data << uint8(nameData->Class); | |
| diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp | |
| index 92551cf92e..ade0c56125 100644 | |
| --- a/src/server/game/World/World.cpp | |
| +++ b/src/server/game/World/World.cpp | |
| @@ -1217,6 +1217,7 @@ void World::LoadConfigSettings(bool reload) | |
| m_float_configs[CONFIG_ARENA_MATCHMAKER_RATING_MODIFIER] = sConfigMgr->GetFloatDefault("Arena.ArenaMatchmakerRatingModifier", 24.0f); | |
| m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true); | |
| + m_bool_configs[BATTLEGROUND_CROSSFACTION_ENABLED] = sConfigMgr->GetBoolDefault("CrossfactionBG.enable", true); | |
| m_int_configs[CONFIG_CREATURE_PICKPOCKET_REFILL] = sConfigMgr->GetIntDefault("Creature.PickPocketRefillDelay", 10 * MINUTE); | |
| m_int_configs[CONFIG_CREATURE_STOP_FOR_PLAYER] = sConfigMgr->GetIntDefault("Creature.MovingStopTimeForPlayer", 3 * MINUTE * IN_MILLISECONDS); | |
| diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h | |
| index 3765fb81e3..579ed40e72 100644 | |
| --- a/src/server/game/World/World.h | |
| +++ b/src/server/game/World/World.h | |
| @@ -177,6 +177,7 @@ enum WorldBoolConfigs | |
| CONFIG_CACHE_DATA_QUERIES, | |
| CONFIG_CHECK_GOBJECT_LOS, | |
| CONFIG_RESPAWN_DYNAMIC_ESCORTNPC, | |
| + BATTLEGROUND_CROSSFACTION_ENABLED, | |
| BOOL_CONFIG_VALUE_COUNT | |
| }; | |
| diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist | |
| index fa0ddf42a7..889f33eaab 100644 | |
| --- a/src/server/worldserver/worldserver.conf.dist | |
| +++ b/src/server/worldserver/worldserver.conf.dist | |
| @@ -4077,3 +4077,13 @@ Metric.OverallStatusInterval = 1 | |
| # | |
| ################################################################################################### | |
| +# CROSSFACTION BG CONFIG | |
| +# Enable Crossfaction battleground | |
| +# Default: 1 - on | |
| +# 0 - off | |
| +# Discord : Ac_Dev#8552 | |
| +# | |
| + | |
| +CrossfactionBG.enable = 1 | |
| + | |
| +################################################################################################### | |
| -- | |
| 2.26.0.windows.1 | |
where exactly i said that it's my 'release' ?
i just updated the original patch by Lillecarl for last trinitycore rev
emu-devstore can suck everyone's dick, does emu-devstore made it? no. LittleCarl made it!
WTF @Adeer . its for me :D
go away
gj
@Adeer Are you seriously trying to claim this as "yours"? That's just pathetic.
Problems aplying on last trinitycore commit 5b355c57baf1c06082f78fd311f87a18fa0d257e
Salam Mishe Id Telegrametono Bedin ? Kare Vajebi Daram
How do i apply the diff? trailing white space :( ? PLEASE ASSIST :D
@Lillecarl Can you help me apply to latest trinity rev 3.3.5 ?
trailing white space
@irancore can you please assist me ? :)
; / desperate... must I manually add?
Line 597 - Pointer to incomplete class type is not allowed? please assist?
@nyhmii include WorldSession.h in custom.cpp your problem will be fix
@simpatiaga https://t.me/Amr721
hello can you update this to latest revision please i have allots of errors ; (
i almost fixed all but i'm stuck, with pCurrChar->GetBattleground error on Characterhandler
updated again <
@irancore
Hi. Is this script actually working on Last Trinitycore Révision without bug ?
Delete, not your release. Stolen from emu-devstore.com.