void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStorageTransfer& voidStorageTransfer) { Creature* unit = _player->GetNPCIfCanInteractWith(voidStorageTransfer.Npc, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s not found or player can't interact with it.", voidStorageTransfer.Npc.ToString().c_str()); return; } if (!_player->IsVoidStorageUnlocked()) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) queried void storage without unlocking it.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str()); return; } if (voidStorageTransfer.Deposits.size() > _player->GetNumOfVoidStorageFreeSlots()) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); return; } uint32 freeBagSlots = 0; if (!voidStorageTransfer.Withdrawals.empty()) { // make this a Player function for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* bag = _player->GetBagByPos(i)) freeBagSlots += bag->GetFreeSlots(); for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) if (!_player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) ++freeBagSlots; } if (voidStorageTransfer.Withdrawals.size() > freeBagSlots) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); return; } if (!_player->HasEnoughMoney(uint64(voidStorageTransfer.Deposits.size() * VOID_STORAGE_STORE_ITEM_COST))) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY); return; } WorldPackets::VoidStorage::VoidStorageTransferChanges voidStorageTransferChanges; voidStorageTransferChanges.AddedItems.reserve(VOID_STORAGE_MAX_DEPOSIT); voidStorageTransferChanges.RemovedItems.reserve(VOID_STORAGE_MAX_DEPOSIT); uint8 depositCount = 0; for (uint32 i = 0; i < voidStorageTransfer.Deposits.size(); ++i) { Item* item = _player->GetItemByGuid(voidStorageTransfer.Deposits[i]); if (!item) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s wants to deposit an invalid item (%s).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Deposits[i].ToString().c_str()); continue; } VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetGuidValue(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor(), item->GetModifier(ITEM_MODIFIER_UPGRADE_ID), item->GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS)); WorldPackets::VoidStorage::VoidItem voidItem; voidItem.Guid = ObjectGuid::Create<HighGuid::Item>(itemVS.ItemId); voidItem.Creator = item->GetGuidValue(ITEM_FIELD_CREATOR); voidItem.Item.Initialize(&itemVS); voidItem.Slot = _player->AddVoidStorageItem(std::move(itemVS)); voidStorageTransferChanges.AddedItems.push_back(voidItem); _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); ++depositCount; } int64 cost = depositCount * VOID_STORAGE_STORE_ITEM_COST; _player->ModifyMoney(-cost); for (uint32 i = 0; i < voidStorageTransfer.Withdrawals.size(); ++i) { uint8 slot = 0; VoidStorageItem* itemVS = _player->GetVoidStorageItem(voidStorageTransfer.Withdrawals[i].GetCounter(), slot); if (!itemVS) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s tried to withdraw an invalid item (id: %s)", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Withdrawals[i].ToString().c_str()); continue; } ItemPosCountVec dest; InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1); if (msg != EQUIP_ERR_OK) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s couldn't withdraw item id %s because inventory was full.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Withdrawals[i].ToString().c_str()); return; } Item* item = _player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId, GuidSet(), itemVS->BonusListIDs); item->SetUInt32Value(ITEM_FIELD_PROPERTY_SEED, itemVS->ItemSuffixFactor); item->SetGuidValue(ITEM_FIELD_CREATOR, itemVS->CreatorGuid); item->SetModifier(ITEM_MODIFIER_UPGRADE_ID, itemVS->ItemUpgradeId); item->SetBinding(true); voidStorageTransferChanges.RemovedItems.push_back(ObjectGuid::Create<HighGuid::Item>(itemVS->ItemId)); _player->DeleteVoidStorageItem(slot); } SendPacket(voidStorageTransferChanges.Write()); SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NO_ERROR); }
void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) { DEBUG_LOG("Received opcode CMSG_WRAP_ITEM"); uint8 gift_bag, gift_slot, item_bag, item_slot; //recv_data.hexlike(); recv_data >> gift_bag >> gift_slot; // paper recv_data >> item_bag >> item_slot; // item DEBUG_LOG("WRAP: receive gift_bag = %u, gift_slot = %u, item_bag = %u, item_slot = %u", gift_bag, gift_slot, item_bag, item_slot); Item *gift = _player->GetItemByPos( gift_bag, gift_slot ); if (!gift) { _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL ); return; } if (!gift->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPER))// cheating: non-wrapper wrapper { _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL ); return; } Item *item = _player->GetItemByPos( item_bag, item_slot ); if (!item) { _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, item, NULL ); return; } if (item == gift) // not possible with packet from real client { _player->SendEquipError( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL ); return; } if (item->IsEquipped()) { _player->SendEquipError( EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, item, NULL ); return; } if (!item->GetGuidValue(ITEM_FIELD_GIFTCREATOR).IsEmpty())// HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); { _player->SendEquipError( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL ); return; } if (item->IsBag()) { _player->SendEquipError( EQUIP_ERR_BAGS_CANT_BE_WRAPPED, item, NULL ); return; } if (item->IsSoulBound()) { _player->SendEquipError( EQUIP_ERR_BOUND_CANT_BE_WRAPPED, item, NULL ); return; } if (item->GetMaxStackCount() != 1) { _player->SendEquipError( EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, item, NULL ); return; } // maybe not correct check (it is better than nothing) if (item->GetProto()->MaxCount > 0) { _player->SendEquipError( EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, item, NULL ); return; } CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS)); item->SetEntry(gift->GetEntry()); switch (item->GetEntry()) { case 5042: item->SetEntry( 5043); break; case 5048: item->SetEntry( 5044); break; case 17303: item->SetEntry(17302); break; case 17304: item->SetEntry(17305); break; case 17307: item->SetEntry(17308); break; case 21830: item->SetEntry(21831); break; } item->SetGuidValue(ITEM_FIELD_GIFTCREATOR, _player->GetObjectGuid()); item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); item->SetState(ITEM_CHANGED, _player); if(item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` { // after save it will be impossible to remove the item from the queue item->RemoveFromUpdateQueueOf(_player); item->SaveToDB(); // item gave inventory record unchanged and can be save standalone } CharacterDatabase.CommitTransaction(); uint32 count = 1; _player->DestroyItemCount(gift, count, true); }
void WorldSession::HandleWrapItem(WorldPackets::Item::WrapItem& packet) { if (packet.Inv.Items.size() != 2) { TC_LOG_ERROR("network", "HandleWrapItem - Invalid itemCount (" SZFMTD ")", packet.Inv.Items.size()); return; } /// @todo: 6.x find better way for read // Gift uint8 giftContainerSlot = packet.Inv.Items[0].ContainerSlot; uint8 giftSlot = packet.Inv.Items[0].Slot; // Item uint8 itemContainerSlot = packet.Inv.Items[1].ContainerSlot; uint8 itemSlot = packet.Inv.Items[1].Slot; TC_LOG_DEBUG("network", "HandleWrapItem - Receive giftContainerSlot = %u, giftSlot = %u, itemContainerSlot = %u, itemSlot = %u", giftContainerSlot, giftSlot, itemContainerSlot, itemSlot); Item* gift = _player->GetItemByPos(giftContainerSlot, giftSlot); if (!gift) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL); return; } if (!(gift->GetTemplate()->GetFlags() & ITEM_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL); return; } Item* item = _player->GetItemByPos(itemContainerSlot, itemSlot); if (!item) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL); return; } if (item == gift) // not possable with pacjket from real client { _player->SendEquipError(EQUIP_ERR_CANT_WRAP_WRAPPED, item, NULL); return; } if (item->IsEquipped()) { _player->SendEquipError(EQUIP_ERR_CANT_WRAP_EQUIPPED, item, NULL); return; } if (!item->GetGuidValue(ITEM_FIELD_GIFTCREATOR).IsEmpty()) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); { _player->SendEquipError(EQUIP_ERR_CANT_WRAP_WRAPPED, item, NULL); return; } if (item->IsBag()) { _player->SendEquipError(EQUIP_ERR_CANT_WRAP_BAGS, item, NULL); return; } if (item->IsSoulBound()) { _player->SendEquipError(EQUIP_ERR_CANT_WRAP_BOUND, item, NULL); return; } if (item->GetMaxStackCount() != 1) { _player->SendEquipError(EQUIP_ERR_CANT_WRAP_STACKABLE, item, NULL); return; } // maybe not correct check (it is better than nothing) if (item->GetTemplate()->GetMaxCount() > 0) { _player->SendEquipError(EQUIP_ERR_CANT_WRAP_UNIQUE, item, NULL); return; } SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GIFT); stmt->setUInt64(0, item->GetOwnerGUID().GetCounter()); stmt->setUInt64(1, item->GetGUID().GetCounter()); stmt->setUInt32(2, item->GetEntry()); stmt->setUInt32(3, item->GetUInt32Value(ITEM_FIELD_FLAGS)); trans->Append(stmt); item->SetEntry(gift->GetEntry()); switch (item->GetEntry()) { case 5042: item->SetEntry(5043); break; case 5048: item->SetEntry(5044); break; case 17303: item->SetEntry(17302); break; case 17304: item->SetEntry(17305); break; case 17307: item->SetEntry(17308); break; case 21830: item->SetEntry(21831); break; } item->SetGuidValue(ITEM_FIELD_GIFTCREATOR, _player->GetGUID()); item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED); item->SetState(ITEM_CHANGED, _player); if (item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` { // after save it will be impossible to remove the item from the queue item->RemoveFromUpdateQueueOf(_player); item->SaveToDB(trans); // item gave inventory record unchanged and can be save standalone } CharacterDatabase.CommitTransaction(trans); uint32 count = 1; _player->DestroyItemCount(gift, count, true); }
void WorldSession::HandleAutoEquipItemOpcode(WorldPackets::Item::AutoEquipItem& autoEquipItem) { if (autoEquipItem.Inv.Items.size() != 1) { TC_LOG_ERROR("network", "HandleAutoEquipItemOpcode - Invalid itemCount (" SZFMTD ")", autoEquipItem.Inv.Items.size()); return; } TC_LOG_DEBUG("network", "HandleAutoEquipItemOpcode: receive PackSlot: %u, Slot: %u", autoEquipItem.PackSlot, autoEquipItem.Slot); Item* srcItem = _player->GetItemByPos(autoEquipItem.PackSlot, autoEquipItem.Slot); if (!srcItem) return; // only at cheat uint16 dest; InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, srcItem, !srcItem->IsBag()); if (msg != EQUIP_ERR_OK) { _player->SendEquipError(msg, srcItem); return; } uint16 src = srcItem->GetPos(); if (dest == src) // prevent equip in same slot, only at cheat return; Item* dstItem = _player->GetItemByPos(dest); if (!dstItem) // empty slot, simple case { if (!srcItem->GetChildItem().IsEmpty()) { InventoryResult childEquipResult = _player->CanEquipChildItem(srcItem); if (childEquipResult != EQUIP_ERR_OK) { _player->SendEquipError(msg, srcItem); return; } } _player->RemoveItem(autoEquipItem.PackSlot, autoEquipItem.Slot, true); _player->EquipItem(dest, srcItem, true); if (!srcItem->GetChildItem().IsEmpty()) _player->EquipChildItem(autoEquipItem.PackSlot, autoEquipItem.Slot, srcItem); _player->AutoUnequipOffhandIfNeed(); } else // have currently equipped item, not simple case { uint8 dstbag = dstItem->GetBagSlot(); uint8 dstslot = dstItem->GetSlot(); msg = _player->CanUnequipItem(dest, !srcItem->IsBag()); if (msg != EQUIP_ERR_OK) { _player->SendEquipError(msg, dstItem); return; } if (!dstItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_CHILD)) { // check dest->src move possibility ItemPosCountVec sSrc; uint16 eSrc = 0; if (_player->IsInventoryPos(src)) { msg = _player->CanStoreItem(autoEquipItem.PackSlot, autoEquipItem.Slot, sSrc, dstItem, true); if (msg != EQUIP_ERR_OK) msg = _player->CanStoreItem(autoEquipItem.PackSlot, NULL_SLOT, sSrc, dstItem, true); if (msg != EQUIP_ERR_OK) msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sSrc, dstItem, true); } else if (_player->IsBankPos(src)) { msg = _player->CanBankItem(autoEquipItem.PackSlot, autoEquipItem.Slot, sSrc, dstItem, true); if (msg != EQUIP_ERR_OK) msg = _player->CanBankItem(autoEquipItem.PackSlot, NULL_SLOT, sSrc, dstItem, true); if (msg != EQUIP_ERR_OK) msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, sSrc, dstItem, true); } else if (_player->IsEquipmentPos(src)) { msg = _player->CanEquipItem(autoEquipItem.Slot, eSrc, dstItem, true); if (msg == EQUIP_ERR_OK) msg = _player->CanUnequipItem(eSrc, true); } if (msg == EQUIP_ERR_OK && Player::IsEquipmentPos(dest) && !srcItem->GetChildItem().IsEmpty()) msg = _player->CanEquipChildItem(srcItem); if (msg != EQUIP_ERR_OK) { _player->SendEquipError(msg, dstItem, srcItem); return; } // now do moves, remove... _player->RemoveItem(dstbag, dstslot, false); _player->RemoveItem(autoEquipItem.PackSlot, autoEquipItem.Slot, false); // add to dest _player->EquipItem(dest, srcItem, true); // add to src if (_player->IsInventoryPos(src)) _player->StoreItem(sSrc, dstItem, true); else if (_player->IsBankPos(src)) _player->BankItem(sSrc, dstItem, true); else if (_player->IsEquipmentPos(src)) _player->EquipItem(eSrc, dstItem, true); if (Player::IsEquipmentPos(dest) && !srcItem->GetChildItem().IsEmpty()) _player->EquipChildItem(autoEquipItem.PackSlot, autoEquipItem.Slot, srcItem); } else { if (Item* parentItem = _player->GetItemByGuid(dstItem->GetGuidValue(ITEM_FIELD_CREATOR))) { if (Player::IsEquipmentPos(dest)) { _player->AutoUnequipChildItem(parentItem); // dest is now empty _player->SwapItem(src, dest); // src is now empty _player->SwapItem(parentItem->GetPos(), src); } } } _player->AutoUnequipOffhandIfNeed(); } }
void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) { TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData(); ByteBuffer itemData(7*2 + 7*4 + 3*4 + 3*4 + 1); uint8 count = 0; for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) if (view_trade->GetItem(TradeSlots(i))) ++count; WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 4*6 + 8 + 1 + 3 + count * 70); data << uint32(0); // CGTradeInfo::m_tradeID data << uint32(0); // unk 2 data << uint64(view_trade->GetMoney()); // trader gold data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases data << uint32(0); // unk 5 data << uint8(trader_data); // 1 means traders data, 0 means own data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases data.WriteBits(count, 22); for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) { Item* item = view_trade->GetItem(TradeSlots(i)); if (!item) continue; ObjectGuid giftCreatorGuid = item->GetGuidValue(ITEM_FIELD_GIFTCREATOR); ObjectGuid creatorGuid = item->GetGuidValue(ITEM_FIELD_CREATOR); data.WriteBit(giftCreatorGuid[7]); data.WriteBit(giftCreatorGuid[1]); bool notWrapped = data.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)); data.WriteBit(giftCreatorGuid[3]); if (notWrapped) { data.WriteBit(creatorGuid[7]); data.WriteBit(creatorGuid[1]); data.WriteBit(creatorGuid[4]); data.WriteBit(creatorGuid[6]); data.WriteBit(creatorGuid[2]); data.WriteBit(creatorGuid[3]); data.WriteBit(creatorGuid[5]); data.WriteBit(item->GetTemplate()->LockID != 0); data.WriteBit(creatorGuid[0]); itemData.WriteByteSeq(creatorGuid[1]); itemData << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS /*3*/; ++enchant_slot) itemData << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot))); itemData << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); itemData.WriteByteSeq(creatorGuid[6]); itemData.WriteByteSeq(creatorGuid[2]); itemData.WriteByteSeq(creatorGuid[7]); itemData.WriteByteSeq(creatorGuid[4]); itemData << uint32(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT)); itemData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); itemData << uint32(item->GetItemRandomPropertyId()); itemData.WriteByteSeq(creatorGuid[3]); itemData << uint32(0); // unk7 itemData.WriteByteSeq(creatorGuid[0]); itemData << uint32(item->GetSpellCharges()); itemData << uint32(item->GetItemSuffixFactor()); itemData.WriteByteSeq(creatorGuid[5]); } data.WriteBit(giftCreatorGuid[6]); data.WriteBit(giftCreatorGuid[4]); data.WriteBit(giftCreatorGuid[2]); data.WriteBit(giftCreatorGuid[0]); data.WriteBit(giftCreatorGuid[5]); itemData.WriteByteSeq(giftCreatorGuid[6]); itemData.WriteByteSeq(giftCreatorGuid[1]); itemData.WriteByteSeq(giftCreatorGuid[7]); itemData.WriteByteSeq(giftCreatorGuid[4]); itemData << uint32(item->GetTemplate()->ItemId); itemData.WriteByteSeq(giftCreatorGuid[0]); itemData << uint32(item->GetCount()); itemData.WriteByteSeq(giftCreatorGuid[5]); itemData << uint8(i); itemData.WriteByteSeq(giftCreatorGuid[2]); itemData.WriteByteSeq(giftCreatorGuid[3]); } data.FlushBits(); data.append(itemData); SendPacket(&data); }
void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM"); uint8 gift_bag, gift_slot, item_bag, item_slot; recvData >> gift_bag >> gift_slot; // paper recvData >> item_bag >> item_slot; // item TC_LOG_DEBUG("network", "WRAP: receive gift_bag = %u, gift_slot = %u, item_bag = %u, item_slot = %u", gift_bag, gift_slot, item_bag, item_slot); Item* gift = _player->GetItemByPos(gift_bag, gift_slot); if (!gift) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, nullptr); return; } if (!(gift->GetTemplate()->Flags & ITEM_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, nullptr); return; } Item* item = _player->GetItemByPos(item_bag, item_slot); if (!item) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr); return; } if (item == gift) // not possable with pacjket from real client { _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, nullptr); return; } if (item->IsEquipped()) { _player->SendEquipError(EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, item, nullptr); return; } if (!item->GetGuidValue(ITEM_FIELD_GIFTCREATOR).IsEmpty()) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); { _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, nullptr); return; } if (item->IsBag()) { _player->SendEquipError(EQUIP_ERR_BAGS_CANT_BE_WRAPPED, item, nullptr); return; } if (item->IsSoulBound()) { _player->SendEquipError(EQUIP_ERR_BOUND_CANT_BE_WRAPPED, item, nullptr); return; } if (item->GetMaxStackCount() != 1) { _player->SendEquipError(EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, item, nullptr); return; } // maybe not correct check (it is better than nothing) if (item->GetTemplate()->MaxCount>0) { _player->SendEquipError(EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, item, nullptr); return; } SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GIFT); stmt->setUInt32(0, item->GetOwnerGUID().GetCounter()); stmt->setUInt32(1, item->GetGUID().GetCounter()); stmt->setUInt32(2, item->GetEntry()); stmt->setUInt32(3, item->GetUInt32Value(ITEM_FIELD_FLAGS)); trans->Append(stmt); item->SetEntry(gift->GetEntry()); switch (item->GetEntry()) { case 5042: item->SetEntry(5043); break; case 5048: item->SetEntry(5044); break; case 17303: item->SetEntry(17302); break; case 17304: item->SetEntry(17305); break; case 17307: item->SetEntry(17308); break; case 21830: item->SetEntry(21831); break; } item->SetGuidValue(ITEM_FIELD_GIFTCREATOR, _player->GetGUID()); item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED); item->SetState(ITEM_CHANGED, _player); if (item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` { // after save it will be impossible to remove the item from the queue RemoveItemFromUpdateQueueOf(item, _player); item->SaveToDB(trans); // item gave inventory record unchanged and can be save standalone } CharacterDatabase.CommitTransaction(trans); uint32 count = 1; _player->DestroyItemCount(gift, count, true); }
void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStorageTransfer& voidStorageTransfer) { if (voidStorageTransfer.DepositsCount > VOID_STORAGE_MAX_DEPOSIT) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) wants to deposit more than 9 items (%u).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.DepositsCount); return; } if (voidStorageTransfer.WithdrawalsCount > VOID_STORAGE_MAX_WITHDRAW) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) wants to withdraw more than 9 items (%u).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.WithdrawalsCount); return; } Creature* unit = _player->GetNPCIfCanInteractWith(voidStorageTransfer.Npc, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s not found or player can't interact with it.", voidStorageTransfer.Npc.ToString().c_str()); return; } if (!_player->IsVoidStorageUnlocked()) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) queried void storage without unlocking it.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str()); return; } if (voidStorageTransfer.DepositsCount > _player->GetNumOfVoidStorageFreeSlots()) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); return; } uint32 freeBagSlots = 0; if (voidStorageTransfer.WithdrawalsCount) { // make this a Player function for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* bag = _player->GetBagByPos(i)) freeBagSlots += bag->GetFreeSlots(); for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) if (!_player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) ++freeBagSlots; } if (voidStorageTransfer.WithdrawalsCount > freeBagSlots) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); return; } if (!_player->HasEnoughMoney(uint64(voidStorageTransfer.DepositsCount * VOID_STORAGE_STORE_ITEM_COST))) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY); return; } std::pair<VoidStorageItem, uint8> depositItems[VOID_STORAGE_MAX_DEPOSIT]; uint8 depositCount = 0; for (uint32 i = 0; i < voidStorageTransfer.DepositsCount; ++i) { Item* item = _player->GetItemByGuid(voidStorageTransfer.Deposits[i]); if (!item) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s wants to deposit an invalid item (%s).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Deposits[i].ToString().c_str()); continue; } // TODO: Save these fields to database - for now disallow storing these items to prevent data loss if (item->GetUInt32Value(ITEM_FIELD_MODIFIERS_MASK) || !item->GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS).empty()) continue; VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetGuidValue(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor()); uint8 slot = _player->AddVoidStorageItem(itemVS); depositItems[depositCount++] = std::make_pair(itemVS, slot); _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); } int64 cost = depositCount * VOID_STORAGE_STORE_ITEM_COST; _player->ModifyMoney(-cost); VoidStorageItem withdrawItems[VOID_STORAGE_MAX_WITHDRAW]; uint8 withdrawCount = 0; for (uint32 i = 0; i < voidStorageTransfer.WithdrawalsCount; ++i) { uint8 slot = 0; VoidStorageItem* itemVS = _player->GetVoidStorageItem(voidStorageTransfer.Withdrawals[i].GetCounter(), slot); if (!itemVS) { TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s tried to withdraw an invalid item (id: %s)", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Withdrawals[i].ToString().c_str()); continue; } ItemPosCountVec dest; InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1); if (msg != EQUIP_ERR_OK) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s couldn't withdraw item id %s because inventory was full.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Withdrawals[i].ToString().c_str()); return; } Item* item = _player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId); item->SetUInt32Value(ITEM_FIELD_PROPERTY_SEED, itemVS->ItemSuffixFactor); item->SetGuidValue(ITEM_FIELD_CREATOR, itemVS->CreatorGuid); item->SetBinding(true); _player->SendNewItem(item, 1, false, false, false); withdrawItems[withdrawCount++] = *itemVS; _player->DeleteVoidStorageItem(slot); } WorldPackets::VoidStorage::VoidStorageTransferChanges voidStorageTransferChanges; voidStorageTransferChanges.AddedItems.resize(depositCount); voidStorageTransferChanges.RemovedItems.resize(withdrawCount); for (uint8 i = 0; i < depositCount; ++i) { voidStorageTransferChanges.AddedItems[i].Guid = ObjectGuid::Create<HighGuid::Item>(depositItems[i].first.ItemId); voidStorageTransferChanges.AddedItems[i].Creator = depositItems[i].first.CreatorGuid; voidStorageTransferChanges.AddedItems[i].Slot = depositItems[i].second; voidStorageTransferChanges.AddedItems[i].Item.Initialize(&depositItems[i].first); } for (uint8 i = 0; i < withdrawCount; ++i) voidStorageTransferChanges.RemovedItems[i] = ObjectGuid::Create<HighGuid::Item>(withdrawItems[i].ItemId); SendPacket(voidStorageTransferChanges.Write()); SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NO_ERROR); }