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