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:
Shauren
2022-04-14 23:31:17 +02:00
parent 15fe4e09d4
commit 84486ded67
10 changed files with 78 additions and 47 deletions

View File

@@ -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)

View File

@@ -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; }

View File

@@ -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

View File

@@ -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);

View File

@@ -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();

View File

@@ -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];

View File

@@ -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...

View File

@@ -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);

View File

@@ -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());
}

View File

@@ -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);
}