OregonCore  revision 3611e8a-git
Your Favourite TBC server
ItemHandler.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore 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 "Common.h"
19 #include "WorldPacket.h"
20 #include "WorldSession.h"
21 #include "Opcodes.h"
22 #include "Log.h"
23 #include "ObjectMgr.h"
24 #include "Player.h"
25 #include "Item.h"
26 
28 {
29  //sLog.outDebug("WORLD: CMSG_SPLIT_ITEM");
30  uint8 srcbag, srcslot, dstbag, dstslot, count;
31 
32  recv_data >> srcbag >> srcslot >> dstbag >> dstslot >> count;
33  //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u, count = %u", srcbag, srcslot, dstbag, dstslot, count);
34 
35  uint16 src = ((srcbag << 8) | srcslot);
36  uint16 dst = ((dstbag << 8) | dstslot);
37 
38  if (src == dst)
39  return;
40 
41  if (count == 0)
42  return; //check count - if zero it's fake packet
43 
44  if (!_player->IsValidPos(srcbag, srcslot))
45  {
47  return;
48  }
49 
50  if (!_player->IsValidPos(dstbag, dstslot))
51  {
53  return;
54  }
55 
56  _player->SplitItem(src, dst, count);
57 }
58 
60 {
61  //sLog.outDebug("WORLD: CMSG_SWAP_INV_ITEM");
62  uint8 srcslot, dstslot;
63 
64  recv_data >> srcslot >> dstslot;
65  //sLog.outDebug("STORAGE: receive srcslot = %u, dstslot = %u", srcslot, dstslot);
66 
67  // prevent attempt swap same item to current position generated by client at special checting sequence
68  if (srcslot == dstslot)
69  return;
70 
71  if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, srcslot))
72  {
74  return;
75  }
76 
77  if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, dstslot))
78  {
80  return;
81  }
82 
83  uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
84  uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
85 
86  _player->SwapItem(src, dst);
87 }
88 
90 {
91  uint64 itemguid;
92  uint8 dstslot;
93  recv_data >> itemguid >> dstslot;
94 
95  // cheating attempt, client should never send opcode in that case
97  return;
98 
99  Item* item = _player->GetItemByGuid(itemguid);
100  uint16 dstpos = dstslot | (INVENTORY_SLOT_BAG_0 << 8);
101 
102  if (!item || item->GetPos() == dstpos)
103  return;
104 
105  _player->SwapItem(item->GetPos(), dstpos);
106 }
107 
109 {
110  //sLog.outDebug("WORLD: CMSG_SWAP_ITEM");
111  uint8 dstbag, dstslot, srcbag, srcslot;
112 
113  recv_data >> dstbag >> dstslot >> srcbag >> srcslot ;
114  //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u", srcbag, srcslot, dstbag, dstslot);
115 
116  uint16 src = ((srcbag << 8) | srcslot);
117  uint16 dst = ((dstbag << 8) | dstslot);
118 
119  // prevent attempt swap same item to current position generated by client at special checting sequence
120  if (src == dst)
121  return;
122 
123  if (!_player->IsValidPos(srcbag, srcslot))
124  {
126  return;
127  }
128 
129  if (!_player->IsValidPos(dstbag, dstslot))
130  {
132  return;
133  }
134 
135  _player->SwapItem(src, dst);
136 }
137 
139 {
140  //sLog.outDebug("WORLD: CMSG_AUTOEQUIP_ITEM");
141  uint8 srcbag, srcslot;
142 
143  recv_data >> srcbag >> srcslot;
144  //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot);
145 
146  Item* pSrcItem = _player->GetItemByPos(srcbag, srcslot);
147  if (!pSrcItem)
148  return; // only at cheat
149 
150  uint16 dest;
151  uint8 msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag());
152  if (msg != EQUIP_ERR_OK)
153  {
154  _player->SendEquipError(msg, pSrcItem, NULL);
155  return;
156  }
157 
158  uint16 src = pSrcItem->GetPos();
159  if (dest == src) // prevent equip in same slot, only at cheat
160  return;
161 
162  Item* pDstItem = _player->GetItemByPos(dest);
163  if (!pDstItem) // empty slot, simple case
164  {
165  _player->RemoveItem(srcbag, srcslot, true);
166  _player->EquipItem(dest, pSrcItem, true);
168  }
169  else // have currently equipped item, not simple case
170  {
171  uint8 dstbag = pDstItem->GetBagSlot();
172  uint8 dstslot = pDstItem->GetSlot();
173 
174  msg = _player->CanUnequipItem(dest, !pSrcItem->IsBag());
175  if (msg != EQUIP_ERR_OK)
176  {
177  _player->SendEquipError(msg, pDstItem, NULL);
178  return;
179  }
180 
181  // check dest->src move possibility
182  ItemPosCountVec sSrc;
183  uint16 eSrc = 0;
184  if (_player->IsInventoryPos(src))
185  {
186  msg = _player->CanStoreItem(srcbag, srcslot, sSrc, pDstItem, true);
187  if (msg != EQUIP_ERR_OK)
188  msg = _player->CanStoreItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
189  if (msg != EQUIP_ERR_OK)
190  msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
191  }
192  else if (_player->IsBankPos(src))
193  {
194  msg = _player->CanBankItem(srcbag, srcslot, sSrc, pDstItem, true);
195  if (msg != EQUIP_ERR_OK)
196  msg = _player->CanBankItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
197  if (msg != EQUIP_ERR_OK)
198  msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
199  }
200  else if (_player->IsEquipmentPos(src))
201  {
202  msg = _player->CanEquipItem(srcslot, eSrc, pDstItem, true);
203  if (msg == EQUIP_ERR_OK)
204  msg = _player->CanUnequipItem(eSrc, true);
205  }
206 
207  if (msg != EQUIP_ERR_OK)
208  {
209  _player->SendEquipError(msg, pDstItem, pSrcItem);
210  return;
211  }
212 
213  // now do moves, remove...
214  _player->RemoveItem(dstbag, dstslot, false);
215  _player->RemoveItem(srcbag, srcslot, false);
216 
217  // add to dest
218  _player->EquipItem(dest, pSrcItem, true);
219 
220  // add to src
221  if (_player->IsInventoryPos(src))
222  _player->StoreItem(sSrc, pDstItem, true);
223  else if (_player->IsBankPos(src))
224  _player->BankItem(sSrc, pDstItem, true);
225  else if (_player->IsEquipmentPos(src))
226  _player->EquipItem(eSrc, pDstItem, true);
227 
229  }
230 }
231 
233 {
234  //sLog.outDebug("WORLD: CMSG_DESTROYITEM");
235  uint8 bag, slot, count, data1, data2, data3;
236 
237  recv_data >> bag >> slot >> count >> data1 >> data2 >> data3;
238  //sLog.outDebug("STORAGE: receive bag = %u, slot = %u, count = %u", bag, slot, count);
239 
240  uint16 pos = (bag << 8) | slot;
241 
242  // prevent drop unequipable items (in combat, for example) and non-empty bags
243  if (_player->IsEquipmentPos(pos) || _player->IsBagPos(pos))
244  {
245  uint8 msg = _player->CanUnequipItem(pos, false);
246  if (msg != EQUIP_ERR_OK)
247  {
248  _player->SendEquipError(msg, _player->GetItemByPos(pos), NULL);
249  return;
250  }
251  }
252 
253  Item* pItem = _player->GetItemByPos(bag, slot);
254  if (!pItem)
255  {
257  return;
258  }
259 
260  if (count)
261  {
262  uint32 i_count = count;
263  _player->DestroyItemCount(pItem, i_count, true);
264  }
265  else
266  _player->DestroyItem(bag, slot, true);
267 }
268 
269 // Only _static_ data send in this packet !!!
271 {
272  //sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE");
273  uint32 item;
274  recv_data >> item;
275 
276  sLog.outDetail("STORAGE: Item Query = %u", item);
277 
278  ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(item);
279  if (pProto)
280  {
281  std::string Name = pProto->Name1;
282  std::string Description = pProto->Description;
283 
284  int loc_idx = GetSessionDbLocaleIndex();
285  if (loc_idx >= 0)
286  {
287  ItemLocale const* il = sObjectMgr.GetItemLocale(pProto->ItemId);
288  if (il)
289  {
290  if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
291  Name = il->Name[loc_idx];
292  if (il->Description.size() > size_t(loc_idx) && !il->Description[loc_idx].empty())
293  Description = il->Description[loc_idx];
294  }
295  }
296  // guess size
298  data << pProto->ItemId;
299  data << pProto->Class;
300  data << pProto->SubClass;
301  data << pProto->SoundOverrideSubclass;
302  data << Name;
303  data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
304  data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
305  data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
306  data << pProto->DisplayInfoID;
307  data << pProto->Quality;
308  data << pProto->Flags;
309  data << pProto->BuyPrice;
310  data << pProto->SellPrice;
311  data << pProto->InventoryType;
312  data << pProto->AllowableClass;
313  data << pProto->AllowableRace;
314  data << pProto->ItemLevel;
315  data << pProto->RequiredLevel;
316  data << pProto->RequiredSkill;
317  data << pProto->RequiredSkillRank;
318  data << pProto->RequiredSpell;
319  data << pProto->RequiredHonorRank;
320  data << pProto->RequiredCityRank;
321  data << pProto->RequiredReputationFaction;
322  data << pProto->RequiredReputationRank;
323  data << pProto->MaxCount;
324  data << pProto->Stackable;
325  data << pProto->ContainerSlots;
326  for (int i = 0; i < 10; i++)
327  {
328  data << pProto->ItemStat[i].ItemStatType;
329  data << pProto->ItemStat[i].ItemStatValue;
330  }
331  for (int i = 0; i < 5; i++)
332  {
333  data << pProto->Damage[i].DamageMin;
334  data << pProto->Damage[i].DamageMax;
335  data << pProto->Damage[i].DamageType;
336  }
337 
338  // resistances (7)
339  data << pProto->Armor;
340  data << pProto->HolyRes;
341  data << pProto->FireRes;
342  data << pProto->NatureRes;
343  data << pProto->FrostRes;
344  data << pProto->ShadowRes;
345  data << pProto->ArcaneRes;
346 
347  data << pProto->Delay;
348  data << pProto->AmmoType;
349  data << pProto->RangedModRange;
350 
351  for (int s = 0; s < 5; ++s)
352  {
353  // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
354  // use `item_template` or if not set then only use spell cooldowns
355  SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId);
356  if (spell)
357  {
358  bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0;
359 
360  data << pProto->Spells[s].SpellId;
361  data << pProto->Spells[s].SpellTrigger;
362  data << uint32(-abs(pProto->Spells[s].SpellCharges));
363 
364  if (db_data)
365  {
366  data << uint32(pProto->Spells[s].SpellCooldown);
367  data << uint32(pProto->Spells[s].SpellCategory);
368  data << uint32(pProto->Spells[s].SpellCategoryCooldown);
369  }
370  else
371  {
372  data << uint32(spell->RecoveryTime);
373  data << uint32(spell->Category);
374  data << uint32(spell->CategoryRecoveryTime);
375  }
376  }
377  else
378  {
379  data << uint32(0);
380  data << uint32(0);
381  data << uint32(0);
382  data << uint32(-1);
383  data << uint32(0);
384  data << uint32(-1);
385  }
386  }
387  data << pProto->Bonding;
388  data << Description;
389  data << pProto->PageText;
390  data << pProto->LanguageID;
391  data << pProto->PageMaterial;
392  data << pProto->StartQuest;
393  data << pProto->LockID;
394  data << pProto->Material;
395  data << pProto->Sheath;
396  data << pProto->RandomProperty;
397  data << pProto->RandomSuffix;
398  data << pProto->Block;
399  data << pProto->ItemSet;
400  data << pProto->MaxDurability;
401  data << pProto->Area;
402  data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
403  data << pProto->BagFamily;
404  data << pProto->TotemCategory;
405  for (int s = 0; s < 3; ++s)
406  {
407  data << pProto->Socket[s].Color;
408  data << pProto->Socket[s].Content;
409  }
410  data << pProto->socketBonus;
411  data << pProto->GemProperties;
412  data << pProto->RequiredDisenchantSkill;
413  data << pProto->ArmorDamageModifier;
414  data << uint32(0); // added in 2.4.2.8209, duration (seconds)
415  SendPacket(&data);
416  }
417  else
418  {
419  sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item);
421  data << uint32(item | 0x80000000);
422  SendPacket(&data);
423  }
424 }
425 
427 {
428  //sLog.outDebug("WORLD: CMSG_READ_ITEM");
429 
430  uint8 bag, slot;
431  recv_data >> bag >> slot;
432 
433  //sLog.outDetail("STORAGE: Read bag = %u, slot = %u", bag, slot);
434  Item* pItem = _player->GetItemByPos(bag, slot);
435 
436  if (pItem && pItem->GetProto()->PageText)
437  {
438  WorldPacket data;
439 
440  uint8 msg = _player->CanUseItem(pItem);
441  if (msg == EQUIP_ERR_OK)
442  {
443  data.Initialize (SMSG_READ_ITEM_OK, 8);
444  sLog.outDetail("STORAGE: Item page sent");
445  }
446  else
447  {
449  sLog.outDetail("STORAGE: Unable to read item");
450  _player->SendEquipError(msg, pItem, NULL);
451  }
452  data << pItem->GetGUID();
453  SendPacket(&data);
454  }
455  else
457 }
458 
460 {
461  sLog.outDebug("WORLD: Received CMSG_PAGE_TEXT_QUERY");
462 
463  uint32 itemid;
464  uint64 guid;
465 
466  recv_data >> itemid >> guid;
467 
468  sLog.outDetail("Packet Info: itemid: %u guidlow: %u guidentry: %u guidhigh: %u",
469  itemid, GUID_LOPART(guid), GUID_ENPART(guid), GUID_HIPART(guid));
470 }
471 
473 {
474  sLog.outDebug("WORLD: Received CMSG_SELL_ITEM");
475  uint64 vendorguid, itemguid;
476  uint8 _count;
477 
478  recv_data >> vendorguid >> itemguid >> _count;
479 
480  // prevent possible overflow, as Oregon uses uint32 for item count
481  uint32 count = _count;
482 
483  if (!itemguid)
484  return;
485 
486  Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);
487  if (!pCreature)
488  {
489  sLog.outDebug("WORLD: HandleSellItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)));
490  _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, itemguid, 0);
491  return;
492  }
493 
494  // remove fake death
495  if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
497 
498  Item* pItem = _player->GetItemByGuid(itemguid);
499  if (pItem)
500  {
501  // prevent sell not owner item
502  if (_player->GetGUID() != pItem->GetOwnerGUID())
503  {
504  _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0);
505  return;
506  }
507 
508  // prevent sell non empty bag by drag-and-drop at vendor's item list
509  if (pItem->IsBag() && !((Bag*)pItem)->IsEmpty())
510  {
511  _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0);
512  return;
513  }
514 
515  // prevent sell currently looted item
516  if (_player->GetLootGUID() == pItem->GetGUID())
517  {
518  _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0);
519  return;
520  }
521 
522  // special case at auto sell (sell all)
523  if (count == 0)
524  count = pItem->GetCount();
525  else
526  {
527  // prevent sell more items that exist in stack (possible only not from client)
528  if (count > pItem->GetCount())
529  {
530  _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0);
531  return;
532  }
533  }
534 
535  ItemTemplate const* pProto = pItem->GetProto();
536  if (pProto)
537  {
538  if (pProto->SellPrice > 0)
539  {
540  if (count < pItem->GetCount()) // need split items
541  {
542  Item* pNewItem = pItem->CloneItem(count, _player);
543  if (!pNewItem)
544  {
545  sLog.outError("WORLD: HandleSellItemOpcode - could not create clone of item %u; count = %u", pItem->GetEntry(), count);
546  _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0);
547  return;
548  }
549 
550  pItem->SetCount(pItem->GetCount() - count);
551  _player->ItemRemovedQuestCheck(pItem->GetEntry(), count);
552  if (_player->IsInWorld())
553  pItem->SendUpdateToPlayer(_player);
554  pItem->SetState(ITEM_CHANGED, _player);
555 
556  _player->AddItemToBuyBackSlot(pNewItem);
557  if (_player->IsInWorld())
558  pNewItem->SendUpdateToPlayer(_player);
559  }
560  else
561  {
562  _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
563  _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
566  }
567 
568  _player->ModifyMoney(pProto->SellPrice * count);
569  }
570  else
571  _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0);
572  return;
573  }
574  }
575  _player->SendSellError(SELL_ERR_CANT_FIND_ITEM, pCreature, itemguid, 0);
576  return;
577 }
578 
580 {
581  sLog.outDebug("WORLD: Received CMSG_BUYBACK_ITEM");
582  uint64 vendorguid;
583  uint32 slot;
584 
585  recv_data >> vendorguid >> slot;
586 
587  Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);
588  if (!pCreature)
589  {
590  sLog.outDebug("WORLD: HandleBuybackItem - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorguid)));
592  return;
593  }
594 
595  // remove fake death
596  if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
598 
599  Item* pItem = _player->GetItemFromBuyBackSlot(slot);
600  if (pItem)
601  {
603  if (_player->GetMoney() < price)
604  {
605  _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, pItem->GetEntry(), 0);
606  return;
607  }
608 
609  ItemPosCountVec dest;
610  uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
611  if (msg == EQUIP_ERR_OK)
612  {
613  _player->ModifyMoney(-(int32)price);
614  _player->RemoveItemFromBuyBackSlot(slot, false);
615  _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
616  _player->StoreItem(dest, pItem, true);
617  }
618  else
619  _player->SendEquipError(msg, pItem, NULL);
620  return;
621  }
622  else
623  _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, 0, 0);
624 }
625 
627 {
628  sLog.outDebug("WORLD: Received CMSG_BUY_ITEM_IN_SLOT");
629  uint64 vendorguid, bagguid;
630  uint32 item;
631  uint8 slot, count;
632 
633  recv_data >> vendorguid >> item >> bagguid >> slot >> count;
634 
635  // client expects count starting at 1, and we send vendorslot+1 to client already
636  if (slot > 0)
637  --slot;
638  else
639  return; // cheating
640 
641  uint8 bag = NULL_BAG; // init for case invalid bagGUID
642 
643  // find bag slot by bag guid
644  if (bagguid == _player->GetGUID())
645  bag = INVENTORY_SLOT_BAG_0;
646  else
647  {
648  for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
649  {
650  if (Bag* pBag = (Bag*)_player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
651  {
652  if (bagguid == pBag->GetGUID())
653  {
654  bag = i;
655  break;
656  }
657  }
658  }
659  }
660 
661  // bag not found, cheating?
662  if (bag == NULL_BAG)
663  return;
664 
665  GetPlayer()->BuyItemFromVendor(vendorguid, item, count, bag, slot);
666 }
667 
669 {
670  sLog.outDebug("WORLD: Received CMSG_BUY_ITEM");
671  uint64 vendorguid;
672  uint32 item;
673  uint8 count, unk1;
674 
675  recv_data >> vendorguid >> item >> count >> unk1;
676 
677  GetPlayer()->BuyItemFromVendor(vendorguid, item, count, NULL_BAG, NULL_SLOT);
678 }
679 
681 {
682  uint64 guid;
683 
684  recv_data >> guid;
685 
686  if (!GetPlayer()->IsAlive())
687  return;
688 
689  sLog.outDebug("WORLD: Recvd CMSG_LIST_INVENTORY");
690 
691  SendListInventory(guid);
692 }
693 
695 {
696  sLog.outDebug("WORLD: Sent SMSG_LIST_INVENTORY");
697 
698  Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);
699  if (!pCreature)
700  {
701  sLog.outDebug("WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorguid)));
703  return;
704  }
705 
706  // remove fake death
707  if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
709 
710  // Stop the npc if moving
711  if (!pCreature->IsStopped())
712  pCreature->StopMoving();
713 
714  VendorItemData const* vItems = pCreature->GetVendorItems();
715  if (!vItems)
716  {
717  WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + 1));
718  data << uint64(vendorguid);
719  data << uint8(0); // count==0, next will be error code
720  data << uint8(0); // "Vendor has no inventory"
721  SendPacket(&data);
722  return;
723  }
724 
725  uint8 numitems = vItems->GetItemCount();
726  uint8 count = 0;
727 
728  WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + numitems * 8 * 4));
729  data << uint64(vendorguid);
730 
731  size_t count_pos = data.wpos();
732  data << uint8(count);
733 
734  float discountMod = _player->GetReputationPriceDiscount(pCreature);
735 
736  for (uint8 i = 0; i < numitems; ++i)
737  {
738  if (VendorItem const* crItem = vItems->GetItem(i))
739  {
740  if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(crItem->item))
741  {
742  if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP && !_player->IsGameMaster())
743  continue;
744 
745  ++count;
746 
747  // reputation discount
748  uint32 price = uint32(floor(pProto->BuyPrice * discountMod));
749 
750  data << uint32(count);
751  data << uint32(crItem->item);
752  data << uint32(pProto->DisplayInfoID);
753  data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem));
754  data << uint32(price);
755  data << uint32(pProto->MaxDurability);
756  data << uint32(pProto->BuyCount);
757  data << uint32(crItem->ExtendedCost);
758  }
759  }
760  }
761 
762  if (count == 0)
763  {
764  data << uint8(0); // "Vendor has no inventory"
765  SendPacket(&data);
766  return;
767  }
768 
769  data.put<uint8>(count_pos, count);
770  SendPacket(&data);
771 }
772 
774 {
775  //sLog.outDebug("WORLD: CMSG_AUTOSTORE_BAG_ITEM");
776  uint8 srcbag, srcslot, dstbag;
777 
778  recv_data >> srcbag >> srcslot >> dstbag;
779  //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u", srcbag, srcslot, dstbag);
780 
781  Item* pItem = _player->GetItemByPos(srcbag, srcslot);
782  if (!pItem)
783  return;
784 
785  if (!_player->IsValidPos(dstbag, NULL_SLOT))
786  {
788  return;
789  }
790 
791  uint16 src = pItem->GetPos();
792 
793  // check unequip potability for equipped items and bank bags
794  if (_player->IsEquipmentPos (src) || _player->IsBagPos (src))
795  {
796  uint8 msg = _player->CanUnequipItem(src, !_player->IsBagPos (src));
797  if (msg != EQUIP_ERR_OK)
798  {
799  _player->SendEquipError(msg, pItem, NULL);
800  return;
801  }
802  }
803 
804  ItemPosCountVec dest;
805  uint8 msg = _player->CanStoreItem(dstbag, NULL_SLOT, dest, pItem, false);
806  if (msg != EQUIP_ERR_OK)
807  {
808  _player->SendEquipError(msg, pItem, NULL);
809  return;
810  }
811 
812  // no-op: placed in same slot
813  if (dest.size() == 1 && dest[0].pos == src)
814  {
815  // just remove grey item state
816  _player->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
817  return;
818  }
819 
820  _player->RemoveItem(srcbag, srcslot, true);
821  _player->StoreItem(dest, pItem, true);
822 }
823 
825 {
826  sLog.outDebug("WORLD: CMSG_BUY_BANK_SLOT");
827 
828  uint64 guid;
829  recvPacket >> guid;
830 
831  // cheating protection
832  /* not critical if "cheated", and check skip allow by slots in bank windows open by .bank command.
833  Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER);
834  if (!pCreature)
835  {
836  sLog.outDebug("WORLD: HandleBuyBankSlotOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
837  return;
838  }
839  */
840 
842  // next slot
843  ++slot;
844 
845  sLog.outDetail("PLAYER: Buy bank bag slot, slot number = %u", slot);
846 
847  BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot);
848 
850 
851  if (!slotEntry)
852  {
854  SendPacket(&data);
855  return;
856  }
857 
858  uint32 price = slotEntry->price;
859 
860  if (_player->GetMoney() < price)
861  {
863  SendPacket(&data);
864  return;
865  }
866 
868  _player->ModifyMoney(-int32(price));
869 
870  data << uint32(ERR_BANKSLOT_OK);
871  SendPacket(&data);
872 }
873 
875 {
876  sLog.outDebug("WORLD: CMSG_AUTOBANK_ITEM");
877  uint8 srcbag, srcslot;
878 
879  recvPacket >> srcbag >> srcslot;
880  sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot);
881 
882  Item* pItem = _player->GetItemByPos(srcbag, srcslot);
883  if (!pItem)
884  return;
885 
886  ItemPosCountVec dest;
887  uint8 msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
888  if (msg != EQUIP_ERR_OK)
889  {
890  _player->SendEquipError(msg, pItem, NULL);
891  return;
892  }
893 
894  _player->RemoveItem(srcbag, srcslot, true);
895  _player->BankItem(dest, pItem, true);
896 }
897 
899 {
900  sLog.outDebug("WORLD: CMSG_AUTOSTORE_BANK_ITEM");
901  uint8 srcbag, srcslot;
902 
903  recvPacket >> srcbag >> srcslot;
904  sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot);
905 
906  Item* pItem = _player->GetItemByPos(srcbag, srcslot);
907  if (!pItem)
908  return;
909 
910  if (_player->IsBankPos(srcbag, srcslot)) // moving from bank to inventory
911  {
912  ItemPosCountVec dest;
913  uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
914  if (msg != EQUIP_ERR_OK)
915  {
916  _player->SendEquipError(msg, pItem, NULL);
917  return;
918  }
919 
920  _player->RemoveItem(srcbag, srcslot, true);
921  _player->StoreItem(dest, pItem, true);
922  }
923  else // moving from inventory to bank
924  {
925  ItemPosCountVec dest;
926  uint8 msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
927  if (msg != EQUIP_ERR_OK)
928  {
929  _player->SendEquipError(msg, pItem, NULL);
930  return;
931  }
932 
933  _player->RemoveItem(srcbag, srcslot, true);
934  _player->BankItem(dest, pItem, true);
935  }
936 }
937 
939 {
940  if (!GetPlayer()->IsAlive())
941  {
943  return;
944  }
945 
946  sLog.outDebug("WORLD: CMSG_SET_AMMO");
947  uint32 item;
948 
949  recv_data >> item;
950 
951  if (!item)
952  GetPlayer()->RemoveAmmo();
953  else
954  GetPlayer()->SetAmmo(item);
955 }
956 
958 {
959  WorldPacket data(SMSG_ENCHANTMENTLOG, (8 + 8 + 4 + 4 + 1)); // last check 2.0.10
960  data << uint64(Target);
961  data << uint64(Caster);
962  data << uint32(ItemID);
963  data << uint32(SpellID);
964  data << uint8(0);
965  SendPacket(&data);
966 }
967 
968 void WorldSession::SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid, uint32 slot, uint32 Duration)
969 {
970  // last check 2.0.10
971  WorldPacket data(SMSG_ITEM_ENCHANT_TIME_UPDATE, (8 + 4 + 4 + 8));
972  data << uint64(Itemguid);
973  data << uint32(slot);
974  data << uint32(Duration);
975  data << uint64(Playerguid);
976  SendPacket(&data);
977 }
978 
980 {
981  uint32 itemid;
982  recv_data >> itemid;
983  recv_data.read_skip<uint64>(); // guid
984 
985  sLog.outDebug("WORLD: CMSG_ITEM_NAME_QUERY %u", itemid);
986  ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(itemid);
987  if (pProto)
988  {
989  std::string Name;
990  Name = pProto->Name1;
991 
992  int loc_idx = GetSessionDbLocaleIndex();
993  if (loc_idx >= 0)
994  {
995  ItemLocale const* il = sObjectMgr.GetItemLocale(pProto->ItemId);
996  if (il)
997  {
998  if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
999  Name = il->Name[loc_idx];
1000  }
1001  }
1002  // guess size
1004  data << uint32(pProto->ItemId);
1005  data << Name;
1006  data << uint32(pProto->InventoryType);
1007  SendPacket(&data);
1008  return;
1009  }
1010  // This is a BS check, there are lots of items listed in Item.dbc that do not even exist on official -- so we can NEVER get the data for them.
1011  // If you *really* want to spam your error log -- uncomment this.
1012  /* else
1013  {
1014  // listed in dbc or not expected to exist unknown item
1015  if (sItemStore.LookupEntry(itemid))
1016  sLog.outErrorDb("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (item listed in Item.dbc but not exist in DB)", itemid);
1017  else
1018  sLog.outError("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (unknown item, not listed in Item.dbc)", itemid);
1019  } */
1020 }
1021 
1023 {
1024  sLog.outDebug("Received opcode CMSG_WRAP_ITEM");
1025 
1026  uint8 gift_bag, gift_slot, item_bag, item_slot;
1027  //recv_data.hexlike();
1028 
1029  recv_data >> gift_bag >> gift_slot; // paper
1030  recv_data >> item_bag >> item_slot; // item
1031 
1032  sLog.outDebug("WRAP: receive gift_bag = %u, gift_slot = %u, item_bag = %u, item_slot = %u", gift_bag, gift_slot, item_bag, item_slot);
1033 
1034  Item* gift = _player->GetItemByPos(gift_bag, gift_slot);
1035  if (!gift)
1036  {
1038  return;
1039  }
1040 
1041  if (!(gift->GetProto()->Flags & ITEM_PROTO_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper
1042  {
1044  return;
1045  }
1046 
1047  Item* item = _player->GetItemByPos(item_bag, item_slot);
1048 
1049  if (!item)
1050  {
1052  return;
1053  }
1054 
1055  if (item == gift) // not possable with pacjket from real client
1056  {
1058  return;
1059  }
1060 
1061  if (item->IsEquipped())
1062  {
1064  return;
1065  }
1066 
1067  if (item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR)) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
1068  {
1070  return;
1071  }
1072 
1073  if (item->IsBag())
1074  {
1076  return;
1077  }
1078 
1079  if (item->IsSoulBound())
1080  {
1082  return;
1083  }
1084 
1085  if (item->GetMaxStackCount() != 1)
1086  {
1088  return;
1089  }
1090 
1091  // maybe not correct check (it is better than nothing)
1092  if (item->GetProto()->MaxCount > 0)
1093  {
1095  return;
1096  }
1097 
1099  CharacterDatabase.PExecute("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS));
1100  item->SetEntry(gift->GetEntry());
1101 
1102  switch (item->GetEntry())
1103  {
1104  case 5042:
1105  item->SetEntry(5043);
1106  break;
1107  case 5048:
1108  item->SetEntry(5044);
1109  break;
1110  case 17303:
1111  item->SetEntry(17302);
1112  break;
1113  case 17304:
1114  item->SetEntry(17305);
1115  break;
1116  case 17307:
1117  item->SetEntry(17308);
1118  break;
1119  case 21830:
1120  item->SetEntry(21831);
1121  break;
1122  }
1125  item->SetState(ITEM_CHANGED, _player);
1126 
1127  if (item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance`
1128  {
1129  // after save it will be impossible to remove the item from the queue
1131  item->SaveToDB(); // item gave inventory record unchanged and can be save standalone
1132  }
1134 
1135  uint32 count = 1;
1136  _player->DestroyItemCount(gift, count, true);
1137 }
1138 
1140 {
1141  sLog.outDebug("WORLD: CMSG_SOCKET_GEMS");
1142 
1143  uint64 guids[4];
1144  uint32 GemEnchants[3], OldEnchants[3];
1145  Item* Gems[3];
1146 
1147  for (int i = 0; i < 4; i++)
1148  recv_data >> guids[i];
1149 
1150  if (!guids[0])
1151  return;
1152 
1153  //cheat -> tried to socket same gem multiple times
1154  if ((guids[1] && (guids[1] == guids[2] || guids[1] == guids[3])) || (guids[2] && (guids[2] == guids[3])))
1155  return;
1156 
1157  Item* itemTarget = _player->GetItemByGuid(guids[0]);
1158  if (!itemTarget) //missing item to socket
1159  return;
1160 
1161  //this slot is excepted when applying / removing meta gem bonus
1162  uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);
1163 
1164  for (int i = 0; i < 3; i++)
1165  Gems[i] = guids[i + 1] ? _player->GetItemByGuid(guids[i + 1]) : NULL;
1166 
1167  GemPropertiesEntry const* GemProps[3];
1168  for (int i = 0; i < 3; ++i) //get geminfo from dbc storage
1169  GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetProto()->GemProperties) : NULL;
1170 
1171  for (int i = 0; i < 3; ++i) //check for hack maybe
1172  {
1173  // tried to put gem in socket where no socket exists / tried to put normal gem in meta socket
1174  // tried to put meta gem in normal socket
1175  if (GemProps[i] && ((!itemTarget->GetProto()->Socket[i].Color) ||
1176  (itemTarget->GetProto()->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META) ||
1177  (itemTarget->GetProto()->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)))
1178  return;
1179  }
1180 
1181  for (int i = 0; i < 3; ++i) //get new and old enchantments
1182  {
1183  GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
1184  OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i));
1185  }
1186 
1187  // check unique-equipped conditions
1188  for (int i = 0; i < 3; ++i)
1189  {
1190  if (Gems[i] && (Gems[i]->GetProto()->Flags & ITEM_PROTO_FLAG_UNIQUE_EQUIPPED))
1191  {
1192  // for equipped item check all equipment for duplicate equipped gems
1193  if (itemTarget->IsEquipped())
1194  {
1195  if (GetPlayer()->GetItemOrItemWithGemEquipped(Gems[i]->GetEntry()))
1196  {
1198  return;
1199  }
1200  }
1201 
1202  // continue check for case when attempt add 2 similar unique equipped gems in one item.
1203  for (int j = 0; j < 3; ++j)
1204  {
1205  if ((i != j) && (Gems[j]) && (Gems[i]->GetProto()->ItemId == Gems[j]->GetProto()->ItemId))
1206  {
1208  return;
1209  }
1210  }
1211  for (int j = 0; j < 3; ++j)
1212  {
1213  if (OldEnchants[j])
1214  {
1215  SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]);
1216  if (!enchantEntry)
1217  continue;
1218 
1219  if ((enchantEntry->GemID == Gems[i]->GetProto()->ItemId) && (i != j))
1220  {
1222  return;
1223  }
1224  }
1225  }
1226  }
1227  }
1228 
1229  bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
1230  _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
1231 
1232  //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
1233 
1234  //remove ALL enchants
1235  for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + 3; ++enchant_slot)
1236  _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);
1237 
1238  for (int i = 0; i < 3; ++i)
1239  {
1240  if (GemEnchants[i])
1241  {
1242  itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), GemEnchants[i], 0, 0);
1243  if (Item* guidItem = _player->GetItemByGuid(guids[i + 1]))
1244  _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true);
1245  }
1246  }
1247 
1248  for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + 3; ++enchant_slot)
1249  _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);
1250 
1251  bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
1252  if (SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
1253  {
1254  _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
1255  itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetProto()->socketBonus : 0), 0, 0);
1256  _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, true);
1257  //it is not displayed, client has an inbuilt system to determine if the bonus is activated
1258  }
1259 
1260  _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item)
1261 }
1262 
1264 {
1265  sLog.outDebug("WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
1266 
1267  uint32 eslot;
1268 
1269  recv_data >> eslot;
1270 
1271  // apply only to equipped item
1273  return;
1274 
1275  Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, eslot);
1276 
1277  if (!item)
1278  return;
1279 
1281  return;
1282 
1285 }
1286 
void HandleSocketOpcode(WorldPacket &recv_data)
uint32 ItemLevel
uint32 Category
Definition: DBCStructure.h:675
uint32 GetCount() const
Definition: Item.h:251
uint32 RequiredSkillRank
ItemTemplate const * GetProto() const
Definition: Item.cpp:460
VendorItem * GetItem(uint32 slot) const
Definition: Creature.h:362
void SetState(ItemUpdateState state, Player *forplayer=NULL)
Definition: Item.cpp:661
uint32 InventoryType
const uint32 & GetUInt32Value(uint16 index) const
Definition: Object.h:228
void read_skip()
Definition: ByteBuffer.h:276
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
std::vector< std::string > Description
void HandleListInventoryOpcode(WorldPacket &recvPacket)
float GetReputationPriceDiscount(Creature const *pCreature) const
Definition: Player.cpp:19452
void HandleAutoEquipItemSlotOpcode(WorldPacket &recvPacket)
Definition: ItemHandler.cpp:89
uint32 RequiredSkill
Item * GetItemFromBuyBackSlot(uint32 slot)
Definition: Player.cpp:11538
int32 SpellCategoryCooldown
_Socket Socket[3]
const uint64 & GetLootGUID() const
Definition: Player.h:1948
void HandleItemQuerySingleOpcode(WorldPacket &recvPacket)
bool BeginTransaction()
Definition: Database.cpp:533
void ToggleMetaGemsActive(uint8 exceptslot, bool apply)
Definition: Player.cpp:18524
uint32 SellPrice
bool IsSoulBound() const
Definition: Item.h:219
std::vector< std::string > Name
_Spell Spells[5]
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: Player.cpp:10789
Item * GetItemOrItemWithGemEquipped(uint32 item) const
Definition: Player.cpp:8878
uint32 GetMaxStackCount() const
Definition: Item.h:259
Item * CloneItem(uint32 count, Player const *player=NULL) const
Definition: Item.cpp:963
void HandleReadItem(WorldPacket &recvPacket)
bool IsValidPos(uint16 pos)
Definition: Player.h:1125
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1190
virtual void SaveToDB()
Definition: Item.cpp:286
float RangedModRange
uint32 socketBonus
void AddItemToBuyBackSlot(Item *pItem)
Definition: Player.cpp:11483
void RemoveSpellsCausingAura(AuraType auraType)
Definition: Unit.cpp:648
uint32 RequiredCityRank
bool IsEquipped() const
Definition: Item.cpp:733
bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint8 bag, uint8 slot)
Definition: Player.cpp:18035
const uint64 & GetUInt64Value(uint16 index) const
Definition: Object.h:234
ItemUpdateState GetState() const
Definition: Item.h:343
uint32 ShadowRes
#define sLog
Log class singleton.
Definition: Log.h:187
uint16 GetPos() const
Definition: Item.h:279
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition: Player.cpp:10615
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:779
ACE_INT32 int32
Definition: Define.h:67
uint32 RequiredReputationFaction
uint32 ArcaneRes
uint32 SpellId
bool GemsFitSockets() const
Definition: Item.cpp:857
void Initialize(uint16 opcode, size_t newres=200)
Definition: WorldPacket.h:37
uint32 NatureRes
bool IsGameMaster() const
Definition: Player.h:1009
uint32 TotemCategory
#define GUID_HIPART(x)
Definition: ObjectGuid.h:82
uint32 SpellTrigger
uint8 GetItemCount() const
Definition: Creature.h:371
void SetCount(uint32 value)
Definition: Item.h:255
Player * GetPlayer() const
Definition: WorldSession.h:104
uint32 GetGUIDLow() const
Definition: Object.h:160
void SetEntry(uint32 entry)
Definition: Object.h:190
float DamageMax
bool IsBag() const
Definition: Item.h:229
uint32 RequiredReputationRank
uint32 SpellCategory
int32 SpellCharges
#define sObjectMgr
Definition: ObjectMgr.h:1285
void SendPacket(WorldPacket const *packet)
bool CommitTransaction()
Definition: Database.cpp:551
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
uint32 DamageType
uint32 Color
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges)
Definition: Item.cpp:816
uint32 RandomSuffix
_ItemStat ItemStat[10]
DBCStorage< BankBagSlotPricesEntry > sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt)
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: Player.cpp:10724
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1109
float ArmorDamageModifier
void HandleSwapInvItemOpcode(WorldPacket &recvPacket)
Definition: ItemHandler.cpp:59
uint8 CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: Player.cpp:9947
void HandleSetAmmoOpcode(WorldPacket &recvPacket)
size_t wpos() const
Definition: ByteBuffer.h:264
Definition: Bag.h:27
void HandleAutoBankItemOpcode(WorldPacket &recvPacket)
ACE_UINT8 uint8
Definition: Define.h:73
void AutoUnequipOffhandIfNeed()
Definition: Player.cpp:19590
uint32 DisplayInfoID
Definition: Unit.h:297
uint8 CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1151
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: Player.cpp:10444
const bool & IsInWorld() const
Definition: Object.h:129
uint32 AllowableClass
bool IsStopped() const
Definition: Unit.h:2006
void RemoveAmmo()
Definition: Player.cpp:10266
_Damage Damage[5]
char * Description
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
Definition: Player.cpp:13812
void HandleBuyItemInSlotOpcode(WorldPacket &recvPacket)
static bool IsBankPos(uint16 pos)
Definition: Player.h:1120
void HandleBuyBankSlotOpcode(WorldPacket &recvPacket)
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:878
void put(size_t pos, T value)
Definition: ByteBuffer.h:79
Definition: Item.h:196
void ClearEnchantment(EnchantmentSlot slot)
Definition: Item.cpp:847
VendorItemData const * GetVendorItems() const
Definition: Creature.cpp:2384
uint32 RequiredLevel
void SendEquipError(uint8 msg, Item *pItem, Item *pItem2)
Definition: Player.cpp:11571
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
void RemoveFromUpdateQueueOf(Player *player)
Definition: Item.cpp:708
uint32 RequiredDisenchantSkill
void HandleItemNameQueryOpcode(WorldPacket &recvPacket)
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: Player.cpp:11830
bool PExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:441
uint32 ItemStatType
void SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid, uint32 slot, uint32 Duration)
uint32 Content
void SetUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:798
uint8 GetSlot() const
Definition: Item.h:266
void SendBuyError(uint8 msg, Creature *pCreature, uint32 item, uint32 param)
Definition: Player.cpp:11597
uint32 MaxDurability
void SendEnchantmentLog(uint64 Target, uint64 Caster, uint32 ItemID, uint32 SpellID)
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:605
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: Player.cpp:13773
ACE_UINT64 uint64
Definition: Define.h:70
uint32 CategoryRecoveryTime
Definition: DBCStructure.h:698
uint32 getClassMask() const
Definition: Unit.h:1040
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1114
Target
void HandleAutoEquipItemOpcode(WorldPacket &recvPacket)
uint32 RecoveryTime
Definition: DBCStructure.h:697
uint32 ContainerSlots
Player * _player
Definition: WorldSession.h:729
int GetSessionDbLocaleIndex() const
Definition: WorldSession.h:237
uint32 GetMoney()
Definition: Player.h:1524
int32 SpellCooldown
void HandleBuyItemOpcode(WorldPacket &recvPacket)
uint32 AllowableRace
DBCStorage< GemPropertiesEntry > sGemPropertiesStore(GemPropertiesEntryfmt)
void HandleSellItemOpcode(WorldPacket &recvPacket)
void HandleSplitItemOpcode(WorldPacket &recvPacket)
Definition: ItemHandler.cpp:27
uint8 CanUnequipItem(uint16 src, bool swap) const
Definition: Player.cpp:9906
EnchantmentSlot
Definition: Item.h:147
void SwapItem(uint16 src, uint16 dst)
Definition: Player.cpp:11135
void SplitItem(uint16 src, uint16 dst, uint32 count)
Definition: Player.cpp:11028
uint32 Stackable
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition: Player.cpp:2191
void HandleBuybackItem(WorldPacket &recvPacket)
void HandlePageQuerySkippedOpcode(WorldPacket &recvPacket)
void HandleWrapItemOpcode(WorldPacket &recvPacket)
void HandleDestroyItemOpcode(WorldPacket &recvPacket)
void HandleSwapItem(WorldPacket &recvPacket)
uint32 GetEntry() const
Definition: Object.h:186
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition: Creature.cpp:2389
uint8 CanUseItem(Item *pItem, bool not_loading=true) const
Definition: Player.cpp:10128
Definition: Item.h:188
uint32 RequiredSpell
DatabaseType CharacterDatabase
Accessor to the character database.
Definition: Main.cpp:54
ACE_UINT16 uint16
Definition: Define.h:72
void ModifyMoney(int32 d)
Definition: Player.h:1528
ACE_UINT32 uint32
Definition: Define.h:71
uint32 RequiredHonorRank
uint32 LanguageID
static bool IsBagPos(uint16 pos)
Definition: Player.cpp:8723
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: Player.cpp:10294
Item * GetItemByPos(uint16 pos) const
Definition: Player.cpp:8612
#define GUID_ENPART(x)
Definition: ObjectGuid.h:109
uint8 GetBagSlot() const
Definition: Item.cpp:728
void StopMoving()
Definition: Unit.cpp:11838
uint32 PageMaterial
uint32 RandomProperty
void HandleAutoStoreBagItemOpcode(WorldPacket &recvPacket)
void SendSellError(uint8 msg, Creature *pCreature, uint64 guid, uint32 param)
Definition: Player.cpp:11609
uint32 SoundOverrideSubclass
void SendUpdateToPlayer(Player *player)
Definition: Object.cpp:207
float DamageMin
uint64 const & GetOwnerGUID() const
Definition: Item.h:208
uint32 BagFamily
int32 ItemStatValue
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition: Object.h:246
void SendListInventory(uint64 guid)
uint32 StartQuest
void HandleCancelTempItemEnchantmentOpcode(WorldPacket &recv_data)
Item * GetItemByGuid(uint64 guid) const
Definition: Player.cpp:8583
uint32 GemProperties
void SetAmmo(uint32 item)
Definition: Player.cpp:10241
void HandleAutoStoreBankItemOpcode(WorldPacket &recvPacket)
const uint64 & GetGUID() const
Definition: Object.h:156
void RemoveItemFromBuyBackSlot(uint32 slot, bool del)
Definition: Player.cpp:11546
uint8 CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: Player.cpp:9758
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:313