Last active
October 20, 2021 18:21
-
-
Save irancore/10913800 to your computer and use it in GitHub Desktop.
Crossfaction Battlegrounds For Last Revision Trinity
This file contains 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
From 4c18aba9cad7ed7120d3ddc2573de93eb653c73e Mon Sep 17 00:00:00 2001 | |
From: irancore <amir.cinderella@gmail.com> | |
Date: Tue, 12 May 2020 02:39:52 +0400 | |
Subject: [PATCH] crossfaction battleground | |
--- | |
src/server/game/Battlegrounds/Arena.cpp | 4 +- | |
.../game/Battlegrounds/Battleground.cpp | 50 ++- | |
src/server/game/Battlegrounds/Battleground.h | 2 +- | |
.../game/Battlegrounds/BattlegroundMgr.cpp | 2 +- | |
.../game/Battlegrounds/BattlegroundQueue.cpp | 89 +++-- | |
.../game/Battlegrounds/BattlegroundQueue.h | 13 +- | |
.../Battlegrounds/Zones/BattlegroundAB.cpp | 2 +- | |
.../Battlegrounds/Zones/BattlegroundAV.cpp | 20 +- | |
.../Battlegrounds/Zones/BattlegroundWS.cpp | 4 +- | |
src/server/game/Custom/Custom.cpp | 322 ++++++++++++++++++ | |
src/server/game/Custom/Custom.h | 36 ++ | |
src/server/game/Entities/Player/Player.cpp | 103 ++++-- | |
src/server/game/Entities/Player/Player.h | 42 ++- | |
src/server/game/Entities/Unit/Unit.cpp | 3 +- | |
src/server/game/Entities/Unit/Unit.h | 6 +- | |
.../game/Handlers/BattleGroundHandler.cpp | 13 +- | |
src/server/game/Handlers/CharacterHandler.cpp | 5 +- | |
src/server/game/Handlers/ChatHandler.cpp | 4 +- | |
src/server/game/Handlers/MovementHandler.cpp | 14 + | |
src/server/game/Handlers/QueryHandler.cpp | 2 +- | |
src/server/game/World/World.cpp | 1 + | |
src/server/game/World/World.h | 1 + | |
src/server/worldserver/worldserver.conf.dist | 10 + | |
23 files changed, 643 insertions(+), 105 deletions(-) | |
create mode 100644 src/server/game/Custom/Custom.cpp | |
create mode 100644 src/server/game/Custom/Custom.h | |
diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp | |
index 1a40c12797..b095959079 100644 | |
--- a/src/server/game/Battlegrounds/Arena.cpp | |
+++ b/src/server/game/Battlegrounds/Arena.cpp | |
@@ -74,9 +74,9 @@ Arena::Arena() | |
void Arena::AddPlayer(Player* player) | |
{ | |
Battleground::AddPlayer(player); | |
- PlayerScores[player->GetGUID().GetCounter()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); | |
+ PlayerScores[player->GetGUID().GetCounter()] = new ArenaScore(player->GetGUID(), player->GetTeam()); | |
- if (player->GetBGTeam() == ALLIANCE) // gold | |
+ if (player->GetTeam() == ALLIANCE) // gold | |
{ | |
if (player->GetTeam() == HORDE) | |
player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true); | |
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp | |
index 6ff4e1c6ea..397d3f5478 100644 | |
--- a/src/server/game/Battlegrounds/Battleground.cpp | |
+++ b/src/server/game/Battlegrounds/Battleground.cpp | |
@@ -244,7 +244,7 @@ inline void Battleground::_CheckSafePositions(uint32 diff) | |
continue; | |
Position pos = player->GetPosition(); | |
- Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetBGTeam())); | |
+ Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetTeam())); | |
if (pos.GetExactDistSq(startPos) > maxDist) | |
{ | |
TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId()); | |
@@ -464,7 +464,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); | |
@@ -637,22 +637,36 @@ 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) | |
{ | |
- FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); | |
- if (!factionEntry) | |
- return; | |
+ FactionEntry const* a_factionEntry = sFactionStore.LookupEntry(a_faction_id); | |
+ FactionEntry const* h_factionEntry = sFactionStore.LookupEntry(h_faction_id); | |
for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) | |
{ | |
Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam"); | |
- if (!player) | |
- continue; | |
+ if (!a_factionEntry || !h_factionEntry) | |
+ return; | |
- uint32 repGain = Reputation; | |
- AddPct(repGain, player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN)); | |
- AddPct(repGain, player->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction_id)); | |
- player->GetReputationMgr().ModifyReputation(factionEntry, repGain); | |
+ for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) | |
+ { | |
+ if (itr->second.OfflineRemoveTime) | |
+ continue; | |
+ | |
+ Player* player = ObjectAccessor::FindPlayer(itr->first); | |
+ | |
+ if (!player) | |
+ { | |
+ TC_LOG_ERROR("bg.battleground", "BattleGround:RewardReputationToTeam: %u not found!", itr->first); | |
+ continue; | |
+ } | |
+ uint32 team = player->GetTeam(); | |
+ if (team == TeamID) | |
+ if (Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam")) | |
+ { | |
+ player->GetReputationMgr().ModifyReputation(player->GetCFSTeam() == ALLIANCE ? a_factionEntry : h_factionEntry, Reputation); | |
+ } | |
+ } | |
} | |
} | |
@@ -797,7 +811,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, player->GetMapId()); | |
} | |
@@ -914,6 +928,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen | |
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 | |
@@ -985,7 +1000,7 @@ void Battleground::AddPlayer(Player* player) | |
// score struct must be created in inherited class | |
- uint32 team = player->GetBGTeam(); | |
+ uint32 team = player->GetTeam(); | |
BattlegroundPlayer bp; | |
bp.OfflineRemoveTime = 0; | |
@@ -1027,6 +1042,7 @@ 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 | |
@@ -1096,8 +1112,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())); | |
} | |
} | |
@@ -1714,7 +1730,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) | |
BuildPvPLogDataPacket(data); | |
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 a4af193dc4..9b75dfbf14 100644 | |
--- a/src/server/game/Battlegrounds/Battleground.h | |
+++ b/src/server/game/Battlegrounds/Battleground.h | |
@@ -384,7 +384,7 @@ class TC_GAME_API 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 variable, uint32 value); | |
virtual void EndBattleground(uint32 winner); | |
void BlockMovement(Player* player); | |
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
index 5b8e99f66f..049e2b6a9a 100644 | |
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp | |
@@ -702,7 +702,7 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt | |
if (Battleground* bg = GetBattleground(instanceId, bgTypeId)) | |
{ | |
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 633226f5ca..913ea3193f 100644 | |
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp | |
@@ -158,8 +158,12 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr | |
index += PVP_TEAMS_COUNT; | |
if (ginfo->Team == HORDE) | |
index++; | |
+ | |
+ if (sWorld->getBoolConfig(BATTLEGROUND_CROSSFACTION_ENABLED) && ArenaType == 0) | |
+ index = BG_QUEUE_CROSSFACTION; | |
+ | |
TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index); | |
- | |
+ | |
uint32 lastOnlineTime = GameTime::GetGameTimeMS(); | |
//announce world (this don't need mutex) | |
@@ -202,31 +206,59 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr | |
{ | |
if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId)) | |
{ | |
- 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, bg->GetName().c_str(), 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().c_str(); | |
+ 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_CROSSFACTION].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_CROSSFACTION].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, bg->GetName().c_str(), q_min_level, q_max_level, | |
- qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); | |
- } | |
+ // std::string bgName = bg->GetName().c_str(); | |
+ char const* bgName = bg->GetName().c_str(); | |
+ 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); | |
+ } | |
+ } | |
} | |
} | |
//release mutex | |
@@ -313,7 +345,8 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid 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 += PVP_TEAMS_COUNT) | |
+ //for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += PVP_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) | |
@@ -503,7 +536,9 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId | |
int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); | |
uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size(); | |
uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size(); | |
- | |
+ if (!bg->isArena()) | |
+ if (FillXPlayersToBG(bracket_id, bg, false)) | |
+ return; | |
// try to get even teams | |
if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_EVEN) | |
{ | |
@@ -777,7 +812,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_CROSSFACTION].empty()) | |
return; | |
// battleground with free slot for player should be always in the beggining of the queue | |
@@ -868,7 +904,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 b7cad6f5d4..166863eac7 100644 | |
--- a/src/server/game/Battlegrounds/BattlegroundQueue.h | |
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.h | |
@@ -41,6 +41,8 @@ struct GroupQueueInfo // stores informatio | |
{ | |
std::map<ObjectGuid, PlayerQueueInfo*> Players; // player queue info map | |
uint32 Team; // Player team (ALLIANCE/HORDE) | |
+ uint32 CFSTeam; | |
+ | |
BattlegroundTypeId BgTypeId; // battleground type id | |
bool IsRated; // rated | |
uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG | |
@@ -60,9 +62,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_CROSSFACTION = 4 | |
}; | |
-#define BG_QUEUE_GROUP_TYPES_COUNT 4 | |
+#define BG_QUEUE_GROUP_TYPES_COUNT 5 | |
enum BattlegroundQueueInvitationType | |
{ | |
@@ -80,7 +83,11 @@ class TC_GAME_API 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 1b3d927840..93a98f919b 100644 | |
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp | |
@@ -143,7 +143,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 5d3fbc4858..a3af506170 100644 | |
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp | |
@@ -96,7 +96,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
if (entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS]) | |
{ | |
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(GetBonusHonorFromKill(BG_AV_KILL_BOSS), HORDE); | |
EndBattleground(HORDE); | |
DelCreature(AV_CPLACE_TRIGGER17); | |
@@ -104,7 +104,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer) | |
else if (entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS]) | |
{ | |
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(GetBonusHonorFromKill(BG_AV_KILL_BOSS), ALLIANCE); | |
EndBattleground(ALLIANCE); | |
DelCreature(AV_CPLACE_TRIGGER19); | |
@@ -117,7 +117,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_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE); | |
UpdateScore(ALLIANCE, (-1)*BG_AV_RES_CAPTAIN); | |
//spawn destroyed aura | |
@@ -136,7 +136,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_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE); | |
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE); | |
UpdateScore(HORDE, (-1)*BG_AV_RES_CAPTAIN); | |
//spawn destroyed aura | |
@@ -158,6 +158,8 @@ 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 CFSteam = GetTeamIndexByTeamId(GetOtherTeam(player->GetTeam())); | |
+ | |
/// @todo add reputation, events (including quest not available anymore, next quest available, go/npc de/spawning)and maybe honor | |
TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed", questid); | |
switch (questid) | |
@@ -182,21 +184,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, CFSteam, 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, CFSteam, 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, CFSteam, 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; | |
@@ -481,7 +483,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(GetBonusHonorFromKill(kills[i]), i == 0 ? ALLIANCE : HORDE); | |
} | |
@@ -586,7 +588,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(GetBonusHonorFromKill(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 8b24aa1bc0..9c3a770821 100644 | |
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | |
@@ -311,7 +311,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 | |
{ | |
@@ -330,8 +329,9 @@ 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/Custom/Custom.cpp b/src/server/game/Custom/Custom.cpp | |
new file mode 100644 | |
index 0000000000..1937dd6f29 | |
--- /dev/null | |
+++ b/src/server/game/Custom/Custom.cpp | |
@@ -0,0 +1,322 @@ | |
+#include "Custom.h" | |
+#include "Battleground.h" | |
+#include "BattlegroundMgr.h" | |
+#include "Player.h" | |
+#include "Chat.h" | |
+#include "BattlegroundQueue.h" | |
+#include "World.h" | |
+#include <cstdarg> | |
+ | |
+uint8 Unit::GetRace(bool forceoriginal) const | |
+{ | |
+ if (GetTypeId() == TYPEID_PLAYER) | |
+ { | |
+ Player* pPlayer = ((Player*)this); | |
+ | |
+ if (forceoriginal) | |
+ return pPlayer->getCFSRace(); | |
+ | |
+ 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(getCFSRace()); | |
+ data << uint8(GetGender()); | |
+ data << uint8(GetClass()); | |
+ data << uint8(0); // is not declined | |
+ | |
+ return true; | |
+} | |
+ | |
+void Player::SetFakeRace() | |
+{ | |
+ m_FakeRace = GetCFSTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN; | |
+} | |
+ | |
+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) | |
+ { | |
+ if (GetCFSTeam() == HORDE) | |
+ { | |
+ if (GetGender() == GENDER_MALE) | |
+ { | |
+ SetDisplayId(19723); | |
+ SetNativeDisplayId(19723); | |
+ } | |
+ else | |
+ { | |
+ SetDisplayId(19724); | |
+ SetNativeDisplayId(19724); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ if (GetGender() == GENDER_MALE) | |
+ { | |
+ SetDisplayId(20578); | |
+ SetNativeDisplayId(20578); | |
+ } | |
+ else | |
+ { | |
+ SetDisplayId(20579); | |
+ SetNativeDisplayId(20579); | |
+ } | |
+ } | |
+ } | |
+ 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(getCFSRace()); | |
+ | |
+ 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().c_str()); | |
+} | |
+ | |
+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(ObjectGuid(*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_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].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_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr) | |
+ { | |
+ if ((*itr)->IsInvitedToBGInstanceGUID) | |
+ continue; | |
+ | |
+ bool alliance = (*itr)->CFSTeam == 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_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].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->CFSTeam == 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/Custom/Custom.h b/src/server/game/Custom/Custom.h | |
new file mode 100644 | |
index 0000000000..885faa094b | |
--- /dev/null | |
+++ b/src/server/game/Custom/Custom.h | |
@@ -0,0 +1,36 @@ | |
+#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 | |
+ | |
+#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 595614ce77..12b16da781 100644 | |
--- a/src/server/game/Entities/Player/Player.cpp | |
+++ b/src/server/game/Entities/Player/Player.cpp | |
@@ -171,6 +171,11 @@ uint32 const MAX_MONEY_AMOUNT = static_cast<uint32>(std::numeric_limits<int32>:: | |
Player::Player(WorldSession* session): Unit(true) | |
{ | |
+ m_FakeRace = 0; | |
+ m_RealRace = 0; | |
+ m_ForgetBGPlayers = false; | |
+ m_ForgetInListPlayers = false; | |
+ | |
m_speakTime = 0; | |
m_speakCount = 0; | |
@@ -520,7 +525,11 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo | |
SetClass(createInfo->Class); | |
SetGender(createInfo->Gender); | |
SetPowerType(Powers(powertype), false); | |
- InitDisplayIds(); | |
+ SetCFSRace(); | |
+ m_team = TeamForRace(getCFSRace()); | |
+ SetFakeRace(); // m_team must be set before this can be used. | |
+ SetFactionForRace(getCFSRace()); | |
+ InitDisplayIds(); | |
UpdatePositionData(); | |
if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP) | |
{ | |
@@ -2581,7 +2590,7 @@ void Player::GiveLevel(uint8 level) | |
guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level); | |
PlayerLevelInfo info; | |
- sObjectMgr->GetPlayerLevelInfo(GetRace(), GetClass(), level, &info); | |
+ sObjectMgr->GetPlayerLevelInfo(getCFSRace(), GetClass(), level, &info); | |
PlayerClassLevelInfo classInfo; | |
sObjectMgr->GetPlayerClassLevelInfo(GetClass(), level, &classInfo); | |
@@ -2716,7 +2725,7 @@ void Player::InitStatsForLevel(bool reapplyMods) | |
sObjectMgr->GetPlayerClassLevelInfo(GetClass(), GetLevel(), &classInfo); | |
PlayerLevelInfo info; | |
- sObjectMgr->GetPlayerLevelInfo(GetRace(), GetClass(), GetLevel(), &info); | |
+ sObjectMgr->GetPlayerLevelInfo(getCFSRace(), GetClass(), GetLevel(), &info); | |
SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)); | |
SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(GetLevel())); | |
@@ -4693,7 +4702,7 @@ Corpse* Player::CreateCorpse() | |
// prevent the existence of 2 corpses for one player | |
SpawnCorpseBones(); | |
- uint32 _cfb1, _cfb2; | |
+ uint32 _cfb1, _cfb2,_uf; | |
Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE); | |
SetPvPDeath(false); | |
@@ -4706,9 +4715,11 @@ Corpse* Player::CreateCorpse() | |
_corpseLocation.WorldRelocate(*this); | |
+ _uf = getCFSRace(); | |
_cfb1 = ((0x00) | (GetRace() << 8) | (GetNativeGender() << 16) | (GetSkinId() << 24)); | |
_cfb2 = (GetFaceId() | (GetHairStyleId() << 8) | (GetHairColorId() << 16) | (GetFacialStyle() << 24)); | |
+ uint8 race = (uint8) (_uf); | |
corpse->SetUInt32Value(CORPSE_FIELD_BYTES_1, _cfb1); | |
corpse->SetUInt32Value(CORPSE_FIELD_BYTES_2, _cfb2); | |
@@ -6508,10 +6519,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 | |
@@ -6612,7 +6623,26 @@ void Player::RewardReputation(Unit* victim, float rate) | |
ReputationOnKillEntry const* Rep = sObjectMgr->GetReputationOnKilEntry(victim->ToCreature()->GetCreatureTemplate()->Entry); | |
if (!Rep) | |
return; | |
+ uint32 repfaction1 = Rep->RepFaction1; | |
+ uint32 repfaction2 = Rep->RepFaction2; | |
+ if (!IsPlayingNative()) | |
+ { | |
+ if (GetCFSTeam() == 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()) | |
@@ -6627,23 +6657,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); | |
- donerep1 = int32(donerep1 * rate); | |
+ 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) | |
GetReputationMgr().ModifyReputation(factionEntry1, donerep1, current_reputation_rank1 > Rep->ReputationMaxCap1); | |
} | |
- 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) | |
GetReputationMgr().ModifyReputation(factionEntry2, donerep2, current_reputation_rank2 > Rep->ReputationMaxCap2); | |
@@ -6743,7 +6773,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; | |
@@ -11766,11 +11796,11 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const | |
if (!proto) | |
return EQUIP_ERR_ITEM_NOT_FOUND; | |
- if (((proto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && GetTeam() != HORDE) || | |
- (((proto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && GetTeam() != ALLIANCE))) | |
+ if (((proto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && GetCFSTeam() != HORDE) || | |
+ (((proto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && GetCFSTeam() != 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 & getCFSRaceMask()) == 0) | |
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; | |
if (proto->RequiredSkill != 0) | |
@@ -17240,6 +17270,11 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) | |
SetClass(fields[4].GetUInt8()); | |
SetGender(gender); | |
+ SetCFSRace(); | |
+ m_team = TeamForRace(getCFSRace()); | |
+ SetFakeRace(); // m_team must be set before this can be used. | |
+ SetFactionForRace(getCFSRace()); | |
+ | |
// check if race/class combination is valid | |
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
if (!info) | |
@@ -17311,10 +17346,6 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) | |
TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: 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; | |
@@ -19250,7 +19281,7 @@ void Player::AddInstanceEnterTime(uint32 instanceId, time_t enterTime) | |
bool Player::_LoadHomeBind(PreparedQueryResult result) | |
{ | |
- PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
+ PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), GetClass()); | |
if (!info) | |
{ | |
TC_LOG_ERROR("entities.player", "Player::_LoadHomeBind: Player '%s' (%s) has incorrect race/class (%u/%u) pair. Can't load.", | |
@@ -19351,7 +19382,7 @@ void Player::SaveToDB(bool create /*=false*/) | |
stmt->setUInt32(index++, GetGUID().GetCounter()); | |
stmt->setUInt32(index++, GetSession()->GetAccountId()); | |
stmt->setString(index++, GetName()); | |
- stmt->setUInt8(index++, GetRace()); | |
+ stmt->setUInt8(index++, getCFSRace()); | |
stmt->setUInt8(index++, GetClass()); | |
stmt->setUInt8(index++, GetNativeGender()); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect | |
stmt->setUInt8(index++, GetLevel()); | |
@@ -19461,7 +19492,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++, getCFSRace()); | |
stmt->setUInt8(index++, GetClass()); | |
stmt->setUInt8(index++, GetNativeGender()); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect | |
stmt->setUInt8(index++, GetLevel()); | |
@@ -21587,22 +21618,25 @@ void Player::InitDataForForm(bool reapplyMods) | |
void Player::InitDisplayIds() | |
{ | |
- PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
+ PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), GetClass()); | |
if (!info) | |
{ | |
TC_LOG_ERROR("entities.player", "Player::InitDisplayIds: Player '%s' (%s) has incorrect race/class pair. Can't init display ids.", GetName().c_str(), GetGUID().ToString().c_str()); | |
return; | |
} | |
+ bool isMorphed = GetNativeDisplayId() != GetDisplayId(); | |
uint8 gender = GetNativeGender(); | |
switch (gender) | |
{ | |
case GENDER_FEMALE: | |
+ if (!isMorphed) | |
SetDisplayId(info->displayId_f); | |
SetNativeDisplayId(info->displayId_f); | |
break; | |
case GENDER_MALE: | |
- SetDisplayId(info->displayId_m); | |
+ if (!isMorphed) | |
+ SetDisplayId(info->displayId_m); | |
SetNativeDisplayId(info->displayId_m); | |
break; | |
default: | |
@@ -22222,10 +22256,10 @@ void Player::SetBGTeam(uint32 team) | |
SetArenaFaction(uint8(team == ALLIANCE ? 1 : 0)); | |
} | |
-uint32 Player::GetBGTeam() const | |
+/*uint32 Player::GetBGTeam() const | |
{ | |
return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); | |
-} | |
+}*/ | |
void Player::LeaveBattleground(bool teleportToEntryPoint) | |
{ | |
@@ -22305,7 +22339,7 @@ void Player::ReportedAfkBy(Player* reporter) | |
WorldLocation Player::GetStartPosition() const | |
{ | |
- PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); | |
+ PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), GetClass()); | |
ASSERT(info); | |
uint32 mapId = info->mapId; | |
if (GetClass() == CLASS_DEATH_KNIGHT && HasSpell(50977)) | |
@@ -26898,3 +26932,14 @@ std::string Player::GetDebugInfo() const | |
sstr << Unit::GetDebugInfo(); | |
return sstr.str(); | |
} | |
+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()); | |
+} | |
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h | |
index 97835fb871..de484f5736 100644 | |
--- a/src/server/game/Entities/Player/Player.h | |
+++ b/src/server/game/Entities/Player/Player.h | |
@@ -883,7 +883,35 @@ class TC_GAME_API 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 FitPlayerInTeam(bool action, Battleground* bg = NULL); | |
+ void DoForgetPlayersInList(); | |
+ void DoForgetPlayersInBG(Battleground* pBattleGround); // void DoForgetPlayersInBG(Battleground* bg); | |
+ uint8 getCFSRace() const { return m_RealRace; } | |
+ void SetCFSRace() { 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 GetCFSTeam() const { return m_team; } | |
+ uint32 GetTeam() const { return m_bgData.bgTeam && GetBattleground() ? m_bgData.bgTeam : m_team; } | |
+ bool SendRealNameQuery(); | |
+ FakePlayers m_FakePlayers; | |
PlayerAI* AI() const { return reinterpret_cast<PlayerAI*>(GetAI()); } | |
void CleanupsBeforeDelete(bool finalCleanup = true) override; | |
@@ -939,7 +967,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> | |
void RemoveSocial(); | |
PlayerTaxi m_taxi; | |
- void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(GetRace(), GetClass(), GetLevel()); } | |
+ void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getCFSRace(), GetClass(), GetLevel()); } | |
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0); | |
bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0); | |
void FinishTaxiFlight(); | |
@@ -1034,6 +1062,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> | |
/// Handles whispers from Addons and players based on sender, receiver's guid and language. | |
void Whisper(std::string const& text, Language language, Player* receiver, bool = false) override; | |
void Whisper(uint32 textId, Player* target, bool isBossWhisper = false) override; | |
+ void BuildPlayerChat(WorldPacket* data, uint8 msgtype, std::string const& text, uint32 language) const; | |
+ | |
/*********************************************************/ | |
/*** STORAGE SYSTEM ***/ | |
@@ -1752,8 +1782,9 @@ class TC_GAME_API 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; } | |
+ //uint32 GetTeam() const { return m_team; } | |
+ TeamId GetTeamId() const { return GetTeam() == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; } | |
+ | |
void SetFactionForRace(uint8 race); | |
void InitDisplayIds(); | |
@@ -1924,8 +1955,7 @@ class TC_GAME_API 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; | |
bool CanReportAfkDueToLimit(); | |
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp | |
index 31ca50eb70..3a5e44b449 100644 | |
--- a/src/server/game/Entities/Unit/Unit.cpp | |
+++ b/src/server/game/Entities/Unit/Unit.cpp | |
@@ -11624,7 +11624,8 @@ 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)) | |
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h | |
index a90145c139..25449c1805 100644 | |
--- a/src/server/game/Entities/Unit/Unit.h | |
+++ b/src/server/game/Entities/Unit/Unit.h | |
@@ -845,9 +845,13 @@ class TC_GAME_API Unit : public WorldObject | |
uint8 GetLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); } | |
uint8 GetLevelForTarget(WorldObject const* /*target*/) const override { return GetLevel(); } | |
void SetLevel(uint8 lvl, bool sendUpdate = true); | |
- uint8 GetRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE); } | |
+ uint8 GetRace(bool forceoriginal = false) const; | |
+ uint8 getCFSRace() { return GetRace(true); } | |
+ | |
+ | |
void SetRace(uint8 race) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, race); } | |
uint32 GetRaceMask() const { return 1 << (GetRace() - 1); } | |
+ uint32 getCFSRaceMask() const { return 1 << (GetRace(true) - 1); } | |
uint8 GetClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); } | |
void SetClass(uint8 unitClass) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, unitClass); } | |
uint32 GetClassMask() const { return 1 << (GetClass() - 1); } | |
diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp | |
index 9245c22ec6..69700e257b 100644 | |
--- a/src/server/game/Handlers/BattleGroundHandler.cpp | |
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp | |
@@ -37,6 +37,7 @@ | |
#include "Player.h" | |
#include "World.h" | |
#include "WorldPacket.h" | |
+#include "Custom/Custom.h" | |
void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) | |
{ | |
@@ -295,14 +296,20 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvDa | |
data << flagCarrierCount; | |
if (allianceFlagCarrier) | |
{ | |
- data << uint64(allianceFlagCarrier->GetGUID()); | |
+ if (allianceFlagCarrier->SendRealNameQuery()) | |
+ data << uint64(allianceFlagCarrier->GetGUID() + LIMIT_UINT32); | |
+ else | |
+ data << uint64(allianceFlagCarrier->GetGUID()); | |
data << float(allianceFlagCarrier->GetPositionX()); | |
data << float(allianceFlagCarrier->GetPositionY()); | |
} | |
if (hordeFlagCarrier) | |
{ | |
- data << uint64(hordeFlagCarrier->GetGUID()); | |
+ if (hordeFlagCarrier->SendRealNameQuery()) | |
+ data << uint64(hordeFlagCarrier->GetGUID() + LIMIT_UINT32); | |
+ else | |
+ data << uint64(hordeFlagCarrier->GetGUID()); | |
data << float(hordeFlagCarrier->GetPositionX()); | |
data << float(hordeFlagCarrier->GetPositionY()); | |
} | |
@@ -567,7 +574,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 ed3923ca97..5821077d58 100644 | |
--- a/src/server/game/Handlers/CharacterHandler.cpp | |
+++ b/src/server/game/Handlers/CharacterHandler.cpp | |
@@ -51,6 +51,8 @@ | |
#include "SystemPackets.h" | |
#include "QueryHolder.h" | |
#include "World.h" | |
+#include "Battleground.h" | |
+#include "ArenaTeamMgr.h" | |
class LoginQueryHolder : public CharacterDatabaseQueryHolder | |
{ | |
@@ -998,7 +1000,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) | |
sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin); | |
TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName()); | |
- | |
+ if (pCurrChar->GetTeam() != pCurrChar->getCFSRace()) | |
+ pCurrChar->FitPlayerInTeam(pCurrChar->GetBattleground() && !pCurrChar->GetBattleground()->isArena() ? true : false, pCurrChar->GetBattleground()); | |
delete holder; | |
} | |
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp | |
index 91475ebbd7..44d73cf7e1 100644 | |
--- a/src/server/game/Handlers/ChatHandler.cpp | |
+++ b/src/server/game/Handlers/ChatHandler.cpp | |
@@ -269,7 +269,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) | |
if (!ValidateHyperlinksAndMaybeKick(msg)) | |
return; | |
} | |
- | |
+ if (!GetPlayer()->IsGameMaster()) | |
+ if (GetPlayer()->SendBattleGroundChat(type, msg)) | |
+ return; | |
switch (type) | |
{ | |
case CHAT_MSG_SAY: | |
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp | |
index 28c7d88f62..4b256d3b84 100644 | |
--- a/src/server/game/Handlers/MovementHandler.cpp | |
+++ b/src/server/game/Handlers/MovementHandler.cpp | |
@@ -656,6 +656,20 @@ void WorldSession::HandleMoveTimeSkippedOpcode(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, clientTimestamp; | |
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp | |
index bbff42acbe..943b66c761 100644 | |
--- a/src/server/game/Handlers/QueryHandler.cpp | |
+++ b/src/server/game/Handlers/QueryHandler.cpp | |
@@ -48,7 +48,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) | |
data << uint8(0); // name known | |
data << nameData->Name; // played name | |
data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds) | |
- data << uint8(nameData->Race); | |
+ data << uint8(player ? player->GetRace() : nameData->Race); | |
data << uint8(nameData->Sex); | |
data << uint8(nameData->Class); | |
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp | |
index 92551cf92e..ade0c56125 100644 | |
--- a/src/server/game/World/World.cpp | |
+++ b/src/server/game/World/World.cpp | |
@@ -1217,6 +1217,7 @@ void World::LoadConfigSettings(bool reload) | |
m_float_configs[CONFIG_ARENA_MATCHMAKER_RATING_MODIFIER] = sConfigMgr->GetFloatDefault("Arena.ArenaMatchmakerRatingModifier", 24.0f); | |
m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true); | |
+ m_bool_configs[BATTLEGROUND_CROSSFACTION_ENABLED] = sConfigMgr->GetBoolDefault("CrossfactionBG.enable", true); | |
m_int_configs[CONFIG_CREATURE_PICKPOCKET_REFILL] = sConfigMgr->GetIntDefault("Creature.PickPocketRefillDelay", 10 * MINUTE); | |
m_int_configs[CONFIG_CREATURE_STOP_FOR_PLAYER] = sConfigMgr->GetIntDefault("Creature.MovingStopTimeForPlayer", 3 * MINUTE * IN_MILLISECONDS); | |
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h | |
index 3765fb81e3..579ed40e72 100644 | |
--- a/src/server/game/World/World.h | |
+++ b/src/server/game/World/World.h | |
@@ -177,6 +177,7 @@ enum WorldBoolConfigs | |
CONFIG_CACHE_DATA_QUERIES, | |
CONFIG_CHECK_GOBJECT_LOS, | |
CONFIG_RESPAWN_DYNAMIC_ESCORTNPC, | |
+ BATTLEGROUND_CROSSFACTION_ENABLED, | |
BOOL_CONFIG_VALUE_COUNT | |
}; | |
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist | |
index fa0ddf42a7..889f33eaab 100644 | |
--- a/src/server/worldserver/worldserver.conf.dist | |
+++ b/src/server/worldserver/worldserver.conf.dist | |
@@ -4077,3 +4077,13 @@ Metric.OverallStatusInterval = 1 | |
# | |
################################################################################################### | |
+# CROSSFACTION BG CONFIG | |
+# Enable Crossfaction battleground | |
+# Default: 1 - on | |
+# 0 - off | |
+# Discord : Ac_Dev#8552 | |
+# | |
+ | |
+CrossfactionBG.enable = 1 | |
+ | |
+################################################################################################### | |
-- | |
2.26.0.windows.1 | |
hello can you update this to latest revision please i have allots of errors ; (
i almost fixed all but i'm stuck, with pCurrChar->GetBattleground error on Characterhandler
updated again <
@irancore
Hi. Is this script actually working on Last Trinitycore Révision without bug ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@nyhmii include WorldSession.h in custom.cpp your problem will be fix
@simpatiaga https://t.me/Amr721