[8449] Deprecate healing/damage item mods and merge internal data in to spell power.
[getmangos.git] / src / game / Item.h
blob5f92232bd18461488f218e9c564d39613b8c9eb9
1 /*
2 * Copyright (C) 2005-2009 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
22 #include "Common.h"
23 #include "Object.h"
24 #include "LootMgr.h"
25 #include "ItemPrototype.h"
27 struct SpellEntry;
28 class Bag;
29 class QueryResult;
30 class Unit;
32 struct ItemSetEffect
34 uint32 setid;
35 uint32 item_count;
36 SpellEntry const *spells[8];
39 enum InventoryChangeFailure
41 EQUIP_ERR_OK = 0,
42 EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1,
43 EQUIP_ERR_ERR_CANT_EQUIP_SKILL = 2,
44 EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT = 3,
45 EQUIP_ERR_BAG_FULL = 4,
46 EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG = 5,
47 EQUIP_ERR_CANT_TRADE_EQUIP_BAGS = 6,
48 EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE = 7,
49 EQUIP_ERR_NO_REQUIRED_PROFICIENCY = 8,
50 EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE = 9,
51 EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM = 10,
52 EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM2 = 11,
53 EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE2 = 12,
54 EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED = 13,
55 EQUIP_ERR_CANT_DUAL_WIELD = 14,
56 EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG = 15,
57 EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 = 16,
58 EQUIP_ERR_CANT_CARRY_MORE_OF_THIS = 17,
59 EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE3 = 18,
60 EQUIP_ERR_ITEM_CANT_STACK = 19,
61 EQUIP_ERR_ITEM_CANT_BE_EQUIPPED = 20,
62 EQUIP_ERR_ITEMS_CANT_BE_SWAPPED = 21,
63 EQUIP_ERR_SLOT_IS_EMPTY = 22,
64 EQUIP_ERR_ITEM_NOT_FOUND = 23,
65 EQUIP_ERR_CANT_DROP_SOULBOUND = 24,
66 EQUIP_ERR_OUT_OF_RANGE = 25,
67 EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT = 26,
68 EQUIP_ERR_COULDNT_SPLIT_ITEMS = 27,
69 EQUIP_ERR_MISSING_REAGENT = 28,
70 EQUIP_ERR_NOT_ENOUGH_MONEY = 29,
71 EQUIP_ERR_NOT_A_BAG = 30,
72 EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS = 31,
73 EQUIP_ERR_DONT_OWN_THAT_ITEM = 32,
74 EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER = 33,
75 EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT = 34,
76 EQUIP_ERR_TOO_FAR_AWAY_FROM_BANK = 35,
77 EQUIP_ERR_ITEM_LOCKED = 36,
78 EQUIP_ERR_YOU_ARE_STUNNED = 37,
79 EQUIP_ERR_YOU_ARE_DEAD = 38,
80 EQUIP_ERR_CANT_DO_RIGHT_NOW = 39,
81 EQUIP_ERR_INT_BAG_ERROR = 40,
82 EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER2 = 41,
83 EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH = 42,
84 EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED = 43,
85 EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED = 44,
86 EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED = 45,
87 EQUIP_ERR_BOUND_CANT_BE_WRAPPED = 46,
88 EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED = 47,
89 EQUIP_ERR_BAGS_CANT_BE_WRAPPED = 48,
90 EQUIP_ERR_ALREADY_LOOTED = 49,
91 EQUIP_ERR_INVENTORY_FULL = 50,
92 EQUIP_ERR_BANK_FULL = 51,
93 EQUIP_ERR_ITEM_IS_CURRENTLY_SOLD_OUT = 52,
94 EQUIP_ERR_BAG_FULL3 = 53,
95 EQUIP_ERR_ITEM_NOT_FOUND2 = 54,
96 EQUIP_ERR_ITEM_CANT_STACK2 = 55,
97 EQUIP_ERR_BAG_FULL4 = 56,
98 EQUIP_ERR_ITEM_SOLD_OUT = 57,
99 EQUIP_ERR_OBJECT_IS_BUSY = 58,
100 EQUIP_ERR_NONE = 59,
101 EQUIP_ERR_NOT_IN_COMBAT = 60,
102 EQUIP_ERR_NOT_WHILE_DISARMED = 61,
103 EQUIP_ERR_BAG_FULL6 = 62,
104 EQUIP_ERR_CANT_EQUIP_RANK = 63,
105 EQUIP_ERR_CANT_EQUIP_REPUTATION = 64,
106 EQUIP_ERR_TOO_MANY_SPECIAL_BAGS = 65,
107 EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW = 66,
108 EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE = 67,
109 EQUIP_ERR_VENDOR_MISSING_TURNINS = 68,
110 EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS = 69,
111 EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS = 70,
112 EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED = 71,
113 EQUIP_ERR_MAIL_BOUND_ITEM = 72,
114 EQUIP_ERR_NO_SPLIT_WHILE_PROSPECTING = 73,
115 EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED = 75,
116 EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED = 76,
117 EQUIP_ERR_TOO_MUCH_GOLD = 77,
118 EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78,
119 EQUIP_ERR_CANNOT_TRADE_THAT = 79,
120 EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80,
121 // no output = 81,
122 EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS = 82,
123 // no output = 83,
124 // crash client = 84,
127 enum BuyFailure
129 BUY_ERR_CANT_FIND_ITEM = 0,
130 BUY_ERR_ITEM_ALREADY_SOLD = 1,
131 BUY_ERR_NOT_ENOUGHT_MONEY = 2,
132 BUY_ERR_SELLER_DONT_LIKE_YOU = 4,
133 BUY_ERR_DISTANCE_TOO_FAR = 5,
134 BUY_ERR_ITEM_SOLD_OUT = 7,
135 BUY_ERR_CANT_CARRY_MORE = 8,
136 BUY_ERR_RANK_REQUIRE = 11,
137 BUY_ERR_REPUTATION_REQUIRE = 12
140 enum SellFailure
142 SELL_ERR_CANT_FIND_ITEM = 1,
143 SELL_ERR_CANT_SELL_ITEM = 2, // merchant doesn't like that item
144 SELL_ERR_CANT_FIND_VENDOR = 3, // merchant doesn't like you
145 SELL_ERR_YOU_DONT_OWN_THAT_ITEM = 4, // you don't own that item
146 SELL_ERR_UNK = 5, // nothing appears...
147 SELL_ERR_ONLY_EMPTY_BAG = 6 // can only do with empty bags
150 // -1 from client enchantment slot number
151 enum EnchantmentSlot
153 PERM_ENCHANTMENT_SLOT = 0,
154 TEMP_ENCHANTMENT_SLOT = 1,
155 SOCK_ENCHANTMENT_SLOT = 2,
156 SOCK_ENCHANTMENT_SLOT_2 = 3,
157 SOCK_ENCHANTMENT_SLOT_3 = 4,
158 BONUS_ENCHANTMENT_SLOT = 5,
159 PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment
160 MAX_INSPECTED_ENCHANTMENT_SLOT = 7,
162 PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix
163 PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix
164 PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty
165 PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty
166 PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty
167 MAX_ENCHANTMENT_SLOT = 12
170 #define MAX_VISIBLE_ITEM_OFFSET 2 // 2 fields per visible item (entry+enchantment)
172 #define MAX_GEM_SOCKETS MAX_ITEM_PROTO_SOCKETS// (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT) and item proto size, equal value expected
174 enum EnchantmentOffset
176 ENCHANTMENT_ID_OFFSET = 0,
177 ENCHANTMENT_DURATION_OFFSET = 1,
178 ENCHANTMENT_CHARGES_OFFSET = 2 // now here not only charges, but something new in wotlk
181 #define MAX_ENCHANTMENT_OFFSET 3
183 enum EnchantmentSlotMask
185 ENCHANTMENT_CAN_SOULBOUND = 0x01,
186 ENCHANTMENT_UNK1 = 0x02,
187 ENCHANTMENT_UNK2 = 0x04,
188 ENCHANTMENT_UNK3 = 0x08
191 enum ItemUpdateState
193 ITEM_UNCHANGED = 0,
194 ITEM_CHANGED = 1,
195 ITEM_NEW = 2,
196 ITEM_REMOVED = 3
199 enum ItemRequiredTargetType
201 ITEM_TARGET_TYPE_CREATURE = 1,
202 ITEM_TARGET_TYPE_DEAD = 2
205 #define MAX_ITEM_REQ_TARGET_TYPE 2
207 struct ItemRequiredTarget
209 ItemRequiredTarget(ItemRequiredTargetType uiType, uint32 uiTargetEntry) : m_uiType(uiType), m_uiTargetEntry(uiTargetEntry) {}
210 ItemRequiredTargetType m_uiType;
211 uint32 m_uiTargetEntry;
213 // helpers
214 bool IsFitToRequirements(Unit* pUnitTarget) const;
217 bool ItemCanGoIntoBag(ItemPrototype const *proto, ItemPrototype const *pBagProto);
219 class MANGOS_DLL_SPEC Item : public Object
221 public:
222 static Item* CreateItem( uint32 item, uint32 count, Player const* player = NULL );
223 Item* CloneItem( uint32 count, Player const* player = NULL ) const;
225 Item ( );
227 virtual bool Create( uint32 guidlow, uint32 itemid, Player const* owner);
229 ItemPrototype const* GetProto() const;
231 uint64 const& GetOwnerGUID() const { return GetUInt64Value(ITEM_FIELD_OWNER); }
232 void SetOwnerGUID(uint64 guid) { SetUInt64Value(ITEM_FIELD_OWNER, guid); }
233 Player* GetOwner()const;
235 void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }
236 bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
237 bool IsBoundAccountWide() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
238 bool IsBindedNotWith(Player const* player) const;
239 bool IsBoundByEnchant() const;
240 virtual void SaveToDB();
241 virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result = NULL);
242 virtual void DeleteFromDB();
243 void DeleteFromInventoryDB();
245 bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
246 bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
247 bool CanBeTraded(bool mail = false) const;
248 void SetInTrade(bool b = true) { mb_in_trade = b; }
249 bool IsInTrade() const { return mb_in_trade; }
251 bool IsFitToSpellRequirements(SpellEntry const* spellInfo) const;
252 bool IsTargetValidForItemUse(Unit* pUnitTarget);
253 bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const;
254 bool GemsFitSockets() const;
256 uint32 GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT); }
257 void SetCount(uint32 value) { SetUInt32Value (ITEM_FIELD_STACK_COUNT, value); }
258 uint32 GetMaxStackCount() const { return GetProto()->GetMaxStackSize(); }
259 uint8 GetGemCountWithID(uint32 GemID) const;
260 uint8 GetGemCountWithLimitCategory(uint32 limitCategory) const;
262 uint8 GetSlot() const {return m_slot;}
263 Bag *GetContainer() { return m_container; }
264 uint8 GetBagSlot() const;
265 void SetSlot(uint8 slot) {m_slot = slot;}
266 uint16 GetPos() const { return uint16(GetBagSlot()) << 8 | GetSlot(); }
267 void SetContainer(Bag *container) { m_container = container; }
269 bool IsInBag() const { return m_container != NULL; }
270 bool IsEquipped() const;
272 uint32 GetSkill();
273 uint32 GetSpell();
275 // RandomPropertyId (signed but stored as unsigned)
276 int32 GetItemRandomPropertyId() const { return GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID); }
277 uint32 GetItemSuffixFactor() const { return GetUInt32Value(ITEM_FIELD_PROPERTY_SEED); }
278 void SetItemRandomProperties(int32 randomPropId);
279 bool UpdateItemSuffixFactor();
280 static int32 GenerateItemRandomPropertyId(uint32 item_id);
281 void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges);
282 void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration);
283 void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);
284 void ClearEnchantment(EnchantmentSlot slot);
285 uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
286 uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
287 uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
289 void SendTimeUpdate(Player* owner);
290 void UpdateDuration(Player* owner, uint32 diff);
292 // spell charges (signed but stored as unsigned)
293 int32 GetSpellCharges(uint8 index/*0..5*/ = 0) const { return GetInt32Value(ITEM_FIELD_SPELL_CHARGES + index); }
294 void SetSpellCharges(uint8 index/*0..5*/, int32 value) { SetInt32Value(ITEM_FIELD_SPELL_CHARGES + index,value); }
296 Loot loot;
297 bool m_lootGenerated;
299 // Update States
300 ItemUpdateState GetState() const { return uState; }
301 void SetState(ItemUpdateState state, Player *forplayer = NULL);
302 void AddToUpdateQueueOf(Player *player);
303 void RemoveFromUpdateQueueOf(Player *player);
304 bool IsInUpdateQueue() const { return uQueuePos != -1; }
305 uint16 GetQueuePos() const { return uQueuePos; }
306 void FSetState(ItemUpdateState state) // forced
308 uState = state;
311 bool hasQuest(uint32 quest_id) const { return GetProto()->StartQuest == quest_id; }
312 bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; }
313 bool IsPotion() const { return GetProto()->IsPotion(); }
314 bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
316 private:
317 uint8 m_slot;
318 Bag *m_container;
319 ItemUpdateState uState;
320 int16 uQueuePos;
321 bool mb_in_trade; // true if item is currently in trade-window
323 #endif