TrinityCore
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Item.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 "Item.h"
19#include "Bag.h"
20#include "Common.h"
21#include "ConditionMgr.h"
22#include "DatabaseEnv.h"
23#include "DBCStores.h"
24#include "GameTime.h"
25#include "ItemEnchantmentMgr.h"
26#include "Log.h"
27#include "LootItemStorage.h"
28#include "Map.h"
29#include "ObjectAccessor.h"
30#include "ObjectMgr.h"
31#include "ScriptMgr.h"
32#include "SpellInfo.h"
33#include "SpellMgr.h"
34#include "StringConvert.h"
35#include "Player.h"
36#include "TradeData.h"
37#include "UpdateData.h"
38#include "World.h"
39#include "WorldPacket.h"
40#include "WorldSession.h"
41
42void AddItemsSetItem(Player* player, Item* item)
43{
44 ItemTemplate const* proto = item->GetTemplate();
45 uint32 setid = proto->ItemSet;
46
47 ItemSetEntry const* set = sItemSetStore.LookupEntry(setid);
48
49 if (!set)
50 {
51 TC_LOG_ERROR("sql.sql", "Item set {} for item (id {}) not found, mods not applied.", setid, proto->ItemId);
52 return;
53 }
54
55 if (set->RequiredSkill && player->GetSkillValue(set->RequiredSkill) < set->RequiredSkillRank)
56 return;
57
58 ItemSetEffect* eff = nullptr;
59
60 for (size_t x = 0; x < player->ItemSetEff.size(); ++x)
61 {
62 if (player->ItemSetEff[x] && player->ItemSetEff[x]->setid == setid)
63 {
64 eff = player->ItemSetEff[x];
65 break;
66 }
67 }
68
69 if (!eff)
70 {
71 eff = new ItemSetEffect();
72 eff->setid = setid;
73
74 size_t x = 0;
75 for (; x < player->ItemSetEff.size(); ++x)
76 if (!player->ItemSetEff[x])
77 break;
78
79 if (x < player->ItemSetEff.size())
80 player->ItemSetEff[x]=eff;
81 else
82 player->ItemSetEff.push_back(eff);
83 }
84
85 ++eff->item_count;
86
87 for (uint32 x = 0; x < MAX_ITEM_SET_SPELLS; ++x)
88 {
89 if (!set->SetSpellID[x])
90 continue;
91 //not enough for spell
92 if (set->SetThreshold[x] > eff->item_count)
93 continue;
94
95 uint32 z = 0;
96 for (; z < MAX_ITEM_SET_SPELLS; ++z)
97 if (eff->spells[z] && eff->spells[z]->Id == set->SetSpellID[x])
98 break;
99
100 if (z < MAX_ITEM_SET_SPELLS)
101 continue;
102
103 //new spell
104 for (uint32 y = 0; y < MAX_ITEM_SET_SPELLS; ++y)
105 {
106 if (!eff->spells[y]) // free slot
107 {
108 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(set->SetSpellID[x]);
109 if (!spellInfo)
110 {
111 TC_LOG_ERROR("entities.player.items", "WORLD: unknown spell id {} in items set {} effects", set->SetSpellID[x], setid);
112 break;
113 }
114
115 // spell cast only if fit form requirement, in other case will cast at form change
116 player->ApplyEquipSpell(spellInfo, nullptr, true);
117 eff->spells[y] = spellInfo;
118 break;
119 }
120 }
121 }
122}
123
124void RemoveItemsSetItem(Player*player, ItemTemplate const* proto)
125{
126 uint32 setid = proto->ItemSet;
127
128 ItemSetEntry const* set = sItemSetStore.LookupEntry(setid);
129
130 if (!set)
131 {
132 TC_LOG_ERROR("sql.sql", "Item set #{} for item #{} not found, mods not removed.", setid, proto->ItemId);
133 return;
134 }
135
136 ItemSetEffect* eff = nullptr;
137 size_t setindex = 0;
138 for (; setindex < player->ItemSetEff.size(); setindex++)
139 {
140 if (player->ItemSetEff[setindex] && player->ItemSetEff[setindex]->setid == setid)
141 {
142 eff = player->ItemSetEff[setindex];
143 break;
144 }
145 }
146
147 // can be in case now enough skill requirement for set appling but set has been appliend when skill requirement not enough
148 if (!eff)
149 return;
150
151 --eff->item_count;
152
153 for (uint32 x = 0; x < MAX_ITEM_SET_SPELLS; x++)
154 {
155 if (!set->SetSpellID[x])
156 continue;
157
158 // enough for spell
159 if (set->SetThreshold[x] <= eff->item_count)
160 continue;
161
162 for (uint32 z = 0; z < MAX_ITEM_SET_SPELLS; z++)
163 {
164 if (eff->spells[z] && eff->spells[z]->Id == set->SetSpellID[x])
165 {
166 // spell can be not active if not fit form requirement
167 player->ApplyEquipSpell(eff->spells[z], nullptr, false);
168 eff->spells[z]=nullptr;
169 break;
170 }
171 }
172 }
173
174 if (!eff->item_count) //all items of a set were removed
175 {
176 ASSERT(eff == player->ItemSetEff[setindex]);
177 delete eff;
178 player->ItemSetEff[setindex] = nullptr;
179 }
180}
181
182bool ItemCanGoIntoBag(ItemTemplate const* pProto, ItemTemplate const* pBagProto)
183{
184 if (!pProto || !pBagProto)
185 return false;
186
187 switch (pBagProto->Class)
188 {
190 switch (pBagProto->SubClass)
191 {
193 return true;
195 if (!(pProto->BagFamily & BAG_FAMILY_MASK_SOUL_SHARDS))
196 return false;
197 return true;
199 if (!(pProto->BagFamily & BAG_FAMILY_MASK_HERBS))
200 return false;
201 return true;
204 return false;
205 return true;
207 if (!(pProto->BagFamily & BAG_FAMILY_MASK_MINING_SUPP))
208 return false;
209 return true;
212 return false;
213 return true;
215 if (!(pProto->BagFamily & BAG_FAMILY_MASK_GEMS))
216 return false;
217 return true;
220 return false;
221 return true;
224 return false;
225 return true;
226 default:
227 return false;
228 }
230 switch (pBagProto->SubClass)
231 {
233 if (!(pProto->BagFamily & BAG_FAMILY_MASK_ARROWS))
234 return false;
235 return true;
237 if (!(pProto->BagFamily & BAG_FAMILY_MASK_BULLETS))
238 return false;
239 return true;
240 default:
241 return false;
242 }
243 }
244 return false;
245}
246
248{
251
253
255 m_slot = 0;
257 uQueuePos = -1;
258 m_container = nullptr;
259 m_lootGenerated = false;
260 mb_in_trade = false;
262
264 m_paidMoney = 0;
266}
267
268bool Item::Create(ObjectGuid::LowType guidlow, uint32 itemId, Player const* owner)
269{
270 Object::_Create(guidlow, 0, HighGuid::Item);
271
272 SetEntry(itemId);
273 SetObjectScale(1.0f);
274
275 if (owner)
276 {
279 }
280
281 ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(itemId);
282 if (!itemProto)
283 return false;
284
288
289 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
290 SetSpellCharges(i, itemProto->Spells[i].SpellCharges);
291
294 return true;
295}
296
297// Returns true if Item is a bag AND it is not empty.
298// Returns false if Item is not a bag OR it is an empty bag.
300{
301 if (Bag const* bag = ToBag())
302 return !bag->IsEmpty();
303 return false;
304}
305
307{
309 return;
310
311 TC_LOG_DEBUG("entities.player.items", "Item::UpdateDuration Item (Entry: {} Duration {} Diff {})", GetEntry(), GetUInt32Value(ITEM_FIELD_DURATION), diff);
312
314 {
315 sScriptMgr->OnItemExpire(owner, GetTemplate());
316 owner->DestroyItem(GetBagSlot(), GetSlot(), true);
317 return;
318 }
319
321 SetState(ITEM_CHANGED, owner); // save new time in database
322}
323
325{
326 bool isInTransaction = bool(trans);
327 if (!isInTransaction)
328 trans = CharacterDatabase.BeginTransaction();
329
331 switch (uState)
332 {
333 case ITEM_NEW:
334 case ITEM_CHANGED:
335 {
336 uint8 index = 0;
338 stmt->setUInt32( index, GetEntry());
339 stmt->setUInt32(++index, GetOwnerGUID().GetCounter());
340 stmt->setUInt32(++index, GetGuidValue(ITEM_FIELD_CREATOR).GetCounter());
341 stmt->setUInt32(++index, GetGuidValue(ITEM_FIELD_GIFTCREATOR).GetCounter());
342 stmt->setUInt32(++index, GetCount());
344
345 std::ostringstream ssSpells;
346 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
347 ssSpells << GetSpellCharges(i) << ' ';
348 stmt->setString(++index, ssSpells.str());
349
351
352 std::ostringstream ssEnchants;
353 for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i)
354 {
355 ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << ' ';
356 ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << ' ';
357 ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << ' ';
358 }
359 stmt->setString(++index, ssEnchants.str());
360
361 stmt->setInt16 (++index, GetItemRandomPropertyId());
364 stmt->setString(++index, m_text);
365 stmt->setUInt32(++index, guid);
366
367 trans->Append(stmt);
368
369 if ((uState == ITEM_CHANGED) && IsWrapped())
370 {
371 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GIFT_OWNER);
372 stmt->setUInt32(0, GetOwnerGUID().GetCounter());
373 stmt->setUInt32(1, guid);
374 trans->Append(stmt);
375 }
376 break;
377 }
378 case ITEM_REMOVED:
379 {
381 stmt->setUInt32(0, guid);
382 trans->Append(stmt);
383
384 if (IsWrapped())
385 {
386 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
387 stmt->setUInt32(0, guid);
388 trans->Append(stmt);
389 }
390
391 if (!isInTransaction)
392 CharacterDatabase.CommitTransaction(trans);
393
394 // Delete the items if this is a container
395 if (!loot.isLooted())
396 sLootItemStorage->RemoveStoredLootForContainer(GetGUID().GetCounter());
397
398 delete this;
399 return;
400 }
401 case ITEM_UNCHANGED:
402 break;
403 }
404
406
407 if (!isInTransaction)
408 CharacterDatabase.CommitTransaction(trans);
409}
410
411bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field* fields, uint32 entry)
412{
413 // 0 1 2 3 4 5 6 7 8 9 10
414 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '{}'", guid);
415
416 // create item before any checks for store correct guid
417 // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB
419
420 // Set entry, MUST be before proto check
421 SetEntry(entry);
422 SetObjectScale(1.0f);
423
424 ItemTemplate const* proto = GetTemplate();
425 if (!proto)
426 {
427 TC_LOG_ERROR("entities.item", "Invalid entry {} for item {}. Refusing to load.", GetEntry(), GetGUID().ToString());
428 return false;
429 }
430
431 // set owner (not if item is only loaded for gbank/auction/mail
432 if (owner_guid)
433 SetOwnerGUID(owner_guid);
434
435 bool need_save = false; // need explicit save data at load fixes
438 SetCount(fields[2].GetUInt32());
439
440 uint32 duration = fields[3].GetUInt32();
442 // update duration if need, and remove if not need
443 if ((proto->Duration == 0) != (duration == 0))
444 {
446 need_save = true;
447 }
448
449 std::vector<std::string_view> tokens = Trinity::Tokenize(fields[4].GetStringView(), ' ', false);
450 if (tokens.size() == MAX_ITEM_PROTO_SPELLS)
451 {
452 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
453 {
454 if (Optional<int32> charges = Trinity::StringTo<int32>(tokens[i]))
455 SetSpellCharges(i, *charges);
456 else
457 TC_LOG_ERROR("entities.item", "Invalid charge info '{}' for item {}, charge data not loaded.", std::string(tokens[i]), GetGUID().ToString());
458 }
459 }
460
461 SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32());
462 // Remove bind flag for items vs NO_BIND set
463 if (IsSoulBound() && proto->Bonding == NO_BIND)
464 {
466 need_save = true;
467 }
468
470 TC_LOG_WARN("entities.item", "Invalid enchantment data '{}' for item {}. Forcing partial load.", fields[6].GetString(), GetGUID().ToString());
471
472 SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16());
473 // recalculate suffix factor
474 if (GetItemRandomPropertyId() < 0)
476
477 uint32 durability = fields[8].GetUInt16();
479 // update max durability (and durability) if need
481
482 // do not overwrite durability for wrapped items
483 if (durability > proto->MaxDurability && !IsWrapped())
484 {
486 need_save = true;
487 }
488
489 SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32());
490 SetText(fields[10].GetString());
491
492 if (need_save) // normal item changed state set not work at loading
493 {
498 stmt->setUInt32(3, guid);
499 CharacterDatabase.Execute(stmt);
500 }
501
502 return true;
503}
504
505/*static*/
507{
509 stmt->setUInt32(0, itemGuid);
510 trans->Append(stmt);
511}
512
514{
515 DeleteFromDB(trans, GetGUID().GetCounter());
516
517 // Delete the items if this is a container
518 if (!loot.isLooted())
519 sLootItemStorage->RemoveStoredLootForContainer(GetGUID().GetCounter());
520}
521
522/*static*/
524{
526 stmt->setUInt32(0, itemGuid);
527 trans->Append(stmt);
528}
529
531{
532 DeleteFromInventoryDB(trans, GetGUID().GetCounter());
533}
534
536{
537 return sObjectMgr->GetItemTemplate(GetEntry());
538}
539
541{
543}
544
545// Just a "legacy shortcut" for proto->GetSkill()
547{
548 ItemTemplate const* proto = GetTemplate();
549 return proto->GetSkill();
550}
551
553{
554 ItemTemplate const* proto = GetTemplate();
555
556 switch (proto->Class)
557 {
559 switch (proto->SubClass)
560 {
561 case ITEM_SUBCLASS_WEAPON_AXE: return 196;
562 case ITEM_SUBCLASS_WEAPON_AXE2: return 197;
563 case ITEM_SUBCLASS_WEAPON_BOW: return 264;
564 case ITEM_SUBCLASS_WEAPON_GUN: return 266;
565 case ITEM_SUBCLASS_WEAPON_MACE: return 198;
566 case ITEM_SUBCLASS_WEAPON_MACE2: return 199;
567 case ITEM_SUBCLASS_WEAPON_POLEARM: return 200;
568 case ITEM_SUBCLASS_WEAPON_SWORD: return 201;
569 case ITEM_SUBCLASS_WEAPON_SWORD2: return 202;
570 case ITEM_SUBCLASS_WEAPON_STAFF: return 227;
571 case ITEM_SUBCLASS_WEAPON_DAGGER: return 1180;
572 case ITEM_SUBCLASS_WEAPON_THROWN: return 2567;
573 case ITEM_SUBCLASS_WEAPON_SPEAR: return 3386;
574 case ITEM_SUBCLASS_WEAPON_CROSSBOW:return 5011;
575 case ITEM_SUBCLASS_WEAPON_WAND: return 5009;
576 default: return 0;
577 }
578 case ITEM_CLASS_ARMOR:
579 switch (proto->SubClass)
580 {
581 case ITEM_SUBCLASS_ARMOR_CLOTH: return 9078;
582 case ITEM_SUBCLASS_ARMOR_LEATHER: return 9077;
583 case ITEM_SUBCLASS_ARMOR_MAIL: return 8737;
584 case ITEM_SUBCLASS_ARMOR_PLATE: return 750;
585 case ITEM_SUBCLASS_ARMOR_SHIELD: return 9116;
586 default: return 0;
587 }
588 }
589 return 0;
590}
591
593{
594 if (!randomPropId)
595 return;
596
597 if (randomPropId > 0)
598 {
599 ItemRandomPropertiesEntry const* item_rand = sItemRandomPropertiesStore.LookupEntry(randomPropId);
600 if (item_rand)
601 {
603 {
606 }
609 }
610 }
611 else
612 {
613 ItemRandomSuffixEntry const* item_rand = sItemRandomSuffixStore.LookupEntry(-randomPropId);
614 if (item_rand)
615 {
618 {
622 }
623
626 }
627 }
628}
629
631{
632 uint32 suffixFactor = GenerateEnchSuffixFactor(GetEntry());
633 if (GetItemSuffixFactor() == suffixFactor)
634 return;
636}
637
638void Item::SetState(ItemUpdateState state, Player* forplayer)
639{
640 if (uState == ITEM_NEW && state == ITEM_REMOVED)
641 {
642 // pretend the item never existed
643 if (forplayer)
644 {
645 RemoveItemFromUpdateQueueOf(this, forplayer);
646 forplayer->DeleteRefundReference(GetGUID());
647 }
648 delete this;
649 return;
650 }
651 if (state != ITEM_UNCHANGED)
652 {
653 // new items must stay in new state until saved
654 if (uState != ITEM_NEW)
655 uState = state;
656
657 if (forplayer)
658 AddItemToUpdateQueueOf(this, forplayer);
659 }
660 else
661 {
662 // unset in queue
663 // the item must be removed from the queue manually
664 uQueuePos = -1;
666 }
667}
668
670{
671 if (item->IsInUpdateQueue())
672 return;
673
674 ASSERT(player != nullptr);
675
676 if (player->GetGUID() != item->GetOwnerGUID())
677 {
678 TC_LOG_DEBUG("entities.player.items", "AddItemToUpdateQueueOf - Owner's guid ({}) and player's guid ({}) don't match!",
679 item->GetOwnerGUID().ToString(), player->GetGUID().ToString());
680 return;
681 }
682
683 if (player->m_itemUpdateQueueBlocked)
684 return;
685
686 player->m_itemUpdateQueue.push_back(item);
687 item->uQueuePos = player->m_itemUpdateQueue.size() - 1;
688}
689
691{
692 if (!item->IsInUpdateQueue())
693 return;
694
695 ASSERT(player != nullptr);
696
697 if (player->GetGUID() != item->GetOwnerGUID())
698 {
699 TC_LOG_DEBUG("entities.player.items", "RemoveItemFromUpdateQueueOf - Owner's guid ({}) and player's guid ({}) don't match!",
700 item->GetOwnerGUID().ToString(), player->GetGUID().ToString());
701 return;
702 }
703
704 if (player->m_itemUpdateQueueBlocked)
705 return;
706
707 player->m_itemUpdateQueue[item->uQueuePos] = nullptr;
708 item->uQueuePos = -1;
709}
710
712{
714}
715
717{
718 return !IsInBag() && m_slot < EQUIPMENT_SLOT_END;
719}
720
721bool Item::CanBeTraded(bool mail, bool trade) const
722{
723 if (m_lootGenerated)
724 return false;
725
726 if ((!mail || !IsBoundAccountWide()) && (IsSoulBound() && (!IsBOPTradeable() || !trade)))
727 return false;
728
729 if (IsBag() && (Player::IsBagPos(GetPos()) || !ToBag()->IsEmpty()))
730 return false;
731
732 if (Player* owner = GetOwner())
733 {
734 if (owner->CanUnequipItem(GetPos(), false) != EQUIP_ERR_OK)
735 return false;
736 if (owner->GetLootGUID() == GetGUID())
737 return false;
738 }
739
740 if (IsBoundByEnchant())
741 return false;
742
743 return true;
744}
745
747{
749 if (!maxDurability)
750 return 0;
751
753 ASSERT(maxDurability >= curDurability);
754
755 uint32 lostDurability = maxDurability - curDurability;
756 if (!lostDurability)
757 return 0;
758
759 ItemTemplate const* itemTemplate = GetTemplate();
760
761 DurabilityCostsEntry const* durabilityCost = sDurabilityCostsStore.LookupEntry(itemTemplate->ItemLevel);
762 if (!durabilityCost)
763 return 0;
764
765 uint32 durabilityQualityEntryId = (itemTemplate->Quality + 1) * 2;
766 DurabilityQualityEntry const* durabilityQualityEntry = sDurabilityQualityStore.LookupEntry(durabilityQualityEntryId);
767 if (!durabilityQualityEntry)
768 return 0;
769
770 uint32 dmultiplier;
771 switch (itemTemplate->Class)
772 {
774 dmultiplier = durabilityCost->WeaponSubClassCost[itemTemplate->SubClass];
775 break;
776 case ITEM_CLASS_ARMOR:
777 dmultiplier = durabilityCost->ArmorSubClassCost[itemTemplate->SubClass];
778 break;
779 default:
780 dmultiplier = 0;
781 break;
782 }
783
784 uint32 cost = static_cast<uint32>(std::round(lostDurability * dmultiplier * double(durabilityQualityEntry->Data)));
785 cost = uint32(cost * discount * sWorld->getRate(RATE_REPAIRCOST));
786
787 if (cost == 0) // Fix for ITEM_QUALITY_ARTIFACT
788 cost = 1;
789
790 return cost;
791}
792
793bool Item::HasEnchantRequiredSkill(Player const* player) const
794{
795 // Check all enchants for required skill
796 for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
797 if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
798 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
799 if (enchantEntry->RequiredSkillID && player->GetSkillValue(enchantEntry->RequiredSkillID) < enchantEntry->RequiredSkillRank)
800 return false;
801
802 return true;
803}
804
806{
807 uint32 level = 0;
808
809 // Check all enchants for required level
810 for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
811 if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
812 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
813 if (enchantEntry->MinLevel > level)
814 level = enchantEntry->MinLevel;
815
816 return level;
817}
818
820{
821 // Check all enchants for soulbound
822 for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
823 if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
824 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
825 if (enchantEntry->Flags & ENCHANTMENT_CAN_SOULBOUND)
826 return true;
827 return false;
828}
829
831{
832 // not allow merge looting currently items
833 if (m_lootGenerated)
834 return EQUIP_ERR_LOOT_GONE;
835
836 // check item type
837 if (GetEntry() != proto->ItemId)
839
840 // check free space (full stacks can't be target of merge
841 if (GetCount() >= proto->GetMaxStackSize())
843
844 return EQUIP_ERR_OK;
845}
846
847bool Item::IsFitToSpellRequirements(SpellInfo const* spellInfo) const
848{
849 ItemTemplate const* proto = GetTemplate();
850
852 if (spellInfo->EquippedItemClass != -1) // -1 == any item class
853 {
854 // Special case - accept vellum for armor/weapon requirements
855 if (isEnchantSpell && ((spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && proto->IsArmorVellum())
856 || (spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && proto->IsWeaponVellum())))
857 return true;
858
859 if (spellInfo->EquippedItemClass != int32(proto->Class))
860 return false; // wrong item class
861
862 if (spellInfo->EquippedItemSubClassMask != 0) // 0 == any subclass
863 {
864 if ((spellInfo->EquippedItemSubClassMask & (1 << proto->SubClass)) == 0)
865 return false; // subclass not present in mask
866 }
867 }
868
869 if (isEnchantSpell && spellInfo->EquippedItemInventoryTypeMask != 0) // 0 == any inventory type
870 {
871 // Special case - accept weapon type for main and offhand requirements
872 if (proto->InventoryType == INVTYPE_WEAPON &&
875 return true;
876 else if ((spellInfo->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0)
877 return false; // inventory type not present in mask
878 }
879
880 return true;
881}
882
883void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster /*= ObjectGuid::Empty*/)
884{
885 // Better lost small time at check in comparison lost time at item save to DB.
886 if ((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges))
887 return;
888
889 Player* owner = GetOwner();
891 {
892 if (uint32 oldEnchant = GetEnchantmentId(slot))
894
895 if (id)
896 owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), caster, GetEntry(), id);
897 }
898
902 SetState(ITEM_CHANGED, owner);
903}
904
906{
907 if (GetEnchantmentDuration(slot) == duration)
908 return;
909
911 SetState(ITEM_CHANGED, owner);
912 // Cannot use GetOwner() here, has to be passed as an argument to avoid freeze due to hashtable locking
913}
914
916{
917 if (GetEnchantmentCharges(slot) == charges)
918 return;
919
922}
923
925{
926 if (!GetEnchantmentId(slot))
927 return;
928
929 for (uint8 x = 0; x < MAX_ITEM_ENCHANTMENT_EFFECTS; ++x)
932}
933
935{
936 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
937 {
939
940 if (!SocketColor) // no socket slot
941 continue;
942
943 uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
944 if (!enchant_id) // no gems on this socket
945 return false;
946
947 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
948 if (!enchantEntry) // invalid gem id on this socket
949 return false;
950
951 uint8 GemColor = 0;
952
953 uint32 gemid = enchantEntry->SrcItemID;
954 if (gemid)
955 {
956 ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemid);
957 if (gemProto)
958 {
959 GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GemProperties);
960 if (gemProperty)
961 GemColor = gemProperty->Type;
962 }
963 }
964
965 if (!(GemColor & SocketColor)) // bad gem color on this socket
966 return false;
967 }
968 return true;
969}
970
972{
973 uint8 count = 0;
974 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
975 {
976 uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
977 if (!enchant_id)
978 continue;
979
980 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
981 if (!enchantEntry)
982 continue;
983
984 if (GemID == enchantEntry->SrcItemID)
985 ++count;
986 }
987 return count;
988}
989
991{
992 uint8 count = 0;
993 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
994 {
995 uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
996 if (!enchant_id)
997 continue;
998
999 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
1000 if (!enchantEntry)
1001 continue;
1002
1003 ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(enchantEntry->SrcItemID);
1004 if (!gemProto)
1005 continue;
1006
1007 if (gemProto->ItemLimitCategory == limitCategory)
1008 ++count;
1009 }
1010 return count;
1011}
1012
1013bool Item::IsLimitedToAnotherMapOrZone(uint32 cur_mapId, uint32 cur_zoneId) const
1014{
1015 ItemTemplate const* proto = GetTemplate();
1016 return proto && ((proto->Map && proto->Map != cur_mapId) || (proto->Area && proto->Area != cur_zoneId));
1017}
1018
1020{
1021 WorldPacket data(SMSG_SOCKET_GEMS_RESULT, 8+4+4+4+4);
1022 data << uint64(GetGUID());
1025
1026 GetOwner()->SendDirectMessage(&data);
1027}
1028
1029// Though the client has the information in the item's data field,
1030// we have to send SMSG_ITEM_TIME_UPDATE to display the remaining
1031// time.
1033{
1035 if (!duration)
1036 return;
1037
1039 data << uint64(GetGUID());
1040 data << uint32(duration);
1041 owner->SendDirectMessage(&data);
1042}
1043
1044Item* Item::CreateItem(uint32 itemEntry, uint32 count, Player const* player /*= nullptr*/)
1045{
1046 if (count < 1)
1047 return nullptr; //don't create item at zero count
1048
1049 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemEntry);
1050 if (proto)
1051 {
1052 if (count > proto->GetMaxStackSize())
1053 count = proto->GetMaxStackSize();
1054
1055 ASSERT_NODEBUGINFO(count != 0 && "pProto->Stackable == 0 but checked at loading already");
1056
1057 Item* item = NewItemOrBag(proto);
1058 if (item->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), itemEntry, player))
1059 {
1060 item->SetCount(count);
1061 return item;
1062 }
1063 else
1064 delete item;
1065 }
1066 else
1067 ABORT();
1068 return nullptr;
1069}
1070
1071Item* Item::CloneItem(uint32 count, Player const* player /*= nullptr*/) const
1072{
1073 Item* newItem = CreateItem(GetEntry(), count, player);
1074 if (!newItem)
1075 return nullptr;
1076
1081 // player CAN be NULL in which case we must not update random properties because that accesses player's item update queue
1082 if (player)
1084 return newItem;
1085}
1086
1087bool Item::IsBindedNotWith(Player const* player) const
1088{
1089 // not binded item
1090 if (!IsSoulBound())
1091 return false;
1092
1093 // own item
1094 if (GetOwnerGUID() == player->GetGUID())
1095 return false;
1096
1097 if (IsBOPTradeable())
1098 if (allowedGUIDs.find(player->GetGUID()) != allowedGUIDs.end())
1099 return false;
1100
1101 // BOA item case
1102 if (IsBoundAccountWide())
1103 return false;
1104
1105 return true;
1106}
1107
1109{
1110 if (Player* owner = GetOwner())
1111 BuildFieldsUpdate(owner, data_map);
1112 ClearUpdateMask(false);
1113}
1114
1116{
1117 if (Player* owner = GetOwner())
1118 {
1119 owner->GetMap()->AddUpdateObject(this);
1120 return true;
1121 }
1122
1123 return false;
1124}
1125
1127{
1128 if (Player* owner = GetOwner())
1129 owner->GetMap()->RemoveUpdateObject(this);
1130}
1131
1133{
1134 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1135
1137 stmt->setUInt32(0, GetGUID().GetCounter());
1138 trans->Append(stmt);
1139
1140 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_REFUND_INSTANCE);
1141 stmt->setUInt32(0, GetGUID().GetCounter());
1142 stmt->setUInt32(1, GetRefundRecipient());
1143 stmt->setUInt32(2, GetPaidMoney());
1145 trans->Append(stmt);
1146
1147 CharacterDatabase.CommitTransaction(trans);
1148}
1149
1151{
1152 if (trans)
1153 {
1155 stmt->setUInt32(0, GetGUID().GetCounter());
1156 (*trans)->Append(stmt);
1157
1158 }
1159}
1160
1161void Item::SetNotRefundable(Player* owner, bool changestate /*=true*/, CharacterDatabaseTransaction* trans /*=nullptr*/)
1162{
1163 if (!IsRefundable())
1164 return;
1165
1167 // Following is not applicable in the trading procedure
1168 if (changestate)
1169 SetState(ITEM_CHANGED, owner);
1170
1172 SetPaidMoney(0);
1175
1177}
1178
1180{
1181 /* Here we update our played time
1182 We simply add a number to the current played time,
1183 based on the time elapsed since the last update hereof.
1184 */
1185 // Get current played time
1187 // Calculate time elapsed since last played time update
1188 time_t curtime = GameTime::GetGameTime();
1189 uint32 elapsed = uint32(curtime - m_lastPlayedTimeUpdate);
1190 uint32 new_playtime = current_playtime + elapsed;
1191 // Check if the refund timer has expired yet
1192 if (new_playtime <= 2*HOUR)
1193 {
1194 // No? Proceed.
1195 // Update the data field
1197 // Flag as changed to get saved to DB
1198 SetState(ITEM_CHANGED, owner);
1199 // Speaks for itself
1200 m_lastPlayedTimeUpdate = curtime;
1201 return;
1202 }
1203 // Yes
1204 SetNotRefundable(owner);
1205}
1206
1208{
1209 time_t curtime = GameTime::GetGameTime();
1210 uint32 elapsed = uint32(curtime - m_lastPlayedTimeUpdate);
1212}
1213
1215{
1216 return (GetPlayedTime() > 2*HOUR);
1217}
1218
1219void Item::SetSoulboundTradeable(GuidSet const& allowedLooters)
1220{
1222 allowedGUIDs = allowedLooters;
1223}
1224
1226{
1228 if (allowedGUIDs.empty())
1229 return;
1230
1231 allowedGUIDs.clear();
1232 SetState(ITEM_CHANGED, currentOwner);
1234 stmt->setUInt32(0, GetGUID().GetCounter());
1235 CharacterDatabase.Execute(stmt);
1236}
1237
1239{
1240 // called from owner's update - GetOwner() MUST be valid
1241 if (GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) + 2*HOUR < GetOwner()->GetTotalPlayedTime())
1242 {
1244 return true; // remove from tradeable list
1245 }
1246
1247 return false;
1248}
1249
1251{
1253
1254 if (Player* player = GetOwner())
1255 {
1256 if (TradeData* tradeData = player->GetTradeData())
1257 {
1258 TradeSlots slot = tradeData->GetTradeSlotForItem(GetGUID());
1259
1260 if (slot != TRADE_SLOT_INVALID)
1261 tradeData->SetItem(slot, this, true);
1262 }
1263 }
1264}
1265
1266std::string Item::GetDebugInfo() const
1267{
1268 std::stringstream sstr;
1269 sstr << Object::GetDebugInfo() << "\n"
1270 << std::boolalpha
1271 << "Owner: " << GetOwnerGUID().ToString() << " Count: " << GetCount()
1272 << " BagSlot: " << std::to_string(GetBagSlot()) << " Slot: " << std::to_string(GetSlot()) << " Equipped: " << IsEquipped();
1273 return sstr.str();
1274}
Item * NewItemOrBag(ItemTemplate const *proto)
Definition: Bag.h:67
@ CHAR_UPD_ITEM_INSTANCE
@ CHAR_UPD_ITEM_INSTANCE_ON_LOAD
@ CHAR_DEL_ITEM_INSTANCE
@ CHAR_DEL_CHAR_INVENTORY_BY_ITEM
@ CHAR_DEL_ITEM_BOP_TRADE
@ CHAR_DEL_ITEM_REFUND_INSTANCE
@ CHAR_UPD_GIFT_OWNER
@ CHAR_DEL_GIFT
@ CHAR_REP_ITEM_INSTANCE
@ CHAR_INS_ITEM_REFUND_INSTANCE
@ HOUR
Definition: Common.h:30
@ ENCHANTMENT_CAN_SOULBOUND
Definition: DBCEnums.h:394
DBCStorage< DurabilityQualityEntry > sDurabilityQualityStore(DurabilityQualityfmt)
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
DBCStorage< ItemSetEntry > sItemSetStore(ItemSetEntryfmt)
DBCStorage< ItemRandomSuffixEntry > sItemRandomSuffixStore(ItemRandomSuffixfmt)
DBCStorage< DurabilityCostsEntry > sDurabilityCostsStore(DurabilityCostsfmt)
DBCStorage< GemPropertiesEntry > sGemPropertiesStore(GemPropertiesEntryfmt)
DBCStorage< ItemRandomPropertiesEntry > sItemRandomPropertiesStore(ItemRandomPropertiesfmt)
#define MAX_ITEM_SET_SPELLS
Definition: DBCStructure.h:975
#define MAX_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:950
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
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
#define ABORT
Definition: Errors.h:74
#define ASSERT_NODEBUGINFO
Definition: Errors.h:69
#define ASSERT
Definition: Errors.h:68
EnchantmentSlot
Definition: ItemDefines.h:148
@ PERM_ENCHANTMENT_SLOT
Definition: ItemDefines.h:149
@ PROP_ENCHANTMENT_SLOT_0
Definition: ItemDefines.h:158
@ MAX_ENCHANTMENT_SLOT
Definition: ItemDefines.h:163
@ PROP_ENCHANTMENT_SLOT_2
Definition: ItemDefines.h:160
@ SOCK_ENCHANTMENT_SLOT
Definition: ItemDefines.h:151
@ BONUS_ENCHANTMENT_SLOT
Definition: ItemDefines.h:154
@ MAX_INSPECTED_ENCHANTMENT_SLOT
Definition: ItemDefines.h:156
InventoryResult
Definition: ItemDefines.h:25
@ EQUIP_ERR_OK
Definition: ItemDefines.h:26
@ EQUIP_ERR_LOOT_GONE
Definition: ItemDefines.h:75
@ EQUIP_ERR_CANT_STACK
Definition: ItemDefines.h:45
uint32 GenerateEnchSuffixFactor(uint32 item_id)
@ ITEM_CLASS_QUIVER
Definition: ItemTemplate.h:307
@ ITEM_CLASS_CONTAINER
Definition: ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:300
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:298
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:367
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:352
@ ITEM_SUBCLASS_WEAPON_AXE2
Definition: ItemTemplate.h:350
@ ITEM_SUBCLASS_WEAPON_SPEAR
Definition: ItemTemplate.h:366
@ ITEM_SUBCLASS_WEAPON_STAFF
Definition: ItemTemplate.h:359
@ ITEM_SUBCLASS_WEAPON_MACE
Definition: ItemTemplate.h:353
@ ITEM_SUBCLASS_WEAPON_MACE2
Definition: ItemTemplate.h:354
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:364
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:351
@ ITEM_SUBCLASS_WEAPON_SWORD
Definition: ItemTemplate.h:356
@ ITEM_SUBCLASS_WEAPON_AXE
Definition: ItemTemplate.h:349
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:368
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:365
@ ITEM_SUBCLASS_WEAPON_SWORD2
Definition: ItemTemplate.h:357
@ ITEM_SUBCLASS_WEAPON_POLEARM
Definition: ItemTemplate.h:355
@ ITEM_FIELD_FLAG_REFUNDABLE
Definition: ItemTemplate.h:126
@ ITEM_FIELD_FLAG_SOULBOUND
Definition: ItemTemplate.h:114
@ ITEM_FIELD_FLAG_BOP_TRADEABLE
Definition: ItemTemplate.h:122
@ BAG_FAMILY_MASK_MINING_SUPP
Definition: ItemTemplate.h:242
@ BAG_FAMILY_MASK_HERBS
Definition: ItemTemplate.h:237
@ BAG_FAMILY_MASK_ENCHANTING_SUPP
Definition: ItemTemplate.h:238
@ BAG_FAMILY_MASK_SOUL_SHARDS
Definition: ItemTemplate.h:234
@ BAG_FAMILY_MASK_INSCRIPTION_SUPP
Definition: ItemTemplate.h:236
@ BAG_FAMILY_MASK_GEMS
Definition: ItemTemplate.h:241
@ BAG_FAMILY_MASK_ARROWS
Definition: ItemTemplate.h:232
@ BAG_FAMILY_MASK_BULLETS
Definition: ItemTemplate.h:233
@ BAG_FAMILY_MASK_ENGINEERING_SUPP
Definition: ItemTemplate.h:239
@ BAG_FAMILY_MASK_LEATHERWORKING_SUPP
Definition: ItemTemplate.h:235
@ ITEM_SUBCLASS_CONTAINER
Definition: ItemTemplate.h:334
@ ITEM_SUBCLASS_INSCRIPTION_CONTAINER
Definition: ItemTemplate.h:342
@ ITEM_SUBCLASS_LEATHERWORKING_CONTAINER
Definition: ItemTemplate.h:341
@ ITEM_SUBCLASS_GEM_CONTAINER
Definition: ItemTemplate.h:339
@ ITEM_SUBCLASS_SOUL_CONTAINER
Definition: ItemTemplate.h:335
@ ITEM_SUBCLASS_ENCHANTING_CONTAINER
Definition: ItemTemplate.h:337
@ ITEM_SUBCLASS_MINING_CONTAINER
Definition: ItemTemplate.h:340
@ ITEM_SUBCLASS_HERB_CONTAINER
Definition: ItemTemplate.h:336
@ ITEM_SUBCLASS_ENGINEERING_CONTAINER
Definition: ItemTemplate.h:338
@ ITEM_SUBCLASS_QUIVER
Definition: ItemTemplate.h:486
@ ITEM_SUBCLASS_AMMO_POUCH
Definition: ItemTemplate.h:487
@ ITEM_SUBCLASS_ARMOR_MAIL
Definition: ItemTemplate.h:398
@ ITEM_SUBCLASS_ARMOR_CLOTH
Definition: ItemTemplate.h:396
@ ITEM_SUBCLASS_ARMOR_LEATHER
Definition: ItemTemplate.h:397
@ ITEM_SUBCLASS_ARMOR_SHIELD
Definition: ItemTemplate.h:401
@ ITEM_SUBCLASS_ARMOR_PLATE
Definition: ItemTemplate.h:399
SocketColor
Definition: ItemTemplate.h:250
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:598
@ NO_BIND
Definition: ItemTemplate.h:98
@ INVTYPE_WEAPON
Definition: ItemTemplate.h:274
@ INVTYPE_WEAPONMAINHAND
Definition: ItemTemplate.h:282
@ INVTYPE_WEAPONOFFHAND
Definition: ItemTemplate.h:283
void AddItemsSetItem(Player *player, Item *item)
Definition: Item.cpp:42
bool ItemCanGoIntoBag(ItemTemplate const *pProto, ItemTemplate const *pBagProto)
Definition: Item.cpp:182
void RemoveItemsSetItem(Player *player, ItemTemplate const *proto)
Definition: Item.cpp:124
void RemoveItemFromUpdateQueueOf(Item *item, Player *player)
Definition: Item.cpp:690
void AddItemToUpdateQueueOf(Item *item, Player *player)
Definition: Item.cpp:669
#define MAX_GEM_SOCKETS
Definition: Item.h:40
#define MAX_ENCHANTMENT_OFFSET
Definition: Item.h:49
ItemUpdateState
Definition: Item.h:52
@ ITEM_CHANGED
Definition: Item.h:54
@ ITEM_REMOVED
Definition: Item.h:56
@ ITEM_NEW
Definition: Item.h:55
@ ITEM_UNCHANGED
Definition: Item.h:53
@ ENCHANTMENT_ID_OFFSET
Definition: Item.h:44
@ ENCHANTMENT_CHARGES_OFFSET
Definition: Item.h:46
@ ENCHANTMENT_DURATION_OFFSET
Definition: Item.h:45
#define TC_LOG_WARN(filterType__,...)
Definition: Log.h:162
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
#define sLootItemStorage
@ TYPEID_ITEM
Definition: ObjectGuid.h:36
std::set< ObjectGuid > GuidSet
Definition: ObjectGuid.h:261
@ TYPEMASK_ITEM
Definition: ObjectGuid.h:50
#define sObjectMgr
Definition: ObjectMgr.h:1723
std::unordered_map< Player *, UpdateData > UpdateDataMapType
Definition: Object.h:63
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
@ EQUIPMENT_SLOT_END
Definition: Player.h:549
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:525
#define sScriptMgr
Definition: ScriptMgr.h:1169
@ SPELL_EFFECT_ENCHANT_ITEM
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
#define sSpellMgr
Definition: SpellMgr.h:738
TradeSlots
Definition: TradeData.h:24
@ TRADE_SLOT_INVALID
Definition: TradeData.h:28
@ UPDATEFLAG_LOWGUID
Definition: UpdateData.h:45
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_STACK_COUNT
Definition: UpdateFields.h:39
@ ITEM_FIELD_DURATION
Definition: UpdateFields.h:40
@ ITEM_END
Definition: UpdateFields.h:73
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
@ ITEM_FIELD_RANDOM_PROPERTIES_ID
Definition: UpdateFields.h:68
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ ITEM_FIELD_OWNER
Definition: UpdateFields.h:35
@ ITEM_FIELD_GIFTCREATOR
Definition: UpdateFields.h:38
@ ITEM_FIELD_PROPERTY_SEED
Definition: UpdateFields.h:67
@ ITEM_FIELD_ENCHANTMENT_1_1
Definition: UpdateFields.h:43
@ ITEM_FIELD_CREATE_PLAYED_TIME
Definition: UpdateFields.h:71
@ ITEM_FIELD_CONTAINED
Definition: UpdateFields.h:36
Definition: Bag.h:27
Class used to access individual fields of database query result.
Definition: Field.h:92
uint16 GetUInt16() const
Definition: Field.cpp:45
uint32 GetUInt32() const
Definition: Field.cpp:61
Definition: Item.h:62
std::string GetDebugInfo() const override
Definition: Item.cpp:1266
uint32 GetEnchantRequiredLevel() const
Definition: Item.cpp:805
uint32 GetPlayedTime()
Definition: Item.cpp:1207
static void DeleteFromInventoryDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition: Item.cpp:523
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:638
uint32 GetPaidExtendedCost() const
Definition: Item.h:192
uint8 GetSlot() const
Definition: Item.h:126
void UpdateItemSuffixFactor()
Definition: Item.cpp:630
bool IsWrapped() const
Definition: Item.h:100
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:162
bool AddToObjectUpdate() override
Definition: Item.cpp:1115
void SetText(std::string const &text)
Definition: Item.h:153
virtual bool LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field *fields, uint32 entry)
Definition: Item.cpp:411
void UpdateDuration(Player *owner, uint32 diff)
Definition: Item.cpp:306
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition: Item.cpp:324
void BuildUpdate(UpdateDataMapType &) override
Definition: Item.cpp:1108
bool IsLimitedToAnotherMapOrZone(uint32 cur_mapId, uint32 cur_zoneId) const
Definition: Item.cpp:1013
Item()
Definition: Item.cpp:247
void DeleteRefundDataFromDB(CharacterDatabaseTransaction *trans)
Definition: Item.cpp:1150
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:148
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:161
static Item * CreateItem(uint32 itemEntry, uint32 count, Player const *player=nullptr)
Definition: Item.cpp:1044
Item * CloneItem(uint32 count, Player const *player=nullptr) const
Definition: Item.cpp:1071
Bag * m_container
Definition: Item.h:214
void SetItemRandomProperties(int32 randomPropId)
Definition: Item.cpp:592
void SetPaidMoney(uint32 money)
Definition: Item.h:187
uint8 GetGemCountWithID(uint32 GemID) const
Definition: Item.cpp:971
bool IsBoundAccountWide() const
Definition: Item.h:82
bool mb_in_trade
Definition: Item.h:217
Bag * ToBag()
Definition: Item.h:95
std::string m_text
Definition: Item.h:212
bool CanBeTraded(bool mail=false, bool trade=false) const
Definition: Item.cpp:721
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:149
uint32 CalculateDurabilityRepairCost(float discount) const
Definition: Item.cpp:746
void SetCount(uint32 value)
Definition: Item.cpp:1250
int32 GetItemRandomPropertyId() const
Definition: Item.h:140
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:535
bool IsBOPTradeable() const
Definition: Item.h:99
bool IsInBag() const
Definition: Item.h:133
bool IsSoulBound() const
Definition: Item.h:81
void SaveRefundDataToDB()
Definition: Item.cpp:1132
void SetNotRefundable(Player *owner, bool changestate=true, CharacterDatabaseTransaction *trans=nullptr)
Definition: Item.cpp:1161
uint32 GetItemSuffixFactor() const
Definition: Item.h:141
friend void RemoveItemFromUpdateQueueOf(Item *item, Player *player)
Definition: Item.cpp:690
bool IsBindedNotWith(Player const *player) const
Definition: Item.cpp:1087
uint32 m_paidMoney
Definition: Item.h:220
bool IsEquipped() const
Definition: Item.cpp:716
void SendTimeUpdate(Player *owner)
Definition: Item.cpp:1032
void SetRefundRecipient(ObjectGuid::LowType pGuidLow)
Definition: Item.h:186
uint32 GetSpell()
Definition: Item.cpp:552
bool IsRefundExpired()
Definition: Item.cpp:1214
void UpdatePlayedTime(Player *owner)
Definition: Item.cpp:1179
Player * GetOwner() const
Definition: Item.cpp:540
ObjectGuid::LowType m_refundRecipient
Definition: Item.h:219
ObjectGuid GetOwnerGUID() const
Definition: Item.h:76
bool HasEnchantRequiredSkill(Player const *player) const
Definition: Item.cpp:793
time_t m_lastPlayedTimeUpdate
Definition: Item.h:218
uint32 GetSkill()
Definition: Item.cpp:546
bool IsRefundable() const
Definition: Item.h:98
uint16 GetPos() const
Definition: Item.h:130
bool GemsFitSockets() const
Definition: Item.cpp:934
bool IsBoundByEnchant() const
Definition: Item.cpp:819
void SetSoulboundTradeable(GuidSet const &allowedLooters)
Definition: Item.cpp:1219
int16 uQueuePos
Definition: Item.h:216
void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges)
Definition: Item.cpp:915
uint32 m_paidExtendedCost
Definition: Item.h:221
bool IsBag() const
Definition: Item.h:102
void RemoveFromObjectUpdate() override
Definition: Item.cpp:1126
void ClearEnchantment(EnchantmentSlot slot)
Definition: Item.cpp:924
void SendUpdateSockets()
Definition: Item.cpp:1019
void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration, Player *owner)
Definition: Item.cpp:905
InventoryResult CanBeMergedPartlyWith(ItemTemplate const *proto) const
Definition: Item.cpp:830
void SetPaidExtendedCost(uint32 iece)
Definition: Item.h:188
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:150
virtual bool Create(ObjectGuid::LowType guidlow, uint32 itemId, Player const *owner)
Definition: Item.cpp:268
uint32 GetPaidMoney() const
Definition: Item.h:191
uint8 GetGemCountWithLimitCategory(uint32 limitCategory) const
Definition: Item.cpp:990
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1225
bool IsNotEmptyBag() const
Definition: Item.cpp:299
bool m_lootGenerated
Definition: Item.h:165
uint32 GetCount() const
Definition: Item.h:119
bool CheckSoulboundTradeExpire()
Definition: Item.cpp:1238
void SetOwnerGUID(ObjectGuid guid)
Definition: Item.h:77
Loot loot
Definition: Item.h:164
uint8 GetBagSlot() const
Definition: Item.cpp:711
uint32 GetRefundRecipient() const
Definition: Item.h:190
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:883
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition: Item.cpp:506
uint8 m_slot
Definition: Item.h:213
friend void AddItemToUpdateQueueOf(Item *item, Player *player)
Definition: Item.cpp:669
bool IsInUpdateQueue() const
Definition: Item.h:170
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:847
GuidSet allowedGUIDs
Definition: Item.h:222
ItemUpdateState uState
Definition: Item.h:215
LowType GetCounter() const
Definition: ObjectGuid.h:158
static ObjectGuid const Empty
Definition: ObjectGuid.h:132
std::string ToString() const
Definition: ObjectGuid.cpp:110
uint32 LowType
Definition: ObjectGuid.h:134
void _Create(ObjectGuid::LowType guidlow, uint32 entry, HighGuid guidhigh)
Definition: Object.cpp:109
void BuildFieldsUpdate(Player *, UpdateDataMapType &) const
Definition: Object.cpp:493
uint16 m_objectType
Definition: Object.h:231
int32 GetInt32Value(uint16 index) const
Definition: Object.cpp:244
void SetInt32Value(uint16 index, int32 value)
Definition: Object.cpp:573
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:250
uint16 m_valuesCount
Definition: Object.h:245
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:761
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:776
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:806
void ClearUpdateMask(bool remove)
Definition: Object.cpp:480
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:700
bool _LoadIntoDataField(std::string const &data, uint32 startOffset, uint32 count)
Definition: Object.cpp:552
uint32 GetEntry() const
Definition: Object.h:80
virtual std::string GetDebugInfo() const
Definition: Object.cpp:900
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:77
void SetEntry(uint32 entry)
Definition: Object.h:81
virtual void SetObjectScale(float scale)
Definition: Object.h:84
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:586
uint16 m_updateFlag
Definition: Object.h:234
ObjectGuid GetGUID() const
Definition: Object.h:78
TypeID m_objectTypeId
Definition: Object.h:233
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:282
Definition: Player.h:915
std::vector< Item * > m_itemUpdateQueue
Definition: Player.h:2370
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6242
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5968
WorldSession * GetSession() const
Definition: Player.h:1712
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: Player.cpp:12247
std::vector< ItemSetEffect * > ItemSetEff
Definition: Player.h:1949
static bool IsBagPos(uint16 pos)
Definition: Player.cpp:9839
void ApplyEquipSpell(SpellInfo const *spellInfo, Item *item, bool apply, bool form_change=false)
Definition: Player.cpp:7687
void DeleteRefundReference(ObjectGuid it)
Definition: Player.cpp:26131
bool m_itemUpdateQueueBlocked
Definition: Player.h:2371
void setInt16(uint8 index, int16 value)
void setUInt16(uint8 index, uint16 value)
void setUInt32(uint8 index, uint32 value)
void setString(uint8 index, std::string const &value)
uint32 Id
Definition: SpellInfo.h:293
int32 EquippedItemClass
Definition: SpellInfo.h:348
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:349
int32 EquippedItemInventoryTypeMask
Definition: SpellInfo.h:350
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:900
void SendEnchantmentLog(ObjectGuid target, ObjectGuid caster, uint32 itemId, uint32 enchantId)
@ SMSG_SOCKET_GEMS_RESULT
Definition: Opcodes.h:1320
@ SMSG_ITEM_TIME_UPDATE
Definition: Opcodes.h:519
#define sWorld
Definition: World.h:893
@ RATE_REPAIRCOST
Definition: World.h:433
time_t GetGameTime()
Definition: GameTime.cpp:42
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
std::string ToString(Type &&val, Params &&... params)
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Util.cpp:56
uint32 ArmorSubClassCost[8]
Definition: DBCStructure.h:621
uint32 WeaponSubClassCost[21]
Definition: DBCStructure.h:620
std::array< uint32, MAX_ITEM_ENCHANTMENT_EFFECTS > Enchantment
Definition: DBCStructure.h:956
std::array< uint32, MAX_ITEM_ENCHANTMENT_EFFECTS > Enchantment
Definition: DBCStructure.h:968
uint32 item_count
Definition: Item.h:36
uint32 setid
Definition: Item.h:35
SpellInfo const * spells[8]
Definition: Item.h:37
uint32 RequiredSkill
Definition: DBCStructure.h:986
uint32 RequiredSkillRank
Definition: DBCStructure.h:987
uint32 SetThreshold[MAX_ITEM_SET_SPELLS]
Definition: DBCStructure.h:985
uint32 SetSpellID[MAX_ITEM_SET_SPELLS]
Definition: DBCStructure.h:984
uint32 Quality
Definition: ItemTemplate.h:611
uint32 ItemLevel
Definition: ItemTemplate.h:620
std::array< _Spell, MAX_ITEM_PROTO_SPELLS > Spells
Definition: ItemTemplate.h:647
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:687
std::array< _Socket, MAX_ITEM_PROTO_SOCKETS > Socket
Definition: ItemTemplate.h:666
bool IsArmorVellum() const
Definition: ItemTemplate.h:703
uint32 ItemSet
Definition: ItemTemplate.h:660
uint32 GemProperties
Definition: ItemTemplate.h:668
uint32 ItemLimitCategory
Definition: ItemTemplate.h:672
uint32 MaxDurability
Definition: ItemTemplate.h:661
uint32 BagFamily
Definition: ItemTemplate.h:664
uint32 InventoryType
Definition: ItemTemplate.h:617
uint32 Duration
Definition: ItemTemplate.h:671
uint32 SubClass
Definition: ItemTemplate.h:607
bool IsWeaponVellum() const
Definition: ItemTemplate.h:702
uint32 Bonding
Definition: ItemTemplate.h:648
uint32 GetSkill() const
bool isLooted() const
Definition: Loot.h:239