Beispiel #1
0
void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData)
{
    TC_LOG_DEBUG("network", "WORLD: CMSG_AUTOSTORE_LOOT_ITEM");
    Player* player = GetPlayer();
    Loot* loot = NULL;

    int32 lootCount = recvData.ReadBits(23);
    ObjectGuid* guids = new ObjectGuid[lootCount];

    for (int i = 0; i < lootCount; i++)
    {
        (guids[i])[2] = recvData.ReadBit();
        (guids[i])[7] = recvData.ReadBit();
        (guids[i])[0] = recvData.ReadBit();
        (guids[i])[6] = recvData.ReadBit();
        (guids[i])[5] = recvData.ReadBit();
        (guids[i])[3] = recvData.ReadBit();
        (guids[i])[1] = recvData.ReadBit();
        (guids[i])[4] = recvData.ReadBit();
    }

    for (int i = 0; i < lootCount; i++)
    {
        recvData.ReadByteSeq((guids[i])[0]);
        recvData.ReadByteSeq((guids[i])[4]);
        recvData.ReadByteSeq((guids[i])[1]);
        recvData.ReadByteSeq((guids[i])[7]);
        recvData.ReadByteSeq((guids[i])[6]);
        recvData.ReadByteSeq((guids[i])[5]);
        recvData.ReadByteSeq((guids[i])[3]);
        recvData.ReadByteSeq((guids[i])[2]);
        uint8 lootSlot;
        recvData >> lootSlot;

        uint64 guid = guids[i];

        if (IS_GAMEOBJECT_GUID(guid))
        {
            GameObject* go = player->GetMap()->GetGameObject(guid);

            // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
            if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player, INTERACTION_DISTANCE)))
            {
                player->SendLootRelease(guid);
                break;
            }

            loot = &go->loot;
        }
        else if (IS_ITEM_GUID(guid))
        {
            Item* pItem = player->GetItemByGuid(guid);

            if (!pItem)
            {
                player->SendLootRelease(guid);
                break;
            }

            loot = &pItem->loot;
        }
        else if (IS_CORPSE_GUID(guid))
        {
            Corpse* bones = ObjectAccessor::GetCorpse(*player, guid);
            if (!bones)
            {
                player->SendLootRelease(guid);
                break;
            }

            loot = &bones->loot;
        }
        else
        {
            Creature* creature = GetPlayer()->GetMap()->GetCreature(guid);

            bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed);

            if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
            {
                player->SendLootRelease(guid);
                break;
            }

            loot = &creature->loot;
        }

        if (!loot->HasLooter(_player->GetGUID()))
            break;

        player->StoreLootItem(lootSlot, loot);

        // If player is removing the last LootItem, delete the empty container.
        if (loot->isLooted() && IS_ITEM_GUID(guid))
            player->GetSession()->DoLootRelease(guid);
    }
    delete [] guids;
}