diff --git a/Source/Framework/Constants/ItemConst.cs b/Source/Framework/Constants/ItemConst.cs index 1681d0381..12ced5bb4 100644 --- a/Source/Framework/Constants/ItemConst.cs +++ b/Source/Framework/Constants/ItemConst.cs @@ -1016,6 +1016,7 @@ namespace Framework.Constants NoSpellEffectTooltipPrefixes = 0x20000 } + [Flags] public enum ItemFlagsCustom { Unused = 0x0001, diff --git a/Source/Game/Handlers/LootHandler.cs b/Source/Game/Handlers/LootHandler.cs index fb34afa31..f121a3076 100644 --- a/Source/Game/Handlers/LootHandler.cs +++ b/Source/Game/Handlers/LootHandler.cs @@ -521,7 +521,7 @@ namespace Game List dest = new(); InventoryResult msg = target.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.itemid, item.count); - if (item.follow_loot_rules && !item.AllowedForPlayer(target)) + if (!item.AllowedForPlayer(target, true)) msg = InventoryResult.CantEquipEver; if (msg != InventoryResult.Ok) { @@ -532,7 +532,6 @@ namespace Game else _player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterOther); - target.SendEquipError(msg, null, null, item.itemid); return; } diff --git a/Source/Game/Loot/Loot.cs b/Source/Game/Loot/Loot.cs index 04785fc6a..c1ebb5eb8 100644 --- a/Source/Game/Loot/Loot.cs +++ b/Source/Game/Loot/Loot.cs @@ -43,7 +43,7 @@ namespace Game.Loots randomBonusListId = ItemEnchantmentManager.GenerateItemRandomBonusListId(itemid); } - public bool AllowedForPlayer(Player player) + public bool AllowedForPlayer(Player player, bool isGivenByMasterLooter = false) { // DB conditions check if (!Global.ConditionMgr.IsObjectMeetToConditions(player, conditions)) @@ -53,10 +53,6 @@ namespace Game.Loots if (pProto == null) return false; - // not show loot for players without profession or those who already know the recipe - if (pProto.GetFlags().HasAnyFlag(ItemFlags.HideUnusableRecipe) && (!player.HasSkill((SkillType)pProto.GetRequiredSkill()) || player.HasSpell((uint)pProto.Effects[1].SpellID))) - return false; - // not show loot for not own team if (pProto.GetFlags2().HasAnyFlag(ItemFlags2.FactionHorde) && player.GetTeam() != Team.Horde) return false; @@ -64,6 +60,45 @@ namespace Game.Loots if (pProto.GetFlags2().HasAnyFlag(ItemFlags2.FactionAlliance) && player.GetTeam() != Team.Alliance) return false; + // Master looter can see certain items even if the character can't loot them + if (!isGivenByMasterLooter && player.GetGroup() && player.GetGroup().GetMasterLooterGuid() == player.GetGUID()) + { + // check quest requirements + if (!pProto.FlagsCu.HasFlag(ItemFlagsCustom.IgnoreQuestStatus) && (needs_quest || pProto.GetStartQuest() != 0)) + return false; + + return true; + } + + // Don't allow loot for players without profession or those who already know the recipe + if (pProto.GetFlags().HasFlag(ItemFlags.HideUnusableRecipe)) + { + if (!player.HasSkill((SkillType)pProto.GetRequiredSkill())) + return false; + + foreach (var itemEffect in pProto.Effects) + { + if (itemEffect.TriggerType != ItemSpelltriggerType.LearnSpellId) + continue; + + if (player.HasSpell((uint)itemEffect.SpellID)) + return false; + } + } + + // Don't allow to loot soulbound recipes that the player has already learned + if (pProto.GetClass() == ItemClass.Recipe && pProto.GetBonding() == ItemBondingType.OnAcquire) + { + foreach (var itemEffect in pProto.Effects) + { + if (itemEffect.TriggerType != ItemSpelltriggerType.LearnSpellId) + continue; + + if (player.HasSpell((uint)itemEffect.SpellID)) + return false; + } + } + // check quest requirements if (!pProto.FlagsCu.HasAnyFlag(ItemFlagsCustom.IgnoreQuestStatus) && ((needs_quest || (pProto.GetStartQuest() != 0 && player.GetQuestStatus(pProto.GetStartQuest()) != QuestStatus.None)) && !player.HasQuestForItem(itemid)))