Rochet2

crossfactionbgbackup

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