Advertisement
Guest User

EmuDevs - Cross Faction Battlegrounds (CFBG)

a guest
Oct 17th, 2014
1,237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 69.29 KB | None | 0 0
  1. Edited For Latest Revision By Wolord of EmuDevs
  2. All Regards To LilleCarl
  3. [PATCH] : CrossFactionBG
  4.  
  5. ---
  6. cmake/compiler/msvc/settings.cmake                 |   2 +-
  7.  .../CrossFactionBG/world.AVFix.sql                 |   3 +
  8.  src/server/game/Battlegrounds/Arena.cpp            |   4 +-
  9.  src/server/game/Battlegrounds/Battleground.cpp     |  47 ++-
  10.  src/server/game/Battlegrounds/Battleground.h       |   2 +-
  11.  src/server/game/Battlegrounds/BattlegroundMgr.cpp  |   2 +-
  12.  .../game/Battlegrounds/BattlegroundQueue.cpp       |  85 ++++--
  13.  src/server/game/Battlegrounds/BattlegroundQueue.h  |  11 +-
  14.  .../game/Battlegrounds/Zones/BattlegroundAB.cpp    |   2 +-
  15.  .../game/Battlegrounds/Zones/BattlegroundAV.cpp    |  19 +-
  16.  .../game/Battlegrounds/Zones/BattlegroundWS.cpp    |   3 +-
  17.  src/server/game/CMakeLists.txt                     |   2 +
  18.  src/server/game/Cfbg/Cfbg.cpp                      | 325 +++++++++++++++++++++
  19.  src/server/game/Cfbg/Cfbg.h                        |  35 +++
  20.  src/server/game/Entities/Player/Player.cpp         |  98 +++++--
  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   |   4 +-
  25.  src/server/game/Handlers/CharacterHandler.cpp      |   3 +
  26.  src/server/game/Handlers/ChatHandler.cpp           |  18 +-
  27.  src/server/game/Handlers/MiscHandler.cpp           |  15 +
  28.  src/server/game/Handlers/QueryHandler.cpp          |   2 +-
  29.  src/server/game/World/World.cpp                    |   2 +
  30.  src/server/game/World/World.h                      |   1 +
  31.  src/server/worldserver/worldserver.conf.dist       |  12 +
  32.  26 files changed, 658 insertions(+), 97 deletions(-)
  33.  create mode 100644 sql/TrinityCore-Patches/CrossFactionBG/world.AVFix.sql
  34.  create mode 100644 src/server/game/Cfbg/Cfbg.cpp
  35.  create mode 100644 src/server/game/Cfbg/Cfbg.h
  36.  
  37. diff --git a/cmake/compiler/msvc/settings.cmake b/cmake/compiler/msvc/settings.cmake
  38. index b68a0de..fe896d8 100644
  39. --- a/cmake/compiler/msvc/settings.cmake
  40. +++ b/cmake/compiler/msvc/settings.cmake
  41. @@ -1,7 +1,7 @@
  42.  # set up output paths for executable binaries (.exe-files, and .dll-files on DLL-capable platforms)
  43.  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
  44.  
  45. -set(MSVC_EXPECTED_VERSION 18.0)
  46. +set(MSVC_EXPECTED_VERSION 16.0)
  47.  
  48.  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MSVC_EXPECTED_VERSION)
  49.    message(FATAL_ERROR "MSVC: TrinityCore requires version ${MSVC_EXPECTED_VERSION} (MSVC 2013) to build but found ${CMAKE_CXX_COMPILER_VERSION}")
  50. diff --git a/sql/TrinityCore-Patches/CrossFactionBG/world.AVFix.sql b/sql/TrinityCore-Patches/CrossFactionBG/world.AVFix.sql
  51. new file mode 100644
  52. index 0000000..a0c7eb9
  53. --- /dev/null
  54. +++ b/sql/TrinityCore-Patches/CrossFactionBG/world.AVFix.sql
  55. @@ -0,0 +1,3 @@
  56. +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);
  57. +
  58. +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);
  59. diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
  60. index cdc6fc3..0830ba1 100644
  61. --- a/src/server/game/Battlegrounds/Arena.cpp
  62. +++ b/src/server/game/Battlegrounds/Arena.cpp
  63. @@ -40,9 +40,9 @@ Arena::Arena()
  64.  void Arena::AddPlayer(Player* player)
  65.  {
  66.      Battleground::AddPlayer(player);
  67. -    PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam());
  68. +    PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetTeam());
  69.  
  70. -    if (player->GetBGTeam() == ALLIANCE)        // gold
  71. +    if (player->GetTeam() == ALLIANCE)        // gold
  72.      {
  73.          if (player->GetTeam() == HORDE)
  74.              player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true);
  75. diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
  76. index 6f6d1b6..8e04104 100644
  77. --- a/src/server/game/Battlegrounds/Battleground.cpp
  78. +++ b/src/server/game/Battlegrounds/Battleground.cpp
  79. @@ -288,7 +288,7 @@ inline void Battleground::_CheckSafePositions(uint32 diff)
  80.              if (Player* player = ObjectAccessor::FindPlayer(itr->first))
  81.              {
  82.                  Position pos = player->GetPosition();
  83. -                Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetBGTeam()));
  84. +                Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetTeam()));
  85.                  if (pos.GetExactDistSq(startPos) > maxDist)
  86.                  {
  87.                      TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId());
  88. @@ -494,7 +494,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
  89.                      WorldPacket status;
  90.                      BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType());
  91.                      uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
  92. -                    sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam());
  93. +                    sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetTeam());
  94.                      player->SendDirectMessage(&status);
  95.  
  96.                      player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
  97. @@ -662,22 +662,34 @@ void Battleground::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
  98.              UpdatePlayerScore(player, SCORE_BONUS_HONOR, Honor);
  99.  }
  100.  
  101. -void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
  102. +void Battleground::RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamID)
  103.  {
  104. -    FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
  105. -    if (!factionEntry)
  106. +    FactionEntry const* a_factionEntry = sFactionStore.LookupEntry(a_faction_id);
  107. +    FactionEntry const* h_factionEntry = sFactionStore.LookupEntry(h_faction_id);
  108. +
  109. +    if (!a_factionEntry || !h_factionEntry)
  110.          return;
  111.  
  112.      for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
  113.      {
  114. -        Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam");
  115. -        if (!player)
  116. +       if (itr->second.OfflineRemoveTime)
  117.              continue;
  118.  
  119. -        uint32 repGain = Reputation;
  120. -        AddPct(repGain, player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN));
  121. -        AddPct(repGain, player->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction_id));
  122. -        player->GetReputationMgr().ModifyReputation(factionEntry, repGain);
  123. +        Player* player = ObjectAccessor::FindPlayer(itr->first);
  124. +
  125. +        if (!player)
  126. +        {
  127. +            TC_LOG_ERROR("bg.battleground", "BattleGround:RewardReputationToTeam: %u not found!", itr->first);
  128. +            continue;
  129. +        }
  130. +
  131. +        //uint32 team = player->GetTeam();
  132. +
  133. +        //if (team == TeamId)
  134. +        if (Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam"))
  135. +        {
  136. +            player->GetReputationMgr().ModifyReputation(player->GetOTeam() == ALLIANCE ? a_factionEntry : h_factionEntry, Reputation);
  137. +        }
  138.      }
  139.  }
  140.  
  141. @@ -830,7 +842,7 @@ void Battleground::EndBattleground(uint32 winner)
  142.          player->SendDirectMessage(&pvpLogData);
  143.  
  144.          WorldPacket data;
  145. -        sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam());
  146. +        sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetTeam());
  147.          player->SendDirectMessage(&data);
  148.          player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
  149.      }
  150. @@ -946,6 +958,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
  151.  
  152.      if (player)
  153.      {
  154. +        player->FitPlayerInTeam(false, this);
  155.          // Do next only if found in battleground
  156.          player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE);  // We're not in BG.
  157.          // reset destination bg team
  158. @@ -1015,7 +1028,7 @@ void Battleground::AddPlayer(Player* player)
  159.      // score struct must be created in inherited class
  160.  
  161.      uint64 guid = player->GetGUID();
  162. -    uint32 team = player->GetBGTeam();
  163. +    uint32 team = player->GetTeam();
  164.  
  165.      BattlegroundPlayer bp;
  166.      bp.OfflineRemoveTime = 0;
  167. @@ -1066,6 +1079,8 @@ void Battleground::AddPlayer(Player* player)
  168.      // setup BG group membership
  169.      PlayerAddedToBGCheckIfBGIsRunning(player);
  170.      AddOrSetPlayerToCorrectBgGroup(player, team);
  171. +
  172. +    player->FitPlayerInTeam(true, this);
  173.  }
  174.  
  175.  // this method adds player to his team's bg group, or sets his correct group if player is already in bg group
  176. @@ -1135,8 +1150,8 @@ void Battleground::EventPlayerLoggedOut(Player* player)
  177.  
  178.          // 1 player is logging out, if it is the last, then end arena!
  179.          if (isArena())
  180. -            if (GetAlivePlayersCountByTeam(player->GetBGTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetBGTeam())))
  181. -                EndBattleground(GetOtherTeam(player->GetBGTeam()));
  182. +            if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam())))
  183. +                EndBattleground(GetOtherTeam(player->GetTeam()));
  184.      }
  185.  }
  186.  
  187. @@ -1744,7 +1759,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
  188.      BuildPvPLogDataPacket(data);
  189.      player->SendDirectMessage(&data);
  190.  
  191. -    sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam());
  192. +    sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetTeam());
  193.      player->SendDirectMessage(&data);
  194.  }
  195.  
  196. diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
  197. index b027019..e30a625 100644
  198. --- a/src/server/game/Battlegrounds/Battleground.h
  199. +++ b/src/server/game/Battlegrounds/Battleground.h
  200. @@ -354,7 +354,7 @@ class Battleground
  201.          void CastSpellOnTeam(uint32 SpellID, uint32 TeamID);
  202.          void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID);
  203.          void RewardHonorToTeam(uint32 Honor, uint32 TeamID);
  204. -        void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID);
  205. +        void RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamId);
  206.          void UpdateWorldState(uint32 Field, uint32 Value);
  207.          void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player);
  208.          virtual void EndBattleground(uint32 winner);
  209. diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  210. index 82ea090..d5370b6 100644
  211. --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  212. +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  213. @@ -695,7 +695,7 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt
  214.      if (Battleground* bg = GetBattleground(instanceId, bgTypeId))
  215.      {
  216.          uint32 mapid = bg->GetMapId();
  217. -        uint32 team = player->GetBGTeam();
  218. +        uint32 team = player->GetTeam();
  219.          if (team == 0)
  220.              team = player->GetTeam();
  221.  
  222. diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  223. index e52f75a..d8d2fd3 100644
  224. --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  225. +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  226. @@ -154,6 +154,10 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
  227.          index += BG_TEAMS_COUNT;
  228.      if (ginfo->Team == HORDE)
  229.          index++;
  230. +
  231. +    if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && ArenaType == 0)
  232. +        index = BG_QUEUE_MIXED;
  233. +
  234.      TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index);
  235.  
  236.      uint32 lastOnlineTime = getMSTime();
  237. @@ -198,33 +202,58 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
  238.          {
  239.              if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId))
  240.              {
  241. -                uint32 MinPlayers = bg->GetMinPlayersPerTeam();
  242. -                uint32 qHorde = 0;
  243. -                uint32 qAlliance = 0;
  244. -                uint32 q_min_level = bracketEntry->minLevel;
  245. -                uint32 q_max_level = bracketEntry->maxLevel;
  246. -                GroupsQueueType::const_iterator itr;
  247. -                for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
  248. -                    if (!(*itr)->IsInvitedToBGInstanceGUID)
  249. -                        qAlliance += (*itr)->Players.size();
  250. -                for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
  251. -                    if (!(*itr)->IsInvitedToBGInstanceGUID)
  252. -                        qHorde += (*itr)->Players.size();
  253. -
  254. -                // Show queue status to player only (when joining queue)
  255. -                if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
  256. +                if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED))
  257.                  {
  258. -                    ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bg->GetName().c_str(), q_min_level, q_max_level,
  259. -                        qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  260. +                    char const* bgName = bg->GetName().c_str();
  261. +                    uint32 MinPlayers = bg->GetMinPlayersPerTeam()*2;
  262. +                    uint32 qPlayers = 0;
  263. +                    uint32 q_min_level = bracketEntry->minLevel;
  264. +                    uint32 q_max_level = bracketEntry->maxLevel;
  265. +                    for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracketId][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_MIXED].end(); ++itr)
  266. +                        if (!(*itr)->IsInvitedToBGInstanceGUID)
  267. +                            qPlayers += (*itr)->Players.size();
  268. +
  269. +                    if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
  270. +                    {
  271. +                        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);
  272. +                    }
  273. +                    else
  274. +                    {
  275. +                        std::ostringstream ss;
  276. +                        ss << "|cffff0000[BG Queue Announcer]:|r " << bgName << " -- [" << q_min_level << "-" << q_max_level << "] " << qPlayers << "/" << MinPlayers;
  277. +                        sWorld->SendGlobalText(ss.str().c_str(), NULL);
  278. +                    }
  279.                  }
  280. -                // System message
  281.                  else
  282.                  {
  283. -                    sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bg->GetName().c_str(), q_min_level, q_max_level,
  284. -                        qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  285. +                    std::string bgName = bg->GetName().c_str();
  286. +                    uint32 MinPlayers = bg->GetMinPlayersPerTeam();
  287. +                    uint32 qHorde = 0;
  288. +                    uint32 qAlliance = 0;
  289. +                    uint32 q_min_level = bracketEntry->minLevel;
  290. +                    uint32 q_max_level = bracketEntry->maxLevel;
  291. +                    GroupsQueueType::const_iterator itr;
  292. +                    for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
  293. +                        if (!(*itr)->IsInvitedToBGInstanceGUID)
  294. +                            qAlliance += (*itr)->Players.size();
  295. +                    for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
  296. +                        if (!(*itr)->IsInvitedToBGInstanceGUID)
  297. +                            qHorde += (*itr)->Players.size();
  298. +
  299. +                    // Show queue status to player only (when joining queue)
  300. +                    if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
  301. +                    {
  302. +                        ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bg->GetName().c_str(), q_min_level, q_max_level,
  303. +                            qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  304. +                    }
  305. +                    // System message
  306. +                    else
  307. +                    {
  308. +                        sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bg->GetName().c_str(), q_min_level, q_max_level,
  309. +                            qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
  310. +                    }
  311.                  }
  312. -            }
  313. -        }
  314. +            }
  315. +        }
  316.          //release mutex
  317.      }
  318.  
  319. @@ -308,7 +337,7 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
  320.      {
  321.          //we must check premade and normal team's queue - because when players from premade are joining bg,
  322.          //they leave groupinfo so we can't use its players size to find out index
  323. -        for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_TEAMS_COUNT)
  324. +        for (uint8 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j)
  325.          {
  326.              GroupsQueueType::iterator k = m_QueuedGroups[bracket_id_tmp][j].begin();
  327.              for (; k != m_QueuedGroups[bracket_id_tmp][j].end(); ++k)
  328. @@ -497,6 +526,10 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId
  329.      int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
  330.      int32 aliFree   = bg->GetFreeSlotsForTeam(ALLIANCE);
  331.  
  332. +    if (!bg->isArena())
  333. +        if (FillXPlayersToBG(bracket_id, bg, false))
  334. +            return;
  335. +
  336.      //iterator for iterating through bg queue
  337.      GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
  338.      //count of groups in queue - used to stop cycles
  339. @@ -745,7 +778,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
  340.      if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
  341.          m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() &&
  342.          m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
  343. -        m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty())
  344. +        m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty() &&
  345. +        m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].empty())
  346.          return;
  347.  
  348.      // battleground with free slot for player should be always in the beggining of the queue
  349. @@ -836,7 +870,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
  350.      {
  351.          // if there are enough players in pools, start new battleground or non rated arena
  352.          if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)
  353. -            || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)))
  354. +            || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam))
  355. +            || CheckCrossFactionMatch(bracket_id, bg_template))
  356.          {
  357.              // we successfully created a pool
  358.              Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false);
  359. diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h
  360. index f95e8ba..5d506eb 100644
  361. --- a/src/server/game/Battlegrounds/BattlegroundQueue.h
  362. +++ b/src/server/game/Battlegrounds/BattlegroundQueue.h
  363. @@ -42,6 +42,7 @@ struct GroupQueueInfo                                       // stores informatio
  364.  {
  365.      std::map<uint64, PlayerQueueInfo*> Players;             // player queue info map
  366.      uint32  Team;                                           // Player team (ALLIANCE/HORDE)
  367. +    uint32  OTeam;                                          // Player team (ALLIANCE/HORDE)
  368.      BattlegroundTypeId BgTypeId;                            // battleground type id
  369.      bool    IsRated;                                        // rated
  370.      uint8   ArenaType;                                      // 2v2, 3v3, 5v5 or 0 when BG
  371. @@ -60,9 +61,10 @@ enum BattlegroundQueueGroupTypes
  372.      BG_QUEUE_PREMADE_ALLIANCE   = 0,
  373.      BG_QUEUE_PREMADE_HORDE      = 1,
  374.      BG_QUEUE_NORMAL_ALLIANCE    = 2,
  375. -    BG_QUEUE_NORMAL_HORDE       = 3
  376. +    BG_QUEUE_NORMAL_HORDE       = 3,
  377. +    BG_QUEUE_MIXED              = 4
  378.  };
  379. -#define BG_QUEUE_GROUP_TYPES_COUNT 4
  380. +#define BG_QUEUE_GROUP_TYPES_COUNT 5
  381.  
  382.  class Battleground;
  383.  class BattlegroundQueue
  384. @@ -74,6 +76,11 @@ class BattlegroundQueue
  385.          void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
  386.          void UpdateEvents(uint32 diff);
  387.  
  388. +        bool FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start = false);
  389. +        typedef std::multimap<int32, GroupQueueInfo*> QueuedGroupMap;
  390. +        int32 PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam);
  391. +        bool CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg);
  392. +
  393.          void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id);
  394.          bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
  395.          bool CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
  396. diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
  397. index 2622ab9..4438c56 100644
  398. --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
  399. +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
  400. @@ -141,7 +141,7 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff)
  401.  
  402.                  if (m_ReputationScoreTics[team] >= m_ReputationTics)
  403.                  {
  404. -                    (team == TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
  405. +                    RewardReputationToTeam(509, 510, 10, team == ALLIANCE ? ALLIANCE : HORDE);
  406.                      m_ReputationScoreTics[team] -= m_ReputationTics;
  407.                  }
  408.  
  409. diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
  410. index fde358b..3f02942 100644
  411. --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
  412. +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
  413. @@ -89,7 +89,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  414.      if (entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS])
  415.      {
  416.          CastSpellOnTeam(23658, HORDE); //this is a spell which finishes a quest where a player has to kill the boss
  417. -        RewardReputationToTeam(729, BG_AV_REP_BOSS, HORDE);
  418. +        RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  419.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), HORDE);
  420.          EndBattleground(HORDE);
  421.          DelCreature(AV_CPLACE_TRIGGER17);
  422. @@ -97,7 +97,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  423.      else if (entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS])
  424.      {
  425.          CastSpellOnTeam(23658, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss
  426. -        RewardReputationToTeam(730, BG_AV_REP_BOSS, ALLIANCE);
  427. +        RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  428.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), ALLIANCE);
  429.          EndBattleground(ALLIANCE);
  430.          DelCreature(AV_CPLACE_TRIGGER19);
  431. @@ -110,7 +110,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  432.              return;
  433.          }
  434.          m_CaptainAlive[0]=false;
  435. -        RewardReputationToTeam(729, BG_AV_REP_CAPTAIN, HORDE);
  436. +        RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  437.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE);
  438.          UpdateScore(ALLIANCE, (-1)*BG_AV_RES_CAPTAIN);
  439.          //spawn destroyed aura
  440. @@ -129,7 +129,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
  441.              return;
  442.          }
  443.          m_CaptainAlive[1]=false;
  444. -        RewardReputationToTeam(730, BG_AV_REP_CAPTAIN, ALLIANCE);
  445. +        RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
  446.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE);
  447.          UpdateScore(HORDE, (-1)*BG_AV_RES_CAPTAIN);
  448.          //spawn destroyed aura
  449. @@ -151,6 +151,7 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
  450.      if (GetStatus() != STATUS_IN_PROGRESS)
  451.          return;//maybe we should log this, cause this must be a cheater or a big bug
  452.      uint8 team = GetTeamIndexByTeamId(player->GetTeam());
  453. +    uint8 oteam = GetTeamIndexByTeamId(GetOtherTeam(player->GetTeam()));
  454.      /// @todo add reputation, events (including quest not available anymore, next quest available, go/npc de/spawning)and maybe honor
  455.      TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed", questid);
  456.      switch (questid)
  457. @@ -175,21 +176,21 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
  458.          case AV_QUEST_A_COMMANDER1:
  459.          case AV_QUEST_H_COMMANDER1:
  460.              m_Team_QuestStatus[team][1]++;
  461. -            RewardReputationToTeam(team, 1, player->GetTeam());
  462. +            RewardReputationToTeam(team, oteam, 1, player->GetTeam());
  463.              if (m_Team_QuestStatus[team][1] == 30)
  464.                  TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
  465.              break;
  466.          case AV_QUEST_A_COMMANDER2:
  467.          case AV_QUEST_H_COMMANDER2:
  468.              m_Team_QuestStatus[team][2]++;
  469. -            RewardReputationToTeam(team, 1, player->GetTeam());
  470. +            RewardReputationToTeam(team, oteam, 1, player->GetTeam());
  471.              if (m_Team_QuestStatus[team][2] == 60)
  472.                  TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
  473.              break;
  474.          case AV_QUEST_A_COMMANDER3:
  475.          case AV_QUEST_H_COMMANDER3:
  476.              m_Team_QuestStatus[team][3]++;
  477. -            RewardReputationToTeam(team, 1, player->GetTeam());
  478. +            RewardReputationToTeam(team, oteam, 1, player->GetTeam());
  479.              if (m_Team_QuestStatus[team][3] == 120)
  480.                  TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
  481.              break;
  482. @@ -471,7 +472,7 @@ void BattlegroundAV::EndBattleground(uint32 winner)
  483.              rep[i]   += BG_AV_REP_SURVIVING_CAPTAIN;
  484.          }
  485.          if (rep[i] != 0)
  486. -            RewardReputationToTeam(i == 0 ? 730 : 729, rep[i], i == 0 ? ALLIANCE : HORDE);
  487. +            RewardReputationToTeam(729, 730, 10, i == ALLIANCE ? ALLIANCE : HORDE);
  488.          if (kills[i] != 0)
  489.              RewardHonorToTeam(GetBonusHonorFromKill(kills[i]), i == 0 ? ALLIANCE : HORDE);
  490.      }
  491. @@ -576,7 +577,7 @@ void BattlegroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
  492.              SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10), RESPAWN_IMMEDIATELY);
  493.  
  494.          UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, -1 * BG_AV_RES_TOWER);
  495. -        RewardReputationToTeam(owner == ALLIANCE ? 730 : 729, BG_AV_REP_TOWER, owner);
  496. +        RewardReputationToTeam(729, 730, BG_AV_REP_TOWER, owner);
  497.          RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), owner);
  498.  
  499.          SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp), RESPAWN_ONE_DAY);
  500. diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
  501. index c50669b..57eb3c0 100644
  502. --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
  503. +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
  504. @@ -309,7 +309,6 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
  505.          if (GetTeamScore(TEAM_ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
  506.              AddPoint(ALLIANCE, 1);
  507.          PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
  508. -        RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
  509.      }
  510.      else
  511.      {
  512. @@ -328,8 +327,8 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
  513.          if (GetTeamScore(TEAM_HORDE) < BG_WS_MAX_TEAM_SCORE)
  514.              AddPoint(HORDE, 1);
  515.          PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
  516. -        RewardReputationToTeam(889, m_ReputationCapture, HORDE);
  517.      }
  518. +    RewardReputationToTeam(890, 889, m_ReputationCapture, player->GetTeam());
  519.      //for flag capture is reward 2 honorable kills
  520.      RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeam());
  521.  
  522. diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
  523. index d7d14e7..92b606d 100644
  524. --- a/src/server/game/CMakeLists.txt
  525. +++ b/src/server/game/CMakeLists.txt
  526. @@ -49,6 +49,7 @@ file(GLOB_RECURSE sources_Tickets Tickets/*.cpp Tickets/*.h)
  527.  file(GLOB_RECURSE sources_Warden Warden/*.cpp Warden/*.h)
  528.  file(GLOB_RECURSE sources_Weather Weather/*.cpp Weather/*.h)
  529.  file(GLOB_RECURSE sources_World World/*.cpp World/*.h)
  530. +file(GLOB_RECURSE sources_Cfbg Cfbg/*.cpp Cfbg/*.h)
  531.  
  532.  # Create game-libary
  533.  
  534. @@ -100,6 +101,7 @@ set(game_STAT_SRCS
  535.    ${sources_Warden}
  536.    ${sources_Weather}
  537.    ${sources_World}
  538. +  ${sources_Cfbg}
  539.  )
  540.  
  541.  include_directories(
  542. diff --git a/src/server/game/Cfbg/Cfbg.cpp b/src/server/game/Cfbg/Cfbg.cpp
  543. new file mode 100644
  544. index 0000000..2ea38c0
  545. --- /dev/null
  546. +++ b/src/server/game/Cfbg/Cfbg.cpp
  547. @@ -0,0 +1,325 @@
  548. +#include "Cfbg.h"
  549. +#include "Battleground.h"
  550. +#include "BattlegroundMgr.h"
  551. +#include "Player.h"
  552. +#include "Chat.h"
  553. +#include "BattlegroundQueue.h"
  554. +
  555. +/*####################################################################################
  556. +###############################CROSSFACTION BATTLEGROUNDS#############################
  557. +####################################################################################*/
  558. +
  559. +uint8 Unit::getRace(bool forceoriginal) const
  560. +{
  561. +    if (GetTypeId() == TYPEID_PLAYER)
  562. +    {
  563. +        Player* player = ((Player*)this);
  564. +
  565. +        if (forceoriginal)
  566. +            return player->getORace();
  567. +
  568. +        if (player->InArena())
  569. +            return GetByteValue(UNIT_FIELD_BYTES_0, 0);
  570. +
  571. +        if (!player->IsPlayingNative())
  572. +            return player->getFRace();
  573. +    }
  574. +
  575. +    return GetByteValue(UNIT_FIELD_BYTES_0, 0);
  576. +}
  577. +
  578. +bool Player::SendRealNameQuery()
  579. +{
  580. +    if (IsPlayingNative())
  581. +        return false;
  582. +
  583. +    WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+10));
  584. +    data.appendPackGUID(GetGUID());                             // player guid
  585. +    data << uint8(0);                                       // added in 3.1; if > 1, then end of packet
  586. +    data << GetName();                                   // played name
  587. +    data << uint8(0);                                       // realm name for cross realm BG usage
  588. +    data << uint8(getORace());
  589. +    data << uint8(getGender());
  590. +    data << uint8(getClass());
  591. +    data << uint8(0);                                   // is not declined
  592. +    GetSession()->SendPacket(&data);
  593. +
  594. +    return true;
  595. +}
  596. +
  597. +void Player::SetFakeRaceAndMorph()
  598. +{
  599. +m_FakeRace = GetOTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN;
  600. +}
  601. +
  602. +bool Player::SendBattleGroundChat(uint32 msgtype, std::string message)
  603. +{
  604. +    // Select distance to broadcast to.
  605. +    float distance = msgtype == CHAT_MSG_SAY ? sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY) : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL);
  606. +
  607. +    if (Battleground* bg = GetBattleground())
  608. +    {
  609. +        if (bg->isArena()) // Only fake chat in BG's. CFBG should not interfere with arenas.
  610. +            return false;
  611. +
  612. +        for (Battleground::BattlegroundPlayerMap::const_iterator itr = bg->GetPlayers().begin(); itr != bg->GetPlayers().end(); ++itr)
  613. +        {
  614. +            if (Player* player = ObjectAccessor::FindPlayer(itr->first))
  615. +            {
  616. +                if (GetDistance2d(player->GetPositionX(), player->GetPositionY()) <= distance)
  617. +                {
  618. +                    WorldPacket data(SMSG_MESSAGECHAT, 200);
  619. +
  620. +                    if (GetTeam() == player->GetTeam())
  621. +                        BuildPlayerChat(&data, msgtype, message, LANG_UNIVERSAL);
  622. +                    else if (msgtype != CHAT_MSG_EMOTE)
  623. +                       BuildPlayerChat(&data, msgtype, message, player->GetTeam() == ALLIANCE ? LANG_ORCISH : LANG_COMMON);
  624. +
  625. +                    player->GetSession()->SendPacket(&data);
  626. +                }
  627. +            }
  628. +        }
  629. +        return true;
  630. +    }
  631. +    else
  632. +        return false;
  633. +}
  634. +
  635. +void Player::MorphFit(bool value)
  636. +{
  637. +    if (!IsPlayingNative() && value)
  638. +    {
  639. +        if (GetOTeam() == HORDE)
  640. +        {
  641. +            if (getGender() == GENDER_MALE)
  642. +            {
  643. +                SetDisplayId(19723);
  644. +                SetNativeDisplayId(19723);
  645. +            }
  646. +            else
  647. +            {
  648. +                SetDisplayId(19724);
  649. +                SetNativeDisplayId(19724);
  650. +            }
  651. +        }
  652. +        else
  653. +        {
  654. +            if (getGender() == GENDER_MALE)
  655. +            {
  656. +                SetDisplayId(20578);
  657. +                SetNativeDisplayId(20578);
  658. +            }
  659. +            else
  660. +            {
  661. +                SetDisplayId(20579);
  662. +                SetNativeDisplayId(20579);
  663. +            }
  664. +        }
  665. +    }
  666. +    else
  667. +        InitDisplayIds();
  668. +}
  669. +
  670. +void Player::FitPlayerInTeam(bool action, Battleground* bg)
  671. +{
  672. +    if (!bg)
  673. +        bg = GetBattleground();
  674. +
  675. +    if ((!bg || bg->isArena()) && action)
  676. +        return;
  677. +
  678. +    if(!IsPlayingNative() && action)
  679. +        setFactionForRace(getRace());
  680. +    else
  681. +        setFactionForRace(getORace());
  682. +
  683. +    if (action)
  684. +        SetForgetBGPlayers(true);
  685. +    else
  686. +        SetForgetInListPlayers(true);
  687. +
  688. +    MorphFit(action);
  689. +
  690. +    if (bg && action)
  691. +        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, bg->GetName().c_str());
  692. +}
  693. +
  694. +void Player::DoForgetPlayersInList()
  695. +{
  696. +    // m_FakePlayers is filled from a vector within the battleground
  697. +    // they were in previously so all players that have been in that BG will be invalidated.
  698. +    for (FakePlayers::const_iterator itr = m_FakePlayers.begin(); itr != m_FakePlayers.end(); ++itr)
  699. +    {
  700. +        WorldPacket data(SMSG_INVALIDATE_PLAYER, 8);
  701. +        data << *itr;
  702. +        GetSession()->SendPacket(&data);
  703. +        if (Player* player = ObjectAccessor::FindPlayer(*itr))
  704. +            GetSession()->SendNameQueryOpcode(player->GetGUID());
  705. +    }
  706. +    m_FakePlayers.clear();
  707. +}
  708. +
  709. +void Player::DoForgetPlayersInBG(Battleground* bg)
  710. +{
  711. +    for (Battleground::BattlegroundPlayerMap::const_iterator itr = bg->GetPlayers().begin(); itr != bg->GetPlayers().end(); ++itr)
  712. +    {
  713. +        // Here we invalidate players in the bg to the added player
  714. +        WorldPacket data1(SMSG_INVALIDATE_PLAYER, 8);
  715. +        data1 << itr->first;
  716. +        GetSession()->SendPacket(&data1);
  717. +
  718. +        if (Player* player = ObjectAccessor::FindPlayer(itr->first))
  719. +        {
  720. +            GetSession()->SendNameQueryOpcode(player->GetGUID()); // Send namequery answer instantly if player is available
  721. +            // Here we invalidate the player added to players in the bg
  722. +            WorldPacket data2(SMSG_INVALIDATE_PLAYER, 8);
  723. +            data2 << GetGUID();
  724. +            player->GetSession()->SendPacket(&data2);
  725. +            player->GetSession()->SendNameQueryOpcode(GetGUID());
  726. +        }
  727. +    }
  728. +}
  729. +
  730. +bool BattlegroundQueue::CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg)
  731. +{
  732. +    if (!sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) || bg->isArena())
  733. +        return false; // Only do this if crossbg's are enabled.
  734. +
  735. +    // Here we will add all players to selectionpool, later we check if there are enough and launch a bg.
  736. +    FillXPlayersToBG(bracket_id, bg, true);
  737. +
  738. +    if (sBattlegroundMgr->isTesting() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount()))
  739. +        return true;
  740. +
  741. +    uint8 MPT = bg->GetMinPlayersPerTeam();
  742. +    if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() < MPT || m_SelectionPools[TEAM_HORDE].GetPlayerCount() < MPT)
  743. +        return false;
  744. +
  745. +    return true;
  746. +}
  747. +
  748. +// This function will invite players in the least populated faction, which makes battleground queues much faster.
  749. +// This function will return true if cross faction battlegrounds are enabled, otherwise return false,
  750. +// which is useful in FillPlayersToBG. Because then we can interrupt the regular invitation if cross faction bg's are enabled.
  751. +bool BattlegroundQueue::FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start)
  752. +{
  753. +    uint8 queuedPeople = 0;
  754. +    for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].end(); ++itr)
  755. +        if (!(*itr)->IsInvitedToBGInstanceGUID)
  756. +            queuedPeople += (*itr)->Players.size();
  757. +
  758. +    if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && (sBattlegroundMgr->isTesting() || queuedPeople >= bg->GetMinPlayersPerTeam()*2 || !start))
  759. +    {
  760. +        int32 aliFree   = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(ALLIANCE);
  761. +        int32 hordeFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(HORDE);
  762. +        // Empty selection pools. They will be refilled from queued groups.
  763. +        m_SelectionPools[TEAM_ALLIANCE].Init();
  764. +        m_SelectionPools[TEAM_HORDE].Init();
  765. +        int32 valiFree = aliFree;
  766. +        int32 vhordeFree = hordeFree;
  767. +        int32 diff = 0;
  768. +
  769. +
  770. +        // Add teams to their own factions as far as possible.
  771. +        if (start)
  772. +        {
  773. +            QueuedGroupMap m_PreGroupMap_a, m_PreGroupMap_h;
  774. +            int32 m_SmallestOfTeams = 0;
  775. +            int32 queuedAlliance = 0;
  776. +            int32 queuedHorde = 0;
  777. +
  778. +            for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].end(); ++itr)
  779. +            {
  780. +                if ((*itr)->IsInvitedToBGInstanceGUID)
  781. +                    continue;
  782. +
  783. +                bool alliance = (*itr)->OTeam == ALLIANCE;
  784. +
  785. +                if (alliance)
  786. +                {
  787. +                    m_PreGroupMap_a.insert(std::make_pair((*itr)->Players.size(), *itr));
  788. +                    queuedAlliance += (*itr)->Players.size();
  789. +                }
  790. +                else
  791. +                {
  792. +                    m_PreGroupMap_h.insert(std::make_pair((*itr)->Players.size(), *itr));
  793. +                    queuedHorde += (*itr)->Players.size();
  794. +                }
  795. +            }
  796. +
  797. +            m_SmallestOfTeams = std::min(std::min(aliFree, queuedAlliance), std::min(hordeFree, queuedHorde));
  798. +
  799. +            valiFree -= PreAddPlayers(m_PreGroupMap_a, m_SmallestOfTeams, aliFree);
  800. +            vhordeFree -= PreAddPlayers(m_PreGroupMap_h, m_SmallestOfTeams, hordeFree);
  801. +        }
  802. +
  803. +        QueuedGroupMap m_QueuedGroupMap;
  804. +
  805. +        for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].end(); ++itr)
  806. +            m_QueuedGroupMap.insert(std::make_pair((*itr)->Players.size(), *itr));
  807. +
  808. +        for (QueuedGroupMap::reverse_iterator itr = m_QueuedGroupMap.rbegin(); itr != m_QueuedGroupMap.rend(); ++itr)
  809. +        {
  810. +            GroupsQueueType allypool = m_SelectionPools[TEAM_ALLIANCE].SelectedGroups;
  811. +            GroupsQueueType hordepool = m_SelectionPools[TEAM_HORDE].SelectedGroups;
  812. +
  813. +            GroupQueueInfo* ginfo = itr->second;
  814. +
  815. +            // If player already was invited via pre adding (add to own team first) or he was already invited to a bg, skip.
  816. +            if (ginfo->IsInvitedToBGInstanceGUID ||
  817. +                std::find(allypool.begin(), allypool.end(), ginfo) != allypool.end() ||
  818. +                std::find(hordepool.begin(), hordepool.end(), ginfo) != hordepool.end() ||
  819. +                (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= bg->GetMinPlayersPerTeam() &&
  820. +                m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= bg->GetMinPlayersPerTeam()))
  821. +                continue;
  822. +
  823. +            diff = abs(valiFree - vhordeFree);
  824. +            bool moreAli = valiFree < vhordeFree;
  825. +
  826. +            if (diff > 0)
  827. +                ginfo->Team = moreAli ? HORDE : ALLIANCE;
  828. +
  829. +            bool alliance = ginfo->Team == ALLIANCE;
  830. +
  831. +            if (m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(ginfo, alliance ? aliFree : hordeFree))
  832. +                alliance ? valiFree -= ginfo->Players.size() : vhordeFree -= ginfo->Players.size();
  833. +        }
  834. +
  835. +        return true;
  836. +    }
  837. +    return false;
  838. +}
  839. +
  840. +int32 BattlegroundQueue::PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam)
  841. +{
  842. +    int32 LeftToAdd = MaxAdd;
  843. +    uint32 Added = 0;
  844. +
  845. +    for (QueuedGroupMap::reverse_iterator itr = m_PreGroupMap.rbegin(); itr != m_PreGroupMap.rend(); ++itr)
  846. +    {
  847. +        int32 PlayerSize = itr->first;
  848. +        bool alliance = itr->second->OTeam == ALLIANCE;
  849. +
  850. +        if (PlayerSize <= LeftToAdd && m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(itr->second, MaxInTeam))
  851. +            LeftToAdd -= PlayerSize, Added -= PlayerSize;
  852. +    }
  853. +
  854. +    return LeftToAdd;
  855. +}
  856. +
  857. +void Player::SendChatMessage(const char *format, ...)
  858. +{
  859. +    if (!IsInWorld())
  860. +        return;
  861. +
  862. +    if (format)
  863. +    {
  864. +        va_list ap;
  865. +        char str [2048];
  866. +        va_start(ap, format);
  867. +        vsnprintf(str, 2048, format, ap);
  868. +        va_end(ap);
  869. +
  870. +        ChatHandler(GetSession()).SendSysMessage(str);
  871. +    }
  872. +}
  873. diff --git a/src/server/game/Cfbg/Cfbg.h b/src/server/game/Cfbg/Cfbg.h
  874. new file mode 100644
  875. index 0000000..45567f8
  876. --- /dev/null
  877. +++ b/src/server/game/Cfbg/Cfbg.h
  878. @@ -0,0 +1,35 @@
  879. +#ifndef _CUSTOM_H
  880. +#define _CUSTOM_H
  881. +
  882. +#define MSG_COLOR_LIGHTRED     "|cffff6060"
  883. +#define MSG_COLOR_LIGHTBLUE    "|cff00ccff"
  884. +#define MSG_COLOR_ANN_GREEN    "|c1f40af20"
  885. +#define MSG_COLOR_RED          "|cffff0000"
  886. +#define MSG_COLOR_GOLD         "|cffffcc00"
  887. +#define MSG_COLOR_SUBWHITE     "|cffbbbbbb"
  888. +#define MSG_COLOR_MAGENTA      "|cffff00ff"
  889. +#define MSG_COLOR_YELLOW       "|cffffff00"
  890. +#define MSG_COLOR_CYAN         "|cff00ffff"
  891. +#define MSG_COLOR_DARKBLUE     "|cff0000ff"
  892. +
  893. +#define MSG_COLOR_GREY         "|cff9d9d9d"
  894. +#define MSG_COLOR_WHITE        "|cffffffff"
  895. +#define MSG_COLOR_GREEN        "|cff1eff00"
  896. +#define MSG_COLOR_BLUE         "|cff0080ff"
  897. +#define MSG_COLOR_PURPLE       "|cffb048f8"
  898. +#define MSG_COLOR_ORANGE       "|cffff8000"
  899. +
  900. +#define MSG_COLOR_DRUID        "|cffff7d0a"
  901. +#define MSG_COLOR_HUNTER       "|cffabd473"
  902. +#define MSG_COLOR_MAGE         "|cff69ccf0"
  903. +#define MSG_COLOR_PALADIN      "|cfff58cba"
  904. +#define MSG_COLOR_PRIEST       "|cffffffff"
  905. +#define MSG_COLOR_ROGUE        "|cfffff569"
  906. +#define MSG_COLOR_SHAMAN       "|cff0070de"
  907. +#define MSG_COLOR_WARLOCK      "|cff9482c9"
  908. +#define MSG_COLOR_WARRIOR      "|cffc79c6e"
  909. +#define MSG_COLOR_DEATH_KNIGHT "|cffc41f3b"
  910. +#define MSG_COLOR_MONK         "|cff00ff96"
  911. +
  912. +#define LIMIT_UINT32 2147483647
  913. +#endif
  914. diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
  915. index 061d960..5219cf4 100644
  916. --- a/src/server/game/Entities/Player/Player.cpp
  917. +++ b/src/server/game/Entities/Player/Player.cpp
  918. @@ -657,6 +657,12 @@ void KillRewarder::Reward()
  919.  
  920.  Player::Player(WorldSession* session): Unit(true)
  921.  {
  922. +    m_FakeRace = 0;
  923. +    m_RealRace = 0;
  924. +    m_FakeMorph = 0;
  925. +    m_ForgetBGPlayers = false;
  926. +    m_ForgetInListPlayers = false;
  927. +
  928.      m_speakTime = 0;
  929.      m_speakCount = 0;
  930.  
  931. @@ -1007,6 +1013,12 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
  932.      uint32 RaceClassGender = (createInfo->Race) | (createInfo->Class << 8) | (createInfo->Gender << 16);
  933.  
  934.      SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24)));
  935. +
  936. +    SetORace();
  937. +    m_team = TeamForRace(getORace());
  938. +    SetFakeRaceAndMorph(); // m_team must be set before this can be used.
  939. +    setFactionForRace(getORace());
  940. +
  941.      InitDisplayIds();
  942.      if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP)
  943.      {
  944. @@ -3016,7 +3028,7 @@ void Player::GiveLevel(uint8 level)
  945.          guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level);
  946.  
  947.      PlayerLevelInfo info;
  948. -    sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info);
  949. +    sObjectMgr->GetPlayerLevelInfo(getORace(), getClass(), level, &info);
  950.  
  951.      PlayerClassLevelInfo classInfo;
  952.      sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo);
  953. @@ -3154,7 +3166,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
  954.      sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), &classInfo);
  955.  
  956.      PlayerLevelInfo info;
  957. -    sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), getLevel(), &info);
  958. +    sObjectMgr->GetPlayerLevelInfo(getORace(), getClass(), getLevel(), &info);
  959.  
  960.      SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
  961.      SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(getLevel()));
  962. @@ -5207,7 +5219,7 @@ void Player::CreateCorpse()
  963.          return;
  964.      }
  965.  
  966. -    _uf = GetUInt32Value(UNIT_FIELD_BYTES_0);
  967. +    _uf = getORace();
  968.      _pb = GetUInt32Value(PLAYER_BYTES);
  969.      _pb2 = GetUInt32Value(PLAYER_BYTES_2);
  970.  
  971. @@ -6893,10 +6905,10 @@ uint32 Player::TeamForRace(uint8 race)
  972.  
  973.  void Player::setFactionForRace(uint8 race)
  974.  {
  975. -    m_team = TeamForRace(race);
  976. +    SetBGTeam(TeamForRace(race));
  977.  
  978.      ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race);
  979. -    setFaction(rEntry ? rEntry->FactionID : 0);
  980. +    setFaction(rEntry ? rEntry->FactionID : getFaction());
  981.  }
  982.  
  983.  ReputationRank Player::GetReputationRank(uint32 faction) const
  984. @@ -6998,6 +7010,27 @@ void Player::RewardReputation(Unit* victim, float rate)
  985.      if (!Rep)
  986.          return;
  987.  
  988. +    uint32 repfaction1 = Rep->RepFaction1;
  989. +    uint32 repfaction2 = Rep->RepFaction2;
  990. +
  991. +    if (!IsPlayingNative())
  992. +    {
  993. +        if (GetOTeam() == ALLIANCE)
  994. +        {
  995. +            if (repfaction1 == 729)
  996. +                repfaction1 = 730;
  997. +            if (repfaction2 == 729)
  998. +                repfaction2 = 730;
  999. +        }
  1000. +        else
  1001. +        {
  1002. +            if (repfaction1 == 730)
  1003. +                repfaction1 = 729;
  1004. +            if (repfaction2 == 730)
  1005. +                repfaction2 = 729;
  1006. +        }
  1007. +    }
  1008. +
  1009.      uint32 ChampioningFaction = 0;
  1010.  
  1011.      if (GetChampioningFaction())
  1012. @@ -7012,23 +7045,23 @@ void Player::RewardReputation(Unit* victim, float rate)
  1013.  
  1014.      uint32 team = GetTeam();
  1015.  
  1016. -    if (Rep->RepFaction1 && (!Rep->TeamDependent || team == ALLIANCE))
  1017. +    if (repfaction1 && (!Rep->TeamDependent || team == ALLIANCE))
  1018.      {
  1019. -        int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
  1020. +        int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : repfaction1);
  1021.          donerep1 = int32(donerep1 * rate);
  1022.  
  1023. -        FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
  1024. +        FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction1);
  1025.          uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1);
  1026.          if (factionEntry1 && current_reputation_rank1 <= Rep->ReputationMaxCap1)
  1027.              GetReputationMgr().ModifyReputation(factionEntry1, donerep1);
  1028.      }
  1029.  
  1030. -    if (Rep->RepFaction2 && (!Rep->TeamDependent || team == HORDE))
  1031. +    if (repfaction2 && (!Rep->TeamDependent || team == HORDE))
  1032.      {
  1033. -        int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
  1034. +        int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : repfaction2);
  1035.          donerep2 = int32(donerep2 * rate);
  1036.  
  1037. -        FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
  1038. +        FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction2);
  1039.          uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2);
  1040.          if (factionEntry2 && current_reputation_rank2 <= Rep->ReputationMaxCap2)
  1041.              GetReputationMgr().ModifyReputation(factionEntry2, donerep2);
  1042. @@ -7123,7 +7156,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
  1043.          if (!victim || victim == this || victim->GetTypeId() != TYPEID_PLAYER)
  1044.              return false;
  1045.  
  1046. -        if (GetBGTeam() == victim->ToPlayer()->GetBGTeam())
  1047. +        if (GetTeam() == victim->ToPlayer()->GetTeam())
  1048.              return false;
  1049.  
  1050.          return true;
  1051. @@ -7447,7 +7480,7 @@ void Player::UpdateArea(uint32 newArea)
  1052.  
  1053.      // previously this was in UpdateZone (but after UpdateArea) so nothing will break
  1054.      pvpInfo.IsInNoPvPArea = false;
  1055. -    if (area && area->IsSanctuary())    // in sanctuary
  1056. +    if(area && area->IsSanctuary() || GetAreaId() == 4413)    // in sanctuary
  1057.      {
  1058.          SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
  1059.          pvpInfo.IsInNoPvPArea = true;
  1060. @@ -11980,13 +12013,13 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
  1061.      if (!proto)
  1062.          return EQUIP_ERR_ITEM_NOT_FOUND;
  1063.  
  1064. -    if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeam() != HORDE)
  1065. +    if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetOTeam() != HORDE)
  1066.          return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
  1067.  
  1068. -    if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeam() != ALLIANCE)
  1069. +    if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetOTeam() != ALLIANCE)
  1070.          return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
  1071.  
  1072. -    if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
  1073. +    if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getORaceMask()) == 0)
  1074.          return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
  1075.  
  1076.      if (proto->RequiredSkill != 0)
  1077. @@ -17244,6 +17277,11 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
  1078.          return false;
  1079.      }
  1080.  
  1081. +    SetORace();
  1082. +    m_team = TeamForRace(getORace());
  1083. +    SetFakeRaceAndMorph(); // m_team must be set before this can be used.
  1084. +    setFactionForRace(getORace());//Need to call it to initialize m_team (m_team can be calculated from race)
  1085. +
  1086.      SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8());
  1087.      SetUInt32Value(PLAYER_XP, fields[7].GetUInt32());
  1088.  
  1089. @@ -17290,10 +17328,6 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
  1090.      TC_LOG_DEBUG("entities.player.loading", "Load Basic value of player %s is: ", m_name.c_str());
  1091.      outDebugValues();
  1092.  
  1093. -    //Need to call it to initialize m_team (m_team can be calculated from race)
  1094. -    //Other way is to saves m_team into characters table.
  1095. -    setFactionForRace(getRace());
  1096. -
  1097.      // load home bind and check in same time class/race pair, it used later for restore broken positions
  1098.      if (!_LoadHomeBind(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_HOME_BIND)))
  1099.          return false;
  1100. @@ -19210,7 +19244,7 @@ void Player::SaveToDB(bool create /*=false*/)
  1101.          stmt->setUInt32(index++, GetGUIDLow());
  1102.          stmt->setUInt32(index++, GetSession()->GetAccountId());
  1103.          stmt->setString(index++, GetName());
  1104. -        stmt->setUInt8(index++, getRace());
  1105. +        stmt->setUInt8(index++, getORace());
  1106.          stmt->setUInt8(index++, getClass());
  1107.          stmt->setUInt8(index++, getGender());
  1108.          stmt->setUInt8(index++, getLevel());
  1109. @@ -19315,7 +19349,7 @@ void Player::SaveToDB(bool create /*=false*/)
  1110.          // Update query
  1111.          stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER);
  1112.          stmt->setString(index++, GetName());
  1113. -        stmt->setUInt8(index++, getRace());
  1114. +        stmt->setUInt8(index++, getORace());
  1115.          stmt->setUInt8(index++, getClass());
  1116.          stmt->setUInt8(index++, getGender());
  1117.          stmt->setUInt8(index++, getLevel());
  1118. @@ -20554,6 +20588,19 @@ void Player::StopCastingCharm()
  1119.      }
  1120.  }
  1121.  
  1122. +void Player::BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language) const
  1123. +{
  1124. +    *data << uint8(msgtype);
  1125. +    *data << uint32(language);
  1126. +    *data << uint64(GetGUID());
  1127. +    *data << uint32(0);                                      // constant unknown time
  1128. +    *data << uint64(GetGUID());
  1129. +    *data << uint32(text.length() + 1);
  1130. +    *data << text;
  1131. +    *data << uint8(GetChatTag());
  1132. +}
  1133. +
  1134. +
  1135.  void Player::Say(const std::string& text, const uint32 language)
  1136.  {
  1137.      std::string _text(text);
  1138. @@ -22360,11 +22407,6 @@ void Player::SetBGTeam(uint32 team)
  1139.      SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? 1 : 0));
  1140.  }
  1141.  
  1142. -uint32 Player::GetBGTeam() const
  1143. -{
  1144. -    return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam();
  1145. -}
  1146. -
  1147.  void Player::LeaveBattleground(bool teleportToEntryPoint)
  1148.  {
  1149.      if (Battleground* bg = GetBattleground())
  1150. @@ -22440,7 +22482,7 @@ void Player::ReportedAfkBy(Player* reporter)
  1151.  
  1152.  WorldLocation Player::GetStartPosition() const
  1153.  {
  1154. -    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  1155. +    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getORace(), getClass());
  1156.      uint32 mapId = info->mapId;
  1157.      if (getClass() == CLASS_DEATH_KNIGHT && HasSpell(50977))
  1158.          mapId = 0;
  1159. diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
  1160. index 27ea835..5958bda 100644
  1161. --- a/src/server/game/Entities/Player/Player.h
  1162. +++ b/src/server/game/Entities/Player/Player.h
  1163. @@ -1100,6 +1100,35 @@ class Player : public Unit, public GridObject<Player>
  1164.      public:
  1165.          explicit Player(WorldSession* session);
  1166.          ~Player();
  1167. +        private:
  1168. +        bool m_ForgetBGPlayers;
  1169. +        bool m_ForgetInListPlayers;
  1170. +        uint8 m_FakeRace;
  1171. +        uint8 m_RealRace;
  1172. +        uint32 m_FakeMorph;
  1173. +    public:
  1174. +        typedef std::vector<uint64> FakePlayers;
  1175. +        void SendChatMessage(const char *format, ...);
  1176. +        void FitPlayerInTeam(bool action, Battleground* bg = NULL);
  1177. +        void DoForgetPlayersInList();
  1178. +        void DoForgetPlayersInBG(Battleground* bg);
  1179. +        uint8 getORace() const { return m_RealRace; }
  1180. +        void SetORace() { m_RealRace = GetByteValue(UNIT_FIELD_BYTES_0, 0); }; // SHOULD ONLY BE CALLED ON LOGIN
  1181. +        void SetFakeRace(); // SHOULD ONLY BE CALLED ON LOGIN
  1182. +        void SetFakeRaceAndMorph(); // SHOULD ONLY BE CALLED ON LOGIN
  1183. +        uint32 GetFakeMorph() { return m_FakeMorph; };
  1184. +        uint8 getFRace() const { return m_FakeRace; }
  1185. +        void SetForgetBGPlayers(bool value) { m_ForgetBGPlayers = value; }
  1186. +        bool ShouldForgetBGPlayers() { return m_ForgetBGPlayers; }
  1187. +        void SetForgetInListPlayers(bool value) { m_ForgetInListPlayers = value; }
  1188. +        bool ShouldForgetInListPlayers() { return m_ForgetInListPlayers; }
  1189. +        bool SendBattleGroundChat(uint32 msgtype, std::string message);
  1190. +        void MorphFit(bool value);
  1191. +        bool IsPlayingNative() const { return GetTeam() == m_team; }
  1192. +        uint32 GetOTeam() const { return m_team; }
  1193. +        uint32 GetTeam() const { return m_bgData.bgTeam && GetBattleground() ? m_bgData.bgTeam : m_team; }
  1194. +        bool SendRealNameQuery();
  1195. +        FakePlayers m_FakePlayers;
  1196.  
  1197.          void CleanupsBeforeDelete(bool finalCleanup = true) override;
  1198.  
  1199. @@ -1154,7 +1183,7 @@ class Player : public Unit, public GridObject<Player>
  1200.          PlayerSocial *GetSocial() { return m_social; }
  1201.  
  1202.          PlayerTaxi m_taxi;
  1203. -        void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
  1204. +        void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getORace(), getClass(), getLevel()); }
  1205.          bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = NULL, uint32 spellid = 0);
  1206.          bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0);
  1207.          void CleanupAfterTaxiFlight();
  1208. @@ -1222,6 +1251,8 @@ class Player : public Unit, public GridObject<Player>
  1209.          void TextEmote(std::string const& text);
  1210.          /// Handles whispers from Addons and players based on sender, receiver's guid and language.
  1211.          void Whisper(std::string const& text, const uint32 language, uint64 receiver);
  1212. +        /// Constructs the player Chat data for the specific functions to use
  1213. +        void BuildPlayerChat(WorldPacket* data, uint8 msgtype, std::string const& text, uint32 language) const;
  1214.  
  1215.          /*********************************************************/
  1216.          /***                    STORAGE SYSTEM                 ***/
  1217. @@ -1927,8 +1958,7 @@ class Player : public Unit, public GridObject<Player>
  1218.          void CheckAreaExploreAndOutdoor(void);
  1219.  
  1220.          static uint32 TeamForRace(uint8 race);
  1221. -        uint32 GetTeam() const { return m_team; }
  1222. -        TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
  1223. +        TeamId GetTeamId() const { return GetTeam() == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
  1224.          void setFactionForRace(uint8 race);
  1225.  
  1226.          void InitDisplayIds();
  1227. @@ -2073,7 +2103,6 @@ class Player : public Unit, public GridObject<Player>
  1228.          void SetBattlegroundEntryPoint();
  1229.  
  1230.          void SetBGTeam(uint32 team);
  1231. -        uint32 GetBGTeam() const;
  1232.  
  1233.          void LeaveBattleground(bool teleportToEntryPoint = true);
  1234.          bool CanJoinToBattleground(Battleground const* bg) const;
  1235. diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
  1236. index bfa57ef..cf01049 100644
  1237. --- a/src/server/game/Entities/Unit/Unit.cpp
  1238. +++ b/src/server/game/Entities/Unit/Unit.cpp
  1239. @@ -15988,7 +15988,7 @@ void Unit::RemoveCharmedBy(Unit* charmer)
  1240.  void Unit::RestoreFaction()
  1241.  {
  1242.      if (GetTypeId() == TYPEID_PLAYER)
  1243. -        ToPlayer()->setFactionForRace(getRace());
  1244. +        ToPlayer()->setFactionForRace(ToPlayer()->getRace());
  1245.      else
  1246.      {
  1247.          if (HasUnitTypeMask(UNIT_MASK_MINION))
  1248. @@ -16739,6 +16739,21 @@ uint32 Unit::GetModelForTotem(PlayerTotemType totemType)
  1249.              }
  1250.              break;
  1251.          }
  1252. +        default: // One standard for other races.
  1253. +        {        // THANKS L30m4nc3r for this
  1254. +            switch (totemType)
  1255. +            {
  1256. +                case SUMMON_TYPE_TOTEM_FIRE:    // fire
  1257. +                    return 4589;
  1258. +                case SUMMON_TYPE_TOTEM_EARTH:   // earth
  1259. +                    return 4588;
  1260. +                case SUMMON_TYPE_TOTEM_WATER:   // water
  1261. +                    return 4587;
  1262. +                case SUMMON_TYPE_TOTEM_AIR:     // air
  1263. +                    return 4590;
  1264. +            }
  1265. +            break;
  1266. +        }
  1267.      }
  1268.      return 0;
  1269.  }
  1270. diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
  1271. index a18bc3b..ea0328b 100644
  1272. --- a/src/server/game/Entities/Unit/Unit.h
  1273. +++ b/src/server/game/Entities/Unit/Unit.h
  1274. @@ -1357,8 +1357,10 @@ class Unit : public WorldObject
  1275.          uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
  1276.          uint8 getLevelForTarget(WorldObject const* /*target*/) const override { return getLevel(); }
  1277.          void SetLevel(uint8 lvl);
  1278. -        uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); }
  1279. +        uint8 getRace(bool forceoriginal = false) const;
  1280. +        uint8 getORace() { return getRace(true); }
  1281.          uint32 getRaceMask() const { return 1 << (getRace()-1); }
  1282. +        uint32 getORaceMask() const { return 1 << (getRace(true) - 1); }
  1283.          uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
  1284.          uint32 getClassMask() const { return 1 << (getClass()-1); }
  1285.          uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
  1286. diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
  1287. index 95e4dd3..0d2cf52 100644
  1288. --- a/src/server/game/Handlers/BattleGroundHandler.cpp
  1289. +++ b/src/server/game/Handlers/BattleGroundHandler.cpp
  1290. @@ -35,6 +35,8 @@
  1291.  #include "DisableMgr.h"
  1292.  #include "Group.h"
  1293.  
  1294. +#include "Cfbg/Cfbg.h"
  1295. +
  1296.  void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData)
  1297.  {
  1298.      uint64 guid;
  1299. @@ -543,7 +545,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
  1300.              {
  1301.                  // this line is checked, i only don't know if GetStartTime is changing itself after bg end!
  1302.                  // send status in Battleground
  1303. -                sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam());
  1304. +                sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetTeam());
  1305.                  SendPacket(&data);
  1306.                  continue;
  1307.              }
  1308. diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
  1309. index bfb88bd..2eda9f2 100644
  1310. --- a/src/server/game/Handlers/CharacterHandler.cpp
  1311. +++ b/src/server/game/Handlers/CharacterHandler.cpp
  1312. @@ -1066,6 +1066,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
  1313.      //
  1314.      // End of prepatch
  1315.      delete holder;
  1316. +
  1317. +    if (pCurrChar->GetTeam() != pCurrChar->GetOTeam())
  1318. +        pCurrChar->FitPlayerInTeam(pCurrChar->GetBattleground() && !pCurrChar->GetBattleground()->isArena() ? true : false, pCurrChar->GetBattleground());
  1319.  }
  1320.      // Prepatch by LordPsyan
  1321.      // 01
  1322. diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
  1323. index eccf7a6..b177617d 100644
  1324. --- a/src/server/game/Handlers/ChatHandler.cpp
  1325. +++ b/src/server/game/Handlers/ChatHandler.cpp
  1326. @@ -48,6 +48,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1327.      recvData >> type;
  1328.      recvData >> lang;
  1329.  
  1330. +    if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && lang != LANG_ADDON)
  1331. +    {
  1332. +        switch (type)
  1333. +        {
  1334. +        case CHAT_MSG_BATTLEGROUND:
  1335. +        case CHAT_MSG_BATTLEGROUND_LEADER:
  1336. +            lang = LANG_UNIVERSAL;
  1337. +        default:
  1338. +            break;
  1339. +        }
  1340. +    }
  1341. +
  1342.      if (type >= MAX_CHAT_MSG_TYPE)
  1343.      {
  1344.          TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type);
  1345. @@ -55,7 +67,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1346.          return;
  1347.      }
  1348.  
  1349. -    if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
  1350. +    if (lang == CHAT_MSG_AFK && type != CHAT_MSG_DND)
  1351.      {
  1352.          TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str());
  1353.          SendNotification(LANG_UNKNOWN_LANGUAGE);
  1354. @@ -253,6 +265,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  1355.                  return;
  1356.              }
  1357.  
  1358. +            if (!GetPlayer()->IsGameMaster())
  1359. +                if (GetPlayer()->SendBattleGroundChat(type, msg))
  1360. +                    return;
  1361. +
  1362.              if (type == CHAT_MSG_SAY)
  1363.                  sender->Say(msg, lang);
  1364.              else if (type == CHAT_MSG_EMOTE)
  1365. diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
  1366. index b6c508e..6c7a23b 100644
  1367. --- a/src/server/game/Handlers/MiscHandler.cpp
  1368. +++ b/src/server/game/Handlers/MiscHandler.cpp
  1369. @@ -1432,6 +1432,21 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket& recvData)
  1370.  
  1371.  void WorldSession::HandleTimeSyncResp(WorldPacket& recvData)
  1372.  {
  1373. +    Battleground* bg = _player->GetBattleground();
  1374. +    if (bg)
  1375. +    {
  1376. +        if (_player->ShouldForgetBGPlayers() && bg)
  1377. +        {
  1378. +            _player->DoForgetPlayersInBG(bg);
  1379. +            _player->SetForgetBGPlayers(false);
  1380. +        }
  1381. +    }
  1382. +    else if (_player->ShouldForgetInListPlayers())
  1383. +    {
  1384. +        _player->DoForgetPlayersInList();
  1385. +        _player->SetForgetInListPlayers(false);
  1386. +    }
  1387. +
  1388.      TC_LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP");
  1389.  
  1390.      uint32 counter, clientTicks;
  1391. diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
  1392. index dbcfb1c..f3ff127 100644
  1393. --- a/src/server/game/Handlers/QueryHandler.cpp
  1394. +++ b/src/server/game/Handlers/QueryHandler.cpp
  1395. @@ -48,7 +48,7 @@ void WorldSession::SendNameQueryOpcode(uint64 guid)
  1396.      data << uint8(0);                               // name known
  1397.      data << nameData->m_name;                       // played name
  1398.      data << uint8(0);                               // realm name - only set for cross realm interaction (such as Battlegrounds)
  1399. -    data << uint8(nameData->m_race);
  1400. +    data << uint8(player ? player->getRace() : nameData->m_race);
  1401.      data << uint8(nameData->m_gender);
  1402.      data << uint8(nameData->m_class);
  1403.  
  1404. diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
  1405. index 79dc565..1a20962 100644
  1406. --- a/src/server/game/World/World.cpp
  1407. +++ b/src/server/game/World/World.cpp
  1408. @@ -1045,6 +1045,8 @@ void World::LoadConfigSettings(bool reload)
  1409.  
  1410.      m_int_configs[CONFIG_CREATURE_PICKPOCKET_REFILL] = sConfigMgr->GetIntDefault("Creature.PickPocketRefillDelay", 10 * MINUTE);
  1411.  
  1412. +    m_bool_configs[BATTLEGROUND_CROSSFACTION_ENABLED]                = sConfigMgr->GetBoolDefault("CrossfactionBG.enable", true);
  1413. +
  1414.      if (int32 clientCacheId = sConfigMgr->GetIntDefault("ClientCacheVersion", 0))
  1415.      {
  1416.          // overwrite DB/old value
  1417. diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
  1418. index 8a36a0a..49b1e77 100644
  1419. --- a/src/server/game/World/World.h
  1420. +++ b/src/server/game/World/World.h
  1421. @@ -85,6 +85,7 @@ enum WorldTimers
  1422.  enum WorldBoolConfigs
  1423.  {
  1424.      CONFIG_DURABILITY_LOSS_IN_PVP = 0,
  1425. +    BATTLEGROUND_CROSSFACTION_ENABLED,
  1426.      CONFIG_ADDON_CHANNEL,
  1427.      CONFIG_ALLOW_PLAYER_COMMANDS,
  1428.      CONFIG_CLEAN_CHARACTER_DB,
  1429. diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
  1430. index 76f9334..5cde086 100644
  1431. --- a/src/server/worldserver/worldserver.conf.dist
  1432. +++ b/src/server/worldserver/worldserver.conf.dist
  1433. @@ -3195,6 +3195,18 @@ PacketSpoof.BanDuration = 86400
  1434.  #
  1435.  ###################################################################################################
  1436.  
  1437. +###################################################################################################
  1438. +#
  1439. +# CROSSFACTION BG CONFIG
  1440. +#
  1441. +#    CrossfactionBG.enable = 1 - Mixed battleground enabled.
  1442. +#    CrossfactionBG.enable = 0 - Mixed battleground disabled.
  1443. +
  1444. +CrossfactionBG.enable = 1
  1445. +
  1446. +#
  1447. +###################################################################################################
  1448. +
  1449. --
  1450. 2.1.0.rc1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement