Advertisement
MarcusWilstrup

CFBG27.diff

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