diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 30d4e85b1..b38cf9f64 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -452,7 +452,6 @@ void Group::Disband(bool hideDestroy) void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) { ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(r.itemid); - uint8 voteMask = pProto->Flags2 & ITEM_FLAGS2_NEED_ROLL_DISABLED ? ROLL_VOTE_MASK_NO_NEED : ROLL_VOTE_MASK_ALL; WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1)); data << r.lootedTargetGUID; // creature guid what we're looting @@ -463,7 +462,9 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) data << uint32(r.itemRandomPropId); // item random property ID data << uint32(r.itemCount); // items in stack data << uint32(CountDown); // the countdown time to choose "need" or "greed" - data << uint8(voteMask); // roll type mask, allowed choices + + size_t voteMaskPos = data.wpos(); + data << uint8(0); // roll type mask, allowed choices (placeholder) for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr) { @@ -471,8 +472,14 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) if(!p || !p->GetSession()) continue; - if(itr->second != ROLL_NOT_VALID) - p->GetSession()->SendPacket( &data ); + if(itr->second == ROLL_NOT_VALID) + continue; + + // dependent from player + RollVoteMask voteMask = GetVoteMaskFor(pProto, p); + data.put(voteMaskPos,uint8(voteMask)); + + p->GetSession()->SendPacket( &data ); } } @@ -622,7 +629,20 @@ void Group::MasterLoot(Creature *creature, Loot* loot) } } -bool Group::CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote vote) +RollVoteMask Group::GetVoteMaskFor( ItemPrototype const* itemProto, Player* player ) +{ + RollVoteMask mask = ROLL_VOTE_MASK_ALL; + + if (itemProto->Flags2 & ITEM_FLAGS2_NEED_ROLL_DISABLED) + mask = RollVoteMask(mask & ~ROLL_VOTE_MASK_NEED); + + if (!itemProto->DisenchantID || uint32(itemProto->RequiredDisenchantSkill) > player->GetSkillValue(SKILL_ENCHANTING)) + mask = RollVoteMask(mask & ~ROLL_VOTE_MASK_DISENCHANT); + + return mask; +} + +bool Group::CountRollVote(Player* player, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote vote) { Rolls::iterator rollI = RollId.begin(); for (; rollI != RollId.end(); ++rollI) @@ -634,10 +654,11 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& looted // possible cheating ItemPrototype const* pProto = ObjectMgr::GetItemPrototype((*rollI)->itemid); - if ((pProto->Flags2 & ITEM_FLAGS2_NEED_ROLL_DISABLED) && vote == ROLL_NEED) + RollVoteMask voteMask = GetVoteMaskFor(pProto, player); + if ((voteMask & (1 << vote)) == 0) return false; - CountRollVote(playerGUID, rollI, vote); // result not related this function result meaning, ignore + CountRollVote(player->GetObjectGuid(), rollI, vote); // result not related this function result meaning, ignore return true; } diff --git a/src/game/Group.h b/src/game/Group.h index 927d326f0..3f2c10ec7 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -28,6 +28,10 @@ #include #include +struct ItemPrototype; +class BattleGround; +class InstanceSave; + #define MAX_GROUP_SIZE 5 #define MAX_RAID_SIZE 40 #define MAX_RAID_SUBGROUPS (MAX_RAID_SIZE / MAX_GROUP_SIZE) @@ -65,8 +69,6 @@ enum RollVoteMask ROLL_VOTE_MASK_DISENCHANT = 0x08, ROLL_VOTE_MASK_ALL = 0x0F, - - ROLL_VOTE_MASK_NO_NEED = ROLL_VOTE_MASK_ALL & ~ROLL_VOTE_MASK_NEED, }; @@ -101,8 +103,6 @@ enum GroupFlagMask GROUP_MAIN_TANK = 0x04, }; -class BattleGround; - enum GroupUpdateFlags { GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing @@ -134,8 +134,6 @@ enum GroupUpdateFlags // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19 static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT] = { 0, 2, 2, 2, 1, 2, 2, 2, 2, 4, 8, 8, 1, 2, 2, 2, 1, 2, 2, 8}; -class InstanceSave; - class Roll : public LootValidatorRef { public: @@ -357,7 +355,7 @@ class MANGOS_DLL_SPEC Group void GroupLoot(Creature *creature, Loot *loot); void NeedBeforeGreed(Creature *creature, Loot *loot); void MasterLoot(Creature *creature, Loot *loot); - bool CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote vote); + bool CountRollVote(Player* player, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote vote); void StartLootRool(Creature* lootTarget, Loot* loot, uint8 itemSlot, bool skipIfCanNotUse); void EndRoll(); @@ -431,6 +429,7 @@ class MANGOS_DLL_SPEC Group void CountTheRoll(Rolls::iterator& roll); // iterator update to next, in CountRollVote if true bool CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& roll, RollVote vote); + static RollVoteMask GetVoteMaskFor(ItemPrototype const* itemProto, Player* player); GroupFlagMask GetFlags(MemberSlot const& slot) const { diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index ef0b40502..98476fa24 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -393,7 +393,7 @@ void WorldSession::HandleLootRoll( WorldPacket &recv_data ) return; // everything is fine, do it, if false then some cheating problem found - if(!group->CountRollVote(GetPlayer()->GetObjectGuid(), lootedTarget, itemSlot, RollVote(rollType))) + if(!group->CountRollVote(GetPlayer(), lootedTarget, itemSlot, RollVote(rollType))) return; switch (rollType) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 365ce48b6..5199f1666 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10214" + #define REVISION_NR "10215" #endif // __REVISION_NR_H__