Advertisement
Guest User

Cross Faction

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