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 "DatabaseEnv.h"
22#include "DBCStores.h"
23#include "Opcodes.h"
24#include "Item.h"
25#include "Log.h"
26#include "ObjectMgr.h"
27#include "Player.h"
28#include "SpellInfo.h"
29#include "QueryPackets.h"
30#include "World.h"
31#include "WorldPacket.h"
32
34{
35 //TC_LOG_DEBUG("network", "WORLD: CMSG_SPLIT_ITEM");
36 uint8 srcbag, srcslot, dstbag, dstslot;
37 uint32 count;
38
39 recvData >> srcbag >> srcslot >> dstbag >> dstslot >> count;
40 //TC_LOG_DEBUG("STORAGE: receive srcbag = {}, srcslot = {}, dstbag = {}, dstslot = {}, count = {}", srcbag, srcslot, dstbag, dstslot, count);
41
42 uint16 src = ((srcbag << 8) | srcslot);
43 uint16 dst = ((dstbag << 8) | dstslot);
44
45 if (src == dst)
46 return;
47
48 if (count == 0)
49 return; //check count - if zero it's fake packet
50
51 if (!_player->IsValidPos(srcbag, srcslot, true))
52 {
54 return;
55 }
56
57 if (!_player->IsValidPos(dstbag, dstslot, false)) // can be autostore pos
58 {
60 return;
61 }
62
63 _player->SplitItem(src, dst, count);
64}
65
67{
68 //TC_LOG_DEBUG("network", "WORLD: CMSG_SWAP_INV_ITEM");
69 uint8 srcslot, dstslot;
70
71 recvData >> dstslot >> srcslot;
72 //TC_LOG_DEBUG("STORAGE: receive srcslot = {}, dstslot = {}", srcslot, dstslot);
73
74 // prevent attempt swap same item to current position generated by client at special checting sequence
75 if (srcslot == dstslot)
76 return;
77
78 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, srcslot, true))
79 {
81 return;
82 }
83
84 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, dstslot, true))
85 {
87 return;
88 }
89
91 {
92 TC_LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
93 return;
94 }
95
97 {
98 TC_LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
99 return;
100 }
101
102 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
103 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
104
105 _player->SwapItem(src, dst);
106}
107
109{
110 ObjectGuid itemguid;
111 uint8 dstslot;
112 recvData >> itemguid >> dstslot;
113
114 // cheating attempt, client should never send opcode in that case
116 return;
117
118 Item* item = _player->GetItemByGuid(itemguid);
119 uint16 dstpos = dstslot | (INVENTORY_SLOT_BAG_0 << 8);
120
121 if (!item || item->GetPos() == dstpos)
122 return;
123
124 _player->SwapItem(item->GetPos(), dstpos);
125}
126
128{
129 //TC_LOG_DEBUG("network", "WORLD: CMSG_SWAP_ITEM");
130 uint8 dstbag, dstslot, srcbag, srcslot;
131
132 recvData >> dstbag >> dstslot >> srcbag >> srcslot;
133 //TC_LOG_DEBUG("STORAGE: receive srcbag = {}, srcslot = {}, dstbag = {}, dstslot = {}", srcbag, srcslot, dstbag, dstslot);
134
135 uint16 src = ((srcbag << 8) | srcslot);
136 uint16 dst = ((dstbag << 8) | dstslot);
137
138 // prevent attempt swap same item to current position generated by client at special checting sequence
139 if (src == dst)
140 return;
141
142 if (!_player->IsValidPos(srcbag, srcslot, true))
143 {
145 return;
146 }
147
148 if (!_player->IsValidPos(dstbag, dstslot, true))
149 {
150 _player->SendEquipError(EQUIP_ERR_WRONG_SLOT, nullptr, nullptr);
151 return;
152 }
153
154 if (_player->IsBankPos(srcbag, srcslot) && !CanUseBank())
155 {
156 TC_LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
157 return;
158 }
159
160 if (_player->IsBankPos(dstbag, dstslot) && !CanUseBank())
161 {
162 TC_LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
163 return;
164 }
165
166 _player->SwapItem(src, dst);
167}
168
170{
171 //TC_LOG_DEBUG("network", "WORLD: CMSG_AUTOEQUIP_ITEM");
172 uint8 srcbag, srcslot;
173
174 recvData >> srcbag >> srcslot;
175 //TC_LOG_DEBUG("STORAGE: receive srcbag = {}, srcslot = {}", srcbag, srcslot);
176
177 Item* pSrcItem = _player->GetItemByPos(srcbag, srcslot);
178 if (!pSrcItem)
179 return; // only at cheat
180
181 uint16 dest;
182 InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag());
183 if (msg != EQUIP_ERR_OK)
184 {
185 _player->SendEquipError(msg, pSrcItem, nullptr);
186 return;
187 }
188
189 uint16 src = pSrcItem->GetPos();
190 if (dest == src) // prevent equip in same slot, only at cheat
191 return;
192
193 Item* pDstItem = _player->GetItemByPos(dest);
194 if (!pDstItem) // empty slot, simple case
195 {
196 _player->RemoveItem(srcbag, srcslot, true);
197 _player->EquipItem(dest, pSrcItem, true);
199 }
200 else // have currently equipped item, not simple case
201 {
202 uint8 dstbag = pDstItem->GetBagSlot();
203 uint8 dstslot = pDstItem->GetSlot();
204
205 msg = _player->CanUnequipItem(dest, !pSrcItem->IsBag());
206 if (msg != EQUIP_ERR_OK)
207 {
208 _player->SendEquipError(msg, pDstItem, nullptr);
209 return;
210 }
211
212 // check dest->src move possibility
213 ItemPosCountVec sSrc;
214 uint16 eSrc = 0;
215 if (_player->IsInventoryPos(src))
216 {
217 msg = _player->CanStoreItem(srcbag, srcslot, sSrc, pDstItem, true);
218 if (msg != EQUIP_ERR_OK)
219 msg = _player->CanStoreItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
220 if (msg != EQUIP_ERR_OK)
221 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
222 }
223 else if (_player->IsBankPos(src))
224 {
225 msg = _player->CanBankItem(srcbag, srcslot, sSrc, pDstItem, true);
226 if (msg != EQUIP_ERR_OK)
227 msg = _player->CanBankItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
228 if (msg != EQUIP_ERR_OK)
229 msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
230 }
231 else if (_player->IsEquipmentPos(src))
232 {
233 msg = _player->CanEquipItem(srcslot, eSrc, pDstItem, true);
234 if (msg == EQUIP_ERR_OK)
235 msg = _player->CanUnequipItem(eSrc, true);
236 }
237
238 if (msg != EQUIP_ERR_OK)
239 {
240 _player->SendEquipError(msg, pDstItem, pSrcItem);
241 return;
242 }
243
244 // now do moves, remove...
245 _player->RemoveItem(dstbag, dstslot, false);
246 _player->RemoveItem(srcbag, srcslot, false);
247
248 // add to dest
249 _player->EquipItem(dest, pSrcItem, true);
250
251 // add to src
252 if (_player->IsInventoryPos(src))
253 _player->StoreItem(sSrc, pDstItem, true);
254 else if (_player->IsBankPos(src))
255 _player->BankItem(sSrc, pDstItem, true);
256 else if (_player->IsEquipmentPos(src))
257 _player->EquipItem(eSrc, pDstItem, true);
258
260
261 // 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)
262 // do this after swaps are done, we pass nullptr because both weapons could be swapped and none of them should be ignored
263 if ((srcbag == INVENTORY_SLOT_BAG_0 && srcslot < INVENTORY_SLOT_BAG_END) || (dstbag == INVENTORY_SLOT_BAG_0 && dstslot < INVENTORY_SLOT_BAG_END))
264 _player->ApplyItemDependentAuras((Item*)nullptr, false);
265 }
266}
267
269{
270 //TC_LOG_DEBUG("network", "WORLD: CMSG_DESTROYITEM");
271 uint8 bag, slot, count, data1, data2, data3;
272
273 recvData >> bag >> slot >> count >> data1 >> data2 >> data3;
274 //TC_LOG_DEBUG("STORAGE: receive bag = {}, slot = {}, count = {}", bag, slot, count);
275
276 uint16 pos = (bag << 8) | slot;
277
278 // prevent drop unequipable items (in combat, for example) and non-empty bags
279 if (_player->IsEquipmentPos(pos) || _player->IsBagPos(pos))
280 {
281 InventoryResult msg = _player->CanUnequipItem(pos, false);
282 if (msg != EQUIP_ERR_OK)
283 {
284 _player->SendEquipError(msg, _player->GetItemByPos(pos), nullptr);
285 return;
286 }
287 }
288
289 Item* pItem = _player->GetItemByPos(bag, slot);
290 if (!pItem)
291 {
293 return;
294 }
295
297 {
299 return;
300 }
301
302 if (count)
303 {
304 uint32 i_count = count;
305 _player->DestroyItemCount(pItem, i_count, true);
306 }
307 else
308 _player->DestroyItem(bag, slot, true);
309}
310
311// Only _static_ data send in this packet !!!
313{
314 TC_LOG_INFO("network", "STORAGE: Item Query = {}", query.ItemID);
315
316 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(query.ItemID))
317 {
318 if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES))
319 SendPacket(&itemTemplate->QueryData[static_cast<uint32>(GetSessionDbLocaleIndex())]);
320 else
321 {
322 WorldPacket response = itemTemplate->BuildQueryData(GetSessionDbLocaleIndex());
323 SendPacket(&response);
324 }
325 }
326 else
327 {
328 TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: {})", query.ItemID);
330 response.ItemID = query.ItemID;
331 SendPacket(response.Write());
332 }
333}
334
336{
337 uint8 bag, slot;
338 recvData >> bag >> slot;
339
340 Item* pItem = _player->GetItemByPos(bag, slot);
341
342 if (pItem && pItem->GetTemplate()->PageText)
343 {
344 WorldPacket data;
345
346 InventoryResult msg = _player->CanUseItem(pItem);
347 if (msg == EQUIP_ERR_OK)
348 {
350 TC_LOG_INFO("network", "STORAGE: Item page sent");
351 }
352 else
353 {
355 TC_LOG_INFO("network", "STORAGE: Unable to read item");
356 _player->SendEquipError(msg, pItem, nullptr);
357 }
358 data << pItem->GetGUID();
359 SendPacket(&data);
360 }
361 else
363}
364
366{
367 TC_LOG_DEBUG("network", "WORLD: Received CMSG_SELL_ITEM");
368 ObjectGuid vendorguid, itemguid;
369 uint32 count;
370
371 recvData >> vendorguid >> itemguid >> count;
372
373 if (!itemguid)
374 return;
375
377 if (!creature)
378 {
379 TC_LOG_DEBUG("network", "WORLD: HandleSellItemOpcode - {} not found or you can not interact with him.", vendorguid.ToString());
380 _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, itemguid, 0);
381 return;
382 }
383
385 {
387 return;
388 }
389
390 // remove fake death
391 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
393
394 Item* pItem = _player->GetItemByGuid(itemguid);
395 if (pItem)
396 {
397 // prevent sell not owner item
398 if (_player->GetGUID() != pItem->GetOwnerGUID())
399 {
400 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
401 return;
402 }
403
404 // prevent sell non empty bag by drag-and-drop at vendor's item list
405 if (pItem->IsNotEmptyBag())
406 {
407 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
408 return;
409 }
410
411 // prevent sell currently looted item
412 if (_player->GetLootGUID() == pItem->GetGUID())
413 {
414 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
415 return;
416 }
417
418 // prevent selling item for sellprice when the item is still refundable
419 // this probably happens when right clicking a refundable item, the client sends both
420 // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
421 if (pItem->IsRefundable())
422 return; // Therefore, no feedback to client
423
424 // special case at auto sell (sell all)
425 if (count == 0)
426 count = pItem->GetCount();
427 else
428 {
429 // prevent sell more items that exist in stack (possible only not from client)
430 if (count > pItem->GetCount())
431 {
432 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
433 return;
434 }
435 }
436
437 ItemTemplate const* pProto = pItem->GetTemplate();
438 if (pProto)
439 {
440 if (pProto->SellPrice > 0)
441 {
442 uint32 money = pProto->SellPrice * count;
443 if (_player->GetMoney() >= MAX_MONEY_AMOUNT - money) // prevent exceeding gold limit
444 {
446 _player->SendSellError(SELL_ERR_UNK, creature, itemguid, 0);
447 return;
448 }
449
450 if (count < pItem->GetCount()) // need split items
451 {
452 Item* pNewItem = pItem->CloneItem(count, _player);
453 if (!pNewItem)
454 {
455 TC_LOG_ERROR("network", "WORLD: HandleSellItemOpcode - could not create clone of item {}; count = {}", pItem->GetEntry(), count);
456 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
457 return;
458 }
459
460 pItem->SetCount(pItem->GetCount() - count);
461 _player->ItemRemovedQuestCheck(pItem->GetEntry(), count);
462 if (_player->IsInWorld())
465
466 _player->AddItemToBuyBackSlot(pNewItem);
467 if (_player->IsInWorld())
468 pNewItem->SendUpdateToPlayer(_player);
469 }
470 else
471 {
472 _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
473 _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
476 }
477
478 _player->ModifyMoney(money);
480 }
481 else
482 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
483 return;
484 }
485 }
486 _player->SendSellError(SELL_ERR_CANT_FIND_ITEM, creature, itemguid, 0);
487 return;
488}
489
491{
492 TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUYBACK_ITEM");
493 ObjectGuid vendorguid;
494 uint32 slot;
495
496 recvData >> vendorguid >> slot;
497
499 if (!creature)
500 {
501 TC_LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit ({}) not found or you can not interact with him.", vendorguid.ToString());
503 return;
504 }
505
506 // remove fake death
507 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
509
510 Item* pItem = _player->GetItemFromBuyBackSlot(slot);
511 if (pItem)
512 {
514 if (!_player->HasEnoughMoney(price))
515 {
517 return;
518 }
519
520 ItemPosCountVec dest;
521 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
522 if (msg == EQUIP_ERR_OK)
523 {
524 _player->ModifyMoney(-(int32)price);
526 _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
527 _player->StoreItem(dest, pItem, true);
528 }
529 else
530 _player->SendEquipError(msg, pItem, nullptr);
531 return;
532 }
533 else
535}
536
538{
539 TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM_IN_SLOT");
540 ObjectGuid vendorguid, bagguid;
541 uint32 item, slot, count;
542 uint8 bagslot;
543
544 recvData >> vendorguid >> item >> slot >> bagguid >> bagslot >> count;
545
546 // client expects count starting at 1, and we send vendorslot+1 to client already
547 if (slot > 0)
548 --slot;
549 else
550 return; // cheating
551
552 uint8 bag = NULL_BAG;
553 if (bagguid == GetPlayer()->GetGUID()) // The client sends the player guid when trying to store an item in the default backpack
555 else if (Item* bagItem = _player->GetItemByGuid(bagguid))
556 bag = bagItem->GetSlot();
557 else
558 return;
559
560 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot);
561}
562
564{
565 TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM");
566 ObjectGuid vendorguid;
567 uint32 item, slot, count;
568 uint8 unk1;
569
570 recvData >> vendorguid >> item >> slot >> count >> unk1;
571
572 // client expects count starting at 1, and we send vendorslot+1 to client already
573 if (slot > 0)
574 --slot;
575 else
576 return; // cheating
577
578 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, NULL_BAG, NULL_SLOT);
579}
580
582{
583 ObjectGuid guid;
584
585 recvData >> guid;
586
587 if (!GetPlayer()->IsAlive())
588 return;
589
590 TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY");
591
592 SendListInventory(guid);
593}
594
596{
598 if (!vendor)
599 {
600 TC_LOG_DEBUG("network", "WORLD: SendListInventory - {} not found or you can not interact with him.", vendorGuid.ToString());
602 return;
603 }
604
605 // remove fake death
606 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
608
609 // Stop the npc if moving
611 vendor->PauseMovement(pause);
612 vendor->SetHomePosition(vendor->GetPosition());
613
614 VendorItemData const* items = vendor->GetVendorItems();
615 if (!items)
616 {
617 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
618 data << vendorGuid;
619 data << uint8(0); // count == 0, next will be error code
620 data << uint8(0); // "Vendor has no inventory"
621 SendPacket(&data);
622 return;
623 }
624
625 uint8 itemCount = items->GetItemCount();
626 uint8 count = 0;
627
628 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
629 data << vendorGuid;
630
631 size_t countPos = data.wpos();
632 data << uint8(count);
633
634 float discountMod = _player->GetReputationPriceDiscount(vendor);
635
636 for (uint8 slot = 0; slot < itemCount; ++slot)
637 {
638 if (VendorItem const* item = items->GetItem(slot))
639 {
640 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item);
641 if (!itemTemplate)
642 continue;
643
644 uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
645 if (!_player->IsGameMaster()) // ignore conditions if GM on
646 {
647 // Respect allowed class
648 if (!(itemTemplate->AllowableClass & _player->GetClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP)
649 continue;
650
651 // Only display items in vendor lists for the team the
652 // player is on. If GM on, display all items.
653 if ((itemTemplate->HasFlag(ITEM_FLAG2_FACTION_HORDE) && _player->GetTeam() == ALLIANCE) ||
654 (itemTemplate->HasFlag(ITEM_FLAG2_FACTION_ALLIANCE) && _player->GetTeam() == HORDE))
655 continue;
656
657 // Items sold out are not displayed in list
658 if (leftInStock == 0)
659 continue;
660 }
661
662 if (!sConditionMgr->IsObjectMeetingVendorItemConditions(vendor->GetEntry(), item->item, _player, vendor))
663 {
664 TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry {} item {}", vendor->GetEntry(), item->item);
665 continue;
666 }
667
668 // reputation discount
669 int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
670
671 data << uint32(slot + 1); // client expects counting to start at 1
672 data << uint32(item->item);
673 data << uint32(itemTemplate->DisplayInfoID);
674 data << int32(leftInStock);
675 data << uint32(price);
676 data << uint32(itemTemplate->MaxDurability);
677 data << uint32(itemTemplate->BuyCount);
678 data << uint32(item->ExtendedCost);
679
680 if (++count >= MAX_VENDOR_ITEMS)
681 break;
682 }
683 }
684
685 if (count == 0)
686 {
687 data << uint8(0);
688 SendPacket(&data);
689 return;
690 }
691
692 data.put<uint8>(countPos, count);
693 SendPacket(&data);
694}
695
697{
698 //TC_LOG_DEBUG("network", "WORLD: CMSG_AUTOSTORE_BAG_ITEM");
699 uint8 srcbag, srcslot, dstbag;
700
701 recvData >> srcbag >> srcslot >> dstbag;
702 //TC_LOG_DEBUG("STORAGE: receive srcbag = {}, srcslot = {}, dstbag = {}", srcbag, srcslot, dstbag);
703
704 Item* pItem = _player->GetItemByPos(srcbag, srcslot);
705 if (!pItem)
706 return;
707
708 if (!_player->IsValidPos(dstbag, NULL_SLOT, false)) // can be autostore pos
709 {
710 _player->SendEquipError(EQUIP_ERR_WRONG_SLOT, nullptr, nullptr);
711 return;
712 }
713
714 uint16 src = pItem->GetPos();
715
716 // check unequip potability for equipped items and bank bags
717 if (_player->IsEquipmentPos (src) || _player->IsBagPos (src))
718 {
720 if (msg != EQUIP_ERR_OK)
721 {
722 _player->SendEquipError(msg, pItem, nullptr);
723 return;
724 }
725 }
726
727 ItemPosCountVec dest;
728 InventoryResult msg = _player->CanStoreItem(dstbag, NULL_SLOT, dest, pItem, false);
729 if (msg != EQUIP_ERR_OK)
730 {
731 _player->SendEquipError(msg, pItem, nullptr);
732 return;
733 }
734
735 // no-op: placed in same slot
736 if (dest.size() == 1 && dest[0].pos == src)
737 {
738 // just remove grey item state
740 return;
741 }
742
743 _player->RemoveItem(srcbag, srcslot, true);
744 _player->StoreItem(dest, pItem, true);
745}
746
748{
749 if (!_player->IsAlive())
750 {
751 _player->SendEquipError(EQUIP_ERR_PLAYER_DEAD, nullptr, nullptr);
752 return;
753 }
754
755 TC_LOG_DEBUG("network", "WORLD: CMSG_SET_AMMO");
756 uint32 item;
757
758 recvData >> item;
759
760 if (item)
761 {
762 if (!_player->GetItemCount(item))
763 {
765 return;
766 }
767
768 _player->SetAmmo(item);
769 }
770 else
772}
773
775{
776 WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4)); // last check 2.0.10
777 data << target.WriteAsPacked();
778 data << caster.WriteAsPacked();
779 data << uint32(itemId);
780 data << uint32(enchantId);
781 GetPlayer()->SendMessageToSet(&data, true);
782}
783
785{
786 // last check 2.0.10
788 data << Itemguid;
789 data << uint32(slot);
790 data << uint32(Duration);
791 data << Playerguid;
792 SendPacket(&data);
793}
794
796{
797 uint32 itemid;
798 recvData >> itemid;
799 recvData.read_skip<uint64>(); // guid
800
801 TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_NAME_QUERY {}", itemid);
802 ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid);
803 if (pName)
804 {
805 std::string Name = pName->name;
806 LocaleConstant localeConstant = GetSessionDbLocaleIndex();
807 if (localeConstant != LOCALE_enUS)
808 if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid))
809 ObjectMgr::GetLocaleString(isnl->Name, localeConstant, Name);
810
811 WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+Name.size()+1+4));
812 data << uint32(itemid);
813 data << Name;
814 data << uint32(pName->InventoryType);
815 SendPacket(&data);
816 }
817}
818
820{
821 TC_LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM");
822
823 uint8 gift_bag, gift_slot, item_bag, item_slot;
824
825 recvData >> gift_bag >> gift_slot; // paper
826 recvData >> item_bag >> item_slot; // item
827
828 TC_LOG_DEBUG("network", "WRAP: receive gift_bag = {}, gift_slot = {}, item_bag = {}, item_slot = {}", gift_bag, gift_slot, item_bag, item_slot);
829
830 Item* gift = _player->GetItemByPos(gift_bag, gift_slot);
831 if (!gift)
832 {
834 return;
835 }
836
837 if (!gift->GetTemplate()->HasFlag(ITEM_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper
838 {
840 return;
841 }
842
843 Item* item = _player->GetItemByPos(item_bag, item_slot);
844
845 if (!item)
846 {
848 return;
849 }
850
851 if (item == gift) // not possable with pacjket from real client
852 {
854 return;
855 }
856
857 if (item->IsEquipped())
858 {
860 return;
861 }
862
863 if (!item->GetGuidValue(ITEM_FIELD_GIFTCREATOR).IsEmpty()) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
864 {
866 return;
867 }
868
869 if (item->IsBag())
870 {
872 return;
873 }
874
875 if (item->IsSoulBound())
876 {
878 return;
879 }
880
881 if (item->GetMaxStackCount() != 1)
882 {
884 return;
885 }
886
887 // maybe not correct check (it is better than nothing)
888 if (item->GetTemplate()->MaxCount > 0)
889 {
891 return;
892 }
893
894 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
895
897 stmt->setUInt32(0, item->GetOwnerGUID().GetCounter());
898 stmt->setUInt32(1, item->GetGUID().GetCounter());
899 stmt->setUInt32(2, item->GetEntry());
901 trans->Append(stmt);
902
903 item->SetEntry(gift->GetEntry());
904
905 switch (item->GetEntry())
906 {
907 case 5042: item->SetEntry(5043); break;
908 case 5048: item->SetEntry(5044); break;
909 case 17303: item->SetEntry(17302); break;
910 case 17304: item->SetEntry(17305); break;
911 case 17307: item->SetEntry(17308); break;
912 case 21830: item->SetEntry(21831); break;
913 }
917
918 if (item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance`
919 {
920 // after save it will be impossible to remove the item from the queue
922 item->SaveToDB(trans); // item gave inventory record unchanged and can be save standalone
923 }
924 CharacterDatabase.CommitTransaction(trans);
925
926 uint32 count = 1;
927 _player->DestroyItemCount(gift, count, true);
928}
929
931{
932 TC_LOG_DEBUG("network", "WORLD: CMSG_SOCKET_GEMS");
933
934 ObjectGuid item_guid;
935 ObjectGuid gem_guids[MAX_GEM_SOCKETS];
936
937 recvData >> item_guid;
938 if (!item_guid)
939 return;
940
941 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
942 recvData >> gem_guids[i];
943
944 //cheat -> tried to socket same gem multiple times
945 if ((!gem_guids[0].IsEmpty() && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) ||
946 (!gem_guids[1].IsEmpty() && (gem_guids[1] == gem_guids[2])))
947 return;
948
949 Item* itemTarget = _player->GetItemByGuid(item_guid);
950 if (!itemTarget) //missing item to socket
951 return;
952
953 ItemTemplate const* itemProto = itemTarget->GetTemplate();
954 if (!itemProto)
955 return;
956
957 //this slot is excepted when applying / removing meta gem bonus
958 uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);
959
960 Item* Gems[MAX_GEM_SOCKETS];
961 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
962 Gems[i] = !gem_guids[i].IsEmpty() ? _player->GetItemByGuid(gem_guids[i]) : nullptr;
963
964 GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS];
965 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage
966 GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GemProperties) : nullptr;
967
968 // Find first prismatic socket
969 int32 firstPrismatic = 0;
970 while (firstPrismatic < MAX_GEM_SOCKETS && itemProto->Socket[firstPrismatic].Color)
971 ++firstPrismatic;
972
973 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe
974 {
975 if (!GemProps[i])
976 continue;
977
978 // tried to put gem in socket where no socket exists (take care about prismatic sockets)
979 if (!itemProto->Socket[i].Color)
980 {
981 // no prismatic socket
983 return;
984
985 if (i != firstPrismatic)
986 return;
987 }
988
989 // tried to put normal gem in meta socket
990 if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->Type != SOCKET_COLOR_META)
991 return;
992
993 // tried to put meta gem in normal socket
994 if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->Type == SOCKET_COLOR_META)
995 return;
996 }
997
998 uint32 GemEnchants[MAX_GEM_SOCKETS];
999 uint32 OldEnchants[MAX_GEM_SOCKETS];
1000 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments
1001 {
1002 GemEnchants[i] = (GemProps[i]) ? GemProps[i]->EnchantID : 0;
1003 OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i));
1004 }
1005
1006 // check unique-equipped conditions
1007 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1008 {
1009 if (!Gems[i])
1010 continue;
1011
1012 // continue check for case when attempt add 2 similar unique equipped gems in one item.
1013 ItemTemplate const* iGemProto = Gems[i]->GetTemplate();
1014
1015 // unique item (for new and already placed bit removed enchantments
1016 if (iGemProto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE))
1017 {
1018 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1019 {
1020 if (i == j) // skip self
1021 continue;
1022
1023 if (Gems[j])
1024 {
1025 if (iGemProto->ItemId == Gems[j]->GetEntry())
1026 {
1028 return;
1029 }
1030 }
1031 else if (OldEnchants[j])
1032 {
1033 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1034 {
1035 if (iGemProto->ItemId == enchantEntry->SrcItemID)
1036 {
1038 return;
1039 }
1040 }
1041 }
1042 }
1043 }
1044
1045 // unique limit type item
1046 int32 limit_newcount = 0;
1047 if (iGemProto->ItemLimitCategory)
1048 {
1049 if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->ItemLimitCategory))
1050 {
1051 // NOTE: limitEntry->Flags is not checked because if item has limit then it is applied in equip case
1052 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1053 {
1054 if (Gems[j])
1055 {
1056 // new gem
1057 if (iGemProto->ItemLimitCategory == Gems[j]->GetTemplate()->ItemLimitCategory)
1058 ++limit_newcount;
1059 }
1060 else if (OldEnchants[j])
1061 {
1062 // existing gem
1063 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1064 if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(enchantEntry->SrcItemID))
1065 if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
1066 ++limit_newcount;
1067 }
1068 }
1069
1070 if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->Quantity)
1071 {
1073 return;
1074 }
1075 }
1076 }
1077
1078 // for equipped item check all equipment for duplicate equipped gems
1079 if (itemTarget->IsEquipped())
1080 {
1081 if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot, std::max(limit_newcount, 0)))
1082 {
1083 _player->SendEquipError(res, itemTarget, nullptr);
1084 return;
1085 }
1086 }
1087 }
1088
1089 bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
1090 _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
1091
1092 //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
1093
1094 //remove ALL enchants
1095 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1096 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);
1097
1098 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1099 {
1100 if (GemEnchants[i])
1101 {
1102 uint32 gemCount = 1;
1103 itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0, _player->GetGUID());
1104 if (Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
1105 _player->DestroyItemCount(guidItem, gemCount, true);
1106 }
1107 }
1108
1109 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
1110 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);
1111
1112 bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
1113 if (SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
1114 {
1115 _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
1116 itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->socketBonus : 0), 0, 0, _player->GetGUID());
1118 //it is not displayed, client has an inbuilt system to determine if the bonus is activated
1119 }
1120
1121 _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item)
1122
1123 _player->RemoveTradeableItem(itemTarget);
1124 itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag
1125
1126 itemTarget->SendUpdateSockets();
1127}
1128
1130{
1131 TC_LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
1132
1133 uint32 slot;
1134
1135 recvData >> slot;
1136
1137 // apply only to equipped item
1139 return;
1140
1142
1143 if (!item)
1144 return;
1145
1147 return;
1148
1151}
1152
1154{
1155 TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND_INFO");
1156
1157 ObjectGuid guid;
1158 recvData >> guid; // item guid
1159
1160 Item* item = _player->GetItemByGuid(guid);
1161 if (!item)
1162 {
1163 TC_LOG_DEBUG("network", "Item refund: item not found!");
1164 return;
1165 }
1166
1167 GetPlayer()->SendRefundInfo(item);
1168}
1169
1171{
1172 TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND");
1173 ObjectGuid guid;
1174 recvData >> guid; // item guid
1175
1176 Item* item = _player->GetItemByGuid(guid);
1177 if (!item)
1178 {
1179 TC_LOG_DEBUG("network", "Item refund: item not found!");
1180 return;
1181 }
1182
1183 // Don't try to refund item currently being disenchanted
1184 if (_player->GetLootGUID() == guid)
1185 return;
1186
1187 GetPlayer()->RefundItem(item);
1188}
1189
1196{
1197 ObjectGuid itemGuid;
1198 recvData >> itemGuid;
1199
1200 TC_LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY {}", itemGuid.ToString());
1201
1202 WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10)); // guess size
1203
1204 if (Item* item = _player->GetItemByGuid(itemGuid))
1205 {
1206 data << uint8(0); // has text
1207 data << itemGuid; // item guid
1208 data << item->GetText();
1209 }
1210 else
1211 {
1212 data << uint8(1); // no text
1213 }
1214
1215 SendPacket(&data);
1216}
@ 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:690
#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:119
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:624
@ INVENTORY_SLOT_BAG_END
Definition Player.h:577
@ BUYBACK_SLOT_START
Definition Player.h:601
#define INVENTORY_SLOT_BAG_0
Definition Player.h:547
@ ALLIANCE
@ HORDE
@ SPELL_AURA_FEIGN_DEATH
@ UNIT_NPC_FLAG_VENDOR
@ UNIT_STATE_DIED
Definition Unit.h:220
@ NULL_BAG
Definition Unit.h:61
@ NULL_SLOT
Definition Unit.h:62
@ PLAYER_FIELD_BUYBACK_PRICE_1
@ ITEM_FIELD_FLAGS
@ ITEM_FIELD_GIFTCREATOR
void read_skip()
Definition ByteBuffer.h:330
size_t wpos() const
Definition ByteBuffer.h:321
void put(std::size_t pos, T value)
Definition ByteBuffer.h:137
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:293
VendorItemData const * GetVendorItems() const
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:186
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
CreatureMovementData const & GetMovementTemplate() const
Definition Item.h:62
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:638
uint8 GetSlot() const
Definition Item.h:126
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition Item.cpp:323
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:148
Item * CloneItem(uint32 count, Player const *player=nullptr) const
Definition Item.cpp:1071
void SetCount(uint32 value)
Definition Item.cpp:1250
ItemTemplate const * GetTemplate() const
Definition Item.cpp:535
bool IsSoulBound() const
Definition Item.h:81
ItemUpdateState GetState() const
Definition Item.h:168
bool IsEquipped() const
Definition Item.cpp:716
ObjectGuid GetOwnerGUID() const
Definition Item.h:76
bool IsRefundable() const
Definition Item.h:98
uint16 GetPos() const
Definition Item.h:130
bool GemsFitSockets() const
Definition Item.cpp:934
bool IsBag() const
Definition Item.h:102
void ClearEnchantment(EnchantmentSlot slot)
Definition Item.cpp:924
void SendUpdateSockets()
Definition Item.cpp:1019
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1225
bool IsNotEmptyBag() const
Definition Item.cpp:298
uint32 GetCount() const
Definition Item.h:119
uint8 GetBagSlot() const
Definition Item.cpp:711
uint32 GetMaxStackCount() const
Definition Item.h:121
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:883
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, size_t locale)
Definition ObjectMgr.h:1525
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:249
bool IsInWorld() const
Definition Object.h:73
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:699
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:200
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:585
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:281
bool IsValidPos(uint16 pos, bool explicit_pos) const
Definition Player.h:1122
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
Definition Player.cpp:16086
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1117
uint32 GetTeam() const
Definition Player.h:1832
InventoryResult CanUnequipItem(uint16 src, bool swap) const
Definition Player.cpp:11139
void ToggleMetaGemsActive(uint8 exceptslot, bool apply)
Definition Player.cpp:21868
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition Player.cpp:10982
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.cpp:11978
void SplitItem(uint16 src, uint16 dst, uint32 count)
Definition Player.cpp:12514
InventoryResult CanEquipUniqueItem(Item *pItem, uint8 except_slot=NULL_SLOT, uint32 limit_count=1) const
Definition Player.cpp:24788
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.cpp:9994
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, WorldObject *ref=nullptr)
Definition Player.cpp:24940
bool ModifyMoney(int32 amount, bool sendError=true)
Definition Player.cpp:22339
void RemoveItemFromBuyBackSlot(uint32 slot, bool del)
Definition Player.cpp:13042
float GetReputationPriceDiscount(Creature const *creature) const
Definition Player.cpp:23175
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition Player.cpp:13431
void AddItemToBuyBackSlot(Item *pItem)
Definition Player.cpp:12977
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition Player.cpp:9438
void SwapItem(uint16 src, uint16 dst)
Definition Player.cpp:12630
void ApplyItemDependentAuras(Item *item, bool apply)
Definition Player.cpp:7534
void RemoveAmmo()
Definition Player.cpp:11610
void SendSellError(SellResult msg, Creature *creature, ObjectGuid guid, uint32 param) const
Definition Player.cpp:13129
void RemoveTradeableItem(Item *item)
Definition Player.cpp:13269
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition Player.cpp:11661
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9552
ObjectGuid GetLootGUID() const
Definition Player.h:1714
void SetAmmo(uint32 item)
Definition Player.cpp:11588
bool HasEnoughMoney(uint32 amount) const
Definition Player.h:1410
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:12113
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1115
uint32 DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition Player.cpp:12209
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, NPCFlags npcFlags) const
Definition Player.cpp:2094
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param) const
Definition Player.cpp:13118
void SendRefundInfo(Item *item)
Definition Player.cpp:25920
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:23378
bool IsGameMaster() const
Definition Player.h:998
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition Player.cpp:11804
uint32 GetMoney() const
Definition Player.h:1408
static bool IsBagPos(uint16 pos)
Definition Player.cpp:9698
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0) const
Definition Player.cpp:13075
Item * GetItemFromBuyBackSlot(uint32 slot)
Definition Player.cpp:13033
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition Player.cpp:11183
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition Player.cpp:16049
static bool IsBankPos(uint16 pos)
Definition Player.h:1120
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:11983
void RefundItem(Item *item)
Definition Player.cpp:26011
void SendMessageToSet(WorldPacket const *data, bool self) const override
Definition Player.h:1747
Item * GetItemByGuid(ObjectGuid guid) const
Definition Player.cpp:9518
bool BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uint32 item, uint32 count, uint8 bag, uint8 slot)
Definition Player.cpp:21405
InventoryResult CanUseItem(Item *pItem, bool not_loading=true) const
Definition Player.cpp:11370
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:3765
uint32 GetClassMask() const
Definition Unit.h:897
void PauseMovement(uint32 timer=0, uint8 slot=0, bool forced=true)
Definition Unit.cpp:10327
bool IsAlive() const
Definition Unit.h:1234
void Initialize(uint16 opcode, size_t newres=200)
Definition WorldPacket.h:73
void HandleDestroyItemOpcode(WorldPacket &recvPacket)
void HandleSocketOpcode(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
void HandleSellItemOpcode(WorldPacket &recvPacket)
void HandleItemNameQueryOpcode(WorldPacket &recvPacket)
void HandleItemQuerySingleOpcode(WorldPackets::Query::QueryItemSingle &query)
LocaleConstant GetSessionDbLocaleIndex() const
void HandleSwapItem(WorldPacket &recvPacket)
void HandleAutoStoreBagItemOpcode(WorldPacket &recvPacket)
void HandleWrapItemOpcode(WorldPacket &recvPacket)
void HandleItemRefund(WorldPacket &recvData)
Player * GetPlayer() const
void HandleAutoEquipItemSlotOpcode(WorldPacket &recvPacket)
void HandleItemRefundInfoRequest(WorldPacket &recvData)
void HandleSwapInvItemOpcode(WorldPacket &recvPacket)
ObjectGuid m_currentBankerGUID
void HandleAutoEquipItemOpcode(WorldPacket &recvPacket)
void SendItemEnchantTimeUpdate(ObjectGuid Playerguid, ObjectGuid Itemguid, uint32 slot, uint32 Duration)
void HandleSetAmmoOpcode(WorldPacket &recvPacket)
void HandleReadItem(WorldPacket &recvPacket)
void HandleBuyItemOpcode(WorldPacket &recvPacket)
void SendEnchantmentLog(ObjectGuid target, ObjectGuid caster, uint32 itemId, uint32 enchantId)
void HandleSplitItemOpcode(WorldPacket &recvPacket)
Player * _player
void SendListInventory(ObjectGuid guid)
bool CanUseBank(ObjectGuid bankerGUID=ObjectGuid::Empty) const
void HandleBuyItemInSlotOpcode(WorldPacket &recvPacket)
void HandleCancelTempEnchantmentOpcode(WorldPacket &recvData)
void HandleItemTextQuery(WorldPacket &recvData)
void HandleBuybackItem(WorldPacket &recvPacket)
void HandleListInventoryOpcode(WorldPacket &recvPacket)
@ SMSG_ITEM_NAME_QUERY_RESPONSE
Definition Opcodes.h:738
@ SMSG_READ_ITEM_FAILED
Definition Opcodes.h:204
@ SMSG_LIST_INVENTORY
Definition Opcodes.h:444
@ 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:900
@ CONFIG_CACHE_DATA_QUERIES
Definition World.h:176
uint32 GetInteractionPauseTimer() const
std::string name
uint32 AllowableClass
std::array< _Socket, MAX_ITEM_PROTO_SOCKETS > Socket
uint32 socketBonus
uint32 DisplayInfoID
bool HasFlag(ItemFlags flag) const
uint32 ItemLimitCategory
uint32 MaxDurability
void GetPosition(float &x, float &y) const
Definition Position.h:84
uint32 GetItemCount() const
VendorItem const * GetItem(uint32 slot) const