mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Battlegrounds: Store mercenary status separately from the aura obtained from gossip as it can be removed at any time
This commit is contained in:
@@ -1050,6 +1050,7 @@ void Battleground::AddPlayer(Player* player)
|
||||
bp.OfflineRemoveTime = 0;
|
||||
bp.Team = team;
|
||||
bp.ActiveSpec = player->GetPrimarySpecialization();
|
||||
bp.Mercenary = player->IsMercenaryForBattlegroundQueueType(GetQueueId());
|
||||
|
||||
bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
|
||||
// Add to list/maps
|
||||
@@ -1124,15 +1125,19 @@ void Battleground::AddPlayer(Player* player)
|
||||
player->SendDirectMessage(startTimer.Write());
|
||||
}
|
||||
|
||||
if (player->HasAura(SPELL_MERCENARY_CONTRACT_HORDE))
|
||||
if (bp.Mercenary)
|
||||
{
|
||||
player->CastSpell(player, SPELL_MERCENARY_HORDE_1, true);
|
||||
player->CastSpell(player, SPELL_MERCENARY_HORDE_2, true);
|
||||
}
|
||||
else if (player->HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE))
|
||||
{
|
||||
player->CastSpell(player, SPELL_MERCENARY_ALLIANCE_1, true);
|
||||
player->CastSpell(player, SPELL_MERCENARY_ALLIANCE_2, true);
|
||||
if (bp.Team == HORDE)
|
||||
{
|
||||
player->CastSpell(player, SPELL_MERCENARY_HORDE_1);
|
||||
player->CastSpell(player, SPELL_MERCENARY_HORDE_REACTIONS);
|
||||
}
|
||||
else if (bp.Team == ALLIANCE)
|
||||
{
|
||||
player->CastSpell(player, SPELL_MERCENARY_ALLIANCE_1);
|
||||
player->CastSpell(player, SPELL_MERCENARY_ALLIANCE_REACTIONS);
|
||||
}
|
||||
player->CastSpell(player, SPELL_MERCENARY_SHAPESHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1856,6 +1861,14 @@ bool Battleground::IsPlayerInBattleground(ObjectGuid guid) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Battleground::IsPlayerMercenaryInBattleground(ObjectGuid guid) const
|
||||
{
|
||||
auto itr = m_Players.find(guid);
|
||||
if (itr != m_Players.end())
|
||||
return itr->second.Mercenary;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
|
||||
{
|
||||
if (GetStatus() != STATUS_WAIT_LEAVE)
|
||||
|
||||
@@ -121,9 +121,10 @@ enum BattlegroundSpells
|
||||
SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2)
|
||||
SPELL_HONORABLE_DEFENDER_60Y = 66157, // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds
|
||||
SPELL_MERCENARY_HORDE_1 = 193864,
|
||||
SPELL_MERCENARY_HORDE_2 = 195838,
|
||||
SPELL_MERCENARY_HORDE_REACTIONS = 195838,
|
||||
SPELL_MERCENARY_ALLIANCE_1 = 193863,
|
||||
SPELL_MERCENARY_ALLIANCE_2 = 195843,
|
||||
SPELL_MERCENARY_ALLIANCE_REACTIONS = 195843,
|
||||
SPELL_MERCENARY_SHAPESHIFT = 193970,
|
||||
};
|
||||
|
||||
enum BattlegroundTimeIntervals
|
||||
@@ -175,6 +176,7 @@ struct BattlegroundPlayer
|
||||
time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes
|
||||
uint32 Team; // Player's team
|
||||
int32 ActiveSpec; // Player's active spec
|
||||
bool Mercenary;
|
||||
};
|
||||
|
||||
struct BattlegroundObjectInfo
|
||||
@@ -492,6 +494,7 @@ class TC_GAME_API Battleground
|
||||
uint32 GetPlayerTeam(ObjectGuid guid) const;
|
||||
uint32 GetOtherTeam(uint32 teamId) const;
|
||||
bool IsPlayerInBattleground(ObjectGuid guid) const;
|
||||
bool IsPlayerMercenaryInBattleground(ObjectGuid guid) const;
|
||||
|
||||
bool ToBeDeleted() const { return m_SetDeleteThis; }
|
||||
void SetDeleteThis() { m_SetDeleteThis = true; }
|
||||
|
||||
@@ -130,7 +130,7 @@ bool BattlegroundQueue::SelectionPool::AddGroup(GroupQueueInfo* ginfo, uint32 de
|
||||
/*********************************************************/
|
||||
|
||||
// add group or player (grp == NULL) to bg queue with the given leader and bg specifications
|
||||
GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PVPDifficultyEntry const* bracketEntry, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 arenateamid)
|
||||
GroupQueueInfo* BattlegroundQueue::AddGroup(Player const* leader, Group const* group, Team team, PVPDifficultyEntry const* bracketEntry, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 arenateamid)
|
||||
{
|
||||
BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
|
||||
|
||||
@@ -140,7 +140,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PVPDiffi
|
||||
ginfo->IsInvitedToBGInstanceGUID = 0;
|
||||
ginfo->JoinTime = GameTime::GetGameTimeMS();
|
||||
ginfo->RemoveInviteTime = 0;
|
||||
ginfo->Team = leader->GetBgQueueTeam();
|
||||
ginfo->Team = team;
|
||||
ginfo->ArenaTeamRating = ArenaRating;
|
||||
ginfo->ArenaMatchmakerRating = MatchmakerRating;
|
||||
ginfo->OpponentsTeamRating = 0;
|
||||
@@ -167,9 +167,9 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PVPDiffi
|
||||
}
|
||||
|
||||
//add players from group to ginfo
|
||||
if (grp)
|
||||
if (group)
|
||||
{
|
||||
for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
for (GroupReference const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
{
|
||||
Player* member = itr->GetSource();
|
||||
if (!member)
|
||||
@@ -179,14 +179,6 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PVPDiffi
|
||||
pl_info.GroupInfo = ginfo;
|
||||
// add the pinfo to ginfo's list
|
||||
ginfo->Players[member->GetGUID()] = &pl_info;
|
||||
|
||||
if (ginfo->Team != member->GetTeam())
|
||||
{
|
||||
if (member->GetTeam() == ALLIANCE)
|
||||
member->CastSpell(member, SPELL_MERCENARY_CONTRACT_HORDE);
|
||||
else
|
||||
member->CastSpell(member, SPELL_MERCENARY_CONTRACT_ALLIANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -79,7 +79,7 @@ class TC_GAME_API BattlegroundQueue
|
||||
bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
|
||||
bool CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
|
||||
bool CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam);
|
||||
GroupQueueInfo* AddGroup(Player* leader, Group* group, PVPDifficultyEntry const* bracketEntry, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 ArenaTeamId = 0);
|
||||
GroupQueueInfo* AddGroup(Player const* leader, Group const* group, Team team, PVPDifficultyEntry const* bracketEntry, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 ArenaTeamId = 0);
|
||||
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount);
|
||||
bool IsPlayerInvited(ObjectGuid pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime);
|
||||
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo* ginfo);
|
||||
|
||||
@@ -6293,17 +6293,6 @@ void Player::SwitchToOppositeTeam(bool apply)
|
||||
m_team = (m_team == ALLIANCE) ? HORDE : ALLIANCE;
|
||||
}
|
||||
|
||||
uint32 Player::GetBgQueueTeam() const
|
||||
{
|
||||
if (HasAura(SPELL_MERCENARY_CONTRACT_HORDE))
|
||||
return HORDE;
|
||||
|
||||
if (HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE))
|
||||
return ALLIANCE;
|
||||
|
||||
return GetTeam();
|
||||
}
|
||||
|
||||
void Player::SetFactionForRace(uint8 race)
|
||||
{
|
||||
m_team = TeamForRace(race);
|
||||
@@ -18164,6 +18153,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
|
||||
currentBg->EventPlayerLoggedIn(this);
|
||||
|
||||
SetInviteForBattlegroundQueueType(bgQueueTypeId, currentBg->GetInstanceID());
|
||||
SetMercenaryForBattlegroundQueueType(bgQueueTypeId, currentBg->IsPlayerMercenaryInBattleground(GetGUID()));
|
||||
}
|
||||
// Bg was not found - go to Entry Point
|
||||
else
|
||||
@@ -25249,6 +25239,7 @@ uint32 Player::AddBattlegroundQueueId(BattlegroundQueueTypeId val)
|
||||
m_bgBattlegroundQueueID[i].bgQueueTypeId = val;
|
||||
m_bgBattlegroundQueueID[i].invitedToInstance = 0;
|
||||
m_bgBattlegroundQueueID[i].joinTime = GameTime::GetGameTime();
|
||||
m_bgBattlegroundQueueID[i].mercenary = HasAura(SPELL_MERCENARY_CONTRACT_HORDE) || HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -25272,6 +25263,7 @@ void Player::RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
|
||||
m_bgBattlegroundQueueID[i].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
|
||||
m_bgBattlegroundQueueID[i].invitedToInstance = 0;
|
||||
m_bgBattlegroundQueueID[i].joinTime = 0;
|
||||
m_bgBattlegroundQueueID[i].mercenary = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -25292,6 +25284,21 @@ bool Player::IsInvitedForBattlegroundInstance(uint32 instanceId) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void Player::SetMercenaryForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, bool mercenary)
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
|
||||
m_bgBattlegroundQueueID[i].mercenary = mercenary;
|
||||
}
|
||||
|
||||
bool Player::IsMercenaryForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
|
||||
return m_bgBattlegroundQueueID[i].mercenary;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::InArena() const
|
||||
{
|
||||
Battleground* bg = GetBattleground();
|
||||
|
||||
@@ -2211,7 +2211,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
static TeamId TeamIdForRace(uint8 race);
|
||||
uint32 GetTeam() const { return m_team; }
|
||||
void SwitchToOppositeTeam(bool apply);
|
||||
uint32 GetBgQueueTeam() const;
|
||||
TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
|
||||
void SetFactionForRace(uint8 race);
|
||||
|
||||
@@ -2392,6 +2391,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val);
|
||||
void SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId);
|
||||
bool IsInvitedForBattlegroundInstance(uint32 instanceId) const;
|
||||
void SetMercenaryForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, bool mercenary);
|
||||
bool IsMercenaryForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const;
|
||||
WorldLocation const& GetBattlegroundEntryPoint() const { return m_bgData.joinPos; }
|
||||
void SetBattlegroundEntryPoint();
|
||||
|
||||
@@ -2826,6 +2827,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
BattlegroundQueueTypeId bgQueueTypeId;
|
||||
uint32 invitedToInstance;
|
||||
uint32 joinTime;
|
||||
bool mercenary;
|
||||
};
|
||||
|
||||
BgBattlegroundQueueID_Rec m_bgBattlegroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];
|
||||
|
||||
@@ -1864,7 +1864,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
|
||||
}
|
||||
}
|
||||
|
||||
GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 /*MaxPlayerCount*/, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid)
|
||||
GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 /*MaxPlayerCount*/, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid) const
|
||||
{
|
||||
// check if this group is LFG group
|
||||
if (isLFGGroup())
|
||||
@@ -1892,10 +1892,11 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
|
||||
|
||||
uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
|
||||
uint32 team = reference->GetTeam();
|
||||
bool isMercenary = reference->HasAura(SPELL_MERCENARY_CONTRACT_HORDE) || reference->HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE);
|
||||
|
||||
// check every member of the group to be able to join
|
||||
memberscount = 0;
|
||||
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount)
|
||||
for (GroupReference const* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount)
|
||||
{
|
||||
Player* member = itr->GetSource();
|
||||
// offline member? don't let join
|
||||
@@ -1940,6 +1941,8 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
|
||||
// check Freeze debuff
|
||||
if (member->HasAura(9454))
|
||||
return ERR_BATTLEGROUND_JOIN_FAILED;
|
||||
if (isMercenary != (member->HasAura(SPELL_MERCENARY_CONTRACT_HORDE) || member->HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE)))
|
||||
return ERR_BATTLEGROUND_JOIN_MERCENARY;
|
||||
}
|
||||
|
||||
// only check for MinPlayerCount since MinPlayerCount == MaxPlayerCount for arenas...
|
||||
|
||||
@@ -341,7 +341,7 @@ class TC_GAME_API Group
|
||||
|
||||
void SetBattlegroundGroup(Battleground* bg);
|
||||
void SetBattlefieldGroup(Battlefield* bf);
|
||||
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid);
|
||||
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid) const;
|
||||
|
||||
void ChangeMembersGroup(ObjectGuid guid, uint8 group);
|
||||
void SwapMembersGroups(ObjectGuid firstGuid, ObjectGuid secondGuid);
|
||||
|
||||
@@ -104,7 +104,22 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
|
||||
|
||||
GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE;
|
||||
|
||||
Group* grp = _player->GetGroup();
|
||||
Group const* grp = _player->GetGroup();
|
||||
|
||||
auto getQueueTeam = [&]() -> Team
|
||||
{
|
||||
// mercenary applies only to unrated battlegrounds
|
||||
if (!bg->isRated() && !bg->isArena())
|
||||
{
|
||||
if (_player->HasAura(SPELL_MERCENARY_CONTRACT_HORDE))
|
||||
return HORDE;
|
||||
|
||||
if (_player->HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE))
|
||||
return ALLIANCE;
|
||||
}
|
||||
|
||||
return Team(_player->GetTeam());
|
||||
};
|
||||
|
||||
// check queue conditions
|
||||
if (!grp)
|
||||
@@ -174,7 +189,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
|
||||
return;
|
||||
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, false, isPremade, 0, 0);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, getQueueTeam(), bracketEntry, false, isPremade, 0, 0);
|
||||
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
|
||||
uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
|
||||
|
||||
@@ -202,11 +217,11 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
|
||||
if (!err)
|
||||
{
|
||||
TC_LOG_DEBUG("bg.battleground", "Battleground: the following players are joining as group:");
|
||||
ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, false, isPremade, 0, 0);
|
||||
ginfo = bgQueue.AddGroup(_player, grp, getQueueTeam(), bracketEntry, false, isPremade, 0, 0);
|
||||
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
for (GroupReference const* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
{
|
||||
Player* member = itr->GetSource();
|
||||
if (!member)
|
||||
@@ -555,7 +570,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPackets::Battleground::Battl
|
||||
{
|
||||
TC_LOG_DEBUG("bg.battleground", "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(packet.TeamSizeIndex), _player->GetName().c_str(), matchmakerRating, arenatype);
|
||||
|
||||
ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, false, arenaRating, matchmakerRating, ateamId);
|
||||
ginfo = bgQueue.AddGroup(_player, grp, Team(_player->GetTeam()), bracketEntry, false, arenaRating, matchmakerRating, ateamId);
|
||||
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
|
||||
@@ -398,10 +398,6 @@ void WorldSession::HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura& canc
|
||||
if (!spellInfo->IsPositive() || spellInfo->IsPassive())
|
||||
return;
|
||||
|
||||
if (spellInfo->Id == SPELL_MERCENARY_CONTRACT_HORDE || spellInfo->Id == SPELL_MERCENARY_CONTRACT_ALLIANCE)
|
||||
if (_player->InBattlegroundQueue())
|
||||
return;
|
||||
|
||||
_player->RemoveOwnedAura(cancelAura.SpellID, cancelAura.CasterGUID, 0, AURA_REMOVE_BY_CANCEL);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user