Core/Loot: Prevent looting bosses by players that have already completed that encounter

Port From (https://github.com/TrinityCore/TrinityCore/commit/9ce47e6809eecc891904e272b368596fdc55e6a4)
This commit is contained in:
hondacrx
2022-10-06 20:50:10 -04:00
parent 2bba8aeb99
commit 39e9e73277
6 changed files with 57 additions and 14 deletions
+1 -1
View File
@@ -5973,7 +5973,7 @@ namespace Game.Entities
return; return;
} }
if (!item.AllowedForPlayer(this)) if (!item.HasAllowedLooter(GetGUID()))
{ {
SendLootReleaseAll(); SendLootReleaseAll();
return; return;
+13
View File
@@ -558,6 +558,19 @@ namespace Game.Entities
SendPacket(transferAborted); SendPacket(transferAborted);
} }
public bool IsLockedToDungeonEncounter(uint dungeonEncounterId)
{
DungeonEncounterRecord dungeonEncounter = CliDB.DungeonEncounterStorage.LookupByKey(dungeonEncounterId);
if (dungeonEncounter == null)
return false;
InstanceLock instanceLock = Global.InstanceLockMgr.FindActiveInstanceLock(GetGUID(), new MapDb2Entries(GetMap().GetEntry(), GetMap().GetMapDifficulty()));
if (instanceLock == null)
return false;
return (instanceLock.GetData().CompletedEncountersMask & (1u << dungeonEncounter.Bit)) != 0;
}
public override void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, LiquidData newLiquidData) public override void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, LiquidData newLiquidData)
{ {
// process liquid auras using generic unit code // process liquid auras using generic unit code
+2 -1
View File
@@ -3130,7 +3130,8 @@ namespace Game.Entities
Loot loot = creature.GetLootForPlayer(this); Loot loot = creature.GetLootForPlayer(this);
if (loot == null || loot.IsLooted()) // nothing to loot or everything looted. if (loot == null || loot.IsLooted()) // nothing to loot or everything looted.
return false; return false;
if (!loot.HasItemForAll() && !loot.HasItemFor(this)) // no loot in creature for this player
if (!loot.HasAllowedLooter(GetGUID()) || (!loot.HasItemForAll() && !loot.HasItemFor(this))) // no loot in creature for this player
return false; return false;
if (loot.loot_type == LootType.Skinning) if (loot.loot_type == LootType.Skinning)
+15 -6
View File
@@ -119,6 +119,9 @@ namespace Game
if (!member) if (!member)
continue; continue;
if (!loot.HasAllowedLooter(member.GetGUID()))
continue;
if (player.IsAtGroupRewardDistance(member)) if (player.IsAtGroupRewardDistance(member))
playersNear.Add(member); playersNear.Add(member);
} }
@@ -406,15 +409,21 @@ namespace Game
{ {
Loot loot = _player.GetAELootView().LookupByKey(req.Object); Loot loot = _player.GetAELootView().LookupByKey(req.Object);
if (loot == null || loot.GetLootMethod() != LootMethod.MasterLoot)
return;
if (!_player.IsInRaidWith(target) || !_player.IsInMap(target)) if (!_player.IsInRaidWith(target) || !_player.IsInMap(target))
{ {
_player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterOther); _player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterOther);
Log.outInfo(LogFilter.Cheat, $"MasterLootItem: Player {GetPlayer().GetName()} tried to give an item to ineligible player {target.GetName()} !"); Log.outInfo(LogFilter.Cheat, $"MasterLootItem: Player {GetPlayer().GetName()} tried to give an item to ineligible player {target.GetName()} !");
return; return;
} }
if (loot == null || loot.GetLootMethod() != LootMethod.MasterLoot) if (!loot.HasAllowedLooter(masterLootItem.Target))
{
_player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterOther);
return; return;
}
if (req.LootListID >= loot.items.Count) if (req.LootListID >= loot.items.Count)
{ {
@@ -426,16 +435,16 @@ namespace Game
List<ItemPosCount> dest = new(); List<ItemPosCount> dest = new();
InventoryResult msg = target.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.itemid, item.count); InventoryResult msg = target.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.itemid, item.count);
if (!item.AllowedForPlayer(target, true)) if (!item.HasAllowedLooter(target.GetGUID()))
msg = InventoryResult.CantEquipEver; msg = InventoryResult.CantEquipEver;
if (msg != InventoryResult.Ok) if (msg != InventoryResult.Ok)
{ {
if (msg == InventoryResult.ItemMaxCount) if (msg == InventoryResult.ItemMaxCount)
_player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterUniqueItem); _player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterUniqueItem);
else if (msg == InventoryResult.InvFull) else if (msg == InventoryResult.InvFull)
_player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterInvFull); _player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterInvFull);
else else
_player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterOther); _player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterOther);
return; return;
} }
+25 -5
View File
@@ -45,7 +45,13 @@ namespace Game.Loots
randomBonusListId = ItemEnchantmentManager.GenerateItemRandomBonusListId(itemid); randomBonusListId = ItemEnchantmentManager.GenerateItemRandomBonusListId(itemid);
} }
public bool AllowedForPlayer(Player player, bool isGivenByMasterLooter = false) /// <summary>
/// Basic checks for player/item compatibility - if false no chance to see the item in the loot - used only for loot generation
/// </summary>
/// <param name="player"></param>
/// <param name="loot"></param>
/// <returns></returns>
public bool AllowedForPlayer(Player player, Loot loot)
{ {
// DB conditions check // DB conditions check
if (!Global.ConditionMgr.IsObjectMeetToConditions(player, conditions)) if (!Global.ConditionMgr.IsObjectMeetToConditions(player, conditions))
@@ -63,7 +69,7 @@ namespace Game.Loots
return false; return false;
// Master looter can see all items even if the character can't loot them // Master looter can see all items even if the character can't loot them
if (!isGivenByMasterLooter && player.GetGroup() && player.GetGroup().GetMasterLooterGuid() == player.GetGUID()) if (loot.GetLootMethod() == LootMethod.MasterLoot && follow_loot_rules && player.GetGroup() != null && player.GetGroup().GetMasterLooterGuid() == player.GetGUID())
return true; return true;
// Don't allow loot for players without profession or those who already know the recipe // Don't allow loot for players without profession or those who already know the recipe
@@ -108,6 +114,11 @@ namespace Game.Loots
allowedGUIDs.Add(player.GetGUID()); allowedGUIDs.Add(player.GetGUID());
} }
public bool HasAllowedLooter(ObjectGuid looter)
{
return allowedGUIDs.Contains(looter);
}
public LootSlotType? GetUiTypeForPlayer(Player player, Loot loot) public LootSlotType? GetUiTypeForPlayer(Player player, Loot loot)
{ {
if (is_looted) if (is_looted)
@@ -439,7 +450,7 @@ namespace Game.Loots
foreach (ObjectGuid allowedLooter in m_lootItem.GetAllowedLooters()) foreach (ObjectGuid allowedLooter in m_lootItem.GetAllowedLooters())
{ {
Player plr = Global.ObjAccessor.GetPlayer(m_map, allowedLooter); Player plr = Global.ObjAccessor.GetPlayer(m_map, allowedLooter);
if (!plr || !m_lootItem.AllowedForPlayer(plr)) // check if player meet the condition to be able to roll this item if (!plr || !m_lootItem.HasAllowedLooter(plr.GetGUID())) // check if player meet the condition to be able to roll this item
{ {
m_rollVoteMap[allowedLooter].Vote = RollVote.NotValid; m_rollVoteMap[allowedLooter].Vote = RollVote.NotValid;
continue; continue;
@@ -692,7 +703,7 @@ namespace Game.Loots
if (lootItem == null || lootItem.is_looted) if (lootItem == null || lootItem.is_looted)
continue; continue;
if (!lootItem.AllowedForPlayer(player)) if (!lootItem.HasAllowedLooter(GetGUID()))
continue; continue;
if (lootItem.is_blocked) if (lootItem.is_blocked)
@@ -817,6 +828,10 @@ namespace Game.Loots
void FillNotNormalLootFor(Player player) void FillNotNormalLootFor(Player player)
{ {
if (_dungeonEncounterId != 0)
if (player.IsLockedToDungeonEncounter(_dungeonEncounterId))
return;
ObjectGuid plguid = player.GetGUID(); ObjectGuid plguid = player.GetGUID();
_allowedLooters.Add(plguid); _allowedLooters.Add(plguid);
@@ -824,7 +839,7 @@ namespace Game.Loots
foreach (LootItem item in items) foreach (LootItem item in items)
{ {
if (!item.AllowedForPlayer(player)) if (!item.AllowedForPlayer(player, this))
continue; continue;
if (item.freeforall) if (item.freeforall)
@@ -921,6 +936,11 @@ namespace Game.Loots
} }
} }
public bool HasAllowedLooter(ObjectGuid looter)
{
return _allowedLooters.Contains(looter);
}
public void GenerateMoneyLoot(uint minAmount, uint maxAmount) public void GenerateMoneyLoot(uint minAmount, uint maxAmount)
{ {
if (maxAmount > 0) if (maxAmount > 0)
+1 -1
View File
@@ -208,7 +208,7 @@ namespace Game.Loots
// saved to the DB that the player never should have gotten. This check prevents that, so that only // saved to the DB that the player never should have gotten. This check prevents that, so that only
// items that the player should get in loot are in the DB. // items that the player should get in loot are in the DB.
// IE: Horde items are not saved to the DB for Ally players. // IE: Horde items are not saved to the DB for Ally players.
if (!li.AllowedForPlayer(player)) if (!li.AllowedForPlayer(player, loot))
continue; continue;
// Don't save currency tokens // Don't save currency tokens