TrinityCore
Loading...
Searching...
No Matches
ItemHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "WorldSession.h"
19#include "Bag.h"
20#include "Common.h"
21#include "Creature.h"
22#include "DatabaseEnv.h"
23#include "DBCStores.h"
24#include "Opcodes.h"
25#include "Item.h"
26#include "ItemPackets.h"
27#include "Log.h"
28#include "NPCPackets.h"
29#include "ObjectMgr.h"
30#include "Player.h"
31#include "SpellInfo.h"
32#include "QueryPackets.h"
33#include "World.h"
34#include "WorldPacket.h"
35
37{
38 TC_LOG_DEBUG("network", "HandleSplitItemOpcode: receive FromPackSlot: {}, FromSlot: {}, ToPackSlot: {}, ToSlot: {}, Quantity: {}",
39 splitItem.FromPackSlot, splitItem.FromSlot, splitItem.ToPackSlot, splitItem.ToSlot, splitItem.Quantity);
40
41 uint16 src = ((splitItem.FromPackSlot << 8) | splitItem.FromSlot);
42 uint16 dst = ((splitItem.ToPackSlot << 8) | splitItem.ToSlot);
43
44 if (src == dst)
45 return;
46
47 // check count - if zero it's fake packet
48 if (!splitItem.Quantity)
49 return;
50
51 if (!_player->IsValidPos(splitItem.FromPackSlot, splitItem.FromSlot, true))
52 {
54 return;
55 }
56
57 if (!_player->IsValidPos(splitItem.ToPackSlot, splitItem.ToSlot, false)) // can be autostore pos
58 {
60 return;
61 }
62
63 _player->SplitItem(src, dst, splitItem.Quantity);
64}
65
67{
68 TC_LOG_DEBUG("network", "HandleSwapInvItemOpcode: receive Slot1: {}, Slot2: {}",
69 swapInvItem.Slot1, swapInvItem.Slot2);
70
71 // prevent attempt swap same item to current position generated by client at special checting sequence
72 if (swapInvItem.Slot1 == swapInvItem.Slot2)
73 return;
74
75 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, swapInvItem.Slot1, true))
76 {
78 return;
79 }
80
81 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, swapInvItem.Slot2, true))
82 {
84 return;
85 }
86
87 if (_player->IsBankPos(INVENTORY_SLOT_BAG_0, swapInvItem.Slot1) && !CanUseBank())
88 {
89 TC_LOG_DEBUG("network", "HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
90 return;
91 }
92
93 if (_player->IsBankPos(INVENTORY_SLOT_BAG_0, swapInvItem.Slot2) && !CanUseBank())
94 {
95 TC_LOG_DEBUG("network", "HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
96 return;
97 }
98
99 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | swapInvItem.Slot1);
100 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | swapInvItem.Slot2);
101
102 _player->SwapItem(src, dst);
103}
104
106{
107 ObjectGuid itemguid;
108 uint8 dstslot;
109 recvData >> itemguid >> dstslot;
110
111 // cheating attempt, client should never send opcode in that case
113 return;
114
115 Item* item = _player->GetItemByGuid(itemguid);
116 uint16 dstpos = dstslot | (INVENTORY_SLOT_BAG_0 << 8);
117
118 if (!item || item->GetPos() == dstpos)
119 return;
120
121 _player->SwapItem(item->GetPos(), dstpos);
122}
123
125{
126 TC_LOG_DEBUG("network", "HandleSwapItem: receive ContainerSlotA: {}, SlotA: {}, ContainerSlotB: {}, SlotB: {}",
127 swapItem.ContainerSlotA, swapItem.SlotA, swapItem.ContainerSlotB, swapItem.SlotB);
128
129 uint16 src = ((swapItem.ContainerSlotA << 8) | swapItem.SlotA);
130 uint16 dst = ((swapItem.ContainerSlotB << 8) | swapItem.SlotB);
131
132 // prevent attempt swap same item to current position generated by client at special checting sequence
133 if (src == dst)
134 return;
135
136 if (!_player->IsValidPos(swapItem.ContainerSlotA, swapItem.SlotA, true))
137 {
139 return;
140 }
141
142 if (!_player->IsValidPos(swapItem.ContainerSlotB, swapItem.SlotB, true))
143 {
145 return;
146 }
147
148 if (_player->IsBankPos(swapItem.ContainerSlotA, swapItem.SlotA) && !CanUseBank())
149 {
150 TC_LOG_DEBUG("network", "HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
151 return;
152 }
153
154 if (_player->IsBankPos(swapItem.ContainerSlotB, swapItem.SlotB) && !CanUseBank())
155 {
156 TC_LOG_DEBUG("network", "HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
157 return;
158 }
159
160 _player->SwapItem(src, dst);
161}
162
164{
165 TC_LOG_DEBUG("network", "HandleAutoEquipItemOpcode: receive PackSlot: {}, Slot: {}",
166 autoEquipItem.PackSlot, autoEquipItem.Slot);
167
168 Item* srcItem = _player->GetItemByPos(autoEquipItem.PackSlot, autoEquipItem.Slot);
169 if (!srcItem)
170 return; // only at cheat
171
172 uint16 dest;
173 InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, srcItem, !srcItem->IsBag());
174 if (msg != EQUIP_ERR_OK)
175 {
176 _player->SendEquipError(msg, srcItem);
177 return;
178 }
179
180 uint16 src = srcItem->GetPos();
181 if (dest == src) // prevent equip in same slot, only at cheat
182 return;
183
184 Item* dstItem = _player->GetItemByPos(dest);
185 if (!dstItem) // empty slot, simple case
186 {
187 _player->RemoveItem(autoEquipItem.PackSlot, autoEquipItem.Slot, true);
188 _player->EquipItem(dest, srcItem, true);
190 }
191 else // have currently equipped item, not simple case
192 {
193 uint8 dstbag = dstItem->GetBagSlot();
194 uint8 dstslot = dstItem->GetSlot();
195
196 msg = _player->CanUnequipItem(dest, !srcItem->IsBag());
197 if (msg != EQUIP_ERR_OK)
198 {
199 _player->SendEquipError(msg, dstItem);
200 return;
201 }
202
203 // check dest->src move possibility
204 ItemPosCountVec sSrc;
205 uint16 eSrc = 0;
206 if (_player->IsInventoryPos(src))
207 {
208 msg = _player->CanStoreItem(autoEquipItem.PackSlot, autoEquipItem.Slot, sSrc, dstItem, true);
209 if (msg != EQUIP_ERR_OK)
210 msg = _player->CanStoreItem(autoEquipItem.PackSlot, NULL_SLOT, sSrc, dstItem, true);
211 if (msg != EQUIP_ERR_OK)
212 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sSrc, dstItem, true);
213 }
214 else if (_player->IsBankPos(src))
215 {
216 msg = _player->CanBankItem(autoEquipItem.PackSlot, autoEquipItem.Slot, sSrc, dstItem, true);
217 if (msg != EQUIP_ERR_OK)
218 msg = _player->CanBankItem(autoEquipItem.PackSlot, NULL_SLOT, sSrc, dstItem, true);
219 if (msg != EQUIP_ERR_OK)
220 msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, sSrc, dstItem, true);
221 }
222 else if (_player->IsEquipmentPos(src))
223 {
224 msg = _player->CanEquipItem(autoEquipItem.Slot, eSrc, dstItem, true);
225 if (msg == EQUIP_ERR_OK)
226 msg = _player->CanUnequipItem(eSrc, true);
227 }
228
229 if (msg != EQUIP_ERR_OK)
230 {
231 _player->SendEquipError(msg, dstItem, srcItem);
232 return;
233 }
234
235 // now do moves, remove...
236 _player->RemoveItem(dstbag, dstslot, false);
237 _player->RemoveItem(autoEquipItem.PackSlot, autoEquipItem.Slot, false);
238
239 // add to dest
240 _player->EquipItem(dest, srcItem, true);
241
242 // add to src
243 if (_player->IsInventoryPos(src))
244 _player->StoreItem(sSrc, dstItem, true);
245 else if (_player->IsBankPos(src))
246 _player->BankItem(sSrc, dstItem, true);
247 else if (_player->IsEquipmentPos(src))
248 _player->EquipItem(eSrc, dstItem, true);
249
251
252 // if inventory item was moved, check if we can remove dependent auras, because they were not removed in Player::RemoveItem (update was set to false)
253 // do this after swaps are done, we pass nullptr because both weapons could be swapped and none of them should be ignored
254 if ((autoEquipItem.PackSlot == INVENTORY_SLOT_BAG_0 && autoEquipItem.Slot < INVENTORY_SLOT_BAG_END) || (dstbag == INVENTORY_SLOT_BAG_0 && dstslot < INVENTORY_SLOT_BAG_END))
255 _player->ApplyItemDependentAuras((Item*)nullptr, false);
256 }
257}
258
260{
261 TC_LOG_DEBUG("network", "HandleDestroyItemOpcode: receive ContainerId: {}, SlotNum: {}, Count: {}",
262 destroyItem.ContainerId, destroyItem.SlotNum, destroyItem.Count);
263
264 uint16 pos = (destroyItem.ContainerId << 8) | destroyItem.SlotNum;
265
266 // prevent drop unequipable items (in combat, for example) and non-empty bags
267 if (_player->IsEquipmentPos(pos) || _player->IsBagPos(pos))
268 {
269 InventoryResult msg = _player->CanUnequipItem(pos, false);
270 if (msg != EQUIP_ERR_OK)
271 {
273 return;
274 }
275 }
276
277 Item* item = _player->GetItemByPos(destroyItem.ContainerId, destroyItem.SlotNum);
278 if (!item)
279 {
281 return;
282 }
283
285 {
287 return;
288 }
289
290 if (destroyItem.Count)
291 _player->DestroyItemCount(item, destroyItem.Count, true);
292 else
293 _player->DestroyItem(destroyItem.ContainerId, destroyItem.SlotNum, true);
294}
295
296// Only _static_ data send in this packet !!!
298{
299 TC_LOG_INFO("network", "STORAGE: Item Query = {}", query.ItemID);
300
301 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(query.ItemID))
302 {
303 if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
304 SendPacket(&itemTemplate->QueryData[static_cast<uint32>(GetSessionDbLocaleIndex())]);
305 else
306 {
307 WorldPacket response = itemTemplate->BuildQueryData(GetSessionDbLocaleIndex());
308 SendPacket(&response);
309 }
310 }
311 else
312 {
313 TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: {})", query.ItemID);
315 response.ItemID = query.ItemID;
316 SendPacket(response.Write());
317 }
318}
319
321{
322 uint8 bag, slot;
323 recvData >> bag >> slot;
324
325 Item* pItem = _player->GetItemByPos(bag, slot);
326
327 if (pItem && pItem->GetTemplate()->GetPageText())
328 {
329 WorldPacket data;
330
331 InventoryResult msg = _player->CanUseItem(pItem);
332 if (msg == EQUIP_ERR_OK)
333 {
335 TC_LOG_INFO("network", "STORAGE: Item page sent");
336 }
337 else
338 {
340 TC_LOG_INFO("network", "STORAGE: Unable to read item");
341 _player->SendEquipError(msg, pItem, nullptr);
342 }
343 data << pItem->GetGUID();
344 SendPacket(&data);
345 }
346 else
348}
349
351{
352 TC_LOG_DEBUG("network", "WORLD: Received CMSG_SELL_ITEM: Vendor %s, Item %s, Amount: %u",
353 packet.VendorGUID.ToString().c_str(), packet.ItemGUID.ToString().c_str(), packet.Amount);
354
355 if (packet.ItemGUID.IsEmpty())
356 return;
357
359 if (!creature)
360 {
361 TC_LOG_DEBUG("network", "WORLD: HandleSellItemOpcode - {} not found or you can not interact with him.", packet.VendorGUID.ToString());
363 return;
364 }
365
367 {
369 return;
370 }
371
372 // remove fake death
373 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
375
376 Item* pItem = _player->GetItemByGuid(packet.ItemGUID);
377 if (pItem)
378 {
379 // prevent sell not owner item
380 if (_player->GetGUID() != pItem->GetOwnerGUID())
381 {
383 return;
384 }
385
386 // prevent sell non empty bag by drag-and-drop at vendor's item list
387 if (pItem->IsNotEmptyBag())
388 {
390 return;
391 }
392
393 // prevent sell currently looted item
394 if (_player->GetLootGUID() == pItem->GetGUID())
395 {
397 return;
398 }
399
400 // prevent selling item for sellprice when the item is still refundable
401 // this probably happens when right clicking a refundable item, the client sends both
402 // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
403 if (pItem->IsRefundable())
404 return; // Therefore, no feedback to client
405
406 // special case at auto sell (sell all)
407 if (packet.Amount == 0)
408 packet.Amount = pItem->GetCount();
409 else
410 {
411 // prevent sell more items that exist in stack (possible only not from client)
412 if (packet.Amount > pItem->GetCount())
413 {
415 return;
416 }
417 }
418
419 ItemTemplate const* pProto = pItem->GetTemplate();
420 if (pProto)
421 {
422 if (uint32 sellPrice = pItem->GetSellPrice(true); sellPrice > 0)
423 {
424 uint32 money = sellPrice * packet.Amount;
425
426 if (_player->GetMoney() >= MAX_MONEY_AMOUNT - money) // prevent exceeding gold limit
427 {
429 _player->SendSellError(SELL_ERR_UNK, creature, packet.ItemGUID, 0);
430 return;
431 }
432
433 if (packet.Amount < pItem->GetCount()) // need split items
434 {
435 Item* pNewItem = pItem->CloneItem(packet.Amount, _player);
436 if (!pNewItem)
437 {
438 TC_LOG_ERROR("network", "WORLD: HandleSellItemOpcode - could not create clone of item {}; count = {}", pItem->GetEntry(), packet.Amount);
440 return;
441 }
442
443 pItem->SetCount(pItem->GetCount() - packet.Amount);
444 _player->ItemRemovedQuestCheck(pItem->GetEntry(), packet.Amount);
445 if (_player->IsInWorld())
448
449 _player->AddItemToBuyBackSlot(pNewItem);
450 if (_player->IsInWorld())
451 pNewItem->SendUpdateToPlayer(_player);
452 }
453 else
454 {
455 _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
456 _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
459 }
460
461 _player->ModifyMoney(money);
463 }
464 else
466 return;
467 }
468 }
470 return;
471}
472
474{
475 TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUYBACK_ITEM: Vendor %s, Slot: %u", packet.VendorGUID.ToString().c_str(), packet.Slot);
476
478 if (!creature)
479 {
480 TC_LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit ({}) not found or you can not interact with him.", packet.VendorGUID.ToString());
482 return;
483 }
484
485 // remove fake death
486 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
488
489 Item* pItem = _player->GetItemFromBuyBackSlot(packet.Slot);
490 if (pItem)
491 {
493 if (!_player->HasEnoughMoney(price))
494 {
496 return;
497 }
498
499 ItemPosCountVec dest;
500 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
501 if (msg == EQUIP_ERR_OK)
502 {
503 _player->ModifyMoney(-(int32)price);
504 _player->RemoveItemFromBuyBackSlot(packet.Slot, false);
505 _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
506 _player->StoreItem(dest, pItem, true);
507 }
508 else
509 _player->SendEquipError(msg, pItem, nullptr);
510 return;
511 }
512 else
514}
515
517{
518 TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM_IN_SLOT");
519 ObjectGuid vendorguid, bagguid;
520 uint32 item, slot, count;
521 uint8 bagslot;
522
523 recvData >> vendorguid >> item >> slot >> bagguid >> bagslot >> count;
524
525 // client expects count starting at 1, and we send vendorslot+1 to client already
526 if (slot > 0)
527 --slot;
528 else
529 return; // cheating
530
531 uint8 bag = NULL_BAG;
532 if (bagguid == GetPlayer()->GetGUID()) // The client sends the player guid when trying to store an item in the default backpack
534 else if (Item* bagItem = _player->GetItemByGuid(bagguid))
535 bag = bagItem->GetSlot();
536 else
537 return;
538
539 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot);
540}
541
543{
544 TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM");
545 ObjectGuid vendorguid;
546 uint32 item, slot, count;
547 uint8 unk1;
548
549 recvData >> vendorguid >> item >> slot >> count >> unk1;
550
551 // client expects count starting at 1, and we send vendorslot+1 to client already
552 if (slot > 0)
553 --slot;
554 else
555 return; // cheating
556
557 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, NULL_BAG, NULL_SLOT);
558}
559
561{
562 TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY");
563
564 if (!GetPlayer()->IsAlive())
565 return;
566
567 SendListInventory(packet.Unit);
568}
569
571{
573 if (!vendor)
574 {
575 TC_LOG_DEBUG("network", "WORLD: SendListInventory - {} not found or you can not interact with him.", vendorGuid.ToString());
577 return;
578 }
579
580 // remove fake death
581 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
583
584 // Stop the npc if moving
586 vendor->PauseMovement(pause);
587 vendor->SetHomePosition(vendor->GetPosition());
588
589 VendorItemData const* vendorItems = vendor->GetVendorItems();
590 uint32 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0;
591
593 packet.Vendor = vendor->GetGUID();
594
595 packet.Items.resize(rawItemCount);
596
597 const float discountMod = _player->GetReputationPriceDiscount(vendor);
598 uint8 count = 0;
599 for (uint32 slot = 0; slot < rawItemCount; ++slot)
600 {
601 VendorItem const* vendorItem = vendorItems->GetItem(slot);
602 if (!vendorItem)
603 continue;
604
605 WorldPackets::NPC::VendorItem& item = packet.Items[count];
606
607 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item);
608 if (!itemTemplate)
609 continue;
610
611 int32 leftInStock = !vendorItem->maxcount ? -1 : int32(vendor->GetVendorItemCurrentCount(vendorItem));
612 if (!_player->IsGameMaster()) // ignore conditions if GM on
613 {
614 // Respect allowed class
615 if (!(itemTemplate->GetAllowableClass() & _player->GetClassMask()) && itemTemplate->GetBonding() == BIND_WHEN_PICKED_UP)
616 continue;
617
618 // Only display items in vendor lists for the team the
619 // player is on. If GM on, display all items.
620 if ((itemTemplate->HasFlag(ITEM_FLAG2_FACTION_HORDE) && _player->GetTeam() == ALLIANCE) ||
621 (itemTemplate->HasFlag(ITEM_FLAG2_FACTION_ALLIANCE) && _player->GetTeam() == HORDE))
622 continue;
623
624 // Items sold out are not displayed in list
625 if (leftInStock == 0)
626 continue;
627 }
628
629 if (!sConditionMgr->IsObjectMeetingVendorItemConditions(vendor->GetEntry(), vendorItem->item, _player, vendor))
630 {
631 TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry {} item {}", vendor->GetEntry(), vendorItem->item);
632 continue;
633 }
634
635 // reputation discount
636 int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->GetBuyPrice() * discountMod)) : 0;
637
638 item.MuID = slot + 1; // client expects counting to start at 1
639 item.Item = vendorItem->item;
640 item.ItemDisplayInfoID = itemTemplate->GetDisplayId();
641 item.Quantity = leftInStock;
642 item.Price = price;
643 item.Durability = itemTemplate->MaxDurability;
644 item.StackCount = itemTemplate->GetBuyCount();
645 item.ExtendedCostID = vendorItem->ExtendedCost;
646
647 if (++count >= MAX_VENDOR_ITEMS)
648 break;
649 }
650
651 // Resize vector to real size (some items can be skipped due to checks)
652 packet.Items.resize(count);
653
654 if (packet.Items.empty())
656
657 SendPacket(packet.Write());
658}
659
661{
662 TC_LOG_DEBUG("network", "HandleAutoStoreBagItemOpcode: receive ContainerSlotA: {}, SlotA: {}, ContainerSlotB: {}",
663 packet.ContainerSlotA, packet.SlotA, packet.ContainerSlotB);
664
665 Item* item = _player->GetItemByPos(packet.ContainerSlotA, packet.SlotA);
666 if (!item)
667 return;
668
669 if (!_player->IsValidPos(packet.ContainerSlotB, NULL_SLOT, false)) // can be autostore pos
670 {
672 return;
673 }
674
675 uint16 src = item->GetPos();
676
677 // check unequip potability for equipped items and bank bags
678 if (_player->IsEquipmentPos(src) || _player->IsBagPos(src))
679 {
681 if (msg != EQUIP_ERR_OK)
682 {
683 _player->SendEquipError(msg, item);
684 return;
685 }
686 }
687
688 ItemPosCountVec dest;
689 InventoryResult msg = _player->CanStoreItem(packet.ContainerSlotB, NULL_SLOT, dest, item, false);
690 if (msg != EQUIP_ERR_OK)
691 {
692 _player->SendEquipError(msg, item);
693 return;
694 }
695
696 // no-op: placed in same slot
697 if (dest.size() == 1 && dest[0].pos == src)
698 {
699 // just remove grey item state
701 return;
702 }
703
704 _player->RemoveItem(packet.ContainerSlotA, packet.SlotA, true);
705 _player->StoreItem(dest, item, true);
706}
707
709{
710 if (!_player->IsAlive())
711 {
712 _player->SendEquipError(EQUIP_ERR_PLAYER_DEAD, nullptr, nullptr);
713 return;
714 }
715
716 TC_LOG_DEBUG("network", "WORLD: CMSG_SET_AMMO");
717 uint32 item;
718
719 recvData >> item;
720
721 if (item)
722 {
723 if (!_player->GetItemCount(item))
724 {
726 return;
727 }
728
729 _player->SetAmmo(item);
730 }
731 else
733}
734
736{
737 WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4)); // last check 2.0.10
738 data << target.WriteAsPacked();
739 data << caster.WriteAsPacked();
740 data << uint32(itemId);
741 data << uint32(enchantId);
742 GetPlayer()->SendMessageToSet(&data, true);
743}
744
746{
747 // last check 2.0.10
749 data << Itemguid;
750 data << uint32(slot);
751 data << uint32(Duration);
752 data << Playerguid;
753 SendPacket(&data);
754}
755
757{
758 uint32 itemid;
759 recvData >> itemid;
760 recvData.read_skip<uint64>(); // guid
761
762 TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_NAME_QUERY {}", itemid);
763 ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid);
764 if (pName)
765 {
766 std::string Name = pName->name;
767 LocaleConstant localeConstant = GetSessionDbLocaleIndex();
768 if (localeConstant != LOCALE_enUS)
769 if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid))
770 ObjectMgr::GetLocaleString(isnl->Name, localeConstant, Name);
771
772 WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+Name.size()+1+4));
773 data << uint32(itemid);
774 data << Name;
775 data << uint32(pName->InventoryType);
776 SendPacket(&data);
777 }
778}
779
781{
782 TC_LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM");
783
784 uint8 gift_bag, gift_slot, item_bag, item_slot;
785
786 recvData >> gift_bag >> gift_slot; // paper
787 recvData >> item_bag >> item_slot; // item
788
789 TC_LOG_DEBUG("network", "WRAP: receive gift_bag = {}, gift_slot = {}, item_bag = {}, item_slot = {}", gift_bag, gift_slot, item_bag, item_slot);
790
791 Item* gift = _player->GetItemByPos(gift_bag, gift_slot);
792 if (!gift)
793 {
795 return;
796 }
797
798 if (!gift->GetTemplate()->HasFlag(ITEM_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper
799 {
801 return;
802 }
803
804 Item* item = _player->GetItemByPos(item_bag, item_slot);
805
806 if (!item)
807 {
809 return;
810 }
811
812 if (item == gift) // not possable with pacjket from real client
813 {
815 return;
816 }
817
818 if (item->IsEquipped())
819 {
821 return;
822 }
823
824 if (!item->GetGuidValue(ITEM_FIELD_GIFTCREATOR).IsEmpty()) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
825 {
827 return;
828 }
829
830 if (item->IsBag())
831 {
833 return;
834 }
835
836 if (item->IsSoulBound())
837 {
839 return;
840 }
841
842 if (item->GetMaxStackCount() != 1)
843 {
845 return;
846 }
847
848 // maybe not correct check (it is better than nothing)
849 if (item->GetTemplate()->GetMaxCount() > 0)
850 {
852 return;
853 }
854
855 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
856
858 stmt->setUInt32(0, item->GetOwnerGUID().GetCounter());
859 stmt->setUInt32(1, item->GetGUID().GetCounter());
860 stmt->setUInt32(2, item->GetEntry());
862 trans->Append(stmt);
863
864 item->SetEntry(gift->GetEntry());
865
866 switch (item->GetEntry())
867 {
868 case 5042: item->SetEntry(5043); break;
869 case 5048: item->SetEntry(5044); break;
870 case 17303: item->SetEntry(17302); break;
871 case 17304: item->SetEntry(17305); break;
872 case 17307: item->SetEntry(17308); break;
873 case 21830: item->SetEntry(21831); break;
874 }
878
879 if (item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance`
880 {
881 // after save it will be impossible to remove the item from the queue
883 item->SaveToDB(trans); // item gave inventory record unchanged and can be save standalone
884 }
885 CharacterDatabase.CommitTransaction(trans);
886
887 uint32 count = 1;
888 _player->DestroyItemCount(gift, count, true);
889}
890
892{
893 TC_LOG_DEBUG("network", "WORLD: CMSG_SOCKET_GEMS");
894
895 ObjectGuid item_guid;
896 ObjectGuid gem_guids[MAX_GEM_SOCKETS];
897
898 recvData >> item_guid;
899 if (!item_guid)
900 return;
901
902 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
903 recvData >> gem_guids[i];
904
905 //cheat -> tried to socket same gem multiple times
906 if ((!gem_guids[0].IsEmpty() && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) ||
907 (!gem_guids[1].IsEmpty() && (gem_guids[1] == gem_guids[2])))
908 return;
909
910 Item* itemTarget = _player->GetItemByGuid(item_guid);
911 if (!itemTarget) //missing item to socket
912 return;
913
914 ItemTemplate const* itemProto = itemTarget->GetTemplate();
915 if (!itemProto)
916 return;
917
918 //this slot is excepted when applying / removing meta gem bonus
919 uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);
920
921 Item* Gems[MAX_GEM_SOCKETS];
922 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
923 Gems[i] = !gem_guids[i].IsEmpty() ? _player->GetItemByGuid(gem_guids[i]) : nullptr;
924
925 GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS];
926 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage
927 GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GetGemProperties()) : nullptr;
928
929 // Find first prismatic socket
930 int32 firstPrismatic = 0;
931 while (firstPrismatic < MAX_GEM_SOCKETS && itemProto->GetSocketColor(firstPrismatic))
932 ++firstPrismatic;
933
934 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe
935 {
936 if (!GemProps[i])
937 continue;
938
939 // tried to put gem in socket where no socket exists (take care about prismatic sockets)
940 if (!itemProto->GetSocketColor(i))
941 {
942 // no prismatic socket
944 return;
945
946 if (i != firstPrismatic)
947 return;
948 }
949
950 // tried to put normal gem in meta socket
951 if (itemProto->GetSocketColor(i) == SOCKET_COLOR_META && GemProps[i]->Type != SOCKET_COLOR_META)
952 return;
953
954 // tried to put meta gem in normal socket
955 if (itemProto->GetSocketColor(i) != SOCKET_COLOR_META && GemProps[i]->Type == SOCKET_COLOR_META)
956 return;
957 }
958
959 uint32 GemEnchants[MAX_GEM_SOCKETS];
960 uint32 OldEnchants[MAX_GEM_SOCKETS];
961 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments
962 {
963 GemEnchants[i] = (GemProps[i]) ? GemProps[i]->EnchantID : 0;
964 OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i));
965 }
966
967 // check unique-equipped conditions
968 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
969 {
970 if (!Gems[i])
971 continue;
972
973 // continue check for case when attempt add 2 similar unique equipped gems in one item.
974 ItemTemplate const* iGemProto = Gems[i]->GetTemplate();
975
976 // unique item (for new and already placed bit removed enchantments
977 if (iGemProto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE))
978 {
979 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
980 {
981 if (i == j) // skip self
982 continue;
983
984 if (Gems[j])
985 {
986 if (iGemProto->GetId() == Gems[j]->GetEntry())
987 {
989 return;
990 }
991 }
992 else if (OldEnchants[j])
993 {
994 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
995 {
996 if (iGemProto->GetId() == enchantEntry->SrcItemID)
997 {
999 return;
1000 }
1001 }
1002 }
1003 }
1004 }
1005
1006 // unique limit type item
1007 int32 limit_newcount = 0;
1008 if (iGemProto->GetItemLimitCategory())
1009 {
1010 if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->GetItemLimitCategory()))
1011 {
1012 // NOTE: limitEntry->Flags is not checked because if item has limit then it is applied in equip case
1013 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1014 {
1015 if (Gems[j])
1016 {
1017 // new gem
1018 if (iGemProto->GetItemLimitCategory() == Gems[j]->GetTemplate()->GetItemLimitCategory())
1019 ++limit_newcount;
1020 }
1021 else if (OldEnchants[j])
1022 {
1023 // existing gem
1024 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1025 if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(enchantEntry->SrcItemID))
1026 if (iGemProto->GetItemLimitCategory() == jProto->GetItemLimitCategory())
1027 ++limit_newcount;
1028 }
1029 }
1030
1031 if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->Quantity)
1032 {
1034 return;
1035 }
1036 }
1037 }
1038
1039 // for equipped item check all equipment for duplicate equipped gems
1040 if (itemTarget->IsEquipped())
1041 {
1042 if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot, std::max(limit_newcount, 0)))
1043 {
1044 _player->SendEquipError(res, itemTarget, nullptr);
1045 return;
1046 }
1047 }
1048 }
1049
1050 bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
1051 _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
1052
1053 //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met
1054
1055 //remove ALL enchants
1056 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1057 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);
1058
1059 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1060 {
1061 if (GemEnchants[i])
1062 {
1063 uint32 gemCount = 1;
1064 itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0, _player->GetGUID());
1065 if (Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
1066 _player->DestroyItemCount(guidItem, gemCount, true);
1067 }
1068 }
1069
1070 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
1071 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);
1072
1073 bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
1074 if (SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
1075 {
1076 _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
1077 itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->GetSocketBonus() : 0), 0, 0, _player->GetGUID());
1079 //it is not displayed, client has an inbuilt system to determine if the bonus is activated
1080 }
1081
1082 _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item)
1083
1084 _player->RemoveTradeableItem(itemTarget);
1085 itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag
1086
1087 itemTarget->SendUpdateSockets();
1088}
1089
1091{
1092 TC_LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
1093
1094 uint32 slot;
1095
1096 recvData >> slot;
1097
1098 // apply only to equipped item
1100 return;
1101
1103
1104 if (!item)
1105 return;
1106
1108 return;
1109
1112}
1113
1115{
1116 Item* item = _player->GetItemByGuid(packet.ItemGUID);
1117 if (!item)
1118 {
1119 TC_LOG_DEBUG("network", "HandleGetItemPurchaseData: Item {} not found!", packet.ItemGUID.ToString());
1120 return;
1121 }
1122
1123 TC_LOG_DEBUG("network", "HandleGetItemPurchaseData: Item {}", packet.ItemGUID.ToString());
1124
1125 GetPlayer()->SendRefundInfo(item);
1126}
1127
1129{
1130 TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND");
1131 ObjectGuid guid;
1132 recvData >> guid; // item guid
1133
1134 Item* item = _player->GetItemByGuid(guid);
1135 if (!item)
1136 {
1137 TC_LOG_DEBUG("network", "Item refund: item not found!");
1138 return;
1139 }
1140
1141 // Don't try to refund item currently being disenchanted
1142 if (_player->GetLootGUID() == guid)
1143 return;
1144
1145 GetPlayer()->RefundItem(item);
1146}
1147
1154{
1155 ObjectGuid itemGuid;
1156 recvData >> itemGuid;
1157
1158 TC_LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY {}", itemGuid.ToString());
1159
1160 WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10)); // guess size
1161
1162 if (Item* item = _player->GetItemByGuid(itemGuid))
1163 {
1164 data << uint8(0); // has text
1165 data << itemGuid; // item guid
1166 data << item->GetText();
1167 }
1168 else
1169 {
1170 data << uint8(1); // no text
1171 }
1172
1173 SendPacket(&data);
1174}
@ CHAR_INS_CHAR_GIFT
LocaleConstant
Definition Common.h:48
@ LOCALE_enUS
Definition Common.h:49
#define sConditionMgr
@ CREATURE_FLAG_EXTRA_NO_SELL_VENDOR
#define MAX_VENDOR_ITEMS
Definition Creature.h:55
@ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS
Definition DBCEnums.h:184
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
DBCStorage< ItemLimitCategoryEntry > sItemLimitCategoryStore(ItemLimitCategoryEntryfmt)
DBCStorage< GemPropertiesEntry > sGemPropertiesStore(GemPropertiesEntryfmt)
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
EnchantmentSlot
@ TEMP_ENCHANTMENT_SLOT
@ PRISMATIC_ENCHANTMENT_SLOT
@ SOCK_ENCHANTMENT_SLOT
@ BONUS_ENCHANTMENT_SLOT
InventoryResult
Definition ItemDefines.h:25
@ EQUIP_ERR_TOO_MUCH_GOLD
@ EQUIP_ERR_CANT_WRAP_BAGS
Definition ItemDefines.h:74
@ EQUIP_ERR_PLAYER_DEAD
Definition ItemDefines.h:64
@ EQUIP_ERR_WRONG_SLOT
Definition ItemDefines.h:29
@ EQUIP_ERR_DROP_BOUND_ITEM
Definition ItemDefines.h:50
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition ItemDefines.h:49
@ EQUIP_ERR_CANT_WRAP_BOUND
Definition ItemDefines.h:72
@ EQUIP_ERR_OK
Definition ItemDefines.h:26
@ EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED
@ EQUIP_ERR_INTERNAL_BAG_ERROR
Definition ItemDefines.h:66
@ EQUIP_ERR_CANT_WRAP_EQUIPPED
Definition ItemDefines.h:70
@ EQUIP_ERR_CANT_WRAP_STACKABLE
Definition ItemDefines.h:69
@ EQUIP_ERR_CANT_WRAP_WRAPPED
Definition ItemDefines.h:71
@ EQUIP_ERR_CANT_WRAP_UNIQUE
Definition ItemDefines.h:73
@ BUY_ERR_CANT_FIND_ITEM
@ BUY_ERR_NOT_ENOUGHT_MONEY
@ SELL_ERR_CANT_FIND_VENDOR
@ SELL_ERR_UNK
@ SELL_ERR_CANT_SELL_TO_THIS_MERCHANT
@ SELL_ERR_CANT_FIND_ITEM
@ SELL_ERR_CANT_SELL_ITEM
@ ITEM_FLAG2_FACTION_HORDE
@ ITEM_FLAG2_FACTION_ALLIANCE
@ ITEM_FIELD_FLAG_WRAPPED
@ ITEM_FLAG_IS_WRAPPER
@ ITEM_FLAG_NO_USER_DESTROY
@ ITEM_FLAG_UNIQUE_EQUIPPABLE
@ SOCKET_COLOR_META
@ BIND_WHEN_PICKED_UP
void RemoveItemFromUpdateQueueOf(Item *item, Player *player)
Definition Item.cpp:696
#define MAX_GEM_SOCKETS
Definition Item.h:40
@ ITEM_CHANGED
Definition Item.h:54
@ ITEM_NEW
Definition Item.h:55
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition Log.h:159
#define sObjectMgr
Definition ObjectMgr.h:1721
uint32 const MAX_MONEY_AMOUNT
Definition Player.cpp:125
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:632
@ INVENTORY_SLOT_BAG_END
Definition Player.h:585
@ BUYBACK_SLOT_START
Definition Player.h:609
#define INVENTORY_SLOT_BAG_0
Definition Player.h:555
@ ALLIANCE
@ HORDE
@ SPELL_AURA_FEIGN_DEATH
@ UNIT_NPC_FLAG_VENDOR
@ UNIT_STATE_DIED
Definition Unit.h:234
@ NULL_BAG
Definition Unit.h:60
@ NULL_SLOT
Definition Unit.h:61
@ PLAYER_FIELD_BUYBACK_PRICE_1
@ ITEM_FIELD_FLAGS
@ ITEM_FIELD_GIFTCREATOR
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:554
void read_skip()
Definition ByteBuffer.h:334
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:302
VendorItemData const * GetVendorItems() const
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:195
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
CreatureMovementData const & GetMovementTemplate() const
Definition Item.h:62
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:644
uint8 GetSlot() const
Definition Item.h:143
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition Item.cpp:329
void ReplaceAllItemFlags(ItemFieldFlags flags)
Definition Item.h:94
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:165
Item * CloneItem(uint32 count, Player const *player=nullptr) const
Definition Item.cpp:1077
void SetCount(uint32 value)
Definition Item.cpp:1293
ItemTemplate const * GetTemplate() const
Definition Item.cpp:541
bool IsSoulBound() const
Definition Item.h:96
ItemUpdateState GetState() const
Definition Item.h:186
bool IsEquipped() const
Definition Item.cpp:722
ObjectGuid GetOwnerGUID() const
Definition Item.h:78
bool IsRefundable() const
Definition Item.h:113
uint16 GetPos() const
Definition Item.h:147
bool GemsFitSockets() const
Definition Item.cpp:940
uint32 GetSellPrice(bool forVendor=false) const
Definition Item.cpp:1148
bool IsBag() const
Definition Item.h:117
void ClearEnchantment(EnchantmentSlot slot)
Definition Item.cpp:930
void SendUpdateSockets()
Definition Item.cpp:1025
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1268
bool IsNotEmptyBag() const
Definition Item.cpp:304
uint32 GetCount() const
Definition Item.h:136
uint8 GetBagSlot() const
Definition Item.cpp:717
uint32 GetMaxStackCount() const
Definition Item.h:138
void SetGiftCreator(ObjectGuid guid)
Definition Item.h:85
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:889
LowType GetCounter() const
Definition ObjectGuid.h:156
static ObjectGuid const Empty
Definition ObjectGuid.h:140
bool IsEmpty() const
Definition ObjectGuid.h:172
PackedGuidWriter WriteAsPacked() const
Definition ObjectGuid.h:152
std::string ToString() const
static std::string_view GetLocaleString(std::vector< std::string > const &data, LocaleConstant locale)
Definition ObjectMgr.h:1519
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:241
bool IsInWorld() const
Definition Object.h:73
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SetEntry(uint32 entry)
Definition Object.h:82
void SendUpdateToPlayer(Player *player)
Definition Object.cpp:192
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:273
bool IsValidPos(uint16 pos, bool explicit_pos) const
Definition Player.h:1100
void SendEquipError(InventoryResult msg, Item const *item1=nullptr, Item const *item2=nullptr, uint32 itemId=0) const
Definition Player.cpp:13070
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
Definition Player.cpp:16099
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1095
uint32 GetTeam() const
Definition Player.h:1818
InventoryResult CanUnequipItem(uint16 src, bool swap) const
Definition Player.cpp:11137
void ToggleMetaGemsActive(uint8 exceptslot, bool apply)
Definition Player.cpp:21865
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition Player.cpp:10980
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.cpp:11976
void SplitItem(uint16 src, uint16 dst, uint32 count)
Definition Player.cpp:12512
InventoryResult CanEquipUniqueItem(Item *pItem, uint8 except_slot=NULL_SLOT, uint32 limit_count=1) const
Definition Player.cpp:24762
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.cpp:9992
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, WorldObject *ref=nullptr)
Definition Player.cpp:24914
bool ModifyMoney(int32 amount, bool sendError=true)
Definition Player.cpp:22336
void RemoveItemFromBuyBackSlot(uint32 slot, bool del)
Definition Player.cpp:13037
float GetReputationPriceDiscount(Creature const *creature) const
Definition Player.cpp:23150
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition Player.cpp:13432
void AddItemToBuyBackSlot(Item *pItem)
Definition Player.cpp:12975
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition Player.cpp:9436
void SwapItem(uint16 src, uint16 dst)
Definition Player.cpp:12628
void ApplyItemDependentAuras(Item *item, bool apply)
Definition Player.cpp:7535
void RemoveAmmo()
Definition Player.cpp:11608
void SendSellError(SellResult msg, Creature *creature, ObjectGuid guid, uint32 param) const
Definition Player.cpp:13130
void RemoveTradeableItem(Item *item)
Definition Player.cpp:13270
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition Player.cpp:11659
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9550
ObjectGuid GetLootGUID() const
Definition Player.h:1700
void SetAmmo(uint32 item)
Definition Player.cpp:11586
bool HasEnoughMoney(uint32 amount) const
Definition Player.h:1394
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:12111
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1093
uint32 DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition Player.cpp:12207
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, NPCFlags npcFlags) const
Definition Player.cpp:2126
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param) const
Definition Player.cpp:13119
void SendRefundInfo(Item *item)
Definition Player.cpp:25875
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:23353
bool IsGameMaster() const
Definition Player.h:976
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition Player.cpp:11802
uint32 GetMoney() const
Definition Player.h:1392
static bool IsBagPos(uint16 pos)
Definition Player.cpp:9696
Item * GetItemFromBuyBackSlot(uint32 slot)
Definition Player.cpp:13028
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition Player.cpp:11181
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition Player.cpp:16062
static bool IsBankPos(uint16 pos)
Definition Player.h:1098
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:11981
void RefundItem(Item *item)
Definition Player.cpp:25966
void SendMessageToSet(WorldPacket const *data, bool self) const override
Definition Player.h:1733
Item * GetItemByGuid(ObjectGuid guid) const
Definition Player.cpp:9516
bool BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uint32 item, uint32 count, uint8 bag, uint8 slot)
Definition Player.cpp:21402
InventoryResult CanUseItem(Item *pItem, bool not_loading=true) const
Definition Player.cpp:11368
void setUInt32(uint8 index, uint32 value)
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3788
uint32 GetClassMask() const
Definition Unit.h:911
void PauseMovement(uint32 timer=0, uint8 slot=0, bool forced=true)
Definition Unit.cpp:10304
bool IsAlive() const
Definition Unit.h:1247
void Initialize(uint16 opcode, size_t newres=200)
Definition WorldPacket.h:51
WorldPacket const * Write() override
std::vector< VendorItem > Items
Definition NPCPackets.h:104
void HandleAutoEquipItemOpcode(WorldPackets::Item::AutoEquipItem &autoEquipItem)
void HandleSplitItemOpcode(WorldPackets::Item::SplitItem &splitItem)
void HandleBuybackItem(WorldPackets::Item::BuyBackItem &packet)
void HandleSocketOpcode(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
void HandleGetItemPurchaseData(WorldPackets::Item::GetItemPurchaseData &packet)
void HandleItemNameQueryOpcode(WorldPacket &recvPacket)
void HandleItemQuerySingleOpcode(WorldPackets::Query::QueryItemSingle &query)
LocaleConstant GetSessionDbLocaleIndex() const
void HandleWrapItemOpcode(WorldPacket &recvPacket)
void HandleItemRefund(WorldPacket &recvData)
void HandleAutoStoreBagItemOpcode(WorldPackets::Item::AutoStoreBagItem &packet)
Player * GetPlayer() const
void HandleAutoEquipItemSlotOpcode(WorldPacket &recvPacket)
ObjectGuid m_currentBankerGUID
void SendItemEnchantTimeUpdate(ObjectGuid Playerguid, ObjectGuid Itemguid, uint32 slot, uint32 Duration)
void HandleSetAmmoOpcode(WorldPacket &recvPacket)
void HandleReadItem(WorldPacket &recvPacket)
void HandleSwapInvItemOpcode(WorldPackets::Item::SwapInvItem &swapInvItem)
void HandleBuyItemOpcode(WorldPacket &recvPacket)
void HandleDestroyItemOpcode(WorldPackets::Item::DestroyItem &destroyItem)
void SendEnchantmentLog(ObjectGuid target, ObjectGuid caster, uint32 itemId, uint32 enchantId)
Player * _player
void HandleSellItemOpcode(WorldPackets::Item::SellItem &packet)
void SendListInventory(ObjectGuid guid)
void HandleSwapItem(WorldPackets::Item::SwapItem &swapItem)
bool CanUseBank(ObjectGuid bankerGUID=ObjectGuid::Empty) const
void HandleBuyItemInSlotOpcode(WorldPacket &recvPacket)
void HandleCancelTempEnchantmentOpcode(WorldPacket &recvData)
void HandleItemTextQuery(WorldPacket &recvData)
void HandleListInventoryOpcode(WorldPackets::NPC::Hello &packet)
@ SMSG_ITEM_NAME_QUERY_RESPONSE
Definition Opcodes.h:738
@ SMSG_READ_ITEM_FAILED
Definition Opcodes.h:204
@ SMSG_ITEM_TEXT_QUERY_RESPONSE
Definition Opcodes.h:609
@ SMSG_ENCHANTMENTLOG
Definition Opcodes.h:500
@ SMSG_ITEM_ENCHANT_TIME_UPDATE
Definition Opcodes.h:520
@ SMSG_READ_ITEM_OK
Definition Opcodes.h:203
#define sWorld
Definition World.h:901
@ CONFIG_CACHE_DATA_QUERIES
Definition World.h:176
uint32 GetInteractionPauseTimer() const
std::string name
uint32 GetBuyCount() const
int32 GetAllowableClass() const
uint32 GetPageText() const
uint32 GetId() const
SocketColor GetSocketColor(uint32 index) const
int32 GetMaxCount() const
uint32 GetBuyPrice() const
ItemBondingType GetBonding() const
uint32 GetDisplayId() const
uint32 GetItemLimitCategory() const
bool HasFlag(ItemFlags flag) const
uint32 MaxDurability
uint32 GetSocketBonus() const
void GetPosition(float &x, float &y) const
Definition Position.h:84
uint32 GetItemCount() const
VendorItem const * GetItem(uint32 slot) const
uint32 ExtendedCost
bool IsGoldRequired(ItemTemplate const *pProto) const
Definition Creature.cpp:85
uint32 maxcount