diff --git a/Source/Framework/Constants/BattleGroundsConst.cs b/Source/Framework/Constants/BattleGroundsConst.cs index f8844f241..fe4fad12f 100644 --- a/Source/Framework/Constants/BattleGroundsConst.cs +++ b/Source/Framework/Constants/BattleGroundsConst.cs @@ -89,9 +89,10 @@ namespace Framework.Constants public const uint SpellHonorableDefender25y = 68652; // +50% Honor When Standing At A Capture Point That You Control, 25yards Radius (Added In 3.2) public const uint SpellHonorableDefender60y = 66157; // +50% Honor When Standing At A Capture Point That You Control, 60yards Radius (Added In 3.2), Probably For 40+ Player Battlegrounds public const uint SpellMercenaryHorde1 = 193864; - public const uint SpellMercenaryHorde2 = 195838; + public const uint SpellMercenaryHordeReactions = 195838; public const uint SpellMercenaryAlliance1 = 193863; - public const uint SpellMercenaryAlliance2 = 195843; + public const uint SpellMercenaryAllianceReactions = 195843; + public const uint SpellMercenaryShapeshift = 193970; } public enum BattlegroundEventFlags diff --git a/Source/Game/BattleGrounds/BattleGround.cs b/Source/Game/BattleGrounds/BattleGround.cs index 8e96c0a95..a7fbb39b4 100644 --- a/Source/Game/BattleGrounds/BattleGround.cs +++ b/Source/Game/BattleGrounds/BattleGround.cs @@ -997,6 +997,7 @@ namespace Game.BattleGrounds bp.OfflineRemoveTime = 0; bp.Team = team; bp.ActiveSpec = (int)player.GetPrimarySpecialization(); + bp.Mercenary = player.IsMercenaryForBattlegroundQueueType(GetQueueId()); bool isInBattleground = IsPlayerInBattleground(player.GetGUID()); // Add to list/maps @@ -1071,15 +1072,18 @@ namespace Game.BattleGrounds player.SendPacket(timer); } - if (player.HasAura(PlayerConst.SpellMercenaryContractHorde)) + if (bp.Mercenary) { - player.CastSpell(player, BattlegroundConst.SpellMercenaryHorde1, true); - player.CastSpell(player, BattlegroundConst.SpellMercenaryHorde2, true); - } - else if (player.HasAura(PlayerConst.SpellMercenaryContractAlliance)) - { - player.CastSpell(player, BattlegroundConst.SpellMercenaryAlliance1, true); - player.CastSpell(player, BattlegroundConst.SpellMercenaryAlliance2, true); + if (bp.Team == Team.Horde) + { + player.CastSpell(player, BattlegroundConst.SpellMercenaryHorde1, true); + player.CastSpell(player, BattlegroundConst.SpellMercenaryHordeReactions, true); + } + else if (bp.Team == Team.Alliance) + { + player.CastSpell(player, BattlegroundConst.SpellMercenaryAlliance1, true); + player.CastSpell(player, BattlegroundConst.SpellMercenaryAllianceReactions, true); + } } } @@ -1768,6 +1772,15 @@ namespace Game.BattleGrounds return m_Players.ContainsKey(guid); } + public bool IsPlayerMercenaryInBattleground(ObjectGuid guid) + { + var player = m_Players.LookupByKey(guid); + if (player != null) + return player.Mercenary; + + return false; + } + void PlayerAddedToBGCheckIfBGIsRunning(Player player) { if (GetStatus() != BattlegroundStatus.WaitLeave) @@ -2154,8 +2167,9 @@ namespace Game.BattleGrounds public class BattlegroundPlayer { - public long OfflineRemoveTime; // for tracking and removing offline players from queue after 5 Time.Minutes - public Team Team; // Player's team - public int ActiveSpec; + public long OfflineRemoveTime; // for tracking and removing offline players from queue after 5 Time.Minutes + public Team Team; // Player's team + public int ActiveSpec; // Player's active spec + public bool Mercenary; } } diff --git a/Source/Game/BattleGrounds/BattleGroundQueue.cs b/Source/Game/BattleGrounds/BattleGroundQueue.cs index 5632950f9..7295c2509 100644 --- a/Source/Game/BattleGrounds/BattleGroundQueue.cs +++ b/Source/Game/BattleGrounds/BattleGroundQueue.cs @@ -57,7 +57,7 @@ namespace Game.BattleGrounds } // add group or player (grp == null) to bg queue with the given leader and bg specifications - public GroupQueueInfo AddGroup(Player leader, Group grp, PvpDifficultyRecord bracketEntry, bool isPremade, uint ArenaRating, uint MatchmakerRating, uint arenateamid = 0) + public GroupQueueInfo AddGroup(Player leader, Group group, Team team, PvpDifficultyRecord bracketEntry, bool isPremade, uint ArenaRating, uint MatchmakerRating, uint arenateamid = 0) { BattlegroundBracketId bracketId = bracketEntry.GetBracketId(); @@ -67,7 +67,7 @@ namespace Game.BattleGrounds 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; @@ -88,15 +88,15 @@ namespace Game.BattleGrounds //announce world (this don't need mutex) if (m_queueId.Rated && WorldConfig.GetBoolValue(WorldCfg.ArenaQueueAnnouncerEnable)) { - ArenaTeam team = Global.ArenaTeamMgr.GetArenaTeamById(arenateamid); - if (team != null) - Global.WorldMgr.SendWorldText( CypherStrings.ArenaQueueAnnounceWorldJoin, team.GetName(), m_queueId.TeamSize, m_queueId.TeamSize, ginfo.ArenaTeamRating); + ArenaTeam arenaTeam = Global.ArenaTeamMgr.GetArenaTeamById(arenateamid); + if (arenaTeam != null) + Global.WorldMgr.SendWorldText( CypherStrings.ArenaQueueAnnounceWorldJoin, arenaTeam.GetName(), m_queueId.TeamSize, m_queueId.TeamSize, ginfo.ArenaTeamRating); } //add players from group to ginfo - if (grp) + if (group) { - for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.Next()) + for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) { Player member = refe.GetSource(); if (!member) @@ -109,14 +109,6 @@ namespace Game.BattleGrounds m_QueuedPlayers[member.GetGUID()] = pl_info; // add the pinfo to ginfo's list ginfo.Players[member.GetGUID()] = pl_info; - - if (ginfo.Team != member.GetTeam()) - { - if (member.GetTeam() == Team.Alliance) - member.CastSpell(member, PlayerConst.SpellMercenaryContractHorde); - else - member.CastSpell(member, PlayerConst.SpellMercenaryContractAlliance); - } } } else diff --git a/Source/Game/Entities/Player/Player.DB.cs b/Source/Game/Entities/Player/Player.DB.cs index 2b3a92bce..f73055b95 100644 --- a/Source/Game/Entities/Player/Player.DB.cs +++ b/Source/Game/Entities/Player/Player.DB.cs @@ -2828,6 +2828,7 @@ namespace Game.Entities currentBg.EventPlayerLoggedIn(this); SetInviteForBattlegroundQueueType(bgQueueTypeId, currentBg.GetInstanceID()); + SetMercenaryForBattlegroundQueueType(bgQueueTypeId, currentBg.IsPlayerMercenaryInBattleground(GetGUID())); } // Bg was not found - go to Entry Point else diff --git a/Source/Game/Entities/Player/Player.Fields.cs b/Source/Game/Entities/Player/Player.Fields.cs index 0e84f1ff2..53f2c4e17 100644 --- a/Source/Game/Entities/Player/Player.Fields.cs +++ b/Source/Game/Entities/Player/Player.Fields.cs @@ -554,6 +554,7 @@ namespace Game.Entities public BattlegroundQueueTypeId bgQueueTypeId; public uint invitedToInstance; public uint joinTime; + public bool mercenary; } // Holder for Battlegrounddata diff --git a/Source/Game/Entities/Player/Player.PvP.cs b/Source/Game/Entities/Player/Player.PvP.cs index 568ab6098..1caf77c8e 100644 --- a/Source/Game/Entities/Player/Player.PvP.cs +++ b/Source/Game/Entities/Player/Player.PvP.cs @@ -448,6 +448,7 @@ namespace Game.Entities m_bgBattlegroundQueueID[i].bgQueueTypeId = val; m_bgBattlegroundQueueID[i].invitedToInstance = 0; m_bgBattlegroundQueueID[i].joinTime = (uint)GameTime.GetGameTime(); + m_bgBattlegroundQueueID[i].mercenary = HasAura(PlayerConst.SpellMercenaryContractHorde) || HasAura(PlayerConst.SpellMercenaryContractAlliance); return i; } } @@ -471,6 +472,7 @@ namespace Game.Entities m_bgBattlegroundQueueID[i].bgQueueTypeId = default; m_bgBattlegroundQueueID[i].invitedToInstance = 0; m_bgBattlegroundQueueID[i].joinTime = 0; + m_bgBattlegroundQueueID[i].mercenary = false; return; } } @@ -491,6 +493,21 @@ namespace Game.Entities return false; } + void SetMercenaryForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, bool mercenary) + { + for (byte i = 0; i < SharedConst.MaxPlayerBGQueues; ++i) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) + m_bgBattlegroundQueueID[i].mercenary = mercenary; + } + + public bool IsMercenaryForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) + { + for (byte i = 0; i < SharedConst.MaxPlayerBGQueues; ++i) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) + return m_bgBattlegroundQueueID[i].mercenary; + return false; + } + public WorldLocation GetBattlegroundEntryPoint() { return m_bgData.joinPos; } public bool InBattleground() { return m_bgData.bgInstanceID != 0; } diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index f36bff0d3..77f8bd5fb 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -3524,17 +3524,6 @@ namespace Game.Entities m_team = (m_team == Team.Alliance) ? Team.Horde : Team.Alliance; } - public Team GetBgQueueTeam() - { - if (HasAura(PlayerConst.SpellMercenaryContractHorde)) - return Team.Horde; - - if (HasAura(PlayerConst.SpellMercenaryContractAlliance)) - return Team.Alliance; - - return GetTeam(); - } - public Team GetNativeTeam() { return TeamForRace(GetRace()); } public uint GetNativeTeamId() { return TeamIdForRace(GetRace()); } diff --git a/Source/Game/Groups/Group.cs b/Source/Game/Groups/Group.cs index da4dc86af..5ec638bc1 100644 --- a/Source/Game/Groups/Group.cs +++ b/Source/Game/Groups/Group.cs @@ -1802,7 +1802,7 @@ namespace Game.Groups BattlemasterListRecord bgEntry = CliDB.BattlemasterListStorage.LookupByKey(bgOrTemplate.GetTypeID()); if (bgEntry == null) - return GroupJoinBattlegroundResult.JoinFailed; // shouldn't happen + return GroupJoinBattlegroundResult.BattlegroundJoinFailed; // shouldn't happen // check for min / max count uint memberscount = GetMembersCount(); @@ -1814,14 +1814,15 @@ namespace Game.Groups Player reference = GetFirstMember().GetSource(); // no reference found, can't join this way if (!reference) - return GroupJoinBattlegroundResult.JoinFailed; + return GroupJoinBattlegroundResult.BattlegroundJoinFailed; PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bgOrTemplate.GetMapId(), reference.GetLevel()); if (bracketEntry == null) - return GroupJoinBattlegroundResult.JoinFailed; + return GroupJoinBattlegroundResult.BattlegroundJoinFailed; uint arenaTeamId = reference.GetArenaTeamId((byte)arenaSlot); Team team = reference.GetTeam(); + bool isMercenary = reference.HasAura(PlayerConst.SpellMercenaryContractHorde) || reference.HasAura(PlayerConst.SpellMercenaryContractAlliance); // check every member of the group to be able to join memberscount = 0; @@ -1830,7 +1831,7 @@ namespace Game.Groups Player member = refe.GetSource(); // offline member? don't let join if (!member) - return GroupJoinBattlegroundResult.JoinFailed; + return GroupJoinBattlegroundResult.BattlegroundJoinFailed; // rbac permissions if (!member.CanJoinToBattleground(bgOrTemplate)) return GroupJoinBattlegroundResult.JoinTimedOut; @@ -1846,10 +1847,10 @@ namespace Game.Groups return GroupJoinBattlegroundResult.JoinRangeIndex; // don't let join rated matches if the arena team id doesn't match if (isRated && member.GetArenaTeamId((byte)arenaSlot) != arenaTeamId) - return GroupJoinBattlegroundResult.JoinFailed; + return GroupJoinBattlegroundResult.BattlegroundJoinFailed; // don't let join if someone from the group is already in that bg queue if (member.InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) - return GroupJoinBattlegroundResult.JoinFailed; // not blizz-like + return GroupJoinBattlegroundResult.BattlegroundJoinFailed; // not blizz-like // don't let join if someone from the group is in bg queue random bool isInRandomBgQueue = member.InBattlegroundQueueForBattlegroundQueueType(Global.BattlegroundMgr.BGQueueTypeId((ushort)BattlegroundTypeId.RB, BattlegroundQueueIdType.Battleground, false, 0)) || member.InBattlegroundQueueForBattlegroundQueueType(Global.BattlegroundMgr.BGQueueTypeId((ushort)BattlegroundTypeId.RandomEpic, BattlegroundQueueIdType.Battleground, false, 0)); @@ -1869,7 +1870,9 @@ namespace Game.Groups return GroupJoinBattlegroundResult.LfgCantUseBattleground; // check Freeze debuff if (member.HasAura(9454)) - return GroupJoinBattlegroundResult.JoinFailed; + return GroupJoinBattlegroundResult.BattlegroundJoinFailed; + if (isMercenary != (member.HasAura(PlayerConst.SpellMercenaryContractHorde) || member.HasAura(PlayerConst.SpellMercenaryContractAlliance))) + return GroupJoinBattlegroundResult.BattlegroundJoinMercenary; } // only check for MinPlayerCount since MinPlayerCount == MaxPlayerCount for arenas... diff --git a/Source/Game/Handlers/BattleGroundHandler.cs b/Source/Game/Handlers/BattleGroundHandler.cs index 8ee875ce5..2f17afa09 100644 --- a/Source/Game/Handlers/BattleGroundHandler.cs +++ b/Source/Game/Handlers/BattleGroundHandler.cs @@ -101,6 +101,21 @@ namespace Game Group grp = _player.GetGroup(); + Team getQueueTeam() + { + // mercenary applies only to unrated battlegrounds + if (!bg.IsRated() && !bg.IsArena()) + { + if (_player.HasAura(PlayerConst.SpellMercenaryContractHorde)) + return Team.Horde; + + if (_player.HasAura(PlayerConst.SpellMercenaryContractAlliance)) + return Team.Alliance; + } + + return _player.GetTeam(); + } + BattlefieldStatusFailed battlefieldStatusFailed; // check queue conditions if (grp == null) @@ -163,7 +178,7 @@ namespace Game return; BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); - GroupQueueInfo ginfo = bgQueue.AddGroup(GetPlayer(), null, bracketEntry, isPremade, 0, 0); + GroupQueueInfo ginfo = bgQueue.AddGroup(GetPlayer(), null, getQueueTeam(), bracketEntry, isPremade, 0, 0); uint avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); uint queueSlot = GetPlayer().AddBattlegroundQueueId(bgQueueTypeId); @@ -189,7 +204,7 @@ namespace Game if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:"); - ginfo = bgQueue.AddGroup(GetPlayer(), grp, bracketEntry, isPremade, 0, 0); + ginfo = bgQueue.AddGroup(GetPlayer(), grp, getQueueTeam(), bracketEntry, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } @@ -539,7 +554,7 @@ namespace Game { Log.outDebug(LogFilter.Battleground, "Battleground: arena team id {0}, leader {1} queued with matchmaker rating {2} for type {3}", GetPlayer().GetArenaTeamId(packet.TeamSizeIndex), GetPlayer().GetName(), matchmakerRating, arenatype); - ginfo = bgQueue.AddGroup(GetPlayer(), grp, bracketEntry, false, arenaRating, matchmakerRating, ateamId); + ginfo = bgQueue.AddGroup(GetPlayer(), grp, _player.GetTeam(), bracketEntry, false, arenaRating, matchmakerRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } @@ -560,7 +575,7 @@ namespace Game if (!GetPlayer().CanJoinToBattleground(bg)) { BattlefieldStatusFailed battlefieldStatus; - Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bgQueueTypeId, GetPlayer(), 0, GroupJoinBattlegroundResult.JoinFailed, errorGuid); + Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bgQueueTypeId, GetPlayer(), 0, GroupJoinBattlegroundResult.BattlegroundJoinFailed, errorGuid); member.SendPacket(battlefieldStatus); return; } diff --git a/Source/Game/Handlers/SpellHandler.cs b/Source/Game/Handlers/SpellHandler.cs index a2dd8e179..91693f1f7 100644 --- a/Source/Game/Handlers/SpellHandler.cs +++ b/Source/Game/Handlers/SpellHandler.cs @@ -403,10 +403,6 @@ namespace Game if (!spellInfo.IsPositive() || spellInfo.IsPassive()) return; - if (spellInfo.Id == PlayerConst.SpellMercenaryContractHorde || spellInfo.Id == PlayerConst.SpellMercenaryContractAlliance) - if (_player.InBattlegroundQueue()) - return; - GetPlayer().RemoveOwnedAura(cancelAura.SpellID, cancelAura.CasterGUID, 0, AuraRemoveMode.Cancel); }