kusanagy

[PATCH] crossfaction_battleground Rev63 Update

Dec 3rd, 2017
691
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 79.92 KB | None | 0 0
  1. From 05af526143c365d0af4ee43408a79b0957bbe2cd Mon Sep 17 00:00:00 2001
  2. From: irancore <[email protected]>
  3. Date: Sat, 23 Sep 2017 17:52:39 +0330
  4. Subject: [PATCH] crossfaction battleground
  5.  
  6. ---
  7. sql/av_fix.sql                                     |   3 +
  8.  src/server/database/Database/MySQLConnection.cpp   |   4 +-
  9.  src/server/game/Battlegrounds/Arena.cpp            |   4 +-
  10.  src/server/game/Battlegrounds/Battleground.cpp     |  58 ++--
  11.  src/server/game/Battlegrounds/Battleground.h       |   2 +-
  12.  src/server/game/Battlegrounds/BattlegroundMgr.cpp  |   2 +-
  13.  .../game/Battlegrounds/BattlegroundQueue.cpp       |  84 ++++--
  14.  src/server/game/Battlegrounds/BattlegroundQueue.h  |  11 +-
  15.  .../game/Battlegrounds/Zones/BattlegroundAB.cpp    |   2 +-
  16.  .../game/Battlegrounds/Zones/BattlegroundAV.cpp    |  19 +-
  17.  .../game/Battlegrounds/Zones/BattlegroundWS.cpp    |   3 +-
  18.  src/server/game/Custom/Custom.cpp                  | 322 +++++++++++++++++++++
  19.  src/server/game/Custom/Custom.h                    |  36 +++
  20.  src/server/game/Entities/Player/Player.cpp         | 125 +++++---
  21.  src/server/game/Entities/Player/Player.h           |  37 ++-
  22.  src/server/game/Entities/Unit/Unit.cpp             |  17 +-
  23.  src/server/game/Entities/Unit/Unit.h               |   4 +-
  24.  src/server/game/Handlers/BattleGroundHandler.cpp   |  15 +-
  25.  src/server/game/Handlers/CharacterHandler.cpp      |   6 +
  26.  src/server/game/Handlers/ChatHandler.cpp           |  25 +-
  27.  src/server/game/Handlers/MiscHandler.cpp           |  15 +
  28.  src/server/game/Handlers/QueryHandler.cpp          |   2 +-
  29.  src/server/game/World/World.cpp                    |   4 +-
  30.  src/server/game/World/World.h                      |   1 +
  31.  src/server/worldserver/worldserver.conf.dist       |  12 +
  32.  25 files changed, 695 insertions(+), 118 deletions(-)
  33.  create mode 100644 sql/av_fix.sql
  34.  create mode 100644 src/server/game/Custom/Custom.cpp
  35.  create mode 100644 src/server/game/Custom/Custom.h
  36.  
  37. diff --git a/sql/av_fix.sql b/sql/av_fix.sql
  38. new file mode 100644
  39. index 0000000000..02c5ee1bcc
  40. --- /dev/null
  41. +++ b/sql/av_fix.sql
  42. @@ -0,0 +1,3 @@
  43. +UPDATE creature_template SET faction = 1 WHERE entry IN (4255,4257,5134,5135,5139,11948,11949,11997,12050,12096,12127,13086,13096,13138,13216,13257,13296,13298,13299,13317,13318,13319,13320,13326,13327,13331,13422,13437,13438,13439,13442,13443,13447,13546,13576,13577,13598,13617,13797,14187,14188,14284,14762,14763,14765,14766,14768,14769,12047,13396,13358,13080,13078);
  44. +
  45. +UPDATE creature_template SET faction = 2 WHERE entry IN (2225,3343,3625,10364,10367,11946,11947,11998,12051,12052,12053,12097,12121,12122,13088,13089,13097,13137,13140,13143,13144,13145,13146,13147,13152,13153,13154,13176,13179,13180,13181,13218,13236,13284,13316,13359,13377,13397,13425,13428,13441,13448,13536,13539,13545,13597,13616,13618,13798,14185,14186,14282,14285,14772,14773,14774,14775,14776,14777,13332,13099,13079);
  46. \ No newline at end of file
  47. diff --git a/src/server/database/Database/MySQLConnection.cpp b/src/server/database/Database/MySQLConnection.cpp
  48. index 75e6362f87..8198d7f71a 100644
  49. --- a/src/server/database/Database/MySQLConnection.cpp
  50. +++ b/src/server/database/Database/MySQLConnection.cpp
  51. @@ -572,8 +572,8 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo, uint8 attempts /*= 5*/)
  52.          case ER_BAD_FIELD_ERROR:
  53.          case ER_NO_SUCH_TABLE:
  54.              TC_LOG_ERROR("sql.sql", "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
  55. -            std::this_thread::sleep_for(std::chrono::seconds(10));
  56. -            std::abort();
  57. +            //std::this_thread::sleep_for(std::chrono::seconds(10));
  58. +            //std::abort();
  59.              return false;
  60.          case ER_PARSE_ERROR:
  61.              TC_LOG_ERROR("sql.sql", "Error while parsing SQL. Core fix required.");
  62. diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
  63. index b9ec40c7f1..a7d92b6b82 100644
  64. --- a/src/server/game/Battlegrounds/Arena.cpp
  65. +++ b/src/server/game/Battlegrounds/Arena.cpp
  66. @@ -74,9 +74,9 @@ Arena::Arena()
  67.  void Arena::AddPlayer(Player* player)
  68.  {
  69.      Battleground::AddPlayer(player);
  70. -    PlayerScores[player->GetGUID().GetCounter()] = new ArenaScore(player->GetGUID(), player->GetBGTeam());
  71. +    PlayerScores[player->GetGUID().GetCounter()] = new ArenaScore(player->GetGUID(), player->GetTeam());
  72.  
  73. -    if (player->GetBGTeam() == ALLIANCE)        // gold
  74. +    if (player->GetTeam() == ALLIANCE)        // gold
  75.      {
  76.          if (player->GetTeam() == HORDE)
  77.              player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true);
  78. diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
  79. index e184c22354..d4cde3f8cb 100644
  80. --- a/src/server/game/Battlegrounds/Battleground.cpp
  81. +++ b/src/server/game/Battlegrounds/Battleground.cpp
  82. @@ -309,7 +309,7 @@ inline void Battleground::_CheckSafePositions(uint32 diff)
  83.                      continue;
  84.  
  85.                  Position pos = player->GetPosition();
  86. -                Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetBGTeam()));
  87. +                Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetTeam()));
  88.                  if (pos.GetExactDistSq(startPos) > maxDist)
  89.                  {
  90.                      TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId());
  91. @@ -525,7 +525,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
  92.                      WorldPacket status;
  93.                      BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType());
  94.                      uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
  95. -                    sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam());
  96. +                    sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetTeam());
  97.                      player->SendDirectMessage(&status);
  98.  
  99.                      player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
  100. @@ -689,22 +689,37 @@ void Battleground::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
  101.              UpdatePlayerScore(player, SCORE_BONUS_HONOR, Honor);
  102.  }
  103.  
  104. -void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
  105. +void Battleground::RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamID)
  106.  {
  107. -    FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
  108. -    if (!factionEntry)
  109. -        return;
  110. +    FactionEntry const* a_factionEntry = sFactionStore.LookupEntry(a_faction_id);
  111. +    FactionEntry const* h_factionEntry = sFactionStore.LookupEntry(h_faction_id);
  112.  
  113.      for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
  114.      {
  115.          Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam");
  116. -        if (!player)
  117. -            continue;
  118. +       if (!a_factionEntry || !h_factionEntry)
  119. +             return;
  120.  
  121. -        uint32 repGain = Reputation;
  122. -        AddPct(repGain, player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN));
  123. -        AddPct(repGain, player->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction_id));
  124. -        player->GetReputationMgr().ModifyReputation(factionEntry, repGain);
  125. +        for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
  126. +             {
  127. +            if (itr->second.OfflineRemoveTime)
  128. +                 continue;
  129. +            
  130. +                Player* player = ObjectAccessor::FindPlayer(itr->first);
  131. +            
  132. +                if (!player)
  133. +                 {
  134. +                TC_LOG_ERROR("bg.battleground", "BattleGround:RewardReputationToTeam: %u not found!", itr->first);
  135. +                continue;
  136. +                }
  137. +            uint32 team = player->GetTeam();
  138. +            if (team == TeamID)
  139. +                
  140. +                if (Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam"))
  141. +                 {
  142. +                player->GetReputationMgr().ModifyReputation(player->GetCFSTeam() == ALLIANCE ? a_factionEntry : h_factionEntry, Reputation);
  143. +                }
  144. +            }
  145.      }
  146.  }
  147.  
  148. @@ -858,7 +873,7 @@ void Battleground::EndBattleground(uint32 winner)
  149.          player->SendDirectMessage(&pvpLogData);
  150.  
  151.          WorldPacket data;
  152. -        sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam());
  153. +        sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetTeam());
  154.          player->SendDirectMessage(&data);
  155.          player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, player->GetMapId());
  156.      }
  157. @@ -977,6 +992,9 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen
  158.  
  159.      if (player)
  160.      {
  161. +       if (!player->IsPlayingNative())
  162. +       player->AddAura(44311, player);
  163. +       player->FitPlayerInTeam(false, this);
  164.          // Do next only if found in battleground
  165.          player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE);  // We're not in BG.
  166.          // reset destination bg team
  167. @@ -1048,7 +1066,7 @@ void Battleground::AddPlayer(Player* player)
  168.  
  169.      // score struct must be created in inherited class
  170.  
  171. -    uint32 team = player->GetBGTeam();
  172. +    uint32 team = player->GetTeam();
  173.  
  174.      BattlegroundPlayer bp;
  175.      bp.OfflineRemoveTime = 0;
  176. @@ -1090,6 +1108,7 @@ void Battleground::AddPlayer(Player* player)
  177.      // setup BG group membership
  178.      PlayerAddedToBGCheckIfBGIsRunning(player);
  179.      AddOrSetPlayerToCorrectBgGroup(player, team);
  180. +   player->FitPlayerInTeam(true, this);
  181.  }
  182.  
  183.  // this method adds player to his team's bg group, or sets his correct group if player is already in bg group
  184. @@ -1148,7 +1167,8 @@ void Battleground::EventPlayerLoggedOut(Player* player)
  185.      ObjectGuid guid = player->GetGUID();
  186.      if (!IsPlayerInBattleground(guid))  // Check if this player really is in battleground (might be a GM who teleported inside)
  187.          return;
  188. -
  189. +   if (!player->IsPlayingNative())
  190. +       player->AddAura(44311, player);
  191.      // player is correct pointer, it is checked in WorldSession::LogoutPlayer()
  192.      m_OfflineQueue.push_back(player->GetGUID());
  193.      m_Players[guid].OfflineRemoveTime = GameTime::GetGameTime() + MAX_OFFLINE_TIME;
  194. @@ -1159,8 +1179,8 @@ void Battleground::EventPlayerLoggedOut(Player* player)
  195.  
  196.          // 1 player is logging out, if it is the last, then end arena!
  197.          if (isArena())
  198. -            if (GetAlivePlayersCountByTeam(player->GetBGTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetBGTeam())))
  199. -                EndBattleground(GetOtherTeam(player->GetBGTeam()));
  200. +            if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam())))
  201. +                 EndBattleground(GetOtherTeam(player->GetTeam()));
  202.      }
  203.  }
  204.  
  205. @@ -1793,8 +1813,8 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
  206.      BuildPvPLogDataPacket(data);
  207.      player->SendDirectMessage(&data);
  208.  
  209. -    sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam());
  210. -    player->SendDirectMessage(&data);
  211. +     sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetTeam());
  212. +     player->SendDirectMessage(&data);
  213.  }
  214.  
  215.  uint32 Battleground::GetAlivePlayersCountByTeam(uint32 Team) const
  216. diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
  217. index b19d9c470b..8b1be7281b 100644
  218. --- a/src/server/game/Battlegrounds/Battleground.h
  219. +++ b/src/server/game/Battlegrounds/Battleground.h
  220. @@ -365,7 +365,7 @@ class TC_GAME_API Battleground
  221.          void CastSpellOnTeam(uint32 SpellID, uint32 TeamID);
  222.          void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID);
  223.          void RewardHonorToTeam(uint32 Honor, uint32 TeamID);
  224. -        void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID);
  225. +        void RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamID);
  226.          void UpdateWorldState(uint32 Field, uint32 Value);
  227.          void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player);
  228.          virtual void EndBattleground(uint32 winner);
  229. diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  230. index 728af4fbc8..5f8f848e57 100644
  231. --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  232. +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  233. @@ -711,7 +711,7 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt
  234.      if (Battleground* bg = GetBattleground(instanceId, bgTypeId))
  235.      {
  236.          uint32 mapid = bg->GetMapId();
  237. -        uint32 team = player->GetBGTeam();
  238. +        uint32 team = player->GetTeam();
  239.          if (team == 0)
  240.              team = player->GetTeam();
  241.  
  242. diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  243. index ea83422c20..fe30081156 100644
  244. --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  245. +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  246. @@ -158,8 +158,12 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
  247.          index += BG_TEAMS_COUNT;
  248.      if (ginfo->Team == HORDE)
  249.          index++;
  250. -    TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index);
  251. +  
  252. +   if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && ArenaType == 0)
  253. +    index = BG_QUEUE_CROSSFACTION;
  254.  
  255. +    TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index);
  256. +  
  257.      uint32 lastOnlineTime = GameTime::GetGameTimeMS();
  258.  
  259.      //announce world (this don't need mutex)
  260. @@ -202,30 +206,58 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
  261.          {
  262.              if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId))
  263.              {
  264. -                uint32 MinPlayers = bg->GetMinPlayersPerTeam();
  265. -                uint32 qHorde = 0;
  266. -                uint32 qAlliance = 0;
  267. -                uint32 q_min_level = bracketEntry->minLevel;
  268. -                uint32 q_max_level = bracketEntry->maxLevel;
  269. -                GroupsQueueType::const_iterator itr;
  270. -                for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
  271. -                    if (!(*itr)->IsInvitedToBGInstanceGUID)
  272. -                        qAlliance += (*itr)->Players.size();
  273. -                for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
  274. -                    if (!(*itr)->IsInvitedToBGInstanceGUID)
  275. -                        qHorde += (*itr)->Players.size();
  276. -
  277. -                // Show queue status to player only (when joining queue)
  278. -                if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
  279. +               if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED))
  280.                  {
  281. -                    ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bg->GetName().c_str(), q_min_level, q_max_level,
  282. -                        qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  283. +                    char const* bgName = bg->GetName().c_str();
  284. +                    uint32 MinPlayers = bg->GetMinPlayersPerTeam() * 2;
  285. +                    uint32 qPlayers = 0;
  286. +                    uint32 q_min_level = bracketEntry->minLevel;
  287. +                    uint32 q_max_level = bracketEntry->maxLevel;
  288. +                    for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracketId][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_CROSSFACTION].end(); ++itr)
  289. +                         if (!(*itr)->IsInvitedToBGInstanceGUID)
  290. +                         qPlayers += (*itr)->Players.size();
  291. +                    
  292. +                        if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
  293. +                         {
  294. +                        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);
  295. +                        }
  296. +                    else
  297. +                         {
  298. +                        std::ostringstream ss;
  299. +                        ss << "|cffff0000[BG Queue Announcer]:|r " << bgName << " -- [" << q_min_level << "-" << q_max_level << "] " << qPlayers << "/" << MinPlayers;
  300. +                        sWorld->SendGlobalText(ss.str().c_str(), NULL);
  301. +                        }
  302.                  }
  303.                  // System message
  304.                  else
  305.                  {
  306. -                    sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bg->GetName().c_str(), q_min_level, q_max_level,
  307. -                        qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  308. +                    //      std::string bgName = bg->GetName().c_str();
  309. +                    char const* bgName = bg->GetName().c_str();
  310. +                    uint32 MinPlayers = bg->GetMinPlayersPerTeam();
  311. +                    uint32 qHorde = 0;
  312. +                    uint32 qAlliance = 0;
  313. +                    uint32 q_min_level = bracketEntry->minLevel;
  314. +                    uint32 q_max_level = bracketEntry->maxLevel;
  315. +                    GroupsQueueType::const_iterator itr;
  316. +                    for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
  317. +                         if (!(*itr)->IsInvitedToBGInstanceGUID)
  318. +                        qAlliance += (*itr)->Players.size();
  319. +                    for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
  320. +                         if (!(*itr)->IsInvitedToBGInstanceGUID)
  321. +                        qHorde += (*itr)->Players.size();
  322. +                    
  323. +                                                               // Show queue status to player only (when joining queue)
  324. +                        if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
  325. +                        {
  326. +                        ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, //******
  327. +                            qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  328. +                        }
  329. +                              // System message
  330. +                        else
  331. +                         {
  332. +                        sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level, //*******
  333. +                            qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  334. +                        }
  335.                  }
  336.              }
  337.          }
  338. @@ -313,7 +345,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
  339.      {
  340.          //we must check premade and normal team's queue - because when players from premade are joining bg,
  341.          //they leave groupinfo so we can't use its players size to find out index
  342. -        for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_TEAMS_COUNT)
  343. +        for (uint8 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j)
  344.          {
  345.              GroupsQueueType::iterator k = m_QueuedGroups[bracket_id_tmp][j].begin();
  346.              for (; k != m_QueuedGroups[bracket_id_tmp][j].end(); ++k)
  347. @@ -503,6 +535,10 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId
  348.      int32 aliFree   = bg->GetFreeSlotsForTeam(ALLIANCE);
  349.      uint32 aliCount   = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
  350.      uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
  351. +  
  352. +    if (!bg->isArena())
  353. +         if (FillXPlayersToBG(bracket_id, bg, false))
  354. +         return;
  355.  
  356.      // try to get even teams
  357.      if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_EVEN)
  358. @@ -777,7 +813,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
  359.      if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
  360.          m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() &&
  361.          m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
  362. -        m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty())
  363. +        m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty() &&
  364. +        m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].empty())
  365.          return;
  366.  
  367.      // battleground with free slot for player should be always in the beggining of the queue
  368. @@ -868,7 +905,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
  369.      {
  370.          // if there are enough players in pools, start new battleground or non rated arena
  371.          if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)
  372. -            || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)))
  373. +        || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam))
  374. +        || CheckCrossFactionMatch(bracket_id, bg_template))
  375.          {
  376.              // we successfully created a pool
  377.              Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false);
  378. diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h
  379. index f73573013c..e754ebe9f7 100644
  380. --- a/src/server/game/Battlegrounds/BattlegroundQueue.h
  381. +++ b/src/server/game/Battlegrounds/BattlegroundQueue.h
  382. @@ -42,6 +42,7 @@ struct GroupQueueInfo                                       // stores informatio
  383.  {
  384.      std::map<ObjectGuid, PlayerQueueInfo*> Players;         // player queue info map
  385.      uint32  Team;                                           // Player team (ALLIANCE/HORDE)
  386. +   uint32  CFSTeam;
  387.      BattlegroundTypeId BgTypeId;                            // battleground type id
  388.      bool    IsRated;                                        // rated
  389.      uint8   ArenaType;                                      // 2v2, 3v3, 5v5 or 0 when BG
  390. @@ -60,9 +61,10 @@ enum BattlegroundQueueGroupTypes
  391.      BG_QUEUE_PREMADE_ALLIANCE   = 0,
  392.      BG_QUEUE_PREMADE_HORDE      = 1,
  393.      BG_QUEUE_NORMAL_ALLIANCE    = 2,
  394. -    BG_QUEUE_NORMAL_HORDE       = 3
  395. +    BG_QUEUE_NORMAL_HORDE = 3,
  396. +    BG_QUEUE_CROSSFACTION = 4
  397.  };
  398. -#define BG_QUEUE_GROUP_TYPES_COUNT 4
  399. +#define BG_QUEUE_GROUP_TYPES_COUNT 5
  400.  
  401.  enum BattlegroundQueueInvitationType
  402.  {
  403. @@ -80,6 +82,11 @@ class TC_GAME_API BattlegroundQueue
  404.  
  405.          void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
  406.          void UpdateEvents(uint32 diff);
  407. +      
  408. +        bool FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start = false);
  409. +        typedef std::multimap<int32, GroupQueueInfo*> QueuedGroupMap;
  410. +        int32 PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam);
  411. +        bool CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg);
  412.  
  413.          void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id);
  414.          bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
  415. diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
  416. index 6ef3bbcc3c..d80456ba75 100644
  417. --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
  418. +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
  419. @@ -151,7 +151,7 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff)
  420.  
  421.                  if (m_ReputationScoreTics[team] >= m_ReputationTics)
  422.                  {
  423. -                    (team == TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
  424. +                    RewardReputationToTeam(509, 510, 10, team == ALLIANCE ? ALLIANCE : HORDE);
  425.                      m_ReputationScoreTics[team] -= m_ReputationTics;
  426.                  }
  427.  
  428. diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
  429. index fc2bee156e..3ead97496e 100644
  430. --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
  431. +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
  432. @@ -98,7 +98,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  433.      if (entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS])
  434.      {
  435.          CastSpellOnTeam(23658, HORDE); //this is a spell which finishes a quest where a player has to kill the boss
  436. -        RewardReputationToTeam(729, BG_AV_REP_BOSS, HORDE);
  437. +        RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  438.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), HORDE);
  439.          EndBattleground(HORDE);
  440.          DelCreature(AV_CPLACE_TRIGGER17);
  441. @@ -106,7 +106,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  442.      else if (entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS])
  443.      {
  444.          CastSpellOnTeam(23658, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss
  445. -        RewardReputationToTeam(730, BG_AV_REP_BOSS, ALLIANCE);
  446. +        RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  447.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), ALLIANCE);
  448.          EndBattleground(ALLIANCE);
  449.          DelCreature(AV_CPLACE_TRIGGER19);
  450. @@ -119,7 +119,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  451.              return;
  452.          }
  453.          m_CaptainAlive[0]=false;
  454. -        RewardReputationToTeam(729, BG_AV_REP_CAPTAIN, HORDE);
  455. +        RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  456.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE);
  457.          UpdateScore(ALLIANCE, (-1)*BG_AV_RES_CAPTAIN);
  458.          //spawn destroyed aura
  459. @@ -138,7 +138,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  460.              return;
  461.          }
  462.          m_CaptainAlive[1]=false;
  463. -        RewardReputationToTeam(730, BG_AV_REP_CAPTAIN, ALLIANCE);
  464. +        RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  465.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE);
  466.          UpdateScore(HORDE, (-1)*BG_AV_RES_CAPTAIN);
  467.          //spawn destroyed aura
  468. @@ -160,6 +160,7 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
  469.      if (GetStatus() != STATUS_IN_PROGRESS)
  470.          return;//maybe we should log this, cause this must be a cheater or a big bug
  471.      uint8 team = GetTeamIndexByTeamId(player->GetTeam());
  472. +   uint8 CFSteam = GetTeamIndexByTeamId(GetOtherTeam(player->GetTeam()));
  473.      /// @todo add reputation, events (including quest not available anymore, next quest available, go/npc de/spawning)and maybe honor
  474.      TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed", questid);
  475.      switch (questid)
  476. @@ -184,21 +185,21 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
  477.          case AV_QUEST_A_COMMANDER1:
  478.          case AV_QUEST_H_COMMANDER1:
  479.              m_Team_QuestStatus[team][1]++;
  480. -            RewardReputationToTeam(team, 1, player->GetTeam());
  481. +            RewardReputationToTeam(team, CFSteam, 1, player->GetTeam());
  482.              if (m_Team_QuestStatus[team][1] == 30)
  483.                  TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
  484.              break;
  485.          case AV_QUEST_A_COMMANDER2:
  486.          case AV_QUEST_H_COMMANDER2:
  487.              m_Team_QuestStatus[team][2]++;
  488. -            RewardReputationToTeam(team, 1, player->GetTeam());
  489. +            RewardReputationToTeam(team, CFSteam, 1, player->GetTeam());
  490.              if (m_Team_QuestStatus[team][2] == 60)
  491.                  TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
  492.              break;
  493.          case AV_QUEST_A_COMMANDER3:
  494.          case AV_QUEST_H_COMMANDER3:
  495.              m_Team_QuestStatus[team][3]++;
  496. -            RewardReputationToTeam(team, 1, player->GetTeam());
  497. +            RewardReputationToTeam(team, CFSteam, 1, player->GetTeam());
  498.              if (m_Team_QuestStatus[team][3] == 120)
  499.                  TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
  500.              break;
  501. @@ -480,7 +481,7 @@ void BattlegroundAV::EndBattleground(uint32 winner)
  502.              rep[i]   += BG_AV_REP_SURVIVING_CAPTAIN;
  503.          }
  504.          if (rep[i] != 0)
  505. -            RewardReputationToTeam(i == 0 ? 730 : 729, rep[i], i == 0 ? ALLIANCE : HORDE);
  506. +            RewardReputationToTeam(729, 730, 10, i == ALLIANCE ? ALLIANCE : HORDE);
  507.          if (kills[i] != 0)
  508.              RewardHonorToTeam(GetBonusHonorFromKill(kills[i]), i == 0 ? ALLIANCE : HORDE);
  509.      }
  510. @@ -585,7 +586,7 @@ void BattlegroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
  511.              SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10), RESPAWN_IMMEDIATELY);
  512.  
  513.          UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, -1 * BG_AV_RES_TOWER);
  514. -        RewardReputationToTeam(owner == ALLIANCE ? 730 : 729, BG_AV_REP_TOWER, owner);
  515. +        RewardReputationToTeam(729, 730, BG_AV_REP_TOWER, owner);
  516.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), owner);
  517.  
  518.          SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp), RESPAWN_ONE_DAY);
  519. diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
  520. index 0129197e9e..24700cc199 100644
  521. --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
  522. +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
  523. @@ -317,7 +317,6 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
  524.          if (GetTeamScore(TEAM_ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
  525.              AddPoint(ALLIANCE, 1);
  526.          PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
  527. -        RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
  528.      }
  529.      else
  530.      {
  531. @@ -336,8 +335,8 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
  532.          if (GetTeamScore(TEAM_HORDE) < BG_WS_MAX_TEAM_SCORE)
  533.              AddPoint(HORDE, 1);
  534.          PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
  535. -        RewardReputationToTeam(889, m_ReputationCapture, HORDE);
  536.      }
  537. +   RewardReputationToTeam(890, 889, m_ReputationCapture, player->GetTeam());
  538.      //for flag capture is reward 2 honorable kills
  539.      RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeam());
  540.  
  541. diff --git a/src/server/game/Custom/Custom.cpp b/src/server/game/Custom/Custom.cpp
  542. new file mode 100644
  543. index 0000000000..c289c18bc7
  544. --- /dev/null
  545. +++ b/src/server/game/Custom/Custom.cpp
  546. @@ -0,0 +1,322 @@
  547. +#include "Custom.h"
  548. +#include "Battleground.h"
  549. +#include "BattlegroundMgr.h"
  550. +#include "Player.h"
  551. +#include "Chat.h"
  552. +#include "BattlegroundQueue.h"
  553. +#include "World.h"
  554. +#include <cstdarg>
  555. +
  556. +uint8 Unit::getRace(bool forceoriginal) const
  557. +{
  558. +    if (GetTypeId() == TYPEID_PLAYER)
  559. +    {
  560. +        Player* pPlayer = ((Player*)this);
  561. +
  562. +        if (forceoriginal)
  563. +            return pPlayer->getCFSRace();
  564. +
  565. +        if (pPlayer->InArena())
  566. +            return GetByteValue(UNIT_FIELD_BYTES_0, 0);
  567. +
  568. +        if (!pPlayer->IsPlayingNative())
  569. +            return pPlayer->getFRace();
  570. +    }
  571. +
  572. +    return GetByteValue(UNIT_FIELD_BYTES_0, 0);
  573. +}
  574. +
  575. +bool Player::SendRealNameQuery()
  576. +{
  577. +    if (IsPlayingNative())
  578. +        return false;
  579. +
  580. +    WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10));
  581. +    data.appendPackGUID(GetGUID());                             // player guid
  582. +    data << uint8(0);                                       // added in 3.1; if > 1, then end of packet
  583. +    data << GetName();                                   // played name
  584. +    data << uint8(0);                                       // realm name for cross realm BG usage
  585. +    data << uint8(getCFSRace());
  586. +    data << uint8(getGender());
  587. +    data << uint8(getClass());
  588. +    data << uint8(0);                                   // is not declined
  589. +
  590. +    return true;
  591. +}
  592. +
  593. +void Player::SetFakeRace()
  594. +{
  595. +    m_FakeRace = GetCFSTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN;
  596. +}
  597. +
  598. +bool Player::SendBattleGroundChat(uint32 msgtype, std::string message)
  599. +{
  600. +    // Select distance to broadcast to.
  601. +    float distance = msgtype == CHAT_MSG_SAY ? sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY) : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL);
  602. +
  603. +    if (Battleground* pBattleGround = GetBattleground())
  604. +    {
  605. +        if (pBattleGround->isArena()) // Only fake chat in BG's. CFBG should not interfere with arenas.
  606. +            return false;
  607. +
  608. +        for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr)
  609. +        {
  610. +           if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first))
  611. +            {
  612. +                if (GetDistance2d(pPlayer->GetPositionX(), pPlayer->GetPositionY()) <= distance)
  613. +                {
  614. +                    WorldPacket data(SMSG_MESSAGECHAT, 200);
  615. +
  616. +                    if (GetTeam() == pPlayer->GetTeam())
  617. +                        BuildPlayerChat(&data, msgtype, message, LANG_UNIVERSAL);
  618. +                    else if (msgtype != CHAT_MSG_EMOTE)
  619. +                        BuildPlayerChat(&data, msgtype, message, pPlayer->GetTeam() == ALLIANCE ? LANG_ORCISH : LANG_COMMON);
  620. +
  621. +                    pPlayer->GetSession()->SendPacket(&data);
  622. +                }
  623. +            }
  624. +        }
  625. +        return true;
  626. +    }
  627. +    else
  628. +        return false;
  629. +}
  630. +
  631. +void Player::MorphFit(bool value)
  632. +{
  633. +    if (!IsPlayingNative() && value)
  634. +    {
  635. +        if (GetCFSTeam() == HORDE)
  636. +        {
  637. +            if (getGender() == GENDER_MALE)
  638. +            {
  639. +                SetDisplayId(19723);
  640. +                SetNativeDisplayId(19723);
  641. +            }
  642. +            else
  643. +            {
  644. +                SetDisplayId(19724);
  645. +                SetNativeDisplayId(19724);
  646. +            }
  647. +        }
  648. +        else
  649. +        {
  650. +            if (getGender() == GENDER_MALE)
  651. +            {
  652. +                SetDisplayId(20578);
  653. +                SetNativeDisplayId(20578);
  654. +            }
  655. +            else
  656. +            {
  657. +                SetDisplayId(20579);
  658. +                SetNativeDisplayId(20579);
  659. +            }
  660. +        }
  661. +    }
  662. +    else
  663. +        InitDisplayIds();
  664. +}
  665. +
  666. +void Player::FitPlayerInTeam(bool action, Battleground* pBattleGround)
  667. +{
  668. +    if (!pBattleGround)
  669. +        pBattleGround = GetBattleground();
  670. +
  671. +    if ((!pBattleGround || pBattleGround->isArena()) && action)
  672. +        return;
  673. +
  674. +    if(!IsPlayingNative() && action)
  675. +        setFactionForRace(getRace());
  676. +    else
  677. +        setFactionForRace(getCFSRace());
  678. +
  679. +    if (action)
  680. +        SetForgetBGPlayers(true);
  681. +    else
  682. +        SetForgetInListPlayers(true);
  683. +
  684. +    MorphFit(action);
  685. +
  686. +    if (pBattleGround && action)
  687. +        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());
  688. +}
  689. +
  690. +void Player::DoForgetPlayersInList()
  691. +{
  692. +    // m_FakePlayers is filled from a vector within the battleground
  693. +    // they were in previously so all players that have been in that BG will be invalidated.
  694. +    for (FakePlayers::const_iterator itr = m_FakePlayers.begin(); itr != m_FakePlayers.end(); ++itr)
  695. +    {
  696. +        WorldPacket data(SMSG_INVALIDATE_PLAYER, 8);
  697. +        data << *itr;
  698. +        GetSession()->SendPacket(&data);
  699. +       if (Player* pPlayer = ObjectAccessor::FindPlayer(ObjectGuid(*itr)))
  700. +            GetSession()->SendNameQueryOpcode(pPlayer->GetGUID());
  701. +    }
  702. +    m_FakePlayers.clear();
  703. +}
  704. +
  705. +void Player::DoForgetPlayersInBG(Battleground* pBattleGround)
  706. +{
  707. +    for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr)
  708. +    {
  709. +        // Here we invalidate players in the bg to the added player
  710. +        WorldPacket data1(SMSG_INVALIDATE_PLAYER, 8);
  711. +        data1 << itr->first;
  712. +        GetSession()->SendPacket(&data1);
  713. +
  714. +       if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first))
  715. +        {
  716. +            GetSession()->SendNameQueryOpcode(pPlayer->GetGUID()); // Send namequery answer instantly if player is available
  717. +            // Here we invalidate the player added to players in the bg
  718. +            WorldPacket data2(SMSG_INVALIDATE_PLAYER, 8);
  719. +            data2 << GetGUID();
  720. +            pPlayer->GetSession()->SendPacket(&data2);
  721. +            pPlayer->GetSession()->SendNameQueryOpcode(GetGUID());
  722. +        }
  723. +    }
  724. +}
  725. +
  726. +bool BattlegroundQueue::CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg)
  727. +{
  728. +    if (!sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) || bg->isArena())
  729. +        return false; // Only do this if crossbg's are enabled.
  730. +
  731. +    // Here we will add all players to selectionpool, later we check if there are enough and launch a bg.
  732. +    FillXPlayersToBG(bracket_id, bg, true);
  733. +
  734. +    if (sBattlegroundMgr->isTesting() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount()))
  735. +        return true;
  736. +
  737. +    uint8 MPT = bg->GetMinPlayersPerTeam();
  738. +    if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() < MPT || m_SelectionPools[TEAM_HORDE].GetPlayerCount() < MPT)
  739. +        return false;
  740. +
  741. +    return true;
  742. +}
  743. +
  744. +// This function will invite players in the least populated faction, which makes battleground queues much faster.
  745. +// This function will return true if cross faction battlegrounds are enabled, otherwise return false,
  746. +// which is useful in FillPlayersToBG. Because then we can interrupt the regular invitation if cross faction bg's are enabled.
  747. +bool BattlegroundQueue::FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start)
  748. +{
  749. +    uint8 queuedPeople = 0;
  750. +    for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr)
  751. +        if (!(*itr)->IsInvitedToBGInstanceGUID)
  752. +            queuedPeople += (*itr)->Players.size();
  753. +
  754. +    if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && (sBattlegroundMgr->isTesting() || queuedPeople >= bg->GetMinPlayersPerTeam()*2 || !start))
  755. +    {
  756. +        int32 aliFree   = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(ALLIANCE);
  757. +        int32 hordeFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(HORDE);
  758. +        // Empty selection pools. They will be refilled from queued groups.
  759. +        m_SelectionPools[TEAM_ALLIANCE].Init();
  760. +        m_SelectionPools[TEAM_HORDE].Init();
  761. +        int32 valiFree = aliFree;
  762. +        int32 vhordeFree = hordeFree;
  763. +        int32 diff = 0;
  764. +
  765. +
  766. +        // Add teams to their own factions as far as possible.
  767. +        if (start)
  768. +        {
  769. +            QueuedGroupMap m_PreGroupMap_a, m_PreGroupMap_h;
  770. +            int32 m_SmallestOfTeams = 0;
  771. +            int32 queuedAlliance = 0;
  772. +            int32 queuedHorde = 0;
  773. +
  774. +            for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr)
  775. +            {
  776. +                if ((*itr)->IsInvitedToBGInstanceGUID)
  777. +                    continue;
  778. +
  779. +                bool alliance = (*itr)->CFSTeam == ALLIANCE;
  780. +
  781. +                if (alliance)
  782. +                {
  783. +                    m_PreGroupMap_a.insert(std::make_pair((*itr)->Players.size(), *itr));
  784. +                    queuedAlliance += (*itr)->Players.size();
  785. +                }
  786. +                else
  787. +                {
  788. +                    m_PreGroupMap_h.insert(std::make_pair((*itr)->Players.size(), *itr));
  789. +                    queuedHorde += (*itr)->Players.size();
  790. +                }
  791. +            }
  792. +
  793. +            m_SmallestOfTeams = std::min(std::min(aliFree, queuedAlliance), std::min(hordeFree, queuedHorde));
  794. +
  795. +            valiFree -= PreAddPlayers(m_PreGroupMap_a, m_SmallestOfTeams, aliFree);
  796. +            vhordeFree -= PreAddPlayers(m_PreGroupMap_h, m_SmallestOfTeams, hordeFree);
  797. +        }
  798. +
  799. +        QueuedGroupMap m_QueuedGroupMap;
  800. +
  801. +        for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr)
  802. +            m_QueuedGroupMap.insert(std::make_pair((*itr)->Players.size(), *itr));
  803. +
  804. +        for (QueuedGroupMap::reverse_iterator itr = m_QueuedGroupMap.rbegin(); itr != m_QueuedGroupMap.rend(); ++itr)
  805. +        {
  806. +            GroupsQueueType allypool = m_SelectionPools[TEAM_ALLIANCE].SelectedGroups;
  807. +            GroupsQueueType hordepool = m_SelectionPools[TEAM_HORDE].SelectedGroups;
  808. +
  809. +            GroupQueueInfo* ginfo = itr->second;
  810. +
  811. +            // If player already was invited via pre adding (add to own team first) or he was already invited to a bg, skip.
  812. +            if (ginfo->IsInvitedToBGInstanceGUID ||
  813. +                std::find(allypool.begin(), allypool.end(), ginfo) != allypool.end() ||
  814. +                std::find(hordepool.begin(), hordepool.end(), ginfo) != hordepool.end() ||
  815. +                (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= bg->GetMinPlayersPerTeam() &&
  816. +                m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= bg->GetMinPlayersPerTeam()))
  817. +                continue;
  818. +
  819. +            diff = abs(valiFree - vhordeFree);
  820. +            bool moreAli = valiFree < vhordeFree;
  821. +
  822. +            if (diff > 0)
  823. +                ginfo->Team = moreAli ? HORDE : ALLIANCE;
  824. +
  825. +            bool alliance = ginfo->Team == ALLIANCE;
  826. +
  827. +            if (m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(ginfo, alliance ? aliFree : hordeFree))
  828. +                alliance ? valiFree -= ginfo->Players.size() : vhordeFree -= ginfo->Players.size();
  829. +        }
  830. +
  831. +        return true;
  832. +    }
  833. +    return false;
  834. +}
  835. +
  836. +int32 BattlegroundQueue::PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam)
  837. +{
  838. +    int32 LeftToAdd = MaxAdd;
  839. +    uint32 Added = 0;
  840. +
  841. +    for (QueuedGroupMap::reverse_iterator itr = m_PreGroupMap.rbegin(); itr != m_PreGroupMap.rend(); ++itr)
  842. +    {
  843. +        int32 PlayerSize = itr->first;
  844. +        bool alliance = itr->second->CFSTeam == ALLIANCE;
  845. +
  846. +        if (PlayerSize <= LeftToAdd && m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(itr->second, MaxInTeam))
  847. +            LeftToAdd -= PlayerSize, Added -= PlayerSize;
  848. +    }
  849. +
  850. +    return LeftToAdd;
  851. +}
  852. +
  853. +void Player::SendChatMessage(const char *format, ...)
  854. +{
  855. +    if (!IsInWorld())
  856. +        return;
  857. +
  858. +    if (format)
  859. +    {
  860. +        va_list ap;
  861. +        char str [2048];
  862. +        va_start(ap, format);
  863. +        vsnprintf(str, 2048, format, ap);
  864. +        va_end(ap);
  865. +
  866. +        ChatHandler(GetSession()).SendSysMessage(str);
  867. +    }
  868. +}
  869. \ No newline at end of file
  870. diff --git a/src/server/game/Custom/Custom.h b/src/server/game/Custom/Custom.h
  871. new file mode 100644
  872. index 0000000000..885faa094b
  873. --- /dev/null
  874. +++ b/src/server/game/Custom/Custom.h
  875. @@ -0,0 +1,36 @@
  876. +#ifndef _CUSTOM_H
  877. +#define _CUSTOM_H
  878. +
  879. +#define MSG_COLOR_LIGHTRED     "|cffff6060"
  880. +#define MSG_COLOR_LIGHTBLUE    "|cff00ccff"
  881. +#define MSG_COLOR_ANN_GREEN    "|c1f40af20"
  882. +#define MSG_COLOR_RED          "|cffff0000"
  883. +#define MSG_COLOR_GOLD         "|cffffcc00"
  884. +#define MSG_COLOR_SUBWHITE     "|cffbbbbbb"
  885. +#define MSG_COLOR_MAGENTA      "|cffff00ff"
  886. +#define MSG_COLOR_YELLOW       "|cffffff00"
  887. +#define MSG_COLOR_CYAN         "|cff00ffff"
  888. +#define MSG_COLOR_DARKBLUE     "|cff0000ff"
  889. +
  890. +#define MSG_COLOR_GREY         "|cff9d9d9d"
  891. +#define MSG_COLOR_WHITE        "|cffffffff"
  892. +#define MSG_COLOR_GREEN        "|cff1eff00"
  893. +#define MSG_COLOR_BLUE         "|cff0080ff"
  894. +#define MSG_COLOR_PURPLE       "|cffb048f8"
  895. +#define MSG_COLOR_ORANGE       "|cffff8000"
  896. +
  897. +#define MSG_COLOR_DRUID        "|cffff7d0a"
  898. +#define MSG_COLOR_HUNTER       "|cffabd473"
  899. +#define MSG_COLOR_MAGE         "|cff69ccf0"
  900. +#define MSG_COLOR_PALADIN      "|cfff58cba"
  901. +#define MSG_COLOR_PRIEST       "|cffffffff"
  902. +#define MSG_COLOR_ROGUE        "|cfffff569"
  903. +#define MSG_COLOR_SHAMAN       "|cff0070de"
  904. +#define MSG_COLOR_WARLOCK      "|cff9482c9"
  905. +#define MSG_COLOR_WARRIOR      "|cffc79c6e"
  906. +#define MSG_COLOR_DEATH_KNIGHT "|cffc41f3b"
  907. +#define MSG_COLOR_MONK         "|cff00ff96"
  908. +
  909. +#define LIMIT_UINT32 2147483647
  910. +
  911. +#endif
  912. \ No newline at end of file
  913. diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
  914. index c4e37394ca..49d7d9c99d 100644
  915. --- a/src/server/game/Entities/Player/Player.cpp
  916. +++ b/src/server/game/Entities/Player/Player.cpp
  917. @@ -165,6 +165,11 @@ uint32 const MAX_MONEY_AMOUNT = static_cast<uint32>(std::numeric_limits<int32>::
  918.  
  919.  Player::Player(WorldSession* session): Unit(true)
  920.  {
  921. +   m_FakeRace = 0;
  922. +    m_RealRace = 0;
  923. +    m_ForgetBGPlayers = false;
  924. +    m_ForgetInListPlayers = false;
  925. +
  926.      m_speakTime = 0;
  927.      m_speakCount = 0;
  928.  
  929. @@ -517,7 +522,12 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
  930.      SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, createInfo->Class);
  931.      SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, createInfo->Gender);
  932.      SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, powertype);
  933. -    InitDisplayIds();
  934. +   SetCFSRace();
  935. +    m_team = TeamForRace(getCFSRace());
  936. +    SetFakeRace(); // m_team must be set before this can be used.
  937. +    setFactionForRace(getCFSRace());
  938. +
  939. +   InitDisplayIds();
  940.      if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP)
  941.      {
  942.          SetByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_PVP);
  943. @@ -2581,7 +2591,7 @@ void Player::GiveLevel(uint8 level)
  944.          guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level);
  945.  
  946.      PlayerLevelInfo info;
  947. -    sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info);
  948. +    sObjectMgr->GetPlayerLevelInfo(getCFSRace(), getClass(), level, &info);
  949.  
  950.      PlayerClassLevelInfo classInfo;
  951.      sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo);
  952. @@ -2719,7 +2729,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
  953.      sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), &classInfo);
  954.  
  955.      PlayerLevelInfo info;
  956. -    sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), getLevel(), &info);
  957. +    sObjectMgr->GetPlayerLevelInfo(getCFSRace(), getClass(), getLevel(), &info);
  958.  
  959.      SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
  960.      SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(getLevel()));
  961. @@ -4482,6 +4492,8 @@ void Player::BuildPlayerRepop()
  962.      if (getRace() == RACE_NIGHTELF)
  963.          CastSpell(this, 20584, true);
  964.      CastSpell(this, 8326, true);
  965. +   if (!IsPlayingNative())
  966. +   CastSpell(this, 44311, true);
  967.  
  968.      // there must be SMSG.FORCE_RUN_SPEED_CHANGE, SMSG.FORCE_SWIM_SPEED_CHANGE, SMSG.MOVE_WATER_WALK
  969.      // there must be SMSG.STOP_MIRROR_TIMER
  970. @@ -4548,6 +4560,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
  971.      // This must be called always even on Players with race != RACE_NIGHTELF in case of faction change
  972.      RemoveAurasDueToSpell(20584);                           // RACE_NIGHTELF speed bonuses
  973.      RemoveAurasDueToSpell(8326);                            // SPELL_AURA_GHOST
  974. +   RemoveAurasDueToSpell(44311);                            
  975.  
  976.      if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0))
  977.          SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND);
  978. @@ -4663,7 +4676,7 @@ Corpse* Player::CreateCorpse()
  979.      // prevent the existence of 2 corpses for one player
  980.      SpawnCorpseBones();
  981.  
  982. -    uint32 _cfb1, _cfb2;
  983. +    uint32 _cfb1, _cfb2, _uf;
  984.  
  985.      Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE);
  986.      SetPvPDeath(false);
  987. @@ -4676,11 +4689,13 @@ Corpse* Player::CreateCorpse()
  988.  
  989.      _corpseLocation.WorldRelocate(*this);
  990.  
  991. +   _uf = getCFSRace();
  992.      uint8 skin = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID);
  993.      uint8 face = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID);
  994.      uint8 hairstyle = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID);
  995.      uint8 haircolor = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID);
  996.      uint8 facialhair = GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE);
  997. +   uint8 race       = (uint8) (_uf);
  998.  
  999.      _cfb1 = ((0x00) | (getRace() << 8) | (GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER) << 16) | (skin << 24));
  1000.      _cfb2 = ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24));
  1001. @@ -6473,10 +6488,10 @@ uint32 Player::TeamForRace(uint8 race)
  1002.  
  1003.  void Player::setFactionForRace(uint8 race)
  1004.  {
  1005. -    m_team = TeamForRace(race);
  1006. +   SetBGTeam(TeamForRace(race));
  1007.  
  1008.      ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race);
  1009. -    SetFaction(rEntry ? rEntry->FactionID : 0);
  1010. +   SetFaction(rEntry ? rEntry->FactionID : GetFaction());
  1011.  }
  1012.  
  1013.  ReputationRank Player::GetReputationRank(uint32 faction) const
  1014. @@ -6577,7 +6592,26 @@ void Player::RewardReputation(Unit* victim, float rate)
  1015.      ReputationOnKillEntry const* Rep = sObjectMgr->GetReputationOnKilEntry(victim->ToCreature()->GetCreatureTemplate()->Entry);
  1016.      if (!Rep)
  1017.          return;
  1018. +    uint32 repfaction1 = Rep->RepFaction1;
  1019. +    uint32 repfaction2 = Rep->RepFaction2;
  1020.  
  1021. +    if (!IsPlayingNative())
  1022. +    {
  1023. +        if (GetCFSTeam() == ALLIANCE)
  1024. +        {
  1025. +            if (repfaction1 == 729)
  1026. +                repfaction1 = 730;
  1027. +            if (repfaction2 == 729)
  1028. +                repfaction2 = 730;
  1029. +        }
  1030. +        else
  1031. +        {
  1032. +            if (repfaction1 == 730)
  1033. +                repfaction1 = 729;
  1034. +            if (repfaction2 == 730)
  1035. +                repfaction2 = 729;
  1036. +        }
  1037. +    }
  1038.      uint32 ChampioningFaction = 0;
  1039.  
  1040.      if (GetChampioningFaction())
  1041. @@ -6592,23 +6626,23 @@ void Player::RewardReputation(Unit* victim, float rate)
  1042.  
  1043.      uint32 team = GetTeam();
  1044.  
  1045. -    if (Rep->RepFaction1 && (!Rep->TeamDependent || team == ALLIANCE))
  1046. +    if (repfaction1 && (!Rep->TeamDependent || team == ALLIANCE))
  1047.      {
  1048. -        int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
  1049. +        int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : repfaction1);
  1050.          donerep1 = int32(donerep1 * rate);
  1051.  
  1052. -        FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
  1053. +        FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction1);
  1054.          uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1);
  1055.          if (factionEntry1)
  1056.              GetReputationMgr().ModifyReputation(factionEntry1, donerep1, current_reputation_rank1 > Rep->ReputationMaxCap1);
  1057.      }
  1058.  
  1059. -    if (Rep->RepFaction2 && (!Rep->TeamDependent || team == HORDE))
  1060. +    if (repfaction2 && (!Rep->TeamDependent || team == HORDE))
  1061.      {
  1062. -        int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
  1063. +        int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : repfaction2);
  1064.          donerep2 = int32(donerep2 * rate);
  1065.  
  1066. -        FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
  1067. +        FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction2);
  1068.          uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2);
  1069.          if (factionEntry2)
  1070.              GetReputationMgr().ModifyReputation(factionEntry2, donerep2, current_reputation_rank2 > Rep->ReputationMaxCap2);
  1071. @@ -6703,7 +6737,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
  1072.          if (!victim || victim == this || victim->GetTypeId() != TYPEID_PLAYER)
  1073.              return false;
  1074.  
  1075. -        if (GetBGTeam() == victim->ToPlayer()->GetBGTeam())
  1076. +        if (GetTeam() == victim->ToPlayer()->GetTeam())
  1077.              return false;
  1078.  
  1079.          return true;
  1080. @@ -7066,7 +7100,11 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
  1081.      // if player resurrected at teleport this will be applied in resurrect code
  1082.      if (IsAlive())
  1083.          DestroyZoneLimitedItem(true, newZone);
  1084. -
  1085. +  
  1086. +   if (newZone == 3277 || newZone == 3358 || newZone == 2597 || newZone == 3820 || newZone == 4710 || newZone == 4384)
  1087. +   AddAura(44311,this);   
  1088. +   RemoveAurasDueToSpell(44311);
  1089. +  
  1090.      // check some item equip limitations (in result lost CanTitanGrip at talent reset, for example)
  1091.      AutoUnequipOffhandIfNeed();
  1092.  
  1093. @@ -11641,11 +11679,11 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
  1094.      if (!proto)
  1095.          return EQUIP_ERR_ITEM_NOT_FOUND;
  1096.  
  1097. -    if (((proto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && GetTeam() != HORDE) ||
  1098. -        (((proto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && GetTeam() != ALLIANCE)))
  1099. +    if (((proto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && GetCFSTeam() != HORDE) ||
  1100. +        (((proto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && GetCFSTeam() != ALLIANCE)))
  1101.          return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
  1102.  
  1103. -    if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
  1104. +   if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getCFSRaceMask()) == 0)
  1105.          return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
  1106.  
  1107.      if (proto->RequiredSkill != 0)
  1108. @@ -17003,6 +17041,10 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
  1109.          TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong race/class (%u/%u), can't load.", guid.ToString().c_str(), getRace(), getClass());
  1110.          return false;
  1111.      }
  1112. +   SetCFSRace();
  1113. +    m_team = TeamForRace(getCFSRace());
  1114. +    SetFakeRace(); // m_team must be set before this can be used.
  1115. +    setFactionForRace(getCFSRace());
  1116.  
  1117.      SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8());
  1118.      SetUInt32Value(PLAYER_XP, fields[7].GetUInt32());
  1119. @@ -17071,11 +17113,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
  1120.  
  1121.      TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: Load Basic value of player '%s' is: ", m_name.c_str());
  1122.      outDebugValues();
  1123. -
  1124. -    //Need to call it to initialize m_team (m_team can be calculated from race)
  1125. -    //Other way is to saves m_team into characters table.
  1126. -    setFactionForRace(getRace());
  1127. -
  1128. +  
  1129.      // load home bind and check in same time class/race pair, it used later for restore broken positions
  1130.      if (!_LoadHomeBind(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_HOME_BIND)))
  1131.          return false;
  1132. @@ -19000,11 +19038,11 @@ void Player::AddInstanceEnterTime(uint32 instanceId, time_t enterTime)
  1133.  
  1134.  bool Player::_LoadHomeBind(PreparedQueryResult result)
  1135.  {
  1136. -    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  1137. +    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), getClass());
  1138.      if (!info)
  1139.      {
  1140.          TC_LOG_ERROR("entities.player", "Player::_LoadHomeBind: Player '%s' (%s) has incorrect race/class (%u/%u) pair. Can't load.",
  1141. -            GetGUID().ToString().c_str(), GetName().c_str(), uint32(getRace()), uint32(getClass()));
  1142. +            GetGUID().ToString().c_str(), GetName().c_str(), uint32(getCFSRace()), uint32(getClass()));
  1143.          return false;
  1144.      }
  1145.  
  1146. @@ -19101,7 +19139,7 @@ void Player::SaveToDB(bool create /*=false*/)
  1147.          stmt->setUInt32(index++, GetGUID().GetCounter());
  1148.          stmt->setUInt32(index++, GetSession()->GetAccountId());
  1149.          stmt->setString(index++, GetName());
  1150. -        stmt->setUInt8(index++, getRace());
  1151. +        stmt->setUInt8(index++, getCFSRace());
  1152.          stmt->setUInt8(index++, getClass());
  1153.          stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER));   // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
  1154.          stmt->setUInt8(index++, getLevel());
  1155. @@ -19211,7 +19249,7 @@ void Player::SaveToDB(bool create /*=false*/)
  1156.          // Update query
  1157.          stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER);
  1158.          stmt->setString(index++, GetName());
  1159. -        stmt->setUInt8(index++, getRace());
  1160. +        stmt->setUInt8(index++, getCFSRace());
  1161.          stmt->setUInt8(index++, getClass());
  1162.          stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER));   // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
  1163.          stmt->setUInt8(index++, getLevel());
  1164. @@ -21412,22 +21450,25 @@ void Player::InitDataForForm(bool reapplyMods)
  1165.  
  1166.  void Player::InitDisplayIds()
  1167.  {
  1168. -    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  1169. +    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), getClass());
  1170.      if (!info)
  1171.      {
  1172.          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());
  1173.          return;
  1174.      }
  1175. +    bool isMorphed = GetNativeDisplayId() != GetDisplayId();
  1176.  
  1177.      uint8 gender = GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER);
  1178.      switch (gender)
  1179.      {
  1180.          case GENDER_FEMALE:
  1181. -            SetDisplayId(info->displayId_f);
  1182. +            if (!isMorphed)
  1183. +               SetDisplayId(info->displayId_f);
  1184.              SetNativeDisplayId(info->displayId_f);
  1185.              break;
  1186.          case GENDER_MALE:
  1187. -            SetDisplayId(info->displayId_m);
  1188. +            if (!isMorphed)
  1189. +                SetDisplayId(info->displayId_m);
  1190.              SetNativeDisplayId(info->displayId_m);
  1191.              break;
  1192.          default:
  1193. @@ -22035,11 +22076,6 @@ void Player::SetBGTeam(uint32 team)
  1194.      SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_ARENA_FACTION, uint8(team == ALLIANCE ? 1 : 0));
  1195.  }
  1196.  
  1197. -uint32 Player::GetBGTeam() const
  1198. -{
  1199. -    return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam();
  1200. -}
  1201. -
  1202.  void Player::LeaveBattleground(bool teleportToEntryPoint)
  1203.  {
  1204.      if (Battleground* bg = GetBattleground())
  1205. @@ -22744,12 +22780,12 @@ void Player::LearnCustomSpells()
  1206.          return;
  1207.  
  1208.      // learn default race/class spells
  1209. -    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  1210. +    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), getClass());
  1211.      for (PlayerCreateInfoSpells::const_iterator itr = info->customSpells.begin(); itr != info->customSpells.end(); ++itr)
  1212.      {
  1213.          uint32 tspell = *itr;
  1214.          TC_LOG_DEBUG("entities.player.loading", "Player::LearnCustomSpells: Player '%s' (%s, Class: %u Race: %u): Adding initial spell (SpellID: %u)",
  1215. -            GetName().c_str(), GetGUID().ToString().c_str(), uint32(getClass()), uint32(getRace()), tspell);
  1216. +            GetName().c_str(), GetGUID().ToString().c_str(), uint32(getClass()), uint32(getCFSRace()), tspell);
  1217.          if (!IsInWorld())                                    // will send in INITIAL_SPELLS in list anyway at map add
  1218.              AddSpell(tspell, true, true, true, false);
  1219.          else                                                // but send in normal spell in game learn case
  1220. @@ -22760,7 +22796,7 @@ void Player::LearnCustomSpells()
  1221.  void Player::LearnDefaultSkills()
  1222.  {
  1223.      // learn default race/class skills
  1224. -    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  1225. +    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), getClass());
  1226.      for (PlayerCreateInfoSkills::const_iterator itr = info->skills.begin(); itr != info->skills.end(); ++itr)
  1227.      {
  1228.          uint32 skillId = itr->SkillId;
  1229. @@ -22773,11 +22809,11 @@ void Player::LearnDefaultSkills()
  1230.  
  1231.  void Player::LearnDefaultSkill(uint32 skillId, uint16 rank)
  1232.  {
  1233. -    SkillRaceClassInfoEntry const* rcInfo = GetSkillRaceClassInfo(skillId, getRace(), getClass());
  1234. +    SkillRaceClassInfoEntry const* rcInfo = GetSkillRaceClassInfo(skillId, getCFSRace(), getClass());
  1235.      if (!rcInfo)
  1236.          return;
  1237.  
  1238. -    TC_LOG_DEBUG("entities.player.loading", "PLAYER (Class: %u Race: %u): Adding initial skill, id = %u", uint32(getClass()), uint32(getRace()), skillId);
  1239. +    TC_LOG_DEBUG("entities.player.loading", "PLAYER (Class: %u Race: %u): Adding initial skill, id = %u", uint32(getClass()), uint32(getCFSRace()), skillId);
  1240.      switch (GetSkillRangeType(rcInfo))
  1241.      {
  1242.          case SKILL_RANGE_LANGUAGE:
  1243. @@ -26647,3 +26683,14 @@ void Player::RemoveSocial()
  1244.      sSocialMgr->RemovePlayerSocial(GetGUID());
  1245.      m_social = nullptr;
  1246.  }
  1247. +void Player::BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language) const
  1248. +{
  1249. +    *data << uint8(msgtype);
  1250. +    *data << uint32(language);
  1251. +    *data << uint64(GetGUID());
  1252. +    *data << uint32(0);                                      // constant unknown time
  1253. +    *data << uint64(GetGUID());
  1254. +    *data << uint32(text.length() + 1);
  1255. +    *data << text;
  1256. +    *data << uint8(GetChatTag());
  1257. +}
  1258. diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
  1259. index 6a0520121b..19e90727d6 100644
  1260. --- a/src/server/game/Entities/Player/Player.h
  1261. +++ b/src/server/game/Entities/Player/Player.h
  1262. @@ -884,6 +884,35 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
  1263.      public:
  1264.          explicit Player(WorldSession* session);
  1265.          ~Player();
  1266. +   private:
  1267. +            bool m_ForgetBGPlayers;
  1268. +            bool m_ForgetInListPlayers;
  1269. +            uint8 m_FakeRace;
  1270. +            uint8 m_RealRace;
  1271. +            uint32 m_FakeMorph;
  1272. +            public:
  1273. +                typedef std::vector<uint64> FakePlayers;
  1274. +                void SendChatMessage(const char *format, ...);
  1275. +                void FitPlayerInTeam(bool action, Battleground* pBattleGround = NULL);          // void FitPlayerInTeam(bool action, Battleground* bg = NULL);
  1276. +                void DoForgetPlayersInList();
  1277. +                void DoForgetPlayersInBG(Battleground* pBattleGround);                                          // void DoForgetPlayersInBG(Battleground* bg);
  1278. +                uint8 getCFSRace() const { return m_RealRace; }
  1279. +                void SetCFSRace() { m_RealRace = GetByteValue(UNIT_FIELD_BYTES_0, 0); }; // SHOULD ONLY BE CALLED ON LOGIN
  1280. +                void SetFakeRace(); // SHOULD ONLY BE CALLED ON LOGIN
  1281. +                void SetFakeRaceAndMorph(); // SHOULD ONLY BE CALLED ON LOGIN
  1282. +                uint32 GetFakeMorph() { return m_FakeMorph; };
  1283. +                uint8 getFRace() const { return m_FakeRace; }
  1284. +                void SetForgetBGPlayers(bool value) { m_ForgetBGPlayers = value; }
  1285. +                bool ShouldForgetBGPlayers() { return m_ForgetBGPlayers; }
  1286. +                void SetForgetInListPlayers(bool value) { m_ForgetInListPlayers = value; }
  1287. +                bool ShouldForgetInListPlayers() { return m_ForgetInListPlayers; }
  1288. +                bool SendBattleGroundChat(uint32 msgtype, std::string message);
  1289. +                void MorphFit(bool value);
  1290. +                bool IsPlayingNative() const { return GetTeam() == m_team; }
  1291. +                uint32 GetCFSTeam() const { return m_team; }
  1292. +                uint32 GetTeam() const { return m_bgData.bgTeam && GetBattleground() ? m_bgData.bgTeam : m_team; }
  1293. +                bool SendRealNameQuery();
  1294. +                FakePlayers m_FakePlayers;
  1295.  
  1296.          PlayerAI* AI() const { return reinterpret_cast<PlayerAI*>(i_AI); }
  1297.  
  1298. @@ -941,7 +970,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
  1299.          void RemoveSocial();
  1300.  
  1301.          PlayerTaxi m_taxi;
  1302. -        void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
  1303. +        void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getCFSRace(), getClass(), getLevel()); }
  1304.          bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0);
  1305.          bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0);
  1306.          void CleanupAfterTaxiFlight();
  1307. @@ -1014,6 +1043,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
  1308.          /// Handles whispers from Addons and players based on sender, receiver's guid and language.
  1309.          void Whisper(std::string const& text, Language language, Player* receiver, bool = false) override;
  1310.          void Whisper(uint32 textId, Player* target, bool isBossWhisper = false) override;
  1311. +       void BuildPlayerChat(WorldPacket* data, uint8 msgtype, std::string const& text, uint32 language) const;
  1312. +
  1313.  
  1314.          /*********************************************************/
  1315.          /***                    STORAGE SYSTEM                 ***/
  1316. @@ -1718,8 +1749,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
  1317.          void CheckAreaExploreAndOutdoor(void);
  1318.  
  1319.          static uint32 TeamForRace(uint8 race);
  1320. -        uint32 GetTeam() const { return m_team; }
  1321. -        TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
  1322. +       TeamId GetTeamId() const { return GetTeam() == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
  1323.          void setFactionForRace(uint8 race);
  1324.  
  1325.          void InitDisplayIds();
  1326. @@ -1884,7 +1914,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
  1327.          void SetBattlegroundEntryPoint();
  1328.  
  1329.          void SetBGTeam(uint32 team);
  1330. -        uint32 GetBGTeam() const;
  1331.  
  1332.          void LeaveBattleground(bool teleportToEntryPoint = true);
  1333.          bool CanJoinToBattleground(Battleground const* bg) const;
  1334. diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
  1335. index ffb53507fa..08485abf46 100644
  1336. --- a/src/server/game/Entities/Unit/Unit.cpp
  1337. +++ b/src/server/game/Entities/Unit/Unit.cpp
  1338. @@ -12817,7 +12817,7 @@ void Unit::RemoveCharmedBy(Unit* charmer)
  1339.  void Unit::RestoreFaction()
  1340.  {
  1341.      if (GetTypeId() == TYPEID_PLAYER)
  1342. -        ToPlayer()->setFactionForRace(getRace());
  1343. +        ToPlayer()->setFactionForRace(ToPlayer()->getRace());
  1344.      else
  1345.      {
  1346.          if (HasUnitTypeMask(UNIT_MASK_MINION))
  1347. @@ -13581,6 +13581,21 @@ uint32 Unit::GetModelForTotem(PlayerTotemType totemType)
  1348.              }
  1349.              break;
  1350.          }
  1351. +   default: // One standard for other races.
  1352. +            {
  1353. +                switch (totemType)
  1354. +                {
  1355. +                    case SUMMON_TYPE_TOTEM_FIRE:    // fire
  1356. +                        return 4589;
  1357. +                        case SUMMON_TYPE_TOTEM_EARTH:   // earth
  1358. +                            return 4588;
  1359. +                            case SUMMON_TYPE_TOTEM_WATER:   // water
  1360. +                                return 4587;
  1361. +                                case SUMMON_TYPE_TOTEM_AIR:     // air
  1362. +                                    return 4590;
  1363. +                                    }
  1364. +                break;
  1365. +                } 
  1366.      }
  1367.      return 0;
  1368.  }
  1369. diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
  1370. index e76dcbd84f..6e1e9fdf07 100644
  1371. --- a/src/server/game/Entities/Unit/Unit.h
  1372. +++ b/src/server/game/Entities/Unit/Unit.h
  1373. @@ -1047,8 +1047,10 @@ class TC_GAME_API Unit : public WorldObject
  1374.          uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
  1375.          uint8 getLevelForTarget(WorldObject const* /*target*/) const override { return getLevel(); }
  1376.          void SetLevel(uint8 lvl);
  1377. -        uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE); }
  1378. +        uint8 getRace(bool forceoriginal = false) const;
  1379. +        uint8 getCFSRace() { return getRace(true); }
  1380.          uint32 getRaceMask() const { return 1 << (getRace()-1); }
  1381. +       uint32 getCFSRaceMask() const { return 1 << (getRace(true) - 1); }
  1382.          uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); }
  1383.          uint32 getClassMask() const { return 1 << (getClass()-1); }
  1384.          uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER); }
  1385. diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
  1386. index bb8f52b90f..ec240d9edf 100644
  1387. --- a/src/server/game/Handlers/BattleGroundHandler.cpp
  1388. +++ b/src/server/game/Handlers/BattleGroundHandler.cpp
  1389. @@ -39,6 +39,7 @@
  1390.  #include "Player.h"
  1391.  #include "World.h"
  1392.  #include "WorldPacket.h"
  1393. +#include "Custom/Custom.h"
  1394.  
  1395.  void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData)
  1396.  {
  1397. @@ -288,14 +289,22 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvDa
  1398.      data << flagCarrierCount;
  1399.      if (allianceFlagCarrier)
  1400.      {
  1401. -        data << uint64(allianceFlagCarrier->GetGUID());
  1402. +        if (allianceFlagCarrier->SendRealNameQuery())
  1403. +            data << uint64(allianceFlagCarrier->GetGUID() + LIMIT_UINT32);
  1404. +        else
  1405. +            data << uint64(allianceFlagCarrier->GetGUID());
  1406. +
  1407.          data << float(allianceFlagCarrier->GetPositionX());
  1408.          data << float(allianceFlagCarrier->GetPositionY());
  1409.      }
  1410.  
  1411.      if (hordeFlagCarrier)
  1412.      {
  1413. -        data << uint64(hordeFlagCarrier->GetGUID());
  1414. +            if (hordeFlagCarrier->SendRealNameQuery())
  1415. +            data << uint64(hordeFlagCarrier->GetGUID() + LIMIT_UINT32);
  1416. +        else
  1417. +            data << uint64(hordeFlagCarrier->GetGUID());
  1418. +
  1419.          data << float(hordeFlagCarrier->GetPositionX());
  1420.          data << float(hordeFlagCarrier->GetPositionY());
  1421.      }
  1422. @@ -564,7 +573,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
  1423.              {
  1424.                  // this line is checked, i only don't know if GetStartTime is changing itself after bg end!
  1425.                  // send status in Battleground
  1426. -                sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam());
  1427. +                sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetTeam());
  1428.                  SendPacket(&data);
  1429.                  continue;
  1430.              }
  1431. diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
  1432. index ba0eecb0b3..0f07ef8c03 100644
  1433. --- a/src/server/game/Handlers/CharacterHandler.cpp
  1434. +++ b/src/server/game/Handlers/CharacterHandler.cpp
  1435. @@ -50,6 +50,9 @@
  1436.  #include "SocialMgr.h"
  1437.  #include "QueryHolder.h"
  1438.  #include "World.h"
  1439. +#include "Battleground.h"
  1440. +#include "ArenaTeamMgr.h"
  1441. +#include "AccountMgr.h"
  1442.  
  1443.  class LoginQueryHolder : public SQLQueryHolder
  1444.  {
  1445. @@ -996,6 +999,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
  1446.      TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName());
  1447.  
  1448.      delete holder;
  1449. +   if (pCurrChar->GetTeam() != pCurrChar->getCFSRace())
  1450. +        pCurrChar->FitPlayerInTeam(pCurrChar->GetBattleground() && !pCurrChar->GetBattleground()->isArena() ? true : false, pCurrChar->GetBattleground());
  1451. +   pCurrChar->RemoveAurasDueToSpell(44311);   
  1452.  }
  1453.  
  1454.  void WorldSession::HandleSetFactionAtWar(WorldPacket& recvData)
  1455. diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
  1456. index 85fe6f4e48..9dac0c3320 100644
  1457. --- a/src/server/game/Handlers/ChatHandler.cpp
  1458. +++ b/src/server/game/Handlers/ChatHandler.cpp
  1459. @@ -56,8 +56,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1460.          return;
  1461.      }
  1462.  
  1463. -    if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
  1464. -    {
  1465. +   if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
  1466. +   {
  1467.          TC_LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str());
  1468.          SendNotification(LANG_UNKNOWN_LANGUAGE);
  1469.          recvData.rfinish();
  1470. @@ -67,7 +67,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1471.      Player* sender = GetPlayer();
  1472.  
  1473.      //TC_LOG_DEBUG("CHAT: packet received. type %u, lang %u", type, lang);
  1474. -
  1475. +   if (!sender->IsPlayingNative())
  1476. +    {
  1477.      // prevent talking at unknown language (cheating)
  1478.      LanguageDesc const* langDesc = GetLanguageDescByID(lang);
  1479.      if (!langDesc)
  1480. @@ -97,6 +98,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1481.              return;
  1482.          }
  1483.      }
  1484. +   }
  1485.  
  1486.      if (lang == LANG_ADDON)
  1487.      {
  1488. @@ -249,7 +251,11 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1489.              // Prevent cheating
  1490.              if (!sender->IsAlive())
  1491.                  return;
  1492. -
  1493. +          
  1494. +           if (!sender->IsGameMaster())
  1495. +           if (sender->SendBattleGroundChat(type, msg))
  1496. +           return;
  1497. +      
  1498.              if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
  1499.              {
  1500.                  SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
  1501. @@ -264,7 +270,12 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1502.              // Prevent cheating
  1503.              if (!sender->IsAlive())
  1504.                  return;
  1505. -
  1506. +                       if (!sender->IsGameMaster())
  1507. +           if (sender->SendBattleGroundChat(type, msg))
  1508. +           return;
  1509. +            if (!GetPlayer()->IsGameMaster())
  1510. +                if (GetPlayer()->SendBattleGroundChat(type, msg))
  1511. +                    return;
  1512.              if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_EMOTE_LEVEL_REQ))
  1513.              {
  1514.                  SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_EMOTE_LEVEL_REQ));
  1515. @@ -279,7 +290,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1516.              // Prevent cheating
  1517.              if (!sender->IsAlive())
  1518.                  return;
  1519. -
  1520. +           if (!sender->IsGameMaster())
  1521. +           if (sender->SendBattleGroundChat(type, msg))
  1522. +           return;
  1523.              if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_YELL_LEVEL_REQ))
  1524.              {
  1525.                  SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_YELL_LEVEL_REQ));
  1526. diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
  1527. index a632bf1979..53bce0cc06 100644
  1528. --- a/src/server/game/Handlers/MiscHandler.cpp
  1529. +++ b/src/server/game/Handlers/MiscHandler.cpp
  1530. @@ -1246,6 +1246,21 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket& recvData)
  1531.  
  1532.  void WorldSession::HandleTimeSyncResp(WorldPacket& recvData)
  1533.  {
  1534. +       Battleground* bg = _player->GetBattleground();
  1535. +    if (bg)
  1536. +    {
  1537. +        if (_player->ShouldForgetBGPlayers() && bg)
  1538. +        {
  1539. +            _player->DoForgetPlayersInBG(bg);
  1540. +            _player->SetForgetBGPlayers(false);
  1541. +        }
  1542. +    }
  1543. +    else if (_player->ShouldForgetInListPlayers())
  1544. +    {
  1545. +        _player->DoForgetPlayersInList();
  1546. +        _player->SetForgetInListPlayers(false);
  1547. +    }
  1548. +
  1549.      TC_LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP");
  1550.  
  1551.      uint32 counter, clientTicks;
  1552. diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
  1553. index a2566c9a7f..77ecb9c1c7 100644
  1554. --- a/src/server/game/Handlers/QueryHandler.cpp
  1555. +++ b/src/server/game/Handlers/QueryHandler.cpp
  1556. @@ -48,7 +48,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid)
  1557.      data << uint8(0);                               // name known
  1558.      data << nameData->Name;                         // played name
  1559.      data << uint8(0);                               // realm name - only set for cross realm interaction (such as Battlegrounds)
  1560. -    data << uint8(nameData->Race);
  1561. +    data << uint8(player ? player->getRace() : nameData->Race);
  1562.      data << uint8(nameData->Sex);
  1563.      data << uint8(nameData->Class);
  1564.  
  1565. diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
  1566. index e64300eb5d..e5d6617e54 100644
  1567. --- a/src/server/game/World/World.cpp
  1568. +++ b/src/server/game/World/World.cpp
  1569. @@ -1160,7 +1160,9 @@ void World::LoadConfigSettings(bool reload)
  1570.      m_float_configs[CONFIG_ARENA_MATCHMAKER_RATING_MODIFIER]         = sConfigMgr->GetFloatDefault("Arena.ArenaMatchmakerRatingModifier", 24.0f);
  1571.  
  1572.      m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN]            = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true);
  1573. -
  1574. +  
  1575. +   m_bool_configs[BATTLEGROUND_CROSSFACTION_ENABLED] = sConfigMgr->GetBoolDefault("CrossfactionBG.enable", true);
  1576. +  
  1577.      m_int_configs[CONFIG_CREATURE_PICKPOCKET_REFILL] = sConfigMgr->GetIntDefault("Creature.PickPocketRefillDelay", 10 * MINUTE);
  1578.      m_int_configs[CONFIG_CREATURE_STOP_FOR_PLAYER] = sConfigMgr->GetIntDefault("Creature.MovingStopTimeForPlayer", 3 * MINUTE * IN_MILLISECONDS);
  1579.  
  1580. diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
  1581. index 6c44b1abe1..295ab57ad2 100644
  1582. --- a/src/server/game/World/World.h
  1583. +++ b/src/server/game/World/World.h
  1584. @@ -179,6 +179,7 @@ enum WorldBoolConfigs
  1585.      CONFIG_CACHE_DATA_QUERIES,
  1586.      CONFIG_CHECK_GOBJECT_LOS,
  1587.      CONFIG_RESPAWN_DYNAMIC_ESCORTNPC,
  1588. +   BATTLEGROUND_CROSSFACTION_ENABLED,
  1589.      BOOL_CONFIG_VALUE_COUNT
  1590.  };
  1591.  
  1592. diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
  1593. index 2e900edd2c..0bdad073bf 100644
  1594. --- a/src/server/worldserver/worldserver.conf.dist
  1595. +++ b/src/server/worldserver/worldserver.conf.dist
  1596. @@ -3958,3 +3958,15 @@ Metric.OverallStatusInterval = 1
  1597.  
  1598.  #
  1599.  ###################################################################################################
  1600. +
  1601. +###################################################################################################
  1602. +#      CROSSFACTION BG CONFIG
  1603. +#          Enable Crossfaction battleground
  1604. +#          Default: 1 - on
  1605. +#                   0 - off
  1606. +#
  1607. +
  1608. +CrossfactionBG.enable = 1
  1609. +
  1610. +#
  1611. +###################################################################################################
  1612. \ No newline at end of file
  1613. --
  1614. 2.13.2.windows.1
Advertisement
Add Comment
Please, Sign In to add comment