-
-
Save concept45/10931894 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Revision Source: TDB 335.53 - 2014/03/29 | |
Subject: [PATCH] Implemented Crossfaction Battlegrounds | |
Orginal Code By: Lillecarl | |
Updated For Last Revision Trinity By: amir_cinderella <[email protected]> | |
--- | |
diff --git a/.gitignore b/.gitignore | |
index 7dbed8f..c7cfe74 100644 | |
--- a/.gitignore | |
+++ b/.gitignore | |
@@ -16,3 +16,5 @@ CMakeLists.txt.user | |
*.BACKUP.* | |
*.BASE.* | |
*.LOCAL.* | |
+*.zip | |
+CFBG_GUIDE.txt | |
diff --git a/cmake/compiler/msvc/settings.cmake b/cmake/compiler/msvc/settings.cmake | |
index 3194967..6aa603a 100644 | |
--- a/cmake/compiler/msvc/settings.cmake | |
+++ b/cmake/compiler/msvc/settings.cmake | |
@@ -1,7 +1,7 @@ | |
# set up output paths for executable binaries (.exe-files, and .dll-files on DLL-capable platforms) | |
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) | |
-set(MSVC_EXPECTED_VERSION 18.0) | |
+set(MSVC_EXPECTED_VERSION 16.0) | |
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MSVC_EXPECTED_VERSION) | |
message(FATAL_ERROR "MSVC: TrinityCore requires version ${MSVC_EXPECTED_VERSION} (MSVC 2013) to build but found ${CMAKE_CXX_COMPILER_VERSION}") | |
diff --git a/sql/custom/AVFix.sql b/sql/custom/AVFix.sql | |
new file mode 100644 | |
index 0000000..23b3a92 | |
--- /dev/null | |
+++ b/sql/custom/AVFix.sql | |
@@ -0,0 +1,3 @@ | |
+UPDATE creature_template SET faction_A = 1, faction_H = 1 WHERE entry IN (4255,4257,5134,5135,5139,11948,11949,11997,12050,12096,12127,13086,13096,13138,13216,13257,13296,13298,13299,13317,13318,13319,13320,13326,13327,13331,13422,13437,13438,13439,13442,13443,13447,13546,13576,13577,13598,13617,13797,14187,14188,14284,14762,14763,14765,14766,14768,14769,12047,13396,13358,13080,13078); | |
+ | |
+UPDATE creature_template SET faction_A = 2, faction_H = 2 WHERE entry IN (2225,3343,3625,10364,10367,11946,11947,11998,12051,12052,12053,12097,12121,12122,13088,13089,13097,13137,13140,13143,13144,13145,13146,13147,13152,13153,13154,13176,13179,13180,13181,13218,13236,13284,13316,13359,13377,13397,13425,13428,13441,13448,13536,13539,13545,13597,13616,13618,13798,14185,14186,14282,14285,14772,14773,14774,14775,14776,14777,13332,13099,13079); | |
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp | |
index c4aa3ef..ec2477e 100644 | |
--- a/src/server/game/Battlegrounds/Battleground.cpp | |
+++ b/src/server/game/Battlegrounds/Battleground.cpp | |
@@ -306,7 +306,7 @@ inline void Battleground::_CheckSafePositions(uint32 diff) | |
if (Player* player = ObjectAccessor::FindPlayer(itr->first)) | |
{ | |
player->GetPosition(&pos); | |
- GetTeamStartLoc(player->GetBGTeam(), x, y, z, o); | |
+ GetTeamStartLoc(player->GetTeam(), x, y, z, o); | |
if (pos.GetExactDistSq(x, y, z) > maxDist) | |
{ | |
TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId()); | |
@@ -512,7 +512,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) | |
WorldPacket status; | |
BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); | |
uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); | |
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam()); | |
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetTeam()); | |
player->SendDirectMessage(&status); | |
player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION); | |
@@ -693,12 +693,32 @@ void Battleground::RewardHonorToTeam(uint32 Honor, uint32 TeamID) | |
UpdatePlayerScore(player, SCORE_BONUS_HONOR, Honor); | |
} | |
-void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID) | |
+void Battleground::RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 teamId) | |
{ | |
- if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id)) | |
- for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) | |
- if (Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam")) | |
- player->GetReputationMgr().ModifyReputation(factionEntry, Reputation); | |
+ FactionEntry const* a_factionEntry = sFactionStore.LookupEntry(a_faction_id); | |
+ FactionEntry const* h_factionEntry = sFactionStore.LookupEntry(h_faction_id); | |
+ | |
+ if (!a_factionEntry || !h_factionEntry) | |
+ return; | |
+ | |
+ for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) | |
+ { | |
+ if (itr->second.OfflineRemoveTime) | |
+ continue; | |
+ | |
+ Player* plr = ObjectAccessor::FindPlayer(itr->first); | |
+ | |
+ if (!plr) | |
+ { | |
+ TC_LOG_ERROR("bg.battleground", "BattleGround:RewardReputationToTeam: %u not found!", itr->first); | |
+ continue; | |
+ } | |
+ | |
+ uint32 team = plr->GetTeam(); | |
+ | |
+ if (team == teamId) | |
+ plr->GetReputationMgr().ModifyReputation(plr->GetOTeam() == ALLIANCE ? a_factionEntry : h_factionEntry, Reputation); | |
+ } | |
} | |
void Battleground::UpdateWorldState(uint32 Field, uint32 Value) | |
@@ -907,7 +927,7 @@ void Battleground::EndBattleground(uint32 winner) | |
player->SendDirectMessage(&pvpLogData); | |
WorldPacket data; | |
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam()); | |
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetTeam()); | |
player->SendDirectMessage(&data); | |
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); | |
} | |
@@ -1056,6 +1076,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac | |
if (player) | |
{ | |
+ player->FitPlayerInTeam(false, this); | |
// Do next only if found in battleground | |
player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG. | |
// reset destination bg team | |
@@ -1122,7 +1143,7 @@ void Battleground::AddPlayer(Player* player) | |
// score struct must be created in inherited class | |
uint64 guid = player->GetGUID(); | |
- uint32 team = player->GetBGTeam(); | |
+ uint32 team = player->GetTeam(); | |
BattlegroundPlayer bp; | |
bp.OfflineRemoveTime = 0; | |
@@ -1188,6 +1209,8 @@ void Battleground::AddPlayer(Player* player) | |
// setup BG group membership | |
PlayerAddedToBGCheckIfBGIsRunning(player); | |
AddOrSetPlayerToCorrectBgGroup(player, team); | |
+ | |
+ player->FitPlayerInTeam(true, this); | |
} | |
// this method adds player to his team's bg group, or sets his correct group if player is already in bg group | |
@@ -1257,8 +1280,8 @@ void Battleground::EventPlayerLoggedOut(Player* player) | |
// 1 player is logging out, if it is the last, then end arena! | |
if (isArena()) | |
- if (GetAlivePlayersCountByTeam(player->GetBGTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetBGTeam()))) | |
- EndBattleground(GetOtherTeam(player->GetBGTeam())); | |
+ if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam()))) | |
+ EndBattleground(GetOtherTeam(player->GetTeam())); | |
} | |
} | |
@@ -1858,7 +1881,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) | |
sBattlegroundMgr->BuildPvpLogDataPacket(&data, this); | |
player->SendDirectMessage(&data); | |
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam()); | |
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetTeam()); | |
player->SendDirectMessage(&data); | |
} | |
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h | |
index 5e2aa4b..64b8f8f 100644 | |
--- a/src/server/game/Battlegrounds/Battleground.h | |
+++ b/src/server/game/Battlegrounds/Battleground.h | |
@@ -422,7 +422,7 @@ class Battleground | |
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID); | |
void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID); | |
void RewardHonorToTeam(uint32 Honor, uint32 TeamID); | |
- void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID); | |
+ void RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 teamId); | |
void UpdateWorldState(uint32 Field, uint32 Value); | |
void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player); | |
void EndBattleground(uint32 winner); | |
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
index ab69c95..02a6e9d 100644 | |
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
@@ -284,7 +284,7 @@ void BattlegroundMgr::BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg) | |
Player* player = ObjectAccessor::FindPlayer(itr2->first); | |
uint32 team = bg->GetPlayerTeam(itr2->first); | |
if (!team && player) | |
- team = player->GetBGTeam(); | |
+ team = player->GetTeam(); | |
*data << uint8(team == ALLIANCE ? 1 : 0); // green or yellow | |
} | |
*data << uint32(score->DamageDone); // damage done | |
@@ -894,7 +894,7 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt | |
{ | |
float x, y, z, O; | |
uint32 mapid = bg->GetMapId(); | |
- uint32 team = player->GetBGTeam(); | |
+ uint32 team = player->GetTeam(); | |
if (team == 0) | |
team = player->GetTeam(); | |
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
index 547d6e9..12fc58a 100644 | |
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
@@ -154,6 +154,10 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr | |
index += BG_TEAMS_COUNT; | |
if (ginfo->Team == HORDE) | |
index++; | |
+ | |
+ if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && ArenaType == 0) | |
+ index = BG_QUEUE_MIXED; // BG_QUEUE_*_* -> BG_QUEUE_MIXED | |
+ | |
TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index); | |
uint32 lastOnlineTime = getMSTime(); | |
@@ -199,31 +203,56 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr | |
{ | |
if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId)) | |
{ | |
- char const* bgName = bg->GetName(); | |
- uint32 MinPlayers = bg->GetMinPlayersPerTeam(); | |
- uint32 qHorde = 0; | |
- uint32 qAlliance = 0; | |
- uint32 q_min_level = bracketEntry->minLevel; | |
- uint32 q_max_level = bracketEntry->maxLevel; | |
- GroupsQueueType::const_iterator itr; | |
- for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) | |
- if (!(*itr)->IsInvitedToBGInstanceGUID) | |
- qAlliance += (*itr)->Players.size(); | |
- for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr) | |
- if (!(*itr)->IsInvitedToBGInstanceGUID) | |
- qHorde += (*itr)->Players.size(); | |
- | |
- // Show queue status to player only (when joining queue) | |
- if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) | |
+ if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED)) | |
{ | |
- ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, | |
- qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
+ char const* bgName = bg->GetName(); | |
+ uint32 MinPlayers = bg->GetMinPlayersPerTeam()*2; | |
+ uint32 qPlayers = 0; | |
+ uint32 q_min_level = bracketEntry->minLevel; | |
+ uint32 q_max_level = bracketEntry->maxLevel; | |
+ for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracketId][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_MIXED].end(); ++itr) | |
+ if (!(*itr)->IsInvitedToBGInstanceGUID) | |
+ qPlayers += (*itr)->Players.size(); | |
+ | |
+ if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) | |
+ { | |
+ 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); | |
+ } | |
+ else | |
+ { | |
+ std::ostringstream ss; | |
+ ss << "|cffff0000[BG Queue Announcer]:|r " << bgName << " -- [" << q_min_level << "-" << q_max_level << "] " << qPlayers << "/" << MinPlayers; | |
+ sWorld->SendGlobalText(ss.str().c_str(), NULL); | |
+ } | |
} | |
- // System message | |
else | |
{ | |
- sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level, | |
- qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
+ char const* bgName = bg->GetName(); | |
+ uint32 MinPlayers = bg->GetMinPlayersPerTeam(); | |
+ uint32 qHorde = 0; | |
+ uint32 qAlliance = 0; | |
+ uint32 q_min_level = bracketEntry->minLevel; | |
+ uint32 q_max_level = bracketEntry->maxLevel; | |
+ GroupsQueueType::const_iterator itr; | |
+ for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) | |
+ if (!(*itr)->IsInvitedToBGInstanceGUID) | |
+ qAlliance += (*itr)->Players.size(); | |
+ for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr) | |
+ if (!(*itr)->IsInvitedToBGInstanceGUID) | |
+ qHorde += (*itr)->Players.size(); | |
+ | |
+ // Show queue status to player only (when joining queue) | |
+ if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) | |
+ { | |
+ ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, | |
+ qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
+ } | |
+ // System message | |
+ else | |
+ { | |
+ sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level, | |
+ qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
+ } | |
} | |
} | |
} | |
@@ -310,7 +339,7 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) | |
{ | |
//we must check premade and normal team's queue - because when players from premade are joining bg, | |
//they leave groupinfo so we can't use its players size to find out index | |
- for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_TEAMS_COUNT) | |
+ for (uint8 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j) | |
{ | |
GroupsQueueType::iterator k = m_QueuedGroups[bracket_id_tmp][j].begin(); | |
for (; k != m_QueuedGroups[bracket_id_tmp][j].end(); ++k) | |
@@ -499,6 +528,10 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId | |
int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE); | |
int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); | |
+ if (!bg->isArena()) | |
+ if (FillXPlayersToBG(bracket_id, bg, false)) | |
+ return; | |
+ | |
//iterator for iterating through bg queue | |
GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); | |
//count of groups in queue - used to stop cycles | |
@@ -747,7 +780,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp | |
if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && | |
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() && | |
m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() && | |
- m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty()) | |
+ m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty() && | |
+ m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].empty()) | |
return; | |
// battleground with free slot for player should be always in the beggining of the queue | |
@@ -838,7 +872,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp | |
{ | |
// if there are enough players in pools, start new battleground or non rated arena | |
if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam) | |
- || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam))) | |
+ || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)) | |
+ || CheckCrossFactionMatch(bracket_id, bg_template)) | |
{ | |
// we successfully created a pool | |
Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false); | |
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h | |
index af283cb..da808ef 100644 | |
--- a/src/server/game/Battlegrounds/BattlegroundQueue.h | |
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.h | |
@@ -42,6 +42,7 @@ struct GroupQueueInfo // stores informatio | |
{ | |
std::map<uint64, PlayerQueueInfo*> Players; // player queue info map | |
uint32 Team; // Player team (ALLIANCE/HORDE) | |
+ uint32 OTeam; // Player team (ALLIANCE/HORDE) | |
BattlegroundTypeId BgTypeId; // battleground type id | |
bool IsRated; // rated | |
uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG | |
@@ -60,9 +61,10 @@ enum BattlegroundQueueGroupTypes | |
BG_QUEUE_PREMADE_ALLIANCE = 0, | |
BG_QUEUE_PREMADE_HORDE = 1, | |
BG_QUEUE_NORMAL_ALLIANCE = 2, | |
- BG_QUEUE_NORMAL_HORDE = 3 | |
+ BG_QUEUE_NORMAL_HORDE = 3, | |
+ BG_QUEUE_MIXED = 4 | |
}; | |
-#define BG_QUEUE_GROUP_TYPES_COUNT 4 | |
+#define BG_QUEUE_GROUP_TYPES_COUNT 5 | |
class Battleground; | |
class BattlegroundQueue | |
@@ -74,6 +76,11 @@ class BattlegroundQueue | |
void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0); | |
void UpdateEvents(uint32 diff); | |
+ bool FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start = false); | |
+ typedef std::multimap<int32, GroupQueueInfo*> QueuedGroupMap; | |
+ int32 PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam); | |
+ bool CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg); | |
+ | |
void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id); | |
bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); | |
bool CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers); | |
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
index c05bd98..9d669dc 100644 | |
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
@@ -142,7 +142,7 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff) | |
if (m_ReputationScoreTics[team] >= m_ReputationTics) | |
{ | |
- (team == TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE); | |
+ RewardReputationToTeam(509, 510, 10, team == ALLIANCE ? ALLIANCE : HORDE); | |
m_ReputationScoreTics[team] -= m_ReputationTics; | |
} | |
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
index 610e0bc..429c673 100644 | |
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
@@ -94,7 +94,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
if (entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS][0]) | |
{ | |
CastSpellOnTeam(23658, HORDE); //this is a spell which finishes a quest where a player has to kill the boss | |
- RewardReputationToTeam(729, BG_AV_REP_BOSS, HORDE); | |
+ RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_BOSS), HORDE); | |
EndBattleground(HORDE); | |
DelCreature(AV_CPLACE_TRIGGER17); | |
@@ -102,7 +102,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
else if (entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS][0]) | |
{ | |
CastSpellOnTeam(23658, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss | |
- RewardReputationToTeam(730, BG_AV_REP_BOSS, ALLIANCE); | |
+ RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_BOSS), ALLIANCE); | |
EndBattleground(ALLIANCE); | |
DelCreature(AV_CPLACE_TRIGGER19); | |
@@ -115,7 +115,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
return; | |
} | |
m_CaptainAlive[0]=false; | |
- RewardReputationToTeam(729, BG_AV_REP_CAPTAIN, HORDE); | |
+ RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_CAPTAIN), HORDE); | |
UpdateScore(ALLIANCE, (-1)*BG_AV_RES_CAPTAIN); | |
//spawn destroyed aura | |
@@ -134,7 +134,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
return; | |
} | |
m_CaptainAlive[1]=false; | |
- RewardReputationToTeam(730, BG_AV_REP_CAPTAIN, ALLIANCE); | |
+ RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_CAPTAIN), ALLIANCE); | |
UpdateScore(HORDE, (-1)*BG_AV_RES_CAPTAIN); | |
//spawn destroyed aura | |
@@ -156,6 +156,7 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player) | |
if (GetStatus() != STATUS_IN_PROGRESS) | |
return;//maybe we should log this, cause this must be a cheater or a big bug | |
uint8 team = GetTeamIndexByTeamId(player->GetTeam()); | |
+ uint8 oteam = GetTeamIndexByTeamId(GetOtherTeam(player->GetTeam())); | |
/// @todo add reputation, events (including quest not available anymore, next quest availabe, go/npc de/spawning)and maybe honor | |
TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed", questid); | |
switch (questid) | |
@@ -180,21 +181,21 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player) | |
case AV_QUEST_A_COMMANDER1: | |
case AV_QUEST_H_COMMANDER1: | |
m_Team_QuestStatus[team][1]++; | |
- RewardReputationToTeam(team, 1, player->GetTeam()); | |
+ RewardReputationToTeam(team, oteam, 1, player->GetTeam()); | |
if (m_Team_QuestStatus[team][1] == 30) | |
TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid); | |
break; | |
case AV_QUEST_A_COMMANDER2: | |
case AV_QUEST_H_COMMANDER2: | |
m_Team_QuestStatus[team][2]++; | |
- RewardReputationToTeam(team, 1, player->GetTeam()); | |
+ RewardReputationToTeam(team, oteam, 1, player->GetTeam()); | |
if (m_Team_QuestStatus[team][2] == 60) | |
TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid); | |
break; | |
case AV_QUEST_A_COMMANDER3: | |
case AV_QUEST_H_COMMANDER3: | |
m_Team_QuestStatus[team][3]++; | |
- RewardReputationToTeam(team, 1, player->GetTeam()); | |
+ RewardReputationToTeam(team, oteam, 1, player->GetTeam()); | |
if (m_Team_QuestStatus[team][3] == 120) | |
TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid); | |
break; | |
@@ -506,7 +507,7 @@ void BattlegroundAV::EndBattleground(uint32 winner) | |
rep[i] += BG_AV_REP_SURVIVING_CAPTAIN; | |
} | |
if (rep[i] != 0) | |
- RewardReputationToTeam(i == 0 ? 730 : 729, rep[i], i == 0 ? ALLIANCE : HORDE); | |
+ RewardReputationToTeam(729, 730, 10, i == ALLIANCE ? ALLIANCE : HORDE); | |
if (kills[i] != 0) | |
RewardHonorToTeam(GetBonusHonor(kills[i]), i == 0 ? ALLIANCE : HORDE); | |
} | |
@@ -625,7 +626,7 @@ void BattlegroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node) | |
SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10), RESPAWN_IMMEDIATELY); | |
UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, -1 * BG_AV_RES_TOWER); | |
- RewardReputationToTeam(owner == ALLIANCE ? 730 : 729, BG_AV_REP_TOWER, owner); | |
+ RewardReputationToTeam(729, 730, BG_AV_REP_TOWER, owner); | |
RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_TOWER), owner); | |
SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp), RESPAWN_ONE_DAY); | |
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
index 92d56bb..0dae635 100644 | |
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
@@ -312,7 +312,6 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player) | |
if (GetTeamScore(TEAM_ALLIANCE) < BG_WS_MAX_TEAM_SCORE) | |
AddPoint(ALLIANCE, 1); | |
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE); | |
- RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE); | |
} | |
else | |
{ | |
@@ -331,8 +330,8 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player) | |
if (GetTeamScore(TEAM_HORDE) < BG_WS_MAX_TEAM_SCORE) | |
AddPoint(HORDE, 1); | |
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE); | |
- RewardReputationToTeam(889, m_ReputationCapture, HORDE); | |
} | |
+ RewardReputationToTeam(890, 889, m_ReputationCapture, player->GetTeam()); | |
//for flag capture is reward 2 honorable kills | |
RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeam()); | |
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt | |
index bf46c1f..a87edb0 100644 | |
--- a/src/server/game/CMakeLists.txt | |
+++ b/src/server/game/CMakeLists.txt | |
@@ -48,6 +48,7 @@ file(GLOB_RECURSE sources_Tickets Tickets/*.cpp Tickets/*.h) | |
file(GLOB_RECURSE sources_Warden Warden/*.cpp Warden/*.h) | |
file(GLOB_RECURSE sources_Weather Weather/*.cpp Weather/*.h) | |
file(GLOB_RECURSE sources_World World/*.cpp World/*.h) | |
+file(GLOB_RECURSE sources_Cfbg Cfbg/*.cpp Cfbg/*.h) | |
# Create game-libary | |
@@ -98,6 +99,7 @@ set(game_STAT_SRCS | |
${sources_Warden} | |
${sources_Weather} | |
${sources_World} | |
+ ${sources_Cfbg} | |
) | |
include_directories( | |
diff --git a/src/server/game/Cfbg/Cfbg.cpp b/src/server/game/Cfbg/Cfbg.cpp | |
new file mode 100644 | |
index 0000000..39946c7 | |
--- /dev/null | |
+++ b/src/server/game/Cfbg/Cfbg.cpp | |
@@ -0,0 +1,339 @@ | |
+#include "Cfbg.h" | |
+#include "Battleground.h" | |
+#include "BattlegroundMgr.h" | |
+#include "Player.h" | |
+#include "Chat.h" | |
+#include "BattlegroundQueue.h" | |
+ | |
+/*#################################################################################### | |
+###############################CROSSFACTION BATTLEGROUNDS############################# | |
+####################################################################################*/ | |
+ | |
+uint8 Unit::getRace(bool forceoriginal) const | |
+{ | |
+ if (GetTypeId() == TYPEID_PLAYER) | |
+ { | |
+ Player* pPlayer = ((Player*)this); | |
+ | |
+ if (forceoriginal) | |
+ return pPlayer->getORace(); | |
+ | |
+ if (pPlayer->InArena()) | |
+ return GetByteValue(UNIT_FIELD_BYTES_0, 0); | |
+ | |
+ if (!pPlayer->IsPlayingNative()) | |
+ return pPlayer->getFRace(); | |
+ } | |
+ | |
+ return GetByteValue(UNIT_FIELD_BYTES_0, 0); | |
+} | |
+ | |
+bool Player::SendRealNameQuery() | |
+{ | |
+ if (IsPlayingNative()) | |
+ return false; | |
+ | |
+ WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10)); | |
+ data.appendPackGUID(GetGUID()); // player guid | |
+ data << uint8(0); // added in 3.1; if > 1, then end of packet | |
+ data << GetName(); // played name | |
+ data << uint8(0); // realm name for cross realm BG usage | |
+ data << uint8(getORace()); | |
+ data << uint8(getGender()); | |
+ data << uint8(getClass()); | |
+ data << uint8(0); // is not declined | |
+ GetSession()->SendPacket(&data); | |
+ | |
+ return true; | |
+} | |
+ | |
+void Player::SetFakeRaceAndMorph() | |
+{ | |
+ if (getClass() == CLASS_DRUID) | |
+ { | |
+ if (GetOTeam() == ALLIANCE) | |
+ { | |
+ m_FakeMorph = getGender() == GENDER_MALE ? FAKE_M_TAUREN : FAKE_F_TAUREN; | |
+ m_FakeRace = RACE_TAUREN; | |
+ } | |
+ else if (getGender() == GENDER_MALE) // HORDE PLAYER, ONLY HAVE MALE NELF ID | |
+ { | |
+ m_FakeMorph = FAKE_M_NELF; | |
+ m_FakeRace = RACE_NIGHTELF; | |
+ } | |
+ else | |
+ m_FakeRace = GetOTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN; | |
+ } | |
+ else if (getClass() == CLASS_SHAMAN && GetOTeam() == HORDE && getGender() == GENDER_FEMALE) | |
+ { | |
+ m_FakeMorph = FAKE_F_DRANAEI; // Female Draenei | |
+ m_FakeRace = RACE_DRAENEI; | |
+ } | |
+ else | |
+ { | |
+ m_FakeRace = GetOTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN; | |
+ | |
+ if (GetOTeam() == HORDE) | |
+ { | |
+ if (getGender() == GENDER_MALE) | |
+ m_FakeMorph = 19723; | |
+ else | |
+ m_FakeMorph = 19724; | |
+ } | |
+ else | |
+ { | |
+ if (getGender() == GENDER_MALE) | |
+ m_FakeMorph = 20578; | |
+ else | |
+ m_FakeMorph = 20579; | |
+ } | |
+ } | |
+} | |
+ | |
+bool Player::SendBattleGroundChat(uint32 msgtype, std::string message) | |
+{ | |
+ // Select distance to broadcast to. | |
+ float distance = msgtype == CHAT_MSG_SAY ? sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY) : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL); | |
+ | |
+ if (Battleground* pBattleGround = GetBattleground()) | |
+ { | |
+ if (pBattleGround->isArena()) // Only fake chat in BG's. CFBG should not interfere with arenas. | |
+ return false; | |
+ | |
+ for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr) | |
+ { | |
+ if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first)) | |
+ { | |
+ if (GetDistance2d(pPlayer->GetPositionX(), pPlayer->GetPositionY()) <= distance) | |
+ { | |
+ WorldPacket data(SMSG_MESSAGECHAT, 200); | |
+ | |
+ if (GetTeam() == pPlayer->GetTeam()) | |
+ BuildPlayerChat(&data, msgtype, message, LANG_UNIVERSAL); | |
+ else if (msgtype != CHAT_MSG_EMOTE) | |
+ BuildPlayerChat(&data, msgtype, message, pPlayer->GetTeam() == ALLIANCE ? LANG_ORCISH : LANG_COMMON); | |
+ | |
+ pPlayer->GetSession()->SendPacket(&data); | |
+ } | |
+ } | |
+ } | |
+ return true; | |
+ } | |
+ else | |
+ return false; | |
+} | |
+ | |
+void Player::MorphFit(bool value) | |
+{ | |
+ if (!IsPlayingNative() && value) | |
+ { | |
+ SetDisplayId(GetFakeMorph()); | |
+ SetNativeDisplayId(GetFakeMorph()); | |
+ } | |
+ else | |
+ InitDisplayIds(); | |
+} | |
+ | |
+void Player::FitPlayerInTeam(bool action, Battleground* pBattleGround) | |
+{ | |
+ if (!pBattleGround) | |
+ pBattleGround = GetBattleground(); | |
+ | |
+ if ((!pBattleGround || pBattleGround->isArena()) && action) | |
+ return; | |
+ | |
+ if(!IsPlayingNative() && action) | |
+ setFactionForRace(getRace()); | |
+ else | |
+ setFactionForRace(getORace()); | |
+ | |
+ if (action) | |
+ SetForgetBGPlayers(true); | |
+ else | |
+ SetForgetInListPlayers(true); | |
+ | |
+ MorphFit(action); | |
+ | |
+ if (pBattleGround && action) | |
+ 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()); | |
+} | |
+ | |
+void Player::DoForgetPlayersInList() | |
+{ | |
+ // m_FakePlayers is filled from a vector within the battleground | |
+ // they were in previously so all players that have been in that BG will be invalidated. | |
+ for (FakePlayers::const_iterator itr = m_FakePlayers.begin(); itr != m_FakePlayers.end(); ++itr) | |
+ { | |
+ WorldPacket data(SMSG_INVALIDATE_PLAYER, 8); | |
+ data << *itr; | |
+ GetSession()->SendPacket(&data); | |
+ if (Player* pPlayer = ObjectAccessor::FindPlayer(*itr)) | |
+ GetSession()->SendNameQueryOpcode(pPlayer->GetGUID()); | |
+ } | |
+ m_FakePlayers.clear(); | |
+} | |
+ | |
+void Player::DoForgetPlayersInBG(Battleground* pBattleGround) | |
+{ | |
+ for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr) | |
+ { | |
+ // Here we invalidate players in the bg to the added player | |
+ WorldPacket data1(SMSG_INVALIDATE_PLAYER, 8); | |
+ data1 << itr->first; | |
+ GetSession()->SendPacket(&data1); | |
+ | |
+ if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first)) | |
+ { | |
+ GetSession()->SendNameQueryOpcode(pPlayer->GetGUID()); // Send namequery answer instantly if player is available | |
+ // Here we invalidate the player added to players in the bg | |
+ WorldPacket data2(SMSG_INVALIDATE_PLAYER, 8); | |
+ data2 << GetGUID(); | |
+ pPlayer->GetSession()->SendPacket(&data2); | |
+ pPlayer->GetSession()->SendNameQueryOpcode(GetGUID()); | |
+ } | |
+ } | |
+} | |
+ | |
+bool BattlegroundQueue::CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg) | |
+{ | |
+ if (!sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) || bg->isArena()) | |
+ return false; // Only do this if crossbg's are enabled. | |
+ | |
+ // Here we will add all players to selectionpool, later we check if there are enough and launch a bg. | |
+ FillXPlayersToBG(bracket_id, bg, true); | |
+ | |
+ if (sBattlegroundMgr->isTesting() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) | |
+ return true; | |
+ | |
+ uint8 MPT = bg->GetMinPlayersPerTeam(); | |
+ if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() < MPT || m_SelectionPools[TEAM_HORDE].GetPlayerCount() < MPT) | |
+ return false; | |
+ | |
+ return true; | |
+} | |
+ | |
+// This function will invite players in the least populated faction, which makes battleground queues much faster. | |
+// This function will return true if cross faction battlegrounds are enabled, otherwise return false, | |
+// which is useful in FillPlayersToBG. Because then we can interrupt the regular invitation if cross faction bg's are enabled. | |
+bool BattlegroundQueue::FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start) | |
+{ | |
+ uint8 queuedPeople = 0; | |
+ for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].end(); ++itr) | |
+ if (!(*itr)->IsInvitedToBGInstanceGUID) | |
+ queuedPeople += (*itr)->Players.size(); | |
+ | |
+ if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && (sBattlegroundMgr->isTesting() || queuedPeople >= bg->GetMinPlayersPerTeam()*2 || !start)) | |
+ { | |
+ int32 aliFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(ALLIANCE); | |
+ int32 hordeFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(HORDE); | |
+ // Empty selection pools. They will be refilled from queued groups. | |
+ m_SelectionPools[TEAM_ALLIANCE].Init(); | |
+ m_SelectionPools[TEAM_HORDE].Init(); | |
+ int32 valiFree = aliFree; | |
+ int32 vhordeFree = hordeFree; | |
+ int32 diff = 0; | |
+ | |
+ | |
+ // Add teams to their own factions as far as possible. | |
+ if (start) | |
+ { | |
+ QueuedGroupMap m_PreGroupMap_a, m_PreGroupMap_h; | |
+ int32 m_SmallestOfTeams = 0; | |
+ int32 queuedAlliance = 0; | |
+ int32 queuedHorde = 0; | |
+ | |
+ for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].end(); ++itr) | |
+ { | |
+ if ((*itr)->IsInvitedToBGInstanceGUID) | |
+ continue; | |
+ | |
+ bool alliance = (*itr)->OTeam == ALLIANCE; | |
+ | |
+ if (alliance) | |
+ { | |
+ m_PreGroupMap_a.insert(std::make_pair((*itr)->Players.size(), *itr)); | |
+ queuedAlliance += (*itr)->Players.size(); | |
+ } | |
+ else | |
+ { | |
+ m_PreGroupMap_h.insert(std::make_pair((*itr)->Players.size(), *itr)); | |
+ queuedHorde += (*itr)->Players.size(); | |
+ } | |
+ } | |
+ | |
+ m_SmallestOfTeams = std::min(std::min(aliFree, queuedAlliance), std::min(hordeFree, queuedHorde)); | |
+ | |
+ valiFree -= PreAddPlayers(m_PreGroupMap_a, m_SmallestOfTeams, aliFree); | |
+ vhordeFree -= PreAddPlayers(m_PreGroupMap_h, m_SmallestOfTeams, hordeFree); | |
+ } | |
+ | |
+ QueuedGroupMap m_QueuedGroupMap; | |
+ | |
+ for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_MIXED].end(); ++itr) | |
+ m_QueuedGroupMap.insert(std::make_pair((*itr)->Players.size(), *itr)); | |
+ | |
+ for (QueuedGroupMap::reverse_iterator itr = m_QueuedGroupMap.rbegin(); itr != m_QueuedGroupMap.rend(); ++itr) | |
+ { | |
+ GroupsQueueType allypool = m_SelectionPools[TEAM_ALLIANCE].SelectedGroups; | |
+ GroupsQueueType hordepool = m_SelectionPools[TEAM_HORDE].SelectedGroups; | |
+ | |
+ GroupQueueInfo* ginfo = itr->second; | |
+ | |
+ // If player already was invited via pre adding (add to own team first) or he was already invited to a bg, skip. | |
+ if (ginfo->IsInvitedToBGInstanceGUID || | |
+ std::find(allypool.begin(), allypool.end(), ginfo) != allypool.end() || | |
+ std::find(hordepool.begin(), hordepool.end(), ginfo) != hordepool.end() || | |
+ (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= bg->GetMinPlayersPerTeam() && | |
+ m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= bg->GetMinPlayersPerTeam())) | |
+ continue; | |
+ | |
+ diff = abs(valiFree - vhordeFree); | |
+ bool moreAli = valiFree < vhordeFree; | |
+ | |
+ if (diff > 0) | |
+ ginfo->Team = moreAli ? HORDE : ALLIANCE; | |
+ | |
+ bool alliance = ginfo->Team == ALLIANCE; | |
+ | |
+ if (m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(ginfo, alliance ? aliFree : hordeFree)) | |
+ alliance ? valiFree -= ginfo->Players.size() : vhordeFree -= ginfo->Players.size(); | |
+ } | |
+ | |
+ return true; | |
+ } | |
+ return false; | |
+} | |
+ | |
+int32 BattlegroundQueue::PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam) | |
+{ | |
+ int32 LeftToAdd = MaxAdd; | |
+ uint32 Added = 0; | |
+ | |
+ for (QueuedGroupMap::reverse_iterator itr = m_PreGroupMap.rbegin(); itr != m_PreGroupMap.rend(); ++itr) | |
+ { | |
+ int32 PlayerSize = itr->first; | |
+ bool alliance = itr->second->OTeam == ALLIANCE; | |
+ | |
+ if (PlayerSize <= LeftToAdd && m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(itr->second, MaxInTeam)) | |
+ LeftToAdd -= PlayerSize, Added -= PlayerSize; | |
+ } | |
+ | |
+ return LeftToAdd; | |
+} | |
+ | |
+void Player::SendChatMessage(const char *format, ...) | |
+{ | |
+ if (!IsInWorld()) | |
+ return; | |
+ | |
+ if (format) | |
+ { | |
+ va_list ap; | |
+ char str [2048]; | |
+ va_start(ap, format); | |
+ vsnprintf(str, 2048, format, ap); | |
+ va_end(ap); | |
+ | |
+ ChatHandler(GetSession()).SendSysMessage(str); | |
+ } | |
+} | |
diff --git a/src/server/game/Cfbg/Cfbg.h b/src/server/game/Cfbg/Cfbg.h | |
new file mode 100644 | |
index 0000000..bda4199 | |
--- /dev/null | |
+++ b/src/server/game/Cfbg/Cfbg.h | |
@@ -0,0 +1,44 @@ | |
+#ifndef _CUSTOM_H | |
+#define _CUSTOM_H | |
+ | |
+#define MSG_COLOR_LIGHTRED "|cffff6060" | |
+#define MSG_COLOR_LIGHTBLUE "|cff00ccff" | |
+#define MSG_COLOR_ANN_GREEN "|c1f40af20" | |
+#define MSG_COLOR_RED "|cffff0000" | |
+#define MSG_COLOR_GOLD "|cffffcc00" | |
+#define MSG_COLOR_SUBWHITE "|cffbbbbbb" | |
+#define MSG_COLOR_MAGENTA "|cffff00ff" | |
+#define MSG_COLOR_YELLOW "|cffffff00" | |
+#define MSG_COLOR_CYAN "|cff00ffff" | |
+#define MSG_COLOR_DARKBLUE "|cff0000ff" | |
+ | |
+#define MSG_COLOR_GREY "|cff9d9d9d" | |
+#define MSG_COLOR_WHITE "|cffffffff" | |
+#define MSG_COLOR_GREEN "|cff1eff00" | |
+#define MSG_COLOR_BLUE "|cff0080ff" | |
+#define MSG_COLOR_PURPLE "|cffb048f8" | |
+#define MSG_COLOR_ORANGE "|cffff8000" | |
+ | |
+#define MSG_COLOR_DRUID "|cffff7d0a" | |
+#define MSG_COLOR_HUNTER "|cffabd473" | |
+#define MSG_COLOR_MAGE "|cff69ccf0" | |
+#define MSG_COLOR_PALADIN "|cfff58cba" | |
+#define MSG_COLOR_PRIEST "|cffffffff" | |
+#define MSG_COLOR_ROGUE "|cfffff569" | |
+#define MSG_COLOR_SHAMAN "|cff0070de" | |
+#define MSG_COLOR_WARLOCK "|cff9482c9" | |
+#define MSG_COLOR_WARRIOR "|cffc79c6e" | |
+#define MSG_COLOR_DEATH_KNIGHT "|cffc41f3b" | |
+#define MSG_COLOR_MONK "|cff00ff96" | |
+ | |
+#define LIMIT_UINT32 2147483647 | |
+ | |
+enum FakeMorphs | |
+{ | |
+ FAKE_F_TAUREN = 20584, | |
+ FAKE_M_TAUREN = 20585, | |
+ FAKE_M_NELF = 20318, | |
+ FAKE_F_DRANAEI = 20323, | |
+}; | |
+ | |
+#endif | |
\ No newline at end of file | |
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp | |
index eb9392f..0e321e7 100644 | |
--- a/src/server/game/Entities/Player/Player.cpp | |
+++ b/src/server/game/Entities/Player/Player.cpp | |
@@ -653,6 +653,12 @@ Player::Player(WorldSession* session): Unit(true) | |
#pragma warning(default:4355) | |
#endif | |
+ m_FakeRace = 0; | |
+ m_RealRace = 0; | |
+ m_FakeMorph = 0; | |
+ m_ForgetBGPlayers = false; | |
+ m_ForgetInListPlayers = false; | |
+ | |
m_speakTime = 0; | |
m_speakCount = 0; | |
@@ -1001,6 +1007,12 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) | |
uint32 RaceClassGender = (createInfo->Race) | (createInfo->Class << 8) | (createInfo->Gender << 16); | |
SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24))); | |
+ | |
+ SetORace(); | |
+ m_team = TeamForRace(getORace()); | |
+ SetFakeRaceAndMorph(); // m_team must be set before this can be used. | |
+ setFactionForRace(getORace()); | |
+ | |
InitDisplayIds(); | |
if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP) | |
{ | |
@@ -3025,7 +3037,7 @@ void Player::GiveLevel(uint8 level) | |
guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level); | |
PlayerLevelInfo info; | |
- sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info); | |
+ sObjectMgr->GetPlayerLevelInfo(getORace(), getClass(), level, &info); | |
PlayerClassLevelInfo classInfo; | |
sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo); | |
@@ -3163,7 +3175,7 @@ void Player::InitStatsForLevel(bool reapplyMods) | |
sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), &classInfo); | |
PlayerLevelInfo info; | |
- sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), getLevel(), &info); | |
+ sObjectMgr->GetPlayerLevelInfo(getORace(), getClass(), getLevel(), &info); | |
SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)); | |
SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(getLevel())); | |
@@ -5261,7 +5273,7 @@ void Player::CreateCorpse() | |
return; | |
} | |
- _uf = GetUInt32Value(UNIT_FIELD_BYTES_0); | |
+ _uf = getORace(); | |
_pb = GetUInt32Value(PLAYER_BYTES); | |
_pb2 = GetUInt32Value(PLAYER_BYTES_2); | |
@@ -6924,10 +6936,10 @@ uint32 Player::TeamForRace(uint8 race) | |
void Player::setFactionForRace(uint8 race) | |
{ | |
- m_team = TeamForRace(race); | |
+ SetBGTeam(TeamForRace(race)); | |
ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race); | |
- setFaction(rEntry ? rEntry->FactionID : 0); | |
+ setFaction(rEntry ? rEntry->FactionID : getFaction()); | |
} | |
ReputationRank Player::GetReputationRank(uint32 faction) const | |
@@ -7029,6 +7041,27 @@ void Player::RewardReputation(Unit* victim, float rate) | |
if (!Rep) | |
return; | |
+ uint32 repfaction1 = Rep->RepFaction1; | |
+ uint32 repfaction2 = Rep->RepFaction2; | |
+ | |
+ if (!IsPlayingNative()) | |
+ { | |
+ if (GetOTeam() == ALLIANCE) | |
+ { | |
+ if (repfaction1 == 729) | |
+ repfaction1 = 730; | |
+ if (repfaction2 == 729) | |
+ repfaction2 = 730; | |
+ } | |
+ else | |
+ { | |
+ if (repfaction1 == 730) | |
+ repfaction1 = 729; | |
+ if (repfaction2 == 730) | |
+ repfaction2 = 729; | |
+ } | |
+ } | |
+ | |
uint32 ChampioningFaction = 0; | |
if (GetChampioningFaction()) | |
@@ -7043,23 +7076,23 @@ void Player::RewardReputation(Unit* victim, float rate) | |
uint32 team = GetTeam(); | |
- if (Rep->RepFaction1 && (!Rep->TeamDependent || team == ALLIANCE)) | |
+ if (repfaction1 && (!Rep->TeamDependent || team == ALLIANCE)) | |
{ | |
- int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); | |
+ int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : repfaction1); | |
donerep1 = int32(donerep1 * rate); | |
- FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); | |
+ FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction1); | |
uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1); | |
if (factionEntry1 && current_reputation_rank1 <= Rep->ReputationMaxCap1) | |
GetReputationMgr().ModifyReputation(factionEntry1, donerep1); | |
} | |
- if (Rep->RepFaction2 && (!Rep->TeamDependent || team == HORDE)) | |
+ if (repfaction2 && (!Rep->TeamDependent || team == HORDE)) | |
{ | |
- int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); | |
+ int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : repfaction2); | |
donerep2 = int32(donerep2 * rate); | |
- FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); | |
+ FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction2); | |
uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2); | |
if (factionEntry2 && current_reputation_rank2 <= Rep->ReputationMaxCap2) | |
GetReputationMgr().ModifyReputation(factionEntry2, donerep2); | |
@@ -7154,7 +7187,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto | |
if (!victim || victim == this || victim->GetTypeId() != TYPEID_PLAYER) | |
return false; | |
- if (GetBGTeam() == victim->ToPlayer()->GetBGTeam()) | |
+ if (GetTeam() == victim->ToPlayer()->GetTeam()) | |
return false; | |
return true; | |
@@ -11961,13 +11994,13 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const | |
if (proto) | |
{ | |
- if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeam() != HORDE) | |
+ if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetOTeam() != HORDE) | |
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; | |
- if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeam() != ALLIANCE) | |
+ if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetOTeam() != ALLIANCE) | |
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; | |
- if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0) | |
+ if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getORaceMask()) == 0) | |
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; | |
if (proto->RequiredSkill != 0) | |
@@ -17182,6 +17215,11 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) | |
bytes0 |= gender << 16; // gender | |
SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0); | |
+ SetORace(); | |
+ m_team = TeamForRace(getORace()); | |
+ SetFakeRaceAndMorph(); // m_team must be set before this can be used. | |
+ setFactionForRace(getORace());//Need to call it to initialize m_team (m_team can be calculated from race) | |
+ | |
SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8()); | |
SetUInt32Value(PLAYER_XP, fields[7].GetUInt32()); | |
@@ -17228,10 +17266,6 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) | |
TC_LOG_DEBUG("entities.player.loading", "Load Basic value of player %s is: ", m_name.c_str()); | |
outDebugValues(); | |
- //Need to call it to initialize m_team (m_team can be calculated from race) | |
- //Other way is to saves m_team into characters table. | |
- setFactionForRace(getRace()); | |
- | |
// load home bind and check in same time class/race pair, it used later for restore broken positions | |
if (!_LoadHomeBind(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_HOME_BIND))) | |
return false; | |
@@ -17500,7 +17534,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) | |
if (!map) | |
{ | |
- PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass()); | |
+ PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getORace(), getClass()); | |
mapId = info->mapId; | |
Relocate(info->positionX, info->positionY, info->positionZ, 0.0f); | |
map = sMapMgr->CreateMap(mapId, this); | |
@@ -19147,7 +19181,7 @@ void Player::SaveToDB(bool create /*=false*/) | |
stmt->setUInt32(index++, GetGUIDLow()); | |
stmt->setUInt32(index++, GetSession()->GetAccountId()); | |
stmt->setString(index++, GetName()); | |
- stmt->setUInt8(index++, getRace()); | |
+ stmt->setUInt8(index++, getORace()); | |
stmt->setUInt8(index++, getClass()); | |
stmt->setUInt8(index++, getGender()); | |
stmt->setUInt8(index++, getLevel()); | |
@@ -19252,7 +19286,7 @@ void Player::SaveToDB(bool create /*=false*/) | |
// Update query | |
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER); | |
stmt->setString(index++, GetName()); | |
- stmt->setUInt8(index++, getRace()); | |
+ stmt->setUInt8(index++, getORace()); | |
stmt->setUInt8(index++, getClass()); | |
stmt->setUInt8(index++, getGender()); | |
stmt->setUInt8(index++, getLevel()); | |
@@ -20491,6 +20525,19 @@ void Player::StopCastingCharm() | |
} | |
} | |
+void Player::BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language) const | |
+{ | |
+ *data << uint8(msgtype); | |
+ *data << uint32(language); | |
+ *data << uint64(GetGUID()); | |
+ *data << uint32(0); // constant unknown time | |
+ *data << uint64(GetGUID()); | |
+ *data << uint32(text.length() + 1); | |
+ *data << text; | |
+ *data << uint8(GetChatTag()); | |
+} | |
+ | |
+ | |
void Player::Say(const std::string& text, const uint32 language) | |
{ | |
std::string _text(text); | |
@@ -22276,11 +22323,6 @@ void Player::SetBGTeam(uint32 team) | |
SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? 1 : 0)); | |
} | |
-uint32 Player::GetBGTeam() const | |
-{ | |
- return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); | |
-} | |
- | |
void Player::LeaveBattleground(bool teleportToEntryPoint) | |
{ | |
if (Battleground* bg = GetBattleground()) | |
@@ -22356,7 +22398,7 @@ void Player::ReportedAfkBy(Player* reporter) | |
WorldLocation Player::GetStartPosition() const | |
{ | |
- PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass()); | |
+ PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getORace(), getClass()); | |
uint32 mapId = info->mapId; | |
if (getClass() == CLASS_DEATH_KNIGHT && HasSpell(50977)) | |
mapId = 0; | |
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h | |
index 2eb740f..38f3d24 100644 | |
--- a/src/server/game/Entities/Player/Player.h | |
+++ b/src/server/game/Entities/Player/Player.h | |
@@ -1067,6 +1067,35 @@ class Player : public Unit, public GridObject<Player> | |
public: | |
explicit Player(WorldSession* session); | |
~Player(); | |
+ private: | |
+ bool m_ForgetBGPlayers; | |
+ bool m_ForgetInListPlayers; | |
+ uint8 m_FakeRace; | |
+ uint8 m_RealRace; | |
+ uint32 m_FakeMorph; | |
+ public: | |
+ typedef std::vector<uint64> FakePlayers; | |
+ void SendChatMessage(const char *format, ...); | |
+ void FitPlayerInTeam(bool action, Battleground* pBattleGround = NULL); | |
+ void DoForgetPlayersInList(); | |
+ void DoForgetPlayersInBG(Battleground* pBattleGround); | |
+ uint8 getORace() const { return m_RealRace; } | |
+ void SetORace() { m_RealRace = GetByteValue(UNIT_FIELD_BYTES_0, 0); }; // SHOULD ONLY BE CALLED ON LOGIN | |
+ void SetFakeRace(); // SHOULD ONLY BE CALLED ON LOGIN | |
+ void SetFakeRaceAndMorph(); // SHOULD ONLY BE CALLED ON LOGIN | |
+ uint32 GetFakeMorph() { return m_FakeMorph; }; | |
+ uint8 getFRace() const { return m_FakeRace; } | |
+ void SetForgetBGPlayers(bool value) { m_ForgetBGPlayers = value; } | |
+ bool ShouldForgetBGPlayers() { return m_ForgetBGPlayers; } | |
+ void SetForgetInListPlayers(bool value) { m_ForgetInListPlayers = value; } | |
+ bool ShouldForgetInListPlayers() { return m_ForgetInListPlayers; } | |
+ bool SendBattleGroundChat(uint32 msgtype, std::string message); | |
+ void MorphFit(bool value); | |
+ bool IsPlayingNative() const { return GetTeam() == m_team; } | |
+ uint32 GetOTeam() const { return m_team; } | |
+ uint32 GetTeam() const { return m_bgData.bgTeam && GetBattleground() ? m_bgData.bgTeam : m_team; } | |
+ bool SendRealNameQuery(); | |
+ FakePlayers m_FakePlayers; | |
void CleanupsBeforeDelete(bool finalCleanup = true); | |
@@ -1120,7 +1149,7 @@ class Player : public Unit, public GridObject<Player> | |
PlayerSocial *GetSocial() { return m_social; } | |
PlayerTaxi m_taxi; | |
- void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); } | |
+ void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getORace(), getClass(), getLevel()); } | |
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = NULL, uint32 spellid = 0); | |
bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0); | |
void CleanupAfterTaxiFlight(); | |
@@ -1188,6 +1217,8 @@ class Player : public Unit, public GridObject<Player> | |
void TextEmote(std::string const& text); | |
/// Handles whispers from Addons and players based on sender, receiver's guid and language. | |
void Whisper(std::string const& text, const uint32 language, uint64 receiver); | |
+ /// Constructs the player Chat data for the specific functions to use | |
+ void BuildPlayerChat(WorldPacket* data, uint8 msgtype, std::string const& text, uint32 language) const; | |
/*********************************************************/ | |
/*** STORAGE SYSTEM ***/ | |
@@ -1887,8 +1918,7 @@ class Player : public Unit, public GridObject<Player> | |
void CheckAreaExploreAndOutdoor(void); | |
static uint32 TeamForRace(uint8 race); | |
- uint32 GetTeam() const { return m_team; } | |
- TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; } | |
+ TeamId GetTeamId() const { return GetTeam() == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; } | |
void setFactionForRace(uint8 race); | |
void InitDisplayIds(); | |
@@ -2032,7 +2062,6 @@ class Player : public Unit, public GridObject<Player> | |
void SetBattlegroundEntryPoint(); | |
void SetBGTeam(uint32 team); | |
- uint32 GetBGTeam() const; | |
void LeaveBattleground(bool teleportToEntryPoint = true); | |
bool CanJoinToBattleground(Battleground const* bg) const; | |
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp | |
index 379cecc..06b5424 100644 | |
--- a/src/server/game/Entities/Unit/Unit.cpp | |
+++ b/src/server/game/Entities/Unit/Unit.cpp | |
@@ -15910,7 +15910,7 @@ void Unit::RemoveCharmedBy(Unit* charmer) | |
void Unit::RestoreFaction() | |
{ | |
if (GetTypeId() == TYPEID_PLAYER) | |
- ToPlayer()->setFactionForRace(getRace()); | |
+ ToPlayer()->setFactionForRace(ToPlayer()->getRace()); | |
else | |
{ | |
if (HasUnitTypeMask(UNIT_MASK_MINION)) | |
@@ -16658,6 +16658,21 @@ uint32 Unit::GetModelForTotem(PlayerTotemType totemType) | |
} | |
break; | |
} | |
+ default: // One standard for other races. | |
+ { // THANKS L30m4nc3r for this | |
+ switch (totemType) | |
+ { | |
+ case SUMMON_TYPE_TOTEM_FIRE: // fire | |
+ return 4589; | |
+ case SUMMON_TYPE_TOTEM_EARTH: // earth | |
+ return 4588; | |
+ case SUMMON_TYPE_TOTEM_WATER: // water | |
+ return 4587; | |
+ case SUMMON_TYPE_TOTEM_AIR: // air | |
+ return 4590; | |
+ } | |
+ break; | |
+ } | |
} | |
return 0; | |
} | |
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h | |
index 6b6d844..64dcbae 100644 | |
--- a/src/server/game/Entities/Unit/Unit.h | |
+++ b/src/server/game/Entities/Unit/Unit.h | |
@@ -1353,8 +1353,10 @@ class Unit : public WorldObject | |
uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); } | |
uint8 getLevelForTarget(WorldObject const* /*target*/) const { return getLevel(); } | |
void SetLevel(uint8 lvl); | |
- uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); } | |
+ uint8 getRace(bool forceoriginal = false) const; | |
+ uint8 getORace() { return getRace(true); } | |
uint32 getRaceMask() const { return 1 << (getRace()-1); } | |
+ uint32 getORaceMask() const { return 1 << (getRace(true) - 1); } | |
uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); } | |
uint32 getClassMask() const { return 1 << (getClass()-1); } | |
uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); } | |
diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp | |
index 0dfe396..042fd07 100644 | |
--- a/src/server/game/Handlers/BattleGroundHandler.cpp | |
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp | |
@@ -35,6 +35,8 @@ | |
#include "DisableMgr.h" | |
#include "Group.h" | |
+#include "Cfbg/Cfbg.h" | |
+ | |
void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) | |
{ | |
uint64 guid; | |
@@ -543,7 +545,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) | |
{ | |
// this line is checked, i only don't know if GetStartTime is changing itself after bg end! | |
// send status in Battleground | |
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); | |
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetTeam()); | |
SendPacket(&data); | |
continue; | |
} | |
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp | |
index f9a5ec2..d006b44 100644 | |
--- a/src/server/game/Handlers/CharacterHandler.cpp | |
+++ b/src/server/game/Handlers/CharacterHandler.cpp | |
@@ -1032,6 +1032,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) | |
sScriptMgr->OnPlayerLogin(pCurrChar); | |
delete holder; | |
+ | |
+ if (pCurrChar->GetTeam() != pCurrChar->GetOTeam()) | |
+ pCurrChar->FitPlayerInTeam(pCurrChar->GetBattleground() && !pCurrChar->GetBattleground()->isArena() ? true : false, pCurrChar->GetBattleground()); | |
} | |
void WorldSession::HandleSetFactionAtWar(WorldPacket& recvData) | |
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp | |
index fbc7856..d89e625 100644 | |
--- a/src/server/game/Handlers/ChatHandler.cpp | |
+++ b/src/server/game/Handlers/ChatHandler.cpp | |
@@ -48,6 +48,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) | |
recvData >> type; | |
recvData >> lang; | |
+ if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && lang != LANG_ADDON) | |
+ { | |
+ switch (type) | |
+ { | |
+ case CHAT_MSG_BATTLEGROUND: | |
+ case CHAT_MSG_BATTLEGROUND_LEADER: | |
+ lang = LANG_UNIVERSAL; | |
+ default: | |
+ break; | |
+ } | |
+ } | |
+ | |
if (type >= MAX_CHAT_MSG_TYPE) | |
{ | |
TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type); | |
@@ -261,6 +273,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) | |
return; | |
} | |
+ if (!GetPlayer()->IsGameMaster()) | |
+ if (GetPlayer()->SendBattleGroundChat(type, msg)) | |
+ return; | |
+ | |
if (type == CHAT_MSG_SAY) | |
sender->Say(msg, lang); | |
else if (type == CHAT_MSG_EMOTE) | |
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp | |
index 4fd1d51..390a589 100644 | |
--- a/src/server/game/Handlers/MiscHandler.cpp | |
+++ b/src/server/game/Handlers/MiscHandler.cpp | |
@@ -1425,6 +1425,21 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket& recvData) | |
void WorldSession::HandleTimeSyncResp(WorldPacket& recvData) | |
{ | |
+ Battleground* bg = _player->GetBattleground(); | |
+ if (bg) | |
+ { | |
+ if (_player->ShouldForgetBGPlayers() && bg) | |
+ { | |
+ _player->DoForgetPlayersInBG(bg); | |
+ _player->SetForgetBGPlayers(false); | |
+ } | |
+ } | |
+ else if (_player->ShouldForgetInListPlayers()) | |
+ { | |
+ _player->DoForgetPlayersInList(); | |
+ _player->SetForgetInListPlayers(false); | |
+ } | |
+ | |
TC_LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP"); | |
uint32 counter, clientTicks; | |
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp | |
index e30260d..3f26035 100644 | |
--- a/src/server/game/Handlers/QueryHandler.cpp | |
+++ b/src/server/game/Handlers/QueryHandler.cpp | |
@@ -48,7 +48,7 @@ void WorldSession::SendNameQueryOpcode(uint64 guid) | |
data << uint8(0); // name known | |
data << nameData->m_name; // played name | |
data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds) | |
- data << uint8(nameData->m_race); | |
+ data << uint8(player ? player->getRace() : nameData->m_race); | |
data << uint8(nameData->m_gender); | |
data << uint8(nameData->m_class); | |
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp | |
index 729dfac..f3bf130 100644 | |
--- a/src/server/game/World/World.cpp | |
+++ b/src/server/game/World/World.cpp | |
@@ -1044,6 +1044,8 @@ void World::LoadConfigSettings(bool reload) | |
m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true); | |
+ m_bool_configs[BATTLEGROUND_CROSSFACTION_ENABLED] = sConfigMgr->GetBoolDefault("CrossfactionBG.enable", true); | |
+ | |
if (int32 clientCacheId = sConfigMgr->GetIntDefault("ClientCacheVersion", 0)) | |
{ | |
// overwrite DB/old value | |
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h | |
index 4c43507..fb0d461 100644 | |
--- a/src/server/game/World/World.h | |
+++ b/src/server/game/World/World.h | |
@@ -85,6 +85,7 @@ enum WorldTimers | |
enum WorldBoolConfigs | |
{ | |
CONFIG_DURABILITY_LOSS_IN_PVP = 0, | |
+ BATTLEGROUND_CROSSFACTION_ENABLED, | |
CONFIG_ADDON_CHANNEL, | |
CONFIG_ALLOW_PLAYER_COMMANDS, | |
CONFIG_CLEAN_CHARACTER_DB, | |
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist | |
index 1762859..a1b10eb 100644 | |
--- a/src/server/worldserver/worldserver.conf.dist | |
+++ b/src/server/worldserver/worldserver.conf.dist | |
@@ -2843,3 +2843,15 @@ PacketSpoof.BanDuration = 86400 | |
# | |
################################################################################################### | |
+ | |
+################################################################################################### | |
+# | |
+# CROSSFACTION BG CONFIG | |
+# | |
+# CrossfactionBG.enable = 1 - Mixed battleground enabled. | |
+# CrossfactionBG.enable = 0 - Mixed battleground disabled. | |
+ | |
+CrossfactionBG.enable = 1 | |
+ | |
+# | |
+################################################################################################### | |
\ No newline at end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment