SHOW:
|
|
- or go back to the newest paste.
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 | +################################################################################################### |