Advertisement
Guest User

CrossBgFaction TDB 58

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