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:
@@ -5973,7 +5973,7 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item.AllowedForPlayer(this))
|
||||
if (!item.HasAllowedLooter(GetGUID()))
|
||||
{
|
||||
SendLootReleaseAll();
|
||||
return;
|
||||
|
||||
@@ -558,6 +558,19 @@ namespace Game.Entities
|
||||
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)
|
||||
{
|
||||
// process liquid auras using generic unit code
|
||||
|
||||
@@ -3130,7 +3130,8 @@ namespace Game.Entities
|
||||
Loot loot = creature.GetLootForPlayer(this);
|
||||
if (loot == null || loot.IsLooted()) // nothing to loot or everything looted.
|
||||
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;
|
||||
|
||||
if (loot.loot_type == LootType.Skinning)
|
||||
|
||||
@@ -119,6 +119,9 @@ namespace Game
|
||||
if (!member)
|
||||
continue;
|
||||
|
||||
if (!loot.HasAllowedLooter(member.GetGUID()))
|
||||
continue;
|
||||
|
||||
if (player.IsAtGroupRewardDistance(member))
|
||||
playersNear.Add(member);
|
||||
}
|
||||
@@ -406,15 +409,21 @@ namespace Game
|
||||
{
|
||||
Loot loot = _player.GetAELootView().LookupByKey(req.Object);
|
||||
|
||||
if (loot == null || loot.GetLootMethod() != LootMethod.MasterLoot)
|
||||
return;
|
||||
|
||||
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()} !");
|
||||
return;
|
||||
}
|
||||
|
||||
if (loot == null || loot.GetLootMethod() != LootMethod.MasterLoot)
|
||||
if (!loot.HasAllowedLooter(masterLootItem.Target))
|
||||
{
|
||||
_player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterOther);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.LootListID >= loot.items.Count)
|
||||
{
|
||||
@@ -426,16 +435,16 @@ namespace Game
|
||||
|
||||
List<ItemPosCount> dest = new();
|
||||
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;
|
||||
if (msg != InventoryResult.Ok)
|
||||
{
|
||||
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)
|
||||
_player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterInvFull);
|
||||
_player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterInvFull);
|
||||
else
|
||||
_player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterOther);
|
||||
_player.SendLootError(req.Object, loot.GetOwnerGUID(), LootError.MasterOther);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,13 @@ namespace Game.Loots
|
||||
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
|
||||
if (!Global.ConditionMgr.IsObjectMeetToConditions(player, conditions))
|
||||
@@ -63,7 +69,7 @@ namespace Game.Loots
|
||||
return false;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
public bool HasAllowedLooter(ObjectGuid looter)
|
||||
{
|
||||
return allowedGUIDs.Contains(looter);
|
||||
}
|
||||
|
||||
public LootSlotType? GetUiTypeForPlayer(Player player, Loot loot)
|
||||
{
|
||||
if (is_looted)
|
||||
@@ -439,7 +450,7 @@ namespace Game.Loots
|
||||
foreach (ObjectGuid allowedLooter in m_lootItem.GetAllowedLooters())
|
||||
{
|
||||
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;
|
||||
continue;
|
||||
@@ -692,7 +703,7 @@ namespace Game.Loots
|
||||
if (lootItem == null || lootItem.is_looted)
|
||||
continue;
|
||||
|
||||
if (!lootItem.AllowedForPlayer(player))
|
||||
if (!lootItem.HasAllowedLooter(GetGUID()))
|
||||
continue;
|
||||
|
||||
if (lootItem.is_blocked)
|
||||
@@ -817,6 +828,10 @@ namespace Game.Loots
|
||||
|
||||
void FillNotNormalLootFor(Player player)
|
||||
{
|
||||
if (_dungeonEncounterId != 0)
|
||||
if (player.IsLockedToDungeonEncounter(_dungeonEncounterId))
|
||||
return;
|
||||
|
||||
ObjectGuid plguid = player.GetGUID();
|
||||
_allowedLooters.Add(plguid);
|
||||
|
||||
@@ -824,7 +839,7 @@ namespace Game.Loots
|
||||
|
||||
foreach (LootItem item in items)
|
||||
{
|
||||
if (!item.AllowedForPlayer(player))
|
||||
if (!item.AllowedForPlayer(player, this))
|
||||
continue;
|
||||
|
||||
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)
|
||||
{
|
||||
if (maxAmount > 0)
|
||||
|
||||
@@ -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
|
||||
// items that the player should get in loot are in the DB.
|
||||
// IE: Horde items are not saved to the DB for Ally players.
|
||||
if (!li.AllowedForPlayer(player))
|
||||
if (!li.AllowedForPlayer(player, loot))
|
||||
continue;
|
||||
|
||||
// Don't save currency tokens
|
||||
|
||||
Reference in New Issue
Block a user