From 0f77a9b27dbd3a94c379cf328f4879ebe9e75b6c Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sun, 18 Sep 2022 15:54:17 -0400 Subject: [PATCH] Core/Loot: Store method used at loot generation inside Loot object Port From (https://github.com/TrinityCore/TrinityCore/commit/9700b2a78680452d80025121a031da340af51348) --- Source/Game/Entities/Player/Player.Items.cs | 68 ++++++++------------- Source/Game/Entities/Player/Player.cs | 2 +- Source/Game/Entities/Unit/Unit.Combat.cs | 3 +- Source/Game/Groups/Group.cs | 4 +- Source/Game/Handlers/LootHandler.cs | 4 +- Source/Game/Loot/Loot.cs | 10 +-- Source/Game/Mails/MailDraft.cs | 2 +- 7 files changed, 38 insertions(+), 55 deletions(-) diff --git a/Source/Game/Entities/Player/Player.Items.cs b/Source/Game/Entities/Player/Player.Items.cs index 4b9a4945d..0e2126086 100644 --- a/Source/Game/Entities/Player/Player.Items.cs +++ b/Source/Game/Entities/Player/Player.Items.cs @@ -5883,7 +5883,7 @@ namespace Game.Entities public void AutoStoreLoot(uint loot_id, LootStore store, ItemContext context = 0, bool broadcast = false, bool createdByPlayer = false) { AutoStoreLoot(ItemConst.NullBag, ItemConst.NullSlot, loot_id, store, context, broadcast); } void AutoStoreLoot(byte bag, byte slot, uint loot_id, LootStore store, ItemContext context = 0, bool broadcast = false, bool createdByPlayer = false) { - Loot loot = new(null, ObjectGuid.Empty, LootType.None); + Loot loot = new(null, ObjectGuid.Empty, LootType.None, LootMethod.FreeForAll); loot.FillLoot(loot_id, store, this, true, false, LootModes.Default, context); uint max_slot = loot.GetMaxSlotInLootFor(this); @@ -6092,7 +6092,7 @@ namespace Game.Entities // Now we must make bones lootable, and send player loot bones.SetCorpseDynamicFlag(CorpseDynFlags.Lootable); - bones.loot = new Loot(GetMap(), bones.GetGUID(), LootType.Insignia); + bones.loot = new Loot(GetMap(), bones.GetGUID(), LootType.Insignia, looterPlr.GetGroup() != null ? looterPlr.GetGroup().GetLootMethod() : LootMethod.FreeForAll); // For AV Achievement Battleground bg = GetBattleground(); @@ -6189,7 +6189,10 @@ namespace Game.Entities } } - loot = new Loot(GetMap(), guid, loot_type); + Group group = GetGroup(); + bool groupRules = (group != null && go.GetGoInfo().type == GameObjectTypes.Chest && go.GetGoInfo().Chest.usegrouplootrules != 0); + + loot = new Loot(GetMap(), guid, loot_type, groupRules ? group.GetLootMethod() : LootMethod.FreeForAll); if (go.GetMap().Is25ManRaid()) loot.maxDuplicates = 3; @@ -6197,9 +6200,6 @@ namespace Game.Entities if (lootid != 0) { - Group group = GetGroup(); - bool groupRules = (group && go.GetGoInfo().type == GameObjectTypes.Chest && go.GetGoInfo().Chest.usegrouplootrules != 0); - // check current RR player and get next if necessary if (groupRules) group.UpdateLooterGuid(go, true); @@ -6226,22 +6226,18 @@ namespace Game.Entities if (go.GetGoInfo().type == GameObjectTypes.Chest && go.GetGoInfo().Chest.usegrouplootrules != 0) { - var group = GetGroup(); - if (group) + switch (group.GetLootMethod()) { - switch (group.GetLootMethod()) - { - case LootMethod.GroupLoot: - // GroupLoot: rolls items over threshold. Items with quality < threshold, round robin - group.GroupLoot(loot, go); - break; - case LootMethod.MasterLoot: - group.MasterLoot(loot, go); - break; - default: - break; - } - } + case LootMethod.GroupLoot: + // GroupLoot: rolls items over threshold. Items with quality < threshold, round robin + group.GroupLoot(loot, go); + break; + case LootMethod.MasterLoot: + group.MasterLoot(loot, go); + break; + default: + break; + } } go.SetLootState(LootState.Activated, this); @@ -6252,10 +6248,10 @@ namespace Game.Entities Group group = GetGroup(); if (group) { - switch (group.GetLootMethod()) + switch (loot.GetLootMethod()) { case LootMethod.MasterLoot: - permission = PermissionTypes.Master; + permission = group.GetMasterLooterGuid() == GetGUID() ? PermissionTypes.Master : PermissionTypes.Restricted; break; case LootMethod.FreeForAll: permission = PermissionTypes.All; @@ -6288,7 +6284,7 @@ namespace Game.Entities if (!item.m_lootGenerated && !Global.LootItemStorage.LoadStoredLoot(item, this)) { item.m_lootGenerated = true; - loot = new Loot(GetMap(), guid, loot_type); + loot = new Loot(GetMap(), guid, loot_type, LootMethod.FreeForAll); item.loot = loot; switch (loot_type) @@ -6359,7 +6355,7 @@ namespace Game.Entities { creature.StartPickPocketRefillTimer(); - loot = new Loot(GetMap(), creature.GetGUID(), LootType.Pickpocketing); + loot = new Loot(GetMap(), creature.GetGUID(), LootType.Pickpocketing, LootMethod.FreeForAll); creature.loot = loot; uint lootid = creature.GetCreatureTemplate().PickPocketId; if (lootid != 0) @@ -6402,7 +6398,7 @@ namespace Game.Entities Group group = creature.GetLootRecipientGroup(); if (group) { - switch (group.GetLootMethod()) + switch (loot.GetLootMethod()) { case LootMethod.GroupLoot: // GroupLoot: rolls items over threshold. Items with quality < threshold, round robin @@ -6439,7 +6435,7 @@ namespace Game.Entities Group group = GetGroup(); if (group == creature.GetLootRecipientGroup()) { - switch (group.GetLootMethod()) + switch (loot.GetLootMethod()) { case LootMethod.MasterLoot: permission = PermissionTypes.Master; @@ -6465,29 +6461,13 @@ namespace Game.Entities if (permission != PermissionTypes.None) { - LootMethod _lootMethod = LootMethod.FreeForAll; - Group group = GetGroup(); - if (group) - { - Creature creature = GetMap().GetCreature(guid); - if (creature) - { - Player recipient = creature.GetLootRecipient(); - if (recipient) - { - if (group == recipient.GetGroup()) - _lootMethod = group.GetLootMethod(); - } - } - } - if (!guid.IsItem() && !aeLooting) SetLootGUID(guid); LootResponse packet = new(); packet.Owner = guid; packet.LootObj = loot.GetGUID(); - packet.LootMethod = _lootMethod; + packet.LootMethod = loot.GetLootMethod(); packet.AcquireReason = (byte)SharedConst.GetLootTypeForClient(loot_type); packet.Acquired = true; // false == No Loot (this too^^) packet.AELooting = aeLooting; diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 4492d904b..293bc981c 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -3133,7 +3133,7 @@ namespace Game.Entities else if (thisGroup != creature.GetLootRecipientGroup()) return false; - switch (thisGroup.GetLootMethod()) + switch (loot.GetLootMethod()) { case LootMethod.PersonalLoot:// @todo implement personal loot (http://wow.gamepedia.com/Loot#Personal_Loot) return false; diff --git a/Source/Game/Entities/Unit/Unit.Combat.cs b/Source/Game/Entities/Unit/Unit.Combat.cs index d2f543f60..f5bdcfa94 100644 --- a/Source/Game/Entities/Unit/Unit.Combat.cs +++ b/Source/Game/Entities/Unit/Unit.Combat.cs @@ -774,9 +774,10 @@ namespace Game.Entities else player.SendPacket(partyKillLog); + // Generate loot before updating looter if (creature) { - creature.loot = new Loot(creature.GetMap(), creature.GetGUID(), LootType.Corpse); + creature.loot = new Loot(creature.GetMap(), creature.GetGUID(), LootType.Corpse, group != null ? group.GetLootMethod() : LootMethod.FreeForAll); Loot loot = creature.loot; if (creature.GetMap().Is25ManRaid()) loot.maxDuplicates = 3; diff --git a/Source/Game/Groups/Group.cs b/Source/Game/Groups/Group.cs index 14501f234..e70e1f660 100644 --- a/Source/Game/Groups/Group.cs +++ b/Source/Game/Groups/Group.cs @@ -967,7 +967,7 @@ namespace Game.Groups lootList.Owner = creature.GetGUID(); lootList.LootObj = creature.loot.GetGUID(); - if (GetLootMethod() == LootMethod.MasterLoot && creature.loot.HasOverThresholdItem()) + if (creature.loot.GetLootMethod() == LootMethod.MasterLoot && creature.loot.HasOverThresholdItem()) lootList.Master = GetMasterLooterGuid(); if (groupLooter) @@ -1364,7 +1364,7 @@ namespace Game.Groups player.AutoStoreLoot(disenchant.Id, LootStorage.Disenchant, ItemContext.None, true); else // If the player's inventory is full, send the disenchant result in a mail. { - Loot loot = new(allowedMap, roll.GetLoot().GetOwnerGUID(), LootType.Disenchanting); + Loot loot = new(allowedMap, roll.GetLoot().GetOwnerGUID(), LootType.Disenchanting, roll.GetLoot().GetLootMethod()); loot.FillLoot(disenchant.Id, LootStorage.Disenchant, player, true); uint max_slot = loot.GetMaxSlotInLootFor(player); diff --git a/Source/Game/Handlers/LootHandler.cs b/Source/Game/Handlers/LootHandler.cs index f2311fa42..47b27dffc 100644 --- a/Source/Game/Handlers/LootHandler.cs +++ b/Source/Game/Handlers/LootHandler.cs @@ -392,7 +392,7 @@ namespace Game { AELootResult aeResult = new(); - if (GetPlayer().GetGroup() == null || GetPlayer().GetGroup().GetLooterGuid() != GetPlayer().GetGUID() || GetPlayer().GetGroup().GetLootMethod() != LootMethod.MasterLoot) + if (GetPlayer().GetGroup() == null || GetPlayer().GetGroup().GetLooterGuid() != GetPlayer().GetGUID()) { GetPlayer().SendLootError(ObjectGuid.Empty, ObjectGuid.Empty, LootError.DidntKill); return; @@ -417,7 +417,7 @@ namespace Game return; } - if (loot == null) + if (loot == null || loot.GetLootMethod() != LootMethod.MasterLoot) return; byte slotid = (byte)(req.LootListID - 1); diff --git a/Source/Game/Loot/Loot.cs b/Source/Game/Loot/Loot.cs index 35b8196bf..f987c218a 100644 --- a/Source/Game/Loot/Loot.cs +++ b/Source/Game/Loot/Loot.cs @@ -166,13 +166,14 @@ namespace Game.Loots public class Loot { - public Loot(Map map, ObjectGuid owner, LootType type) + public Loot(Map map, ObjectGuid owner, LootType type, LootMethod lootMethod) { loot_type = type; maxDuplicates = 1; _guid = map ? ObjectGuid.Create(HighGuid.LootObject, map.GetId(), 0, map.GenerateLowGuid(HighGuid.LootObject)) : ObjectGuid.Empty; _owner = owner; _itemContext = ItemContext.None; + _lootMethod = lootMethod; } // Inserts the item into the loot (called by LootTemplate processors) @@ -338,8 +339,7 @@ namespace Game.Loots { LootItem item = quest_items[i]; - if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player.GetGroup() && ((player.GetGroup().GetLootMethod() == LootMethod.MasterLoot - && player.GetGroup().GetMasterLooterGuid() == player.GetGUID()) || player.GetGroup().GetLootMethod() != LootMethod.MasterLoot)))) + if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player.GetGroup() && ((GetLootMethod() == LootMethod.MasterLoot && player.GetGroup().GetMasterLooterGuid() == player.GetGUID()) || GetLootMethod() != LootMethod.MasterLoot)))) { ql.Add(new NotNormalLootItem(i)); @@ -349,7 +349,7 @@ namespace Game.Loots // increase once if one looter only, looter-times if free for all if (item.freeforall || !item.is_blocked) ++unlootedCount; - if (!player.GetGroup() || player.GetGroup().GetLootMethod() != LootMethod.GroupLoot) + if (!player.GetGroup() || GetLootMethod() != LootMethod.GroupLoot) item.is_blocked = true; if (items.Count + ql.Count == SharedConst.MaxNRLootItems) @@ -840,6 +840,7 @@ namespace Game.Loots public ObjectGuid GetGUID() { return _guid; } public ObjectGuid GetOwnerGUID() { return _owner; } + public LootMethod GetLootMethod() { return _lootMethod; } public MultiMap GetPlayerQuestItems() { return PlayerQuestItems; } public MultiMap GetPlayerFFAItems() { return PlayerFFAItems; } @@ -865,6 +866,7 @@ namespace Game.Loots ObjectGuid _guid; ObjectGuid _owner; // The WorldObject that holds this loot ItemContext _itemContext; + LootMethod _lootMethod; } public class AELootResult diff --git a/Source/Game/Mails/MailDraft.cs b/Source/Game/Mails/MailDraft.cs index dce3888ca..9f19135ce 100644 --- a/Source/Game/Mails/MailDraft.cs +++ b/Source/Game/Mails/MailDraft.cs @@ -60,7 +60,7 @@ namespace Game.Mails if (m_mailTemplateId == 123) m_money = 1000000; - Loot mailLoot = new(null, ObjectGuid.Empty, LootType.None); + Loot mailLoot = new(null, ObjectGuid.Empty, LootType.None, LootMethod.FreeForAll); // can be empty mailLoot.FillLoot(m_mailTemplateId, LootStorage.Mail, receiver, true, true, LootModes.Default, ItemContext.None);