Advertisement
Guest User

CFBG-2014

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