Core/Loot: implement automatic pass in group loot for items that cannot be looted.

Port From (https://github.com/TrinityCore/TrinityCore/commit/1c8f94a14f51e5ddfd0eb277e2b709da274e654d)
This commit is contained in:
hondacrx
2021-12-17 19:33:22 -05:00
parent b349f922b2
commit 1bd33fce8e
2 changed files with 38 additions and 16 deletions
+2 -2
View File
@@ -4996,7 +4996,7 @@ namespace Game.Entities
return msg; return msg;
} }
public InventoryResult CanEquipUniqueItem(Item pItem, byte eslot, uint limit_count = 1) public InventoryResult CanEquipUniqueItem(Item pItem, byte eslot = ItemConst.NullSlot, uint limit_count = 1)
{ {
ItemTemplate pProto = pItem.GetTemplate(); ItemTemplate pProto = pItem.GetTemplate();
@@ -5022,7 +5022,7 @@ namespace Game.Entities
return InventoryResult.Ok; return InventoryResult.Ok;
} }
public InventoryResult CanEquipUniqueItem(ItemTemplate itemProto, byte except_slot, uint limit_count = 1) public InventoryResult CanEquipUniqueItem(ItemTemplate itemProto, byte except_slot = ItemConst.NullSlot, uint limit_count = 1)
{ {
// check unique-equipped on item // check unique-equipped on item
if (Convert.ToBoolean(itemProto.GetFlags() & ItemFlags.UniqueEquippable)) if (Convert.ToBoolean(itemProto.GetFlags() & ItemFlags.UniqueEquippable))
+36 -14
View File
@@ -871,13 +871,14 @@ namespace Game.Groups
p.SendPacket(startLootRoll); p.SendPacket(startLootRoll);
} }
void SendLootRoll(ObjectGuid playerGuid, int rollNumber, RollType rollType, Roll roll) void SendLootRoll(ObjectGuid playerGuid, int rollNumber, RollType rollType, Roll roll, bool autoPass = false)
{ {
LootRollBroadcast lootRoll = new(); LootRollBroadcast lootRoll = new();
lootRoll.LootObj = roll.GetTarget().GetGUID(); lootRoll.LootObj = roll.GetTarget().GetGUID();
lootRoll.Player = playerGuid; lootRoll.Player = playerGuid;
lootRoll.Roll = rollNumber; lootRoll.Roll = rollNumber;
lootRoll.RollType = rollType; lootRoll.RollType = rollType;
lootRoll.Autopassed = autoPass;
roll.FillPacket(lootRoll.Item); roll.FillPacket(lootRoll.Item);
foreach (var pair in roll.playerVote) foreach (var pair in roll.playerVote)
@@ -964,6 +965,23 @@ namespace Game.Groups
BroadcastPacket(lootList, false); BroadcastPacket(lootList, false);
} }
public bool CanRollOnItem(LootItem item, Player player)
{
// Players can't roll on unique items if they already reached the maximum quantity of that item
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item.itemid);
if (proto == null)
return false;
uint itemCount = player.GetItemCount(item.itemid);
if ((proto.GetMaxCount() > 0 && itemCount >= proto.GetMaxCount()) || (player.CanEquipUniqueItem(proto) != InventoryResult.Ok))
return false;
if (!item.AllowedForPlayer(player))
return false;
return true;
}
public void GroupLoot(Loot loot, WorldObject lootedObject) public void GroupLoot(Loot loot, WorldObject lootedObject)
{ {
byte itemSlot = 0; byte itemSlot = 0;
@@ -988,18 +1006,17 @@ namespace Game.Groups
if (!playerToRoll || playerToRoll.GetSession() == null) if (!playerToRoll || playerToRoll.GetSession() == null)
continue; continue;
bool allowedForPlayer = lootItem.AllowedForPlayer(playerToRoll); if (playerToRoll.IsAtGroupRewardDistance(lootedObject))
if (allowedForPlayer && playerToRoll.IsAtGroupRewardDistance(lootedObject))
{ {
r.totalPlayersRolling++; r.totalPlayersRolling++;
if (playerToRoll.GetPassOnGroupLoot()) RollType vote = playerToRoll.GetPassOnGroupLoot() ? RollType.Pass : RollType.NotEmitedYet;
if (!CanRollOnItem(lootItem, playerToRoll))
{ {
r.playerVote[playerToRoll.GetGUID()] = RollType.Pass; vote = RollType.Pass;
r.totalPass++; r.totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
// can't broadcast the pass now. need to wait until all rolling players are known.
} }
else
r.playerVote[playerToRoll.GetGUID()] = RollType.NotEmitedYet; r.playerVote[playerToRoll.GetGUID()] = vote;
} }
} }
@@ -1021,7 +1038,7 @@ namespace Game.Groups
continue; continue;
if (pair.Value == RollType.Pass) if (pair.Value == RollType.Pass)
SendLootRoll(p.GetGUID(), -1, RollType.Pass, r); SendLootRoll(p.GetGUID(), -1, RollType.Pass, r, true);
else else
SendLootStartRollToPlayer(60000, lootedObject.GetMapId(), p, p.CanRollForItemInLFG(item, lootedObject) == InventoryResult.Ok, r); SendLootStartRollToPlayer(60000, lootedObject.GetMapId(), p, p.CanRollForItemInLFG(item, lootedObject) == InventoryResult.Ok, r);
} }
@@ -1059,11 +1076,16 @@ namespace Game.Groups
if (!playerToRoll || playerToRoll.GetSession() == null) if (!playerToRoll || playerToRoll.GetSession() == null)
continue; continue;
bool allowedForPlayer = i.AllowedForPlayer(playerToRoll); if (playerToRoll.IsAtGroupRewardDistance(lootedObject))
if (allowedForPlayer && playerToRoll.IsAtGroupRewardDistance(lootedObject))
{ {
r.totalPlayersRolling++; r.totalPlayersRolling++;
r.playerVote[playerToRoll.GetGUID()] = RollType.NotEmitedYet; RollType vote = RollType.NotEmitedYet;
if (!CanRollOnItem(i, playerToRoll))
{
vote = RollType.Pass;
++r.totalPass;
}
r.playerVote[playerToRoll.GetGUID()] = vote;
} }
} }
@@ -1082,7 +1104,7 @@ namespace Game.Groups
continue; continue;
if (pair.Value == RollType.Pass) if (pair.Value == RollType.Pass)
SendLootRoll(p.GetGUID(), -1, RollType.Pass, r); SendLootRoll(p.GetGUID(), -1, RollType.Pass, r, true);
else else
SendLootStartRollToPlayer(60000, lootedObject.GetMapId(), p, p.CanRollForItemInLFG(item, lootedObject) == InventoryResult.Ok, r); SendLootStartRollToPlayer(60000, lootedObject.GetMapId(), p, p.CanRollForItemInLFG(item, lootedObject) == InventoryResult.Ok, r);
} }