diff options
| -rw-r--r-- | src/server/game/Groups/Group.cpp | 99 | ||||
| -rw-r--r-- | src/server/game/Groups/Group.h | 2 |
2 files changed, 66 insertions, 35 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 74fc5cbdfb7..24bc91aad16 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -926,7 +926,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, p->SendDirectMessage(&data); } -void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll) +void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll, bool autoPass) { WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1)); data << uint64(sourceGuid); // guid of the item rolled @@ -937,7 +937,7 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol data << uint32(roll.itemRandomPropId); // Item random property ID data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll - data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed + data << uint8(autoPass); // 1: "You automatically passed on: %s because you cannot loot that item." for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) { @@ -1014,6 +1014,23 @@ void Group::SendLooter(Creature* creature, Player* groupLooter) BroadcastPacket(&data, 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->MaxCount > 0 && static_cast<int32>(itemCount) >= proto->MaxCount) || (player->CanEquipUniqueItem(proto) != EQUIP_ERR_OK)) + return false; + + if (!item.AllowedForPlayer(player)) + return false; + + return true; +} + void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) { std::vector<LootItem>::iterator i; @@ -1045,18 +1062,16 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) Player* member = itr->GetSource(); if (!member || !member->GetSession()) continue; - if (member->IsAtGroupRewardDistance(pLootedObject) && i->AllowedForPlayer(member)) + if (member->IsAtGroupRewardDistance(pLootedObject)) { r->totalPlayersRolling++; - - if (member->GetPassOnGroupLoot()) + RollVote vote = member->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET; + if (!CanRollOnItem(*i, member)) { - r->playerVote[member->GetGUID()] = PASS; - r->totalPass++; - // can't broadcast the pass now. need to wait until all rolling players are known. + vote = PASS; + ++r->totalPass; } - else - r->playerVote[member->GetGUID()] = NOT_EMITED_YET; + r->playerVote[member->GetGUID()] = vote; } } @@ -1069,7 +1084,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) loot->items[itemSlot].is_blocked = true; - // If there is any "auto pass", broadcast the pass now. + // If there are any "auto pass", broadcast them now if (r->totalPass) { for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr) @@ -1079,23 +1094,28 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) continue; if (itr->second == PASS) - SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r); + SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r, true); } } - SendLootStartRoll(60000, pLootedObject->GetMapId(), *r); + if (r->totalPass == r->totalPlayersRolling) + delete r; + else + { + SendLootStartRoll(60000, pLootedObject->GetMapId(), *r); - RollId.push_back(r); + RollId.push_back(r); - if (Creature* creature = pLootedObject->ToCreature()) - { - creature->m_groupLootTimer = 60000; - creature->lootingGroupLowGUID = GetLowGUID(); - } - else if (GameObject* go = pLootedObject->ToGameObject()) - { - go->m_groupLootTimer = 60000; - go->lootingGroupLowGUID = GetLowGUID(); + if (Creature* creature = pLootedObject->ToCreature()) + { + creature->m_groupLootTimer = 60000; + creature->lootingGroupLowGUID = GetLowGUID(); + } + else if (GameObject* go = pLootedObject->ToGameObject()) + { + go->m_groupLootTimer = 60000; + go->lootingGroupLowGUID = GetLowGUID(); + } } } else @@ -1128,10 +1148,16 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) if (!member || !member->GetSession()) continue; - if (member->IsAtGroupRewardDistance(pLootedObject) && i->AllowedForPlayer(member)) + if (member->IsAtGroupRewardDistance(pLootedObject)) { r->totalPlayersRolling++; - r->playerVote[member->GetGUID()] = NOT_EMITED_YET; + RollVote vote = NOT_EMITED_YET; + if (!CanRollOnItem(*i, member)) + { + vote = PASS; + ++r->totalPass; + } + r->playerVote[member->GetGUID()] = vote; } } @@ -1186,17 +1212,16 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) if (!playerToRoll || !playerToRoll->GetSession()) continue; - if (playerToRoll->IsAtGroupRewardDistance(lootedObject) && i->AllowedForPlayer(playerToRoll)) + 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; } } @@ -1261,10 +1286,16 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) if (!playerToRoll || !playerToRoll->GetSession()) continue; - if (playerToRoll->IsAtGroupRewardDistance(lootedObject) && i->AllowedForPlayer(playerToRoll)) + 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; } } diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index a7a962f5758..6ac1b9a9b9c 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -304,7 +304,7 @@ class TC_GAME_API Group bool isRollLootActive() const; void SendLootStartRoll(uint32 CountDown, uint32 mapid, Roll const& r); void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r); - void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const& r); + void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const& r, bool autoPass = false); void SendLootRollWon(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const& r); void SendLootAllPassed(Roll const& roll); void SendLooter(Creature* creature, Player* pLooter); |
