2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef MANGOSSERVER_ITEM_H
20 #define MANGOSSERVER_ITEM_H
25 #include "ItemPrototype.h"
35 SpellEntry
const *spells
[8];
38 enum InventoryChangeFailure
41 EQUIP_ERR_CANT_EQUIP_LEVEL_I
= 1,
42 EQUIP_ERR_ERR_CANT_EQUIP_SKILL
= 2,
43 EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT
= 3,
44 EQUIP_ERR_BAG_FULL
= 4,
45 EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG
= 5,
46 EQUIP_ERR_CANT_TRADE_EQUIP_BAGS
= 6,
47 EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE
= 7,
48 EQUIP_ERR_NO_REQUIRED_PROFICIENCY
= 8,
49 EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE
= 9,
50 EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM
= 10,
51 EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM2
= 11,
52 EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE2
= 12,
53 EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED
= 13,
54 EQUIP_ERR_CANT_DUAL_WIELD
= 14,
55 EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG
= 15,
56 EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2
= 16,
57 EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
= 17,
58 EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE3
= 18,
59 EQUIP_ERR_ITEM_CANT_STACK
= 19,
60 EQUIP_ERR_ITEM_CANT_BE_EQUIPPED
= 20,
61 EQUIP_ERR_ITEMS_CANT_BE_SWAPPED
= 21,
62 EQUIP_ERR_SLOT_IS_EMPTY
= 22,
63 EQUIP_ERR_ITEM_NOT_FOUND
= 23,
64 EQUIP_ERR_CANT_DROP_SOULBOUND
= 24,
65 EQUIP_ERR_OUT_OF_RANGE
= 25,
66 EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT
= 26,
67 EQUIP_ERR_COULDNT_SPLIT_ITEMS
= 27,
68 EQUIP_ERR_MISSING_REAGENT
= 28,
69 EQUIP_ERR_NOT_ENOUGH_MONEY
= 29,
70 EQUIP_ERR_NOT_A_BAG
= 30,
71 EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS
= 31,
72 EQUIP_ERR_DONT_OWN_THAT_ITEM
= 32,
73 EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER
= 33,
74 EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT
= 34,
75 EQUIP_ERR_TOO_FAR_AWAY_FROM_BANK
= 35,
76 EQUIP_ERR_ITEM_LOCKED
= 36,
77 EQUIP_ERR_YOU_ARE_STUNNED
= 37,
78 EQUIP_ERR_YOU_ARE_DEAD
= 38,
79 EQUIP_ERR_CANT_DO_RIGHT_NOW
= 39,
80 EQUIP_ERR_INT_BAG_ERROR
= 40,
81 EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER2
= 41,
82 EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH
= 42,
83 EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED
= 43,
84 EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED
= 44,
85 EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED
= 45,
86 EQUIP_ERR_BOUND_CANT_BE_WRAPPED
= 46,
87 EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED
= 47,
88 EQUIP_ERR_BAGS_CANT_BE_WRAPPED
= 48,
89 EQUIP_ERR_ALREADY_LOOTED
= 49,
90 EQUIP_ERR_INVENTORY_FULL
= 50,
91 EQUIP_ERR_BANK_FULL
= 51,
92 EQUIP_ERR_ITEM_IS_CURRENTLY_SOLD_OUT
= 52,
93 EQUIP_ERR_BAG_FULL3
= 53,
94 EQUIP_ERR_ITEM_NOT_FOUND2
= 54,
95 EQUIP_ERR_ITEM_CANT_STACK2
= 55,
96 EQUIP_ERR_BAG_FULL4
= 56,
97 EQUIP_ERR_ITEM_SOLD_OUT
= 57,
98 EQUIP_ERR_OBJECT_IS_BUSY
= 58,
100 EQUIP_ERR_NOT_IN_COMBAT
= 60,
101 EQUIP_ERR_NOT_WHILE_DISARMED
= 61,
102 EQUIP_ERR_BAG_FULL6
= 62,
103 EQUIP_ERR_CANT_EQUIP_RANK
= 63,
104 EQUIP_ERR_CANT_EQUIP_REPUTATION
= 64,
105 EQUIP_ERR_TOO_MANY_SPECIAL_BAGS
= 65,
106 EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW
= 66,
107 EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE
= 67,
108 EQUIP_ERR_VENDOR_MISSING_TURNINS
= 68,
109 EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS
= 69,
110 EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS
= 70,
111 EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED
= 71,
112 EQUIP_ERR_MAIL_BOUND_ITEM
= 72,
113 EQUIP_ERR_NO_SPLIT_WHILE_PROSPECTING
= 73,
114 EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED
= 75,
115 EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED
= 76,
116 EQUIP_ERR_TOO_MUCH_GOLD
= 77,
117 EQUIP_ERR_NOT_DURING_ARENA_MATCH
= 78,
118 EQUIP_ERR_CANNOT_TRADE_THAT
= 79,
119 EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW
= 80
120 // probably exist more
125 BUY_ERR_CANT_FIND_ITEM
= 0,
126 BUY_ERR_ITEM_ALREADY_SOLD
= 1,
127 BUY_ERR_NOT_ENOUGHT_MONEY
= 2,
128 BUY_ERR_SELLER_DONT_LIKE_YOU
= 4,
129 BUY_ERR_DISTANCE_TOO_FAR
= 5,
130 BUY_ERR_ITEM_SOLD_OUT
= 7,
131 BUY_ERR_CANT_CARRY_MORE
= 8,
132 BUY_ERR_RANK_REQUIRE
= 11,
133 BUY_ERR_REPUTATION_REQUIRE
= 12
138 SELL_ERR_CANT_FIND_ITEM
= 1,
139 SELL_ERR_CANT_SELL_ITEM
= 2, // merchant doesn't like that item
140 SELL_ERR_CANT_FIND_VENDOR
= 3, // merchant doesn't like you
141 SELL_ERR_YOU_DONT_OWN_THAT_ITEM
= 4, // you don't own that item
142 SELL_ERR_UNK
= 5, // nothing appears...
143 SELL_ERR_ONLY_EMPTY_BAG
= 6 // can only do with empty bags
146 // -1 from client enchantment slot number
149 PERM_ENCHANTMENT_SLOT
= 0,
150 TEMP_ENCHANTMENT_SLOT
= 1,
151 SOCK_ENCHANTMENT_SLOT
= 2,
152 SOCK_ENCHANTMENT_SLOT_2
= 3,
153 SOCK_ENCHANTMENT_SLOT_3
= 4,
154 BONUS_ENCHANTMENT_SLOT
= 5,
155 MAX_INSPECTED_ENCHANTMENT_SLOT
= 6,
157 PROP_ENCHANTMENT_SLOT_0
= 6, // used with RandomSuffix
158 PROP_ENCHANTMENT_SLOT_1
= 7, // used with RandomSuffix
159 PROP_ENCHANTMENT_SLOT_2
= 8, // used with RandomSuffix and RandomProperty
160 PROP_ENCHANTMENT_SLOT_3
= 9, // used with RandomProperty
161 PROP_ENCHANTMENT_SLOT_4
= 10, // used with RandomProperty
162 MAX_ENCHANTMENT_SLOT
= 11
165 #define MAX_VISIBLE_ITEM_OFFSET 16 // 16 fields per visible item (creator(2) + enchantments(12) + properties(1) + pad(1))
167 enum EnchantmentOffset
169 ENCHANTMENT_ID_OFFSET
= 0,
170 ENCHANTMENT_DURATION_OFFSET
= 1,
171 ENCHANTMENT_CHARGES_OFFSET
= 2
174 #define MAX_ENCHANTMENT_OFFSET 3
176 enum EnchantmentSlotMask
178 ENCHANTMENT_CAN_SOULBOUND
= 0x01,
179 ENCHANTMENT_UNK1
= 0x02,
180 ENCHANTMENT_UNK2
= 0x04,
181 ENCHANTMENT_UNK3
= 0x08
192 bool ItemCanGoIntoBag(ItemPrototype
const *proto
, ItemPrototype
const *pBagProto
);
194 class MANGOS_DLL_SPEC Item
: public Object
197 static Item
* CreateItem( uint32 item
, uint32 count
, Player
const* player
= NULL
);
198 Item
* CloneItem( uint32 count
, Player
const* player
= NULL
) const;
202 virtual bool Create( uint32 guidlow
, uint32 itemid
, Player
const* owner
);
204 ItemPrototype
const* GetProto() const;
206 uint64
const& GetOwnerGUID() const { return GetUInt64Value(ITEM_FIELD_OWNER
); }
207 void SetOwnerGUID(uint64 guid
) { SetUInt64Value(ITEM_FIELD_OWNER
, guid
); }
208 Player
* GetOwner()const;
210 void SetBinding(bool val
) { ApplyModFlag(ITEM_FIELD_FLAGS
,ITEM_FLAGS_BINDED
,val
); }
211 bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS
, ITEM_FLAGS_BINDED
); }
212 bool IsBindedNotWith(uint64 guid
) const { return IsSoulBound() && GetOwnerGUID()!= guid
; }
213 bool IsBoundByEnchant() const;
214 virtual void SaveToDB();
215 virtual bool LoadFromDB(uint32 guid
, uint64 owner_guid
, QueryResult
*result
= NULL
);
216 virtual void DeleteFromDB();
217 void DeleteFromInventoryDB();
219 bool IsBag() const { return GetProto()->InventoryType
== INVTYPE_BAG
; }
220 bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY
) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY
) == 0; }
221 bool CanBeTraded() const;
222 void SetInTrade(bool b
= true) { mb_in_trade
= b
; }
223 bool IsInTrade() const { return mb_in_trade
; }
225 bool IsFitToSpellRequirements(SpellEntry
const* spellInfo
) const;
226 bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId
, uint32 cur_zoneId
) const;
227 bool GemsFitSockets() const;
229 uint32
GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT
); }
230 void SetCount(uint32 value
) { SetUInt32Value (ITEM_FIELD_STACK_COUNT
, value
); }
231 uint32
GetMaxStackCount() const { return GetProto()->Stackable
; }
232 uint8
GetGemCountWithID(uint32 GemID
) const;
234 uint8
GetSlot() const {return m_slot
;}
235 Bag
*GetContainer() { return m_container
; }
236 uint8
GetBagSlot() const;
237 void SetSlot(uint8 slot
) {m_slot
= slot
;}
238 uint16
GetPos() const { return uint16(GetBagSlot()) << 8 | GetSlot(); }
239 void SetContainer(Bag
*container
) { m_container
= container
; }
241 bool IsInBag() const { return m_container
!= NULL
; }
242 bool IsEquipped() const;
247 // RandomPropertyId (signed but stored as unsigned)
248 int32
GetItemRandomPropertyId() const { return GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID
); }
249 uint32
GetItemSuffixFactor() const { return GetUInt32Value(ITEM_FIELD_PROPERTY_SEED
); }
250 void SetItemRandomProperties(int32 randomPropId
);
251 bool UpdateItemSuffixFactor();
252 static int32
GenerateItemRandomPropertyId(uint32 item_id
);
253 void SetEnchantment(EnchantmentSlot slot
, uint32 id
, uint32 duration
, uint32 charges
);
254 void SetEnchantmentDuration(EnchantmentSlot slot
, uint32 duration
);
255 void SetEnchantmentCharges(EnchantmentSlot slot
, uint32 charges
);
256 void ClearEnchantment(EnchantmentSlot slot
);
257 uint32
GetEnchantmentId(EnchantmentSlot slot
) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT
+ slot
*MAX_ENCHANTMENT_OFFSET
+ ENCHANTMENT_ID_OFFSET
);}
258 uint32
GetEnchantmentDuration(EnchantmentSlot slot
) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT
+ slot
*MAX_ENCHANTMENT_OFFSET
+ ENCHANTMENT_DURATION_OFFSET
);}
259 uint32
GetEnchantmentCharges(EnchantmentSlot slot
) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT
+ slot
*MAX_ENCHANTMENT_OFFSET
+ ENCHANTMENT_CHARGES_OFFSET
);}
261 void SendTimeUpdate(Player
* owner
);
262 void UpdateDuration(Player
* owner
, uint32 diff
);
264 // spell charges (signed but stored as unsigned)
265 int32
GetSpellCharges(uint8 index
/*0..5*/ = 0) const { return GetInt32Value(ITEM_FIELD_SPELL_CHARGES
+ index
); }
266 void SetSpellCharges(uint8 index
/*0..5*/, int32 value
) { SetInt32Value(ITEM_FIELD_SPELL_CHARGES
+ index
,value
); }
269 bool m_lootGenerated
;
272 ItemUpdateState
GetState() const { return uState
; }
273 void SetState(ItemUpdateState state
, Player
*forplayer
= NULL
);
274 void AddToUpdateQueueOf(Player
*player
);
275 void RemoveFromUpdateQueueOf(Player
*player
);
276 bool IsInUpdateQueue() const { return uQueuePos
!= -1; }
277 uint16
GetQueuePos() const { return uQueuePos
; }
278 void FSetState(ItemUpdateState state
) // forced
283 bool hasQuest(uint32 quest_id
) const
285 ItemPrototype
const *itemProto
= GetProto();
286 return itemProto
&& itemProto
->StartQuest
== quest_id
;
288 bool hasInvolvedQuest(uint32
/*quest_id*/) const { return false; }
293 ItemUpdateState uState
;
295 bool mb_in_trade
; // true if item is currently in trade-window