rendered paste bodyIndex: src/game/Group.cpp===================================================================--- src/game/Group.cpp (revision 5515)+++ src/game/Group.cpp (working copy)@@ -37,6 +37,7 @@ m_lootMethod = (LootMethod)0; m_looterGuid = 0; m_lootThreshold = ITEM_QUALITY_UNCOMMON;+ m_looterMasterGuid = 0; for(int i=0; i<TARGETICONCOUNT; i++) m_targetIcons[i] = 0;@@ -69,6 +70,7 @@ m_groupType = GROUPTYPE_NORMAL; m_lootMethod = GROUP_LOOT; m_lootThreshold = ITEM_QUALITY_UNCOMMON;+ m_looterMasterGuid = guid; if(!AddMember(guid, name)) return false;@@ -114,6 +116,7 @@ m_lootMethod = (LootMethod)(*result)[2].GetUInt8(); m_looterGuid = MAKE_GUID((*result)[3].GetUInt32(),HIGHGUID_PLAYER); m_lootThreshold = (ItemQualities)(*result)[4].GetUInt16();+ m_looterMasterGuid = m_looterGuid; for(int i=0; i<TARGETICONCOUNT; i++) m_targetIcons[i] = (*result)[5+i].GetUInt64();@@ -502,6 +505,35 @@ } } +void Group::MasterLoot(uint64 playerGUID, Creature *creature)+{+ Player *player = objmgr.GetPlayer(playerGUID);+ if(!player) return;+ sLog.outDebug("Group::MasterLoot (SMSG_LOOT_MASTER_LIST, 330) player = [%s].", player->GetName());+ + WorldPacket data(SMSG_LOOT_MASTER_LIST, 330);+ uint32 real_count = 0;+ data << (uint8)GetMembersCount();++ for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())+ {+ Player *looter = itr->getSource();+ if (!looter->IsInWorld()) continue;+ if (looter->GetDistance2dSq(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE))+ {+ data << looter->GetGUID();+ ++real_count;+ }+ }+ *(uint8*)&data.contents()[0] = real_count;+ + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())+ {+ Player *looter = itr->getSource();+ if (looter->GetDistance2dSq(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) looter->GetSession()->SendPacket(&data);+ }+}+ void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise) { Rolls::iterator rollI = GetRoll(Guid);Index: src/game/Group.h===================================================================--- src/game/Group.h (revision 5515)+++ src/game/Group.h (working copy)@@ -148,6 +148,7 @@ void SetLootMethod(LootMethod method) { m_lootMethod = method; } void SetLooterGuid(const uint64 &guid) { m_looterGuid = guid; } void SetLootThreshold(ItemQualities threshold) { m_lootThreshold = threshold; }+ void SetLooterMasterGuid(const uint64 &guid) { m_looterMasterGuid = guid; } void Disband(bool hideDestroy=false); // properties accessories@@ -158,6 +159,7 @@ LootMethod GetLootMethod() const { return m_lootMethod; } const uint64& GetLooterGuid() const { return m_looterGuid; } ItemQualities GetLootThreshold() const { return m_lootThreshold; }+ const uint64& GetLooterMasterGuid() const { return m_looterMasterGuid; } // member manipulation methods bool IsMember(uint64 guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); }@@ -260,6 +262,7 @@ void SendLootAllPassed(uint64 Guid, uint32 NumberOfPlayers, const Roll &r); void GroupLoot(uint64 playerGUID, Loot *loot, Creature *creature); void NeedBeforeGreed(uint64 playerGUID, Loot *loot, Creature *creature);+ void MasterLoot(uint64 playerGUID, Creature *creature); Rolls::iterator GetRoll(uint64 Guid) { Rolls::iterator iter;@@ -326,6 +329,7 @@ LootMethod m_lootMethod; ItemQualities m_lootThreshold; uint64 m_looterGuid;+ uint64 m_looterMasterGuid; Rolls RollId; }; #endifIndex: src/game/GroupHandler.cpp===================================================================--- src/game/GroupHandler.cpp (revision 5515)+++ src/game/GroupHandler.cpp (working copy)@@ -363,6 +363,7 @@ group->SetLootMethod((LootMethod)lootMethod); group->SetLooterGuid(lootMaster); group->SetLootThreshold((ItemQualities)lootThreshold);+ group->SetLooterMasterGuid(lootMaster); group->SendUpdate(); } Index: src/game/LootHandler.cpp===================================================================--- src/game/LootHandler.cpp (revision 5515)+++ src/game/LootHandler.cpp (working copy)@@ -424,3 +424,66 @@ //Player is not looking at loot list, he doesn't need to see updates on the loot list loot->RemoveLooter(player->GetGUID()); }++void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )+{+ if(!_player->IsInWorld()) return;++ Creature *pCreature = NULL;+ Loot *pLoot = NULL;+ uint64 creatureguid, target_playerguid;+ uint8 slotid;+ recv_data >> creatureguid >> slotid >> target_playerguid;++ if(_player->GetGroup() == NULL || _player->GetGroup()->GetLooterMasterGuid() != _player->GetGUID())+ return;++ Player *target = objmgr.GetPlayer((uint32)target_playerguid);+ if(!target)+ return;++ sLog.outDebug("WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [%s].", target->GetName()); ++ if(_player->GetLootGUID() != creatureguid)+ return;++ if(IS_CREATURE_GUID(GetPlayer()->GetLootGUID()))+ {+ pCreature = ObjectAccessor::GetCreature(*GetPlayer(), creatureguid);+ if (!pCreature)return;+ pLoot=&pCreature->loot; + }++ if(!pLoot) return;+ if (_player->GetGUID() != _player->GetGroup()->GetLooterMasterGuid())+ {+ _player->SendLootRelease(GetPlayer()->GetLootGUID());+ return;+ }+ + if (slotid > pLoot->items.size())+ {+ sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %d)",GetPlayer()->GetName(), slotid, pLoot->items.size());+ return;+ }++ uint32 amount = pLoot->items.at(slotid).count;+ uint32 itemid = pLoot->items.at(slotid).itemid;+ uint16 dest;+ + uint8 msg = target->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemid );+ if ( msg == EQUIP_ERR_OK )+ {+ Item * newitem = target->StoreNewItem( dest, itemid, amount, true, pLoot->items.at(slotid).randomPropertyId);+ pLoot->items.at(slotid).count=0;+ pLoot->items.at(slotid).is_looted=true;+ target->SendNewItem(newitem, uint32(amount), false, false );+ pLoot->NotifyItemRemoved(slotid);+ --pLoot->unlootedCount;+ }+ else + {+ target->SendEquipError( msg, NULL, NULL );+ return;+ } +}Index: src/game/Player.cpp===================================================================--- src/game/Player.cpp (revision 5515)+++ src/game/Player.cpp (working copy)@@ -6898,6 +6898,9 @@ case NEED_BEFORE_GREED: group->NeedBeforeGreed(recipient->GetGUID(), loot, creature); break;+ case MASTER_LOOT:+ group->MasterLoot(recipient->GetGUID(), creature);+ break; default: break; }@@ -6967,14 +6970,89 @@ if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA) loot_type = LOOT_SKINNING; - WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size - data << uint64(guid);- data << uint8(loot_type);- data << LootView(*loot, q_list, ffa_list, conditional_list, this, permission); - SendDirectMessage(&data); ++ uint8 slottype = 0; // <-- SlotType is the type of the slot (0 = FFA/1 = GL/2 = ML)+ if( GetGroup() )+ {+ if( GetGroup()->GetLootMethod() == MASTER_LOOT ) slottype = 2;+ }+ + if( slottype == 2 && IS_CREATURE_GUID(guid) ) // <-- Only for Creature's Corpse (Offylike is also Object as Chest)+ {+ sLog.outDebug("Player::SendLoot Looter = [%s], LooterMaster = [%s]", GetName(), objmgr.GetPlayer(GetGroup()->GetLooterMasterGuid())->GetName());+ WorldPacket data;+ data.SetOpcode (SMSG_LOOT_RESPONSE);+ data << uint64(guid);+ data << uint8(loot_type);+ data << loot->gold;+ data << (uint8) 0;+ uint32 count = 0;+ uint8 x = 0;+ for(std::vector<LootItem>::iterator itr=loot->items.begin(); itr!=loot->items.end(); itr++,x++)+ { + ItemPrototype const *itemProto = objmgr.GetItemPrototype(itr->itemid); + if (!itemProto) continue; + if (itr->is_looted) continue;+ + data << uint8(x); + data << uint32(itr->itemid);+ data << uint32(itr->count);+ data << uint32(itr->displayid); + if(itr->randomSuffix || itr->randomPropertyId)+ {+ data << uint32(itr->randomSuffix);+ data << uint32(itr->randomPropertyId);+ }+ else+ {+ data << uint32(0);+ data << uint32(0); + }+ + if(itemProto->Quality < GetGroup()->GetLootThreshold()) + {+ data << uint8(0);+ itr->is_underthreshold = true;+ }+ else if( GetGUID() != GetGroup()->GetLooterMasterGuid() )+ {+ data << uint8(1);+ itr->freeforall = false;+ }+ else data << slottype;+ count++;+ }+ for(std::vector<LootItem>::iterator itq=loot->quest_items.begin(); itq!=loot->quest_items.end(); itq++,x++)+ {+ if(!HasQuestForItem(itq->itemid)) continue;+ + data << uint8(x); + data << uint32(itq->itemid);+ data << uint32(itq->count);+ data << uint32(itq->displayid); + data << uint32(0);+ data << uint32(0); + data << uint32(0);+ count++;+ }+ data.wpos (13) ;+ data << (uint8)count;+ GetSession ()->SendPacket(&data);+ } + else // <-- Normal loot in case Master Loot Not Set!+ {+ WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size+ + data << uint64(guid);+ data << uint8(loot_type);+ data << LootView(*loot, q_list, ffa_list, conditional_list, this, permission);+ + SendDirectMessage(&data);+ }+ // add 'this' player as one of the players that are looting 'loot' if (permission != NONE_PERMISSION) loot->AddLooter(GetGUID());Index: src/game/WorldSession.cpp===================================================================--- src/game/WorldSession.cpp (revision 5515)+++ src/game/WorldSession.cpp (working copy)@@ -87,6 +87,7 @@ objmgr.opcodeTable[ CMSG_LOOT_MONEY ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode ); objmgr.opcodeTable[ CMSG_LOOT ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode ); objmgr.opcodeTable[ CMSG_LOOT_RELEASE ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode );+ objmgr.opcodeTable[ CMSG_LOOT_MASTER_GIVE ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode ); objmgr.opcodeTable[ CMSG_WHO ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode ); objmgr.opcodeTable[ CMSG_LOGOUT_REQUEST ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode ); objmgr.opcodeTable[ CMSG_PLAYER_LOGOUT ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode );Index: src/game/WorldSession.h===================================================================--- src/game/WorldSession.h (revision 5515)+++ src/game/WorldSession.h (working copy)@@ -241,6 +241,7 @@ void HandleLootMoneyOpcode(WorldPacket& recvPacket); void HandleLootOpcode(WorldPacket& recvPacket); void HandleLootReleaseOpcode(WorldPacket& recvPacket);+ void HandleLootMasterGiveOpcode(WorldPacket& recvPacket); void HandleWhoOpcode(WorldPacket& recvPacket); void HandleLogoutRequestOpcode(WorldPacket& recvPacket); void HandlePlayerLogoutOpcode(WorldPacket& recvPacket);