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

(cherry picked from commit 00fdf6e99a)
This commit is contained in:
Wyrserth
2019-06-15 15:23:18 +02:00
committed by Shauren
parent 59da957165
commit 1c8f94a14f
2 changed files with 36 additions and 15 deletions

View File

@@ -923,13 +923,14 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,
p->SendDirectMessage(startLootRoll.Write());
}
void Group::SendLootRoll(ObjectGuid playerGuid, int32 rollNumber, uint8 rollType, Roll const& roll) const
void Group::SendLootRoll(ObjectGuid playerGuid, int32 rollNumber, uint8 rollType, Roll const& roll, bool autoPass) const
{
WorldPackets::Loot::LootRollBroadcast lootRoll;
lootRoll.LootObj = roll->GetGUID();
lootRoll.Player = playerGuid;
lootRoll.Roll = rollNumber;
lootRoll.RollType = rollType;
lootRoll.Autopassed = autoPass;
roll.FillPacket(lootRoll.Item);
lootRoll.Write();
@@ -1021,6 +1022,23 @@ void Group::SendLooter(Creature* creature, Player* groupLooter)
BroadcastPacket(lootList.Write(), false);
}
bool CanRollOnItem(const LootItem& item, Player const* player)
{
// Players can't roll on unique items if they already reached the maximum quantity of that item
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
if (!proto)
return false;
uint32 itemCount = player->GetItemCount(item.itemid);
if ((proto->GetMaxCount() > 0 && itemCount >= proto->GetMaxCount()) || (player->CanEquipUniqueItem(proto) != EQUIP_ERR_OK))
return false;
if (!item.AllowedForPlayer(player))
return false;
return true;
}
void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
{
ItemTemplate const* item;
@@ -1043,18 +1061,16 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
if (!playerToRoll || !playerToRoll->GetSession())
continue;
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
if (playerToRoll->GetPassOnGroupLoot())
RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
if (!CanRollOnItem(*i, playerToRoll))
{
r->playerVote[playerToRoll->GetGUID()] = PASS;
r->totalPass++;
// can't broadcast the pass now. need to wait until all rolling players are known.
vote = PASS;
r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
}
else
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
r->playerVote[playerToRoll->GetGUID()] = vote;
}
}
@@ -1075,7 +1091,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
continue;
if (itr->second == PASS)
SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r);
SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r, true);
else
SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
}
@@ -1114,11 +1130,16 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
if (!playerToRoll || !playerToRoll->GetSession())
continue;
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
RollVote vote = NOT_EMITED_YET;
if (!CanRollOnItem(*i, playerToRoll))
{
vote = PASS;
++r->totalPass;
}
r->playerVote[playerToRoll->GetGUID()] = vote;
}
}
@@ -1137,7 +1158,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
continue;
if (itr->second == PASS)
SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r);
SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r, true);
else
SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
}

View File

@@ -389,7 +389,7 @@ class TC_GAME_API Group
bool isRollLootActive() const { return !RollId.empty(); }
void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r) const;
void SendLootRoll(ObjectGuid playerGuid, int32 rollNumber, uint8 rollType, Roll const& roll) const;
void SendLootRoll(ObjectGuid playerGuid, int32 rollNumber, uint8 rollType, Roll const& roll, bool autoPass = false) const;
void SendLootRollWon(ObjectGuid winnerGuid, int32 rollNumber, uint8 rollType, Roll const& roll) const;
void SendLootAllPassed(Roll const& roll) const;
void SendLootRollsComplete(Roll const& roll) const;