rearranged core files
--HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include "Bag.h"
|
||||
#include "Log.h"
|
||||
#include "UpdateData.h"
|
||||
|
||||
Bag::Bag(): Item()
|
||||
{
|
||||
m_objectType |= TYPEMASK_CONTAINER;
|
||||
m_objectTypeId = TYPEID_CONTAINER;
|
||||
|
||||
m_valuesCount = CONTAINER_END;
|
||||
|
||||
memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);
|
||||
}
|
||||
|
||||
Bag::~Bag()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
if (Item *item = m_bagslot[i])
|
||||
{
|
||||
if (item->IsInWorld())
|
||||
{
|
||||
sLog.outCrash("Item %u (slot %u, bag slot %u) in bag %u (slot %u, bag slot %u, m_bagslot %u) is to be deleted but is still in world.",
|
||||
item->GetEntry(), (uint32)item->GetSlot(), (uint32)item->GetBagSlot(),
|
||||
GetEntry(), (uint32)GetSlot(), (uint32)GetBagSlot(), (uint32)i);
|
||||
item->RemoveFromWorld();
|
||||
}
|
||||
delete m_bagslot[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Bag::AddToWorld()
|
||||
{
|
||||
Item::AddToWorld();
|
||||
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->AddToWorld();
|
||||
}
|
||||
|
||||
void Bag::RemoveFromWorld()
|
||||
{
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->RemoveFromWorld();
|
||||
|
||||
Item::RemoveFromWorld();
|
||||
}
|
||||
|
||||
bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
|
||||
{
|
||||
ItemPrototype const * itemProto = objmgr.GetItemPrototype(itemid);
|
||||
|
||||
if (!itemProto || itemProto->ContainerSlots > MAX_BAG_SIZE)
|
||||
return false;
|
||||
|
||||
Object::_Create(guidlow, 0, HIGHGUID_CONTAINER);
|
||||
|
||||
SetEntry(itemid);
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
|
||||
|
||||
SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0);
|
||||
SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0);
|
||||
|
||||
SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability);
|
||||
SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability);
|
||||
SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags);
|
||||
SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1);
|
||||
|
||||
// Setting the number of Slots the Container has
|
||||
SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots);
|
||||
|
||||
// Cleaning 20 slots
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
{
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0);
|
||||
m_bagslot[i] = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bag::SaveToDB()
|
||||
{
|
||||
Item::SaveToDB();
|
||||
}
|
||||
|
||||
bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result)
|
||||
{
|
||||
if (!Item::LoadFromDB(guid, owner_guid, result))
|
||||
return false;
|
||||
|
||||
// cleanup bag content related item value fields (its will be filled correctly from `character_inventory`)
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
{
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0);
|
||||
if (m_bagslot[i])
|
||||
{
|
||||
delete m_bagslot[i];
|
||||
m_bagslot[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bag::DeleteFromDB()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->DeleteFromDB();
|
||||
|
||||
Item::DeleteFromDB();
|
||||
}
|
||||
|
||||
uint32 Bag::GetFreeSlots() const
|
||||
{
|
||||
uint32 slots = 0;
|
||||
for (uint32 i=0; i < GetBagSize(); ++i)
|
||||
if (!m_bagslot[i])
|
||||
++slots;
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
void Bag::RemoveItem(uint8 slot, bool /*update*/)
|
||||
{
|
||||
assert(slot < MAX_BAG_SIZE);
|
||||
|
||||
if (m_bagslot[slot])
|
||||
m_bagslot[slot]->SetContainer(NULL);
|
||||
|
||||
m_bagslot[slot] = NULL;
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (slot * 2), 0);
|
||||
}
|
||||
|
||||
void Bag::StoreItem(uint8 slot, Item *pItem, bool /*update*/)
|
||||
{
|
||||
assert(slot < MAX_BAG_SIZE);
|
||||
|
||||
if (pItem && pItem->GetGUID() != this->GetGUID())
|
||||
{
|
||||
m_bagslot[slot] = pItem;
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (slot * 2), pItem->GetGUID());
|
||||
pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, GetGUID());
|
||||
pItem->SetUInt64Value(ITEM_FIELD_OWNER, GetOwnerGUID());
|
||||
pItem->SetContainer(this);
|
||||
pItem->SetSlot(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void Bag::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
|
||||
{
|
||||
Item::BuildCreateUpdateBlockForPlayer(data, target);
|
||||
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->BuildCreateUpdateBlockForPlayer(data, target);
|
||||
}
|
||||
|
||||
// If the bag is empty returns true
|
||||
bool Bag::IsEmpty() const
|
||||
{
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 Bag::GetItemCount(uint32 item, Item* eItem) const
|
||||
{
|
||||
Item *pItem;
|
||||
uint32 count = 0;
|
||||
for (uint32 i=0; i < GetBagSize(); ++i)
|
||||
{
|
||||
pItem = m_bagslot[i];
|
||||
if (pItem && pItem != eItem && pItem->GetEntry() == item)
|
||||
count += pItem->GetCount();
|
||||
}
|
||||
|
||||
if (eItem && eItem->GetProto()->GemProperties)
|
||||
{
|
||||
for (uint32 i=0; i < GetBagSize(); ++i)
|
||||
{
|
||||
pItem = m_bagslot[i];
|
||||
if (pItem && pItem != eItem && pItem->GetProto()->Socket[0].Color)
|
||||
count += pItem->GetGemCountWithID(item);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8 Bag::GetSlotByItemGUID(uint64 guid) const
|
||||
{
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i] != 0)
|
||||
if (m_bagslot[i]->GetGUID() == guid)
|
||||
return i;
|
||||
|
||||
return NULL_SLOT;
|
||||
}
|
||||
|
||||
Item* Bag::GetItemByPos(uint8 slot) const
|
||||
{
|
||||
if (slot < GetBagSize())
|
||||
return m_bagslot[slot];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_BAG_H
|
||||
#define TRINITY_BAG_H
|
||||
|
||||
// Maximum 36 Slots ((CONTAINER_END - CONTAINER_FIELD_SLOT_1)/2
|
||||
#define MAX_BAG_SIZE 36 // 2.0.12
|
||||
|
||||
#include "Item.h"
|
||||
#include "ItemPrototype.h"
|
||||
|
||||
class Bag : public Item
|
||||
{
|
||||
public:
|
||||
|
||||
Bag();
|
||||
~Bag();
|
||||
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
bool Create(uint32 guidlow, uint32 itemid, Player const* owner);
|
||||
|
||||
void Clear();
|
||||
void StoreItem(uint8 slot, Item *pItem, bool update);
|
||||
void RemoveItem(uint8 slot, bool update);
|
||||
|
||||
Item* GetItemByPos(uint8 slot) const;
|
||||
uint32 GetItemCount(uint32 item, Item* eItem = NULL) const;
|
||||
|
||||
uint8 GetSlotByItemGUID(uint64 guid) const;
|
||||
bool IsEmpty() const;
|
||||
uint32 GetFreeSlots() const;
|
||||
uint32 GetBagSize() const { return GetUInt32Value(CONTAINER_FIELD_NUM_SLOTS); }
|
||||
|
||||
// DB operations
|
||||
// overwrite virtual Item::SaveToDB
|
||||
void SaveToDB();
|
||||
// overwrite virtual Item::LoadFromDB
|
||||
bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result);
|
||||
// overwrite virtual Item::DeleteFromDB
|
||||
void DeleteFromDB();
|
||||
|
||||
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const;
|
||||
|
||||
protected:
|
||||
|
||||
// Bag Storage space
|
||||
Item* m_bagslot[MAX_BAG_SIZE];
|
||||
};
|
||||
|
||||
inline Item* NewItemOrBag(ItemPrototype const * proto)
|
||||
{
|
||||
return (proto->InventoryType == INVTYPE_BAG) ? new Bag : new Item;
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_ITEM_H
|
||||
#define TRINITYCORE_ITEM_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Object.h"
|
||||
#include "LootMgr.h"
|
||||
#include "ItemPrototype.h"
|
||||
|
||||
struct SpellEntry;
|
||||
class Bag;
|
||||
class QueryResult;
|
||||
class Unit;
|
||||
|
||||
struct ItemSetEffect
|
||||
{
|
||||
uint32 setid;
|
||||
uint32 item_count;
|
||||
SpellEntry const *spells[8];
|
||||
};
|
||||
|
||||
enum InventoryChangeFailure
|
||||
{
|
||||
EQUIP_ERR_OK = 0,
|
||||
EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1,
|
||||
EQUIP_ERR_ERR_CANT_EQUIP_SKILL = 2,
|
||||
EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT = 3,
|
||||
EQUIP_ERR_BAG_FULL = 4,
|
||||
EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG = 5,
|
||||
EQUIP_ERR_CANT_TRADE_EQUIP_BAGS = 6,
|
||||
EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE = 7,
|
||||
EQUIP_ERR_NO_REQUIRED_PROFICIENCY = 8,
|
||||
EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE = 9,
|
||||
EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM = 10,
|
||||
EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM2 = 11,
|
||||
EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE2 = 12,
|
||||
EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED = 13,
|
||||
EQUIP_ERR_CANT_DUAL_WIELD = 14,
|
||||
EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG = 15,
|
||||
EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 = 16,
|
||||
EQUIP_ERR_CANT_CARRY_MORE_OF_THIS = 17,
|
||||
EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE3 = 18,
|
||||
EQUIP_ERR_ITEM_CANT_STACK = 19,
|
||||
EQUIP_ERR_ITEM_CANT_BE_EQUIPPED = 20,
|
||||
EQUIP_ERR_ITEMS_CANT_BE_SWAPPED = 21,
|
||||
EQUIP_ERR_SLOT_IS_EMPTY = 22,
|
||||
EQUIP_ERR_ITEM_NOT_FOUND = 23,
|
||||
EQUIP_ERR_CANT_DROP_SOULBOUND = 24,
|
||||
EQUIP_ERR_OUT_OF_RANGE = 25,
|
||||
EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT = 26,
|
||||
EQUIP_ERR_COULDNT_SPLIT_ITEMS = 27,
|
||||
EQUIP_ERR_MISSING_REAGENT = 28,
|
||||
EQUIP_ERR_NOT_ENOUGH_MONEY = 29,
|
||||
EQUIP_ERR_NOT_A_BAG = 30,
|
||||
EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS = 31,
|
||||
EQUIP_ERR_DONT_OWN_THAT_ITEM = 32,
|
||||
EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER = 33,
|
||||
EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT = 34,
|
||||
EQUIP_ERR_TOO_FAR_AWAY_FROM_BANK = 35,
|
||||
EQUIP_ERR_ITEM_LOCKED = 36,
|
||||
EQUIP_ERR_YOU_ARE_STUNNED = 37,
|
||||
EQUIP_ERR_YOU_ARE_DEAD = 38,
|
||||
EQUIP_ERR_CANT_DO_RIGHT_NOW = 39,
|
||||
EQUIP_ERR_INT_BAG_ERROR = 40,
|
||||
EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER2 = 41,
|
||||
EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH = 42,
|
||||
EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED = 43,
|
||||
EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED = 44,
|
||||
EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED = 45,
|
||||
EQUIP_ERR_BOUND_CANT_BE_WRAPPED = 46,
|
||||
EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED = 47,
|
||||
EQUIP_ERR_BAGS_CANT_BE_WRAPPED = 48,
|
||||
EQUIP_ERR_ALREADY_LOOTED = 49,
|
||||
EQUIP_ERR_INVENTORY_FULL = 50,
|
||||
EQUIP_ERR_BANK_FULL = 51,
|
||||
EQUIP_ERR_ITEM_IS_CURRENTLY_SOLD_OUT = 52,
|
||||
EQUIP_ERR_BAG_FULL3 = 53,
|
||||
EQUIP_ERR_ITEM_NOT_FOUND2 = 54,
|
||||
EQUIP_ERR_ITEM_CANT_STACK2 = 55,
|
||||
EQUIP_ERR_BAG_FULL4 = 56,
|
||||
EQUIP_ERR_ITEM_SOLD_OUT = 57,
|
||||
EQUIP_ERR_OBJECT_IS_BUSY = 58,
|
||||
EQUIP_ERR_NONE = 59,
|
||||
EQUIP_ERR_NOT_IN_COMBAT = 60,
|
||||
EQUIP_ERR_NOT_WHILE_DISARMED = 61,
|
||||
EQUIP_ERR_BAG_FULL6 = 62,
|
||||
EQUIP_ERR_CANT_EQUIP_RANK = 63,
|
||||
EQUIP_ERR_CANT_EQUIP_REPUTATION = 64,
|
||||
EQUIP_ERR_TOO_MANY_SPECIAL_BAGS = 65,
|
||||
EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW = 66,
|
||||
EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE = 67,
|
||||
EQUIP_ERR_VENDOR_MISSING_TURNINS = 68,
|
||||
EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS = 69,
|
||||
EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS = 70,
|
||||
EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED = 71,
|
||||
EQUIP_ERR_MAIL_BOUND_ITEM = 72,
|
||||
EQUIP_ERR_NO_SPLIT_WHILE_PROSPECTING = 73,
|
||||
EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED = 75,
|
||||
EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED = 76,
|
||||
EQUIP_ERR_TOO_MUCH_GOLD = 77,
|
||||
EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78,
|
||||
EQUIP_ERR_CANNOT_TRADE_THAT = 79,
|
||||
EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80,
|
||||
// no output = 81,
|
||||
EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS = 82,
|
||||
// no output = 83,
|
||||
// crash client = 84,
|
||||
};
|
||||
|
||||
enum BuyFailure
|
||||
{
|
||||
BUY_ERR_CANT_FIND_ITEM = 0,
|
||||
BUY_ERR_ITEM_ALREADY_SOLD = 1,
|
||||
BUY_ERR_NOT_ENOUGHT_MONEY = 2,
|
||||
BUY_ERR_SELLER_DONT_LIKE_YOU = 4,
|
||||
BUY_ERR_DISTANCE_TOO_FAR = 5,
|
||||
BUY_ERR_ITEM_SOLD_OUT = 7,
|
||||
BUY_ERR_CANT_CARRY_MORE = 8,
|
||||
BUY_ERR_RANK_REQUIRE = 11,
|
||||
BUY_ERR_REPUTATION_REQUIRE = 12
|
||||
};
|
||||
|
||||
enum SellFailure
|
||||
{
|
||||
SELL_ERR_CANT_FIND_ITEM = 1,
|
||||
SELL_ERR_CANT_SELL_ITEM = 2, // merchant doesn't like that item
|
||||
SELL_ERR_CANT_FIND_VENDOR = 3, // merchant doesn't like you
|
||||
SELL_ERR_YOU_DONT_OWN_THAT_ITEM = 4, // you don't own that item
|
||||
SELL_ERR_UNK = 5, // nothing appears...
|
||||
SELL_ERR_ONLY_EMPTY_BAG = 6 // can only do with empty bags
|
||||
};
|
||||
|
||||
// -1 from client enchantment slot number
|
||||
enum EnchantmentSlot
|
||||
{
|
||||
PERM_ENCHANTMENT_SLOT = 0,
|
||||
TEMP_ENCHANTMENT_SLOT = 1,
|
||||
SOCK_ENCHANTMENT_SLOT = 2,
|
||||
SOCK_ENCHANTMENT_SLOT_2 = 3,
|
||||
SOCK_ENCHANTMENT_SLOT_3 = 4,
|
||||
BONUS_ENCHANTMENT_SLOT = 5,
|
||||
PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment
|
||||
MAX_INSPECTED_ENCHANTMENT_SLOT = 7,
|
||||
|
||||
PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix
|
||||
PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix
|
||||
PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty
|
||||
PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty
|
||||
PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty
|
||||
MAX_ENCHANTMENT_SLOT = 12
|
||||
};
|
||||
|
||||
#define MAX_VISIBLE_ITEM_OFFSET 2 // 2 fields per visible item (entry+enchantment)
|
||||
|
||||
#define MAX_GEM_SOCKETS MAX_ITEM_PROTO_SOCKETS// (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT) and item proto size, equal value expected
|
||||
|
||||
enum EnchantmentOffset
|
||||
{
|
||||
ENCHANTMENT_ID_OFFSET = 0,
|
||||
ENCHANTMENT_DURATION_OFFSET = 1,
|
||||
ENCHANTMENT_CHARGES_OFFSET = 2 // now here not only charges, but something new in wotlk
|
||||
};
|
||||
|
||||
#define MAX_ENCHANTMENT_OFFSET 3
|
||||
|
||||
enum EnchantmentSlotMask
|
||||
{
|
||||
ENCHANTMENT_CAN_SOULBOUND = 0x01,
|
||||
ENCHANTMENT_UNK1 = 0x02,
|
||||
ENCHANTMENT_UNK2 = 0x04,
|
||||
ENCHANTMENT_UNK3 = 0x08
|
||||
};
|
||||
|
||||
enum ItemUpdateState
|
||||
{
|
||||
ITEM_UNCHANGED = 0,
|
||||
ITEM_CHANGED = 1,
|
||||
ITEM_NEW = 2,
|
||||
ITEM_REMOVED = 3
|
||||
};
|
||||
|
||||
enum ItemRequiredTargetType
|
||||
{
|
||||
ITEM_TARGET_TYPE_CREATURE = 1,
|
||||
ITEM_TARGET_TYPE_DEAD = 2
|
||||
};
|
||||
|
||||
#define MAX_ITEM_REQ_TARGET_TYPE 2
|
||||
|
||||
struct ItemRequiredTarget
|
||||
{
|
||||
ItemRequiredTarget(ItemRequiredTargetType uiType, uint32 uiTargetEntry) : m_uiType(uiType), m_uiTargetEntry(uiTargetEntry) {}
|
||||
ItemRequiredTargetType m_uiType;
|
||||
uint32 m_uiTargetEntry;
|
||||
|
||||
// helpers
|
||||
bool IsFitToRequirements(Unit* pUnitTarget) const;
|
||||
};
|
||||
|
||||
bool ItemCanGoIntoBag(ItemPrototype const *proto, ItemPrototype const *pBagProto);
|
||||
|
||||
class Item : public Object
|
||||
{
|
||||
public:
|
||||
static Item* CreateItem(uint32 item, uint32 count, Player const* player = NULL);
|
||||
Item* CloneItem(uint32 count, Player const* player = NULL) const;
|
||||
|
||||
Item ();
|
||||
|
||||
virtual bool Create(uint32 guidlow, uint32 itemid, Player const* owner);
|
||||
|
||||
ItemPrototype const* GetProto() const;
|
||||
|
||||
uint64 const& GetOwnerGUID() const { return GetUInt64Value(ITEM_FIELD_OWNER); }
|
||||
void SetOwnerGUID(uint64 guid) { SetUInt64Value(ITEM_FIELD_OWNER, guid); }
|
||||
Player* GetOwner()const;
|
||||
|
||||
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }
|
||||
bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
|
||||
bool IsBoundAccountWide() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
|
||||
bool IsBindedNotWith(Player const* player) const;
|
||||
bool IsBoundByEnchant() const;
|
||||
virtual void SaveToDB();
|
||||
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result);
|
||||
virtual void DeleteFromDB();
|
||||
void DeleteFromInventoryDB();
|
||||
void SaveRefundDataToDB();
|
||||
void DeleteRefundDataFromDB();
|
||||
|
||||
bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
|
||||
bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
|
||||
bool CanBeTraded(bool mail = false) const;
|
||||
void SetInTrade(bool b = true) { mb_in_trade = b; }
|
||||
bool IsInTrade() const { return mb_in_trade; }
|
||||
|
||||
bool HasEnchantRequiredSkill(const Player *pPlayer) const;
|
||||
uint32 GetEnchantRequiredLevel() const;
|
||||
|
||||
bool IsFitToSpellRequirements(SpellEntry const* spellInfo) const;
|
||||
bool IsTargetValidForItemUse(Unit* pUnitTarget);
|
||||
bool IsLimitedToAnotherMapOrZone(uint32 cur_mapId, uint32 cur_zoneId) const;
|
||||
bool GemsFitSockets() const;
|
||||
|
||||
uint32 GetCount() const { return GetUInt32Value(ITEM_FIELD_STACK_COUNT); }
|
||||
void SetCount(uint32 value) { SetUInt32Value(ITEM_FIELD_STACK_COUNT, value); }
|
||||
uint32 GetMaxStackCount() const { return GetProto()->GetMaxStackSize(); }
|
||||
uint8 GetGemCountWithID(uint32 GemID) const;
|
||||
uint8 GetGemCountWithLimitCategory(uint32 limitCategory) const;
|
||||
uint8 CanBeMergedPartlyWith(ItemPrototype const* proto) const;
|
||||
|
||||
uint8 GetSlot() const {return m_slot;}
|
||||
Bag *GetContainer() { return m_container; }
|
||||
uint8 GetBagSlot() const;
|
||||
void SetSlot(uint8 slot) { m_slot = slot; }
|
||||
uint16 GetPos() const { return uint16(GetBagSlot()) << 8 | GetSlot(); }
|
||||
void SetContainer(Bag *container) { m_container = container; }
|
||||
|
||||
bool IsInBag() const { return m_container != NULL; }
|
||||
bool IsEquipped() const;
|
||||
|
||||
uint32 GetSkill();
|
||||
uint32 GetSpell();
|
||||
|
||||
// RandomPropertyId (signed but stored as unsigned)
|
||||
int32 GetItemRandomPropertyId() const { return GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID); }
|
||||
uint32 GetItemSuffixFactor() const { return GetUInt32Value(ITEM_FIELD_PROPERTY_SEED); }
|
||||
void SetItemRandomProperties(int32 randomPropId);
|
||||
bool UpdateItemSuffixFactor();
|
||||
static int32 GenerateItemRandomPropertyId(uint32 item_id);
|
||||
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges);
|
||||
void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration, Player* owner);
|
||||
void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);
|
||||
void ClearEnchantment(EnchantmentSlot slot);
|
||||
uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
|
||||
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
|
||||
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
|
||||
|
||||
std::string const& GetText() const { return m_text; }
|
||||
void SetText(std::string const& text) { m_text = text; }
|
||||
|
||||
void SendTimeUpdate(Player* owner);
|
||||
void UpdateDuration(Player* owner, uint32 diff);
|
||||
|
||||
// spell charges (signed but stored as unsigned)
|
||||
int32 GetSpellCharges(uint8 index/*0..5*/ = 0) const { return GetInt32Value(ITEM_FIELD_SPELL_CHARGES + index); }
|
||||
void SetSpellCharges(uint8 index/*0..5*/, int32 value) { SetInt32Value(ITEM_FIELD_SPELL_CHARGES + index,value); }
|
||||
|
||||
Loot loot;
|
||||
bool m_lootGenerated;
|
||||
|
||||
// Update States
|
||||
ItemUpdateState GetState() const { return uState; }
|
||||
void SetState(ItemUpdateState state, Player *forplayer = NULL);
|
||||
void AddToUpdateQueueOf(Player *player);
|
||||
void RemoveFromUpdateQueueOf(Player *player);
|
||||
bool IsInUpdateQueue() const { return uQueuePos != -1; }
|
||||
uint16 GetQueuePos() const { return uQueuePos; }
|
||||
void FSetState(ItemUpdateState state) // forced
|
||||
{
|
||||
uState = state;
|
||||
}
|
||||
|
||||
bool hasQuest(uint32 quest_id) const { return GetProto()->StartQuest == quest_id; }
|
||||
bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; }
|
||||
bool IsPotion() const { return GetProto()->IsPotion(); }
|
||||
bool IsWeaponVellum() const { return GetProto()->IsWeaponVellum(); }
|
||||
bool IsArmorVellum() const { return GetProto()->IsArmorVellum(); }
|
||||
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
|
||||
|
||||
// Item Refund system
|
||||
void SetNotRefundable(Player *owner, bool changestate = true);
|
||||
void SetRefundRecipient(uint32 pGuidLow) { m_refundRecipient = pGuidLow; }
|
||||
void SetPaidMoney(uint32 money) { m_paidMoney = money; }
|
||||
void SetPaidExtendedCost(uint32 iece) { m_paidExtendedCost = iece; }
|
||||
uint32 GetRefundRecipient() { return m_refundRecipient; }
|
||||
uint32 GetPaidMoney() { return m_paidMoney; }
|
||||
uint32 GetPaidExtendedCost() { return m_paidExtendedCost; }
|
||||
|
||||
void UpdatePlayedTime(Player *owner);
|
||||
uint32 GetPlayedTime();
|
||||
bool IsRefundExpired();
|
||||
|
||||
void BuildUpdate(UpdateDataMapType&);
|
||||
|
||||
private:
|
||||
std::string m_text;
|
||||
uint8 m_slot;
|
||||
Bag *m_container;
|
||||
ItemUpdateState uState;
|
||||
int16 uQueuePos;
|
||||
bool mb_in_trade; // true if item is currently in trade-window
|
||||
time_t m_lastPlayedTimeUpdate;
|
||||
uint32 m_refundRecipient;
|
||||
uint32 m_paidMoney;
|
||||
uint32 m_paidExtendedCost;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <functional>
|
||||
#include "ItemEnchantmentMgr.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ProgressBar.h"
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include "Util.h"
|
||||
|
||||
struct EnchStoreItem
|
||||
{
|
||||
uint32 ench;
|
||||
float chance;
|
||||
|
||||
EnchStoreItem()
|
||||
: ench(0), chance(0) {}
|
||||
|
||||
EnchStoreItem(uint32 _ench, float _chance)
|
||||
: ench(_ench), chance(_chance) {}
|
||||
};
|
||||
|
||||
typedef std::vector<EnchStoreItem> EnchStoreList;
|
||||
typedef UNORDERED_MAP<uint32, EnchStoreList> EnchantmentStore;
|
||||
|
||||
static EnchantmentStore RandomItemEnch;
|
||||
|
||||
void LoadRandomEnchantmentsTable()
|
||||
{
|
||||
RandomItemEnch.clear(); // for reload case
|
||||
|
||||
EnchantmentStore::const_iterator tab;
|
||||
uint32 entry, ench;
|
||||
float chance;
|
||||
uint32 count = 0;
|
||||
|
||||
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, ench, chance FROM item_enchantment_template");
|
||||
|
||||
if (result)
|
||||
{
|
||||
barGoLink bar(result->GetRowCount());
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
bar.step();
|
||||
|
||||
entry = fields[0].GetUInt32();
|
||||
ench = fields[1].GetUInt32();
|
||||
chance = fields[2].GetFloat();
|
||||
|
||||
if (chance > 0.000001f && chance <= 100.0f)
|
||||
RandomItemEnch[entry].push_back(EnchStoreItem(ench, chance));
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u Item Enchantment definitions", count);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outString();
|
||||
sLog.outErrorDb(">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty.");
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetItemEnchantMod(int32 entry)
|
||||
{
|
||||
if (!entry)
|
||||
return 0;
|
||||
|
||||
EnchantmentStore::const_iterator tab;
|
||||
|
||||
if (entry == -1)
|
||||
{
|
||||
tab = RandomItemEnch.begin();
|
||||
entry = urand(1, RandomItemEnch.size()) - 1;
|
||||
for (uint32 i = 0; i < entry; ++i)
|
||||
++tab;
|
||||
}
|
||||
else
|
||||
tab = RandomItemEnch.find(entry);
|
||||
|
||||
if (tab == RandomItemEnch.end())
|
||||
{
|
||||
sLog.outErrorDb("Item RandomProperty / RandomSuffix id #%u used in `item_template` but it does not have records in `item_enchantment_template` table.",entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double dRoll = rand_chance();
|
||||
float fCount = 0;
|
||||
|
||||
for (EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
|
||||
{
|
||||
fCount += ench_iter->chance;
|
||||
|
||||
if (fCount > dRoll) return ench_iter->ench;
|
||||
}
|
||||
|
||||
//we could get here only if sum of all enchantment chances is lower than 100%
|
||||
dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100;
|
||||
fCount = 0;
|
||||
|
||||
for (EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
|
||||
{
|
||||
fCount += ench_iter->chance;
|
||||
|
||||
if (fCount > dRoll) return ench_iter->ench;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 GenerateEnchSuffixFactor(uint32 item_id)
|
||||
{
|
||||
ItemPrototype const *itemProto = objmgr.GetItemPrototype(item_id);
|
||||
|
||||
if (!itemProto)
|
||||
return 0;
|
||||
if (!itemProto->RandomSuffix)
|
||||
return 0;
|
||||
|
||||
RandomPropertiesPointsEntry const *randomProperty = sRandomPropertiesPointsStore.LookupEntry(itemProto->ItemLevel);
|
||||
if (!randomProperty)
|
||||
return 0;
|
||||
|
||||
uint32 suffixFactor;
|
||||
switch(itemProto->InventoryType)
|
||||
{
|
||||
// Items of that type don`t have points
|
||||
case INVTYPE_NON_EQUIP:
|
||||
case INVTYPE_BAG:
|
||||
case INVTYPE_TABARD:
|
||||
case INVTYPE_AMMO:
|
||||
case INVTYPE_QUIVER:
|
||||
case INVTYPE_RELIC:
|
||||
return 0;
|
||||
// Select point coefficient
|
||||
case INVTYPE_HEAD:
|
||||
case INVTYPE_BODY:
|
||||
case INVTYPE_CHEST:
|
||||
case INVTYPE_LEGS:
|
||||
case INVTYPE_2HWEAPON:
|
||||
case INVTYPE_ROBE:
|
||||
suffixFactor = 0;
|
||||
break;
|
||||
case INVTYPE_SHOULDERS:
|
||||
case INVTYPE_WAIST:
|
||||
case INVTYPE_FEET:
|
||||
case INVTYPE_HANDS:
|
||||
case INVTYPE_TRINKET:
|
||||
suffixFactor = 1;
|
||||
break;
|
||||
case INVTYPE_NECK:
|
||||
case INVTYPE_WRISTS:
|
||||
case INVTYPE_FINGER:
|
||||
case INVTYPE_SHIELD:
|
||||
case INVTYPE_CLOAK:
|
||||
case INVTYPE_HOLDABLE:
|
||||
suffixFactor = 2;
|
||||
break;
|
||||
case INVTYPE_WEAPON:
|
||||
case INVTYPE_WEAPONMAINHAND:
|
||||
case INVTYPE_WEAPONOFFHAND:
|
||||
suffixFactor = 3;
|
||||
break;
|
||||
case INVTYPE_RANGED:
|
||||
case INVTYPE_THROWN:
|
||||
case INVTYPE_RANGEDRIGHT:
|
||||
suffixFactor = 4;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
// Select rare/epic modifier
|
||||
switch (itemProto->Quality)
|
||||
{
|
||||
case ITEM_QUALITY_UNCOMMON:
|
||||
return randomProperty->UncommonPropertiesPoints[suffixFactor];
|
||||
case ITEM_QUALITY_RARE:
|
||||
return randomProperty->RarePropertiesPoints[suffixFactor];
|
||||
case ITEM_QUALITY_EPIC:
|
||||
return randomProperty->EpicPropertiesPoints[suffixFactor];
|
||||
case ITEM_QUALITY_LEGENDARY:
|
||||
case ITEM_QUALITY_ARTIFACT:
|
||||
return 0; // not have random properties
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _ITEM_ENCHANTMENT_MGR_H
|
||||
#define _ITEM_ENCHANTMENT_MGR_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
void LoadRandomEnchantmentsTable();
|
||||
uint32 GetItemEnchantMod(int32 entry);
|
||||
uint32 GenerateEnchSuffixFactor(uint32 item_id);
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,670 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _ITEMPROTOTYPE_H
|
||||
#define _ITEMPROTOTYPE_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
enum ItemModType
|
||||
{
|
||||
ITEM_MOD_MANA = 0,
|
||||
ITEM_MOD_HEALTH = 1,
|
||||
ITEM_MOD_AGILITY = 3,
|
||||
ITEM_MOD_STRENGTH = 4,
|
||||
ITEM_MOD_INTELLECT = 5,
|
||||
ITEM_MOD_SPIRIT = 6,
|
||||
ITEM_MOD_STAMINA = 7,
|
||||
ITEM_MOD_DEFENSE_SKILL_RATING = 12,
|
||||
ITEM_MOD_DODGE_RATING = 13,
|
||||
ITEM_MOD_PARRY_RATING = 14,
|
||||
ITEM_MOD_BLOCK_RATING = 15,
|
||||
ITEM_MOD_HIT_MELEE_RATING = 16,
|
||||
ITEM_MOD_HIT_RANGED_RATING = 17,
|
||||
ITEM_MOD_HIT_SPELL_RATING = 18,
|
||||
ITEM_MOD_CRIT_MELEE_RATING = 19,
|
||||
ITEM_MOD_CRIT_RANGED_RATING = 20,
|
||||
ITEM_MOD_CRIT_SPELL_RATING = 21,
|
||||
ITEM_MOD_HIT_TAKEN_MELEE_RATING = 22,
|
||||
ITEM_MOD_HIT_TAKEN_RANGED_RATING = 23,
|
||||
ITEM_MOD_HIT_TAKEN_SPELL_RATING = 24,
|
||||
ITEM_MOD_CRIT_TAKEN_MELEE_RATING = 25,
|
||||
ITEM_MOD_CRIT_TAKEN_RANGED_RATING = 26,
|
||||
ITEM_MOD_CRIT_TAKEN_SPELL_RATING = 27,
|
||||
ITEM_MOD_HASTE_MELEE_RATING = 28,
|
||||
ITEM_MOD_HASTE_RANGED_RATING = 29,
|
||||
ITEM_MOD_HASTE_SPELL_RATING = 30,
|
||||
ITEM_MOD_HIT_RATING = 31,
|
||||
ITEM_MOD_CRIT_RATING = 32,
|
||||
ITEM_MOD_HIT_TAKEN_RATING = 33,
|
||||
ITEM_MOD_CRIT_TAKEN_RATING = 34,
|
||||
ITEM_MOD_RESILIENCE_RATING = 35,
|
||||
ITEM_MOD_HASTE_RATING = 36,
|
||||
ITEM_MOD_EXPERTISE_RATING = 37,
|
||||
ITEM_MOD_ATTACK_POWER = 38,
|
||||
ITEM_MOD_RANGED_ATTACK_POWER = 39,
|
||||
//ITEM_MOD_FERAL_ATTACK_POWER = 40, not in 3.3
|
||||
ITEM_MOD_SPELL_HEALING_DONE = 41, // deprecated
|
||||
ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated
|
||||
ITEM_MOD_MANA_REGENERATION = 43,
|
||||
ITEM_MOD_ARMOR_PENETRATION_RATING = 44,
|
||||
ITEM_MOD_SPELL_POWER = 45,
|
||||
ITEM_MOD_HEALTH_REGEN = 46,
|
||||
ITEM_MOD_SPELL_PENETRATION = 47,
|
||||
ITEM_MOD_BLOCK_VALUE = 48
|
||||
};
|
||||
|
||||
#define MAX_ITEM_MOD 49
|
||||
|
||||
enum ItemSpelltriggerType
|
||||
{
|
||||
ITEM_SPELLTRIGGER_ON_USE = 0, // use after equip cooldown
|
||||
ITEM_SPELLTRIGGER_ON_EQUIP = 1,
|
||||
ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2,
|
||||
ITEM_SPELLTRIGGER_SOULSTONE = 4,
|
||||
/*
|
||||
* ItemSpelltriggerType 5 might have changed on 2.4.3/3.0.3: Such auras
|
||||
* will be applied on item pickup and removed on item loss - maybe on the
|
||||
* other hand the item is destroyed if the aura is removed ("removed on
|
||||
* death" of spell 57348 makes me think so)
|
||||
*/
|
||||
ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown
|
||||
ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SPELLTRIGGER 7
|
||||
|
||||
enum ItemBondingType
|
||||
{
|
||||
NO_BIND = 0,
|
||||
BIND_WHEN_PICKED_UP = 1,
|
||||
BIND_WHEN_EQUIPED = 2,
|
||||
BIND_WHEN_USE = 3,
|
||||
BIND_QUEST_ITEM = 4,
|
||||
BIND_QUEST_ITEM1 = 5 // not used in game
|
||||
};
|
||||
|
||||
#define MAX_BIND_TYPE 6
|
||||
|
||||
// masks for ITEM_FIELD_FLAGS field
|
||||
enum ITEM_FLAGS
|
||||
{
|
||||
ITEM_FLAGS_BINDED = 0x00000001, // set in game at binding, not set in template
|
||||
ITEM_FLAGS_CONJURED = 0x00000002,
|
||||
ITEM_FLAGS_OPENABLE = 0x00000004,
|
||||
ITEM_FLAGS_WRAPPED = 0x00000008,
|
||||
ITEM_FLAGS_BROKEN = 0x00000010, // appears red icon (like when item durability == 0)
|
||||
ITEM_FLAGS_TOTEM = 0x00000020, // ?
|
||||
ITEM_FLAGS_USABLE = 0x00000040, // ?
|
||||
ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper
|
||||
ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not
|
||||
ITEM_FLAGS_REFUNDABLE = 0x00001000, // item cost can be refunded within 2 hours after purchase
|
||||
ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter
|
||||
ITEM_FLAGS_REFUNDABLE_2 = 0x00008000,
|
||||
ITEM_FLAGS_UNK1 = 0x00010000,
|
||||
ITEM_FLAGS_PROSPECTABLE = 0x00040000,
|
||||
ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000,
|
||||
ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000,
|
||||
ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip
|
||||
ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0
|
||||
ITEM_FLAGS_BOA = 0x08000000, // bind on account (set in template for items that can binded in like way)
|
||||
ITEM_FLAGS_TRIGGERED_CAST = 0x10000000, // used by enchanting scrolls made with vellum
|
||||
ITEM_FLAGS_ENCHANT_SCROLL = 0x10000000, // for enchant scrolls
|
||||
ITEM_FLAGS_MILLABLE = 0x20000000,
|
||||
ITEM_FLAGS_BOP_TRADEABLE = 0x80000000
|
||||
};
|
||||
|
||||
enum ItemFlagsExtra
|
||||
{
|
||||
ITEM_FLAGS_EXTRA_HORDE_ONLY = 0x00000001,
|
||||
ITEM_FLAGS_EXTRA_ALLIANCE_ONLY = 0x00000002,
|
||||
ITEM_FLAGS_EXTRA_REFUNDABLE = 0x00000004,
|
||||
ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100
|
||||
};
|
||||
|
||||
enum BAG_FAMILY_MASK
|
||||
{
|
||||
BAG_FAMILY_MASK_NONE = 0x00000000,
|
||||
BAG_FAMILY_MASK_ARROWS = 0x00000001,
|
||||
BAG_FAMILY_MASK_BULLETS = 0x00000002,
|
||||
BAG_FAMILY_MASK_SOUL_SHARDS = 0x00000004,
|
||||
BAG_FAMILY_MASK_LEATHERWORKING_SUPP = 0x00000008,
|
||||
BAG_FAMILY_MASK_INSCRIPTION_SUPP = 0x00000010,
|
||||
BAG_FAMILY_MASK_HERBS = 0x00000020,
|
||||
BAG_FAMILY_MASK_ENCHANTING_SUPP = 0x00000040,
|
||||
BAG_FAMILY_MASK_ENGINEERING_SUPP = 0x00000080,
|
||||
BAG_FAMILY_MASK_KEYS = 0x00000100,
|
||||
BAG_FAMILY_MASK_GEMS = 0x00000200,
|
||||
BAG_FAMILY_MASK_MINING_SUPP = 0x00000400,
|
||||
BAG_FAMILY_MASK_SOULBOUND_EQUIPMENT = 0x00000800,
|
||||
BAG_FAMILY_MASK_VANITY_PETS = 0x00001000,
|
||||
BAG_FAMILY_MASK_CURRENCY_TOKENS = 0x00002000,
|
||||
BAG_FAMILY_MASK_QUEST_ITEMS = 0x00004000
|
||||
};
|
||||
|
||||
enum SocketColor
|
||||
{
|
||||
SOCKET_COLOR_META = 1,
|
||||
SOCKET_COLOR_RED = 2,
|
||||
SOCKET_COLOR_YELLOW = 4,
|
||||
SOCKET_COLOR_BLUE = 8
|
||||
};
|
||||
|
||||
#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE)
|
||||
|
||||
enum InventoryType
|
||||
{
|
||||
INVTYPE_NON_EQUIP = 0,
|
||||
INVTYPE_HEAD = 1,
|
||||
INVTYPE_NECK = 2,
|
||||
INVTYPE_SHOULDERS = 3,
|
||||
INVTYPE_BODY = 4,
|
||||
INVTYPE_CHEST = 5,
|
||||
INVTYPE_WAIST = 6,
|
||||
INVTYPE_LEGS = 7,
|
||||
INVTYPE_FEET = 8,
|
||||
INVTYPE_WRISTS = 9,
|
||||
INVTYPE_HANDS = 10,
|
||||
INVTYPE_FINGER = 11,
|
||||
INVTYPE_TRINKET = 12,
|
||||
INVTYPE_WEAPON = 13,
|
||||
INVTYPE_SHIELD = 14,
|
||||
INVTYPE_RANGED = 15,
|
||||
INVTYPE_CLOAK = 16,
|
||||
INVTYPE_2HWEAPON = 17,
|
||||
INVTYPE_BAG = 18,
|
||||
INVTYPE_TABARD = 19,
|
||||
INVTYPE_ROBE = 20,
|
||||
INVTYPE_WEAPONMAINHAND = 21,
|
||||
INVTYPE_WEAPONOFFHAND = 22,
|
||||
INVTYPE_HOLDABLE = 23,
|
||||
INVTYPE_AMMO = 24,
|
||||
INVTYPE_THROWN = 25,
|
||||
INVTYPE_RANGEDRIGHT = 26,
|
||||
INVTYPE_QUIVER = 27,
|
||||
INVTYPE_RELIC = 28
|
||||
};
|
||||
|
||||
#define MAX_INVTYPE 29
|
||||
|
||||
enum ItemClass
|
||||
{
|
||||
ITEM_CLASS_CONSUMABLE = 0,
|
||||
ITEM_CLASS_CONTAINER = 1,
|
||||
ITEM_CLASS_WEAPON = 2,
|
||||
ITEM_CLASS_GEM = 3,
|
||||
ITEM_CLASS_ARMOR = 4,
|
||||
ITEM_CLASS_REAGENT = 5,
|
||||
ITEM_CLASS_PROJECTILE = 6,
|
||||
ITEM_CLASS_TRADE_GOODS = 7,
|
||||
ITEM_CLASS_GENERIC = 8,
|
||||
ITEM_CLASS_RECIPE = 9,
|
||||
ITEM_CLASS_MONEY = 10,
|
||||
ITEM_CLASS_QUIVER = 11,
|
||||
ITEM_CLASS_QUEST = 12,
|
||||
ITEM_CLASS_KEY = 13,
|
||||
ITEM_CLASS_PERMANENT = 14,
|
||||
ITEM_CLASS_MISC = 15,
|
||||
ITEM_CLASS_GLYPH = 16
|
||||
};
|
||||
|
||||
#define MAX_ITEM_CLASS 17
|
||||
|
||||
enum ItemSubclassConsumable
|
||||
{
|
||||
ITEM_SUBCLASS_CONSUMABLE = 0,
|
||||
ITEM_SUBCLASS_POTION = 1,
|
||||
ITEM_SUBCLASS_ELIXIR = 2,
|
||||
ITEM_SUBCLASS_FLASK = 3,
|
||||
ITEM_SUBCLASS_SCROLL = 4,
|
||||
ITEM_SUBCLASS_FOOD = 5,
|
||||
ITEM_SUBCLASS_ITEM_ENHANCEMENT = 6,
|
||||
ITEM_SUBCLASS_BANDAGE = 7,
|
||||
ITEM_SUBCLASS_CONSUMABLE_OTHER = 8
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_CONSUMABLE 9
|
||||
|
||||
enum ItemSubclassContainer
|
||||
{
|
||||
ITEM_SUBCLASS_CONTAINER = 0,
|
||||
ITEM_SUBCLASS_SOUL_CONTAINER = 1,
|
||||
ITEM_SUBCLASS_HERB_CONTAINER = 2,
|
||||
ITEM_SUBCLASS_ENCHANTING_CONTAINER = 3,
|
||||
ITEM_SUBCLASS_ENGINEERING_CONTAINER = 4,
|
||||
ITEM_SUBCLASS_GEM_CONTAINER = 5,
|
||||
ITEM_SUBCLASS_MINING_CONTAINER = 6,
|
||||
ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7,
|
||||
ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_CONTAINER 9
|
||||
|
||||
enum ItemSubclassWeapon
|
||||
{
|
||||
ITEM_SUBCLASS_WEAPON_AXE = 0,
|
||||
ITEM_SUBCLASS_WEAPON_AXE2 = 1,
|
||||
ITEM_SUBCLASS_WEAPON_BOW = 2,
|
||||
ITEM_SUBCLASS_WEAPON_GUN = 3,
|
||||
ITEM_SUBCLASS_WEAPON_MACE = 4,
|
||||
ITEM_SUBCLASS_WEAPON_MACE2 = 5,
|
||||
ITEM_SUBCLASS_WEAPON_POLEARM = 6,
|
||||
ITEM_SUBCLASS_WEAPON_SWORD = 7,
|
||||
ITEM_SUBCLASS_WEAPON_SWORD2 = 8,
|
||||
ITEM_SUBCLASS_WEAPON_obsolete = 9,
|
||||
ITEM_SUBCLASS_WEAPON_STAFF = 10,
|
||||
ITEM_SUBCLASS_WEAPON_EXOTIC = 11,
|
||||
ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12,
|
||||
ITEM_SUBCLASS_WEAPON_FIST = 13,
|
||||
ITEM_SUBCLASS_WEAPON_MISC = 14,
|
||||
ITEM_SUBCLASS_WEAPON_DAGGER = 15,
|
||||
ITEM_SUBCLASS_WEAPON_THROWN = 16,
|
||||
ITEM_SUBCLASS_WEAPON_SPEAR = 17,
|
||||
ITEM_SUBCLASS_WEAPON_CROSSBOW = 18,
|
||||
ITEM_SUBCLASS_WEAPON_WAND = 19,
|
||||
ITEM_SUBCLASS_WEAPON_FISHING_POLE = 20
|
||||
};
|
||||
|
||||
#define ITEM_SUBCLASS_MASK_WEAPON_RANGED (\
|
||||
(1 << ITEM_SUBCLASS_WEAPON_BOW) | (1 << ITEM_SUBCLASS_WEAPON_GUN) |\
|
||||
(1 << ITEM_SUBCLASS_WEAPON_CROSSBOW) | (1 << ITEM_SUBCLASS_WEAPON_THROWN))
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_WEAPON 21
|
||||
|
||||
enum ItemSubclassGem
|
||||
{
|
||||
ITEM_SUBCLASS_GEM_RED = 0,
|
||||
ITEM_SUBCLASS_GEM_BLUE = 1,
|
||||
ITEM_SUBCLASS_GEM_YELLOW = 2,
|
||||
ITEM_SUBCLASS_GEM_PURPLE = 3,
|
||||
ITEM_SUBCLASS_GEM_GREEN = 4,
|
||||
ITEM_SUBCLASS_GEM_ORANGE = 5,
|
||||
ITEM_SUBCLASS_GEM_META = 6,
|
||||
ITEM_SUBCLASS_GEM_SIMPLE = 7,
|
||||
ITEM_SUBCLASS_GEM_PRISMATIC = 8
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_GEM 9
|
||||
|
||||
enum ItemSubclassArmor
|
||||
{
|
||||
ITEM_SUBCLASS_ARMOR_MISC = 0,
|
||||
ITEM_SUBCLASS_ARMOR_CLOTH = 1,
|
||||
ITEM_SUBCLASS_ARMOR_LEATHER = 2,
|
||||
ITEM_SUBCLASS_ARMOR_MAIL = 3,
|
||||
ITEM_SUBCLASS_ARMOR_PLATE = 4,
|
||||
ITEM_SUBCLASS_ARMOR_BUCKLER = 5,
|
||||
ITEM_SUBCLASS_ARMOR_SHIELD = 6,
|
||||
ITEM_SUBCLASS_ARMOR_LIBRAM = 7,
|
||||
ITEM_SUBCLASS_ARMOR_IDOL = 8,
|
||||
ITEM_SUBCLASS_ARMOR_TOTEM = 9,
|
||||
ITEM_SUBCLASS_ARMOR_SIGIL = 10
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_ARMOR 11
|
||||
|
||||
enum ItemSubclassReagent
|
||||
{
|
||||
ITEM_SUBCLASS_REAGENT = 0
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_REAGENT 1
|
||||
|
||||
enum ItemSubclassProjectile
|
||||
{
|
||||
ITEM_SUBCLASS_WAND = 0, // ABS
|
||||
ITEM_SUBCLASS_BOLT = 1, // ABS
|
||||
ITEM_SUBCLASS_ARROW = 2,
|
||||
ITEM_SUBCLASS_BULLET = 3,
|
||||
ITEM_SUBCLASS_THROWN = 4 // ABS
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_PROJECTILE 5
|
||||
|
||||
enum ItemSubclassTradeGoods
|
||||
{
|
||||
ITEM_SUBCLASS_TRADE_GOODS = 0,
|
||||
ITEM_SUBCLASS_PARTS = 1,
|
||||
ITEM_SUBCLASS_EXPLOSIVES = 2,
|
||||
ITEM_SUBCLASS_DEVICES = 3,
|
||||
ITEM_SUBCLASS_JEWELCRAFTING = 4,
|
||||
ITEM_SUBCLASS_CLOTH = 5,
|
||||
ITEM_SUBCLASS_LEATHER = 6,
|
||||
ITEM_SUBCLASS_METAL_STONE = 7,
|
||||
ITEM_SUBCLASS_MEAT = 8,
|
||||
ITEM_SUBCLASS_HERB = 9,
|
||||
ITEM_SUBCLASS_ELEMENTAL = 10,
|
||||
ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11,
|
||||
ITEM_SUBCLASS_ENCHANTING = 12,
|
||||
ITEM_SUBCLASS_MATERIAL = 13,
|
||||
ITEM_SUBCLASS_ARMOR_ENCHANTMENT = 14,
|
||||
ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_TRADE_GOODS 16
|
||||
|
||||
enum ItemSubclassGeneric
|
||||
{
|
||||
ITEM_SUBCLASS_GENERIC = 0
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_GENERIC 1
|
||||
|
||||
enum ItemSubclassRecipe
|
||||
{
|
||||
ITEM_SUBCLASS_BOOK = 0,
|
||||
ITEM_SUBCLASS_LEATHERWORKING_PATTERN = 1,
|
||||
ITEM_SUBCLASS_TAILORING_PATTERN = 2,
|
||||
ITEM_SUBCLASS_ENGINEERING_SCHEMATIC = 3,
|
||||
ITEM_SUBCLASS_BLACKSMITHING = 4,
|
||||
ITEM_SUBCLASS_COOKING_RECIPE = 5,
|
||||
ITEM_SUBCLASS_ALCHEMY_RECIPE = 6,
|
||||
ITEM_SUBCLASS_FIRST_AID_MANUAL = 7,
|
||||
ITEM_SUBCLASS_ENCHANTING_FORMULA = 8,
|
||||
ITEM_SUBCLASS_FISHING_MANUAL = 9,
|
||||
ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_RECIPE 11
|
||||
|
||||
enum ItemSubclassMoney
|
||||
{
|
||||
ITEM_SUBCLASS_MONEY = 0
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_MONEY 1
|
||||
|
||||
enum ItemSubclassQuiver
|
||||
{
|
||||
ITEM_SUBCLASS_QUIVER0 = 0, // ABS
|
||||
ITEM_SUBCLASS_QUIVER1 = 1, // ABS
|
||||
ITEM_SUBCLASS_QUIVER = 2,
|
||||
ITEM_SUBCLASS_AMMO_POUCH = 3
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_QUIVER 4
|
||||
|
||||
enum ItemSubclassQuest
|
||||
{
|
||||
ITEM_SUBCLASS_QUEST = 0
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_QUEST 1
|
||||
|
||||
enum ItemSubclassKey
|
||||
{
|
||||
ITEM_SUBCLASS_KEY = 0,
|
||||
ITEM_SUBCLASS_LOCKPICK = 1
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_KEY 2
|
||||
|
||||
enum ItemSubclassPermanent
|
||||
{
|
||||
ITEM_SUBCLASS_PERMANENT = 0
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_PERMANENT 1
|
||||
|
||||
enum ItemSubclassJunk
|
||||
{
|
||||
ITEM_SUBCLASS_JUNK = 0,
|
||||
ITEM_SUBCLASS_JUNK_REAGENT = 1,
|
||||
ITEM_SUBCLASS_JUNK_PET = 2,
|
||||
ITEM_SUBCLASS_JUNK_HOLIDAY = 3,
|
||||
ITEM_SUBCLASS_JUNK_OTHER = 4,
|
||||
ITEM_SUBCLASS_JUNK_MOUNT = 5
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_JUNK 6
|
||||
|
||||
enum ItemSubclassGlyph
|
||||
{
|
||||
ITEM_SUBCLASS_GLYPH_WARRIOR = 1,
|
||||
ITEM_SUBCLASS_GLYPH_PALADIN = 2,
|
||||
ITEM_SUBCLASS_GLYPH_HUNTER = 3,
|
||||
ITEM_SUBCLASS_GLYPH_ROGUE = 4,
|
||||
ITEM_SUBCLASS_GLYPH_PRIEST = 5,
|
||||
ITEM_SUBCLASS_GLYPH_DEATH_KNIGHT = 6,
|
||||
ITEM_SUBCLASS_GLYPH_SHAMAN = 7,
|
||||
ITEM_SUBCLASS_GLYPH_MAGE = 8,
|
||||
ITEM_SUBCLASS_GLYPH_WARLOCK = 9,
|
||||
ITEM_SUBCLASS_GLYPH_DRUID = 11
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_GLYPH 12
|
||||
|
||||
const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
|
||||
{
|
||||
MAX_ITEM_SUBCLASS_CONSUMABLE,
|
||||
MAX_ITEM_SUBCLASS_CONTAINER,
|
||||
MAX_ITEM_SUBCLASS_WEAPON,
|
||||
MAX_ITEM_SUBCLASS_GEM,
|
||||
MAX_ITEM_SUBCLASS_ARMOR,
|
||||
MAX_ITEM_SUBCLASS_REAGENT,
|
||||
MAX_ITEM_SUBCLASS_PROJECTILE,
|
||||
MAX_ITEM_SUBCLASS_TRADE_GOODS,
|
||||
MAX_ITEM_SUBCLASS_GENERIC,
|
||||
MAX_ITEM_SUBCLASS_RECIPE,
|
||||
MAX_ITEM_SUBCLASS_MONEY,
|
||||
MAX_ITEM_SUBCLASS_QUIVER,
|
||||
MAX_ITEM_SUBCLASS_QUEST,
|
||||
MAX_ITEM_SUBCLASS_KEY,
|
||||
MAX_ITEM_SUBCLASS_PERMANENT,
|
||||
MAX_ITEM_SUBCLASS_JUNK,
|
||||
MAX_ITEM_SUBCLASS_GLYPH
|
||||
};
|
||||
|
||||
inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass)
|
||||
{
|
||||
switch(ItemClass)
|
||||
{
|
||||
case ITEM_CLASS_WEAPON: return ItemSubClass;
|
||||
case ITEM_CLASS_ARMOR: return ItemSubClass + 21;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
|
||||
#if defined(__GNUC__)
|
||||
#pragma pack(1)
|
||||
#else
|
||||
#pragma pack(push,1)
|
||||
#endif
|
||||
|
||||
struct _Damage
|
||||
{
|
||||
float DamageMin;
|
||||
float DamageMax;
|
||||
uint32 DamageType; // id from Resistances.dbc
|
||||
};
|
||||
|
||||
struct _ItemStat
|
||||
{
|
||||
uint32 ItemStatType;
|
||||
int32 ItemStatValue;
|
||||
};
|
||||
struct _Spell
|
||||
{
|
||||
int32 SpellId; // id from Spell.dbc
|
||||
uint32 SpellTrigger;
|
||||
int32 SpellCharges;
|
||||
float SpellPPMRate;
|
||||
int32 SpellCooldown;
|
||||
uint32 SpellCategory; // id from SpellCategory.dbc
|
||||
int32 SpellCategoryCooldown;
|
||||
};
|
||||
|
||||
struct _Socket
|
||||
{
|
||||
uint32 Color;
|
||||
uint32 Content;
|
||||
};
|
||||
|
||||
#define MAX_ITEM_PROTO_DAMAGES 2 // changed in 3.1.0
|
||||
#define MAX_ITEM_PROTO_SOCKETS 3
|
||||
#define MAX_ITEM_PROTO_SPELLS 5
|
||||
#define MAX_ITEM_PROTO_STATS 10
|
||||
|
||||
struct ItemPrototype
|
||||
{
|
||||
uint32 ItemId;
|
||||
uint32 Class; // id from ItemClass.dbc
|
||||
uint32 SubClass; // id from ItemSubClass.dbc
|
||||
int32 Unk0;
|
||||
char* Name1;
|
||||
uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc
|
||||
uint32 Quality;
|
||||
uint32 Flags;
|
||||
uint32 Flags2;
|
||||
uint32 BuyCount;
|
||||
int32 BuyPrice;
|
||||
uint32 SellPrice;
|
||||
uint32 InventoryType;
|
||||
uint32 AllowableClass;
|
||||
uint32 AllowableRace;
|
||||
uint32 ItemLevel;
|
||||
uint32 RequiredLevel;
|
||||
uint32 RequiredSkill; // id from SkillLine.dbc
|
||||
uint32 RequiredSkillRank;
|
||||
uint32 RequiredSpell; // id from Spell.dbc
|
||||
uint32 RequiredHonorRank;
|
||||
uint32 RequiredCityRank;
|
||||
uint32 RequiredReputationFaction; // id from Faction.dbc
|
||||
uint32 RequiredReputationRank;
|
||||
int32 MaxCount; // <= 0: no limit
|
||||
int32 Stackable; // 0: not allowed, -1: put in player coin info tab and don't limit stacking (so 1 slot)
|
||||
uint32 ContainerSlots;
|
||||
uint32 StatsCount;
|
||||
_ItemStat ItemStat[MAX_ITEM_PROTO_STATS];
|
||||
uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc
|
||||
uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc
|
||||
_Damage Damage[MAX_ITEM_PROTO_DAMAGES];
|
||||
uint32 Armor;
|
||||
uint32 HolyRes;
|
||||
uint32 FireRes;
|
||||
uint32 NatureRes;
|
||||
uint32 FrostRes;
|
||||
uint32 ShadowRes;
|
||||
uint32 ArcaneRes;
|
||||
uint32 Delay;
|
||||
uint32 AmmoType;
|
||||
float RangedModRange;
|
||||
_Spell Spells[MAX_ITEM_PROTO_SPELLS];
|
||||
uint32 Bonding;
|
||||
char* Description;
|
||||
uint32 PageText;
|
||||
uint32 LanguageID;
|
||||
uint32 PageMaterial;
|
||||
uint32 StartQuest; // id from QuestCache.wdb
|
||||
uint32 LockID;
|
||||
int32 Material; // id from Material.dbc
|
||||
uint32 Sheath;
|
||||
int32 RandomProperty; // id from ItemRandomProperties.dbc
|
||||
int32 RandomSuffix; // id from ItemRandomSuffix.dbc
|
||||
uint32 Block;
|
||||
uint32 ItemSet; // id from ItemSet.dbc
|
||||
uint32 MaxDurability;
|
||||
uint32 Area; // id from AreaTable.dbc
|
||||
uint32 Map; // id from Map.dbc
|
||||
uint32 BagFamily; // bit mask (1 << id from ItemBagFamily.dbc)
|
||||
uint32 TotemCategory; // id from TotemCategory.dbc
|
||||
_Socket Socket[MAX_ITEM_PROTO_SOCKETS];
|
||||
uint32 socketBonus; // id from SpellItemEnchantment.dbc
|
||||
uint32 GemProperties; // id from GemProperties.dbc
|
||||
uint32 RequiredDisenchantSkill;
|
||||
float ArmorDamageModifier;
|
||||
int32 Duration; // negative = realtime, positive = ingame time
|
||||
uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
|
||||
uint32 HolidayId; // id from Holidays.dbc
|
||||
uint32 ScriptId;
|
||||
uint32 DisenchantID;
|
||||
uint32 FoodType;
|
||||
uint32 MinMoneyLoot;
|
||||
uint32 MaxMoneyLoot;
|
||||
|
||||
// helpers
|
||||
bool CanChangeEquipStateInCombat() const
|
||||
{
|
||||
switch(InventoryType)
|
||||
{
|
||||
case INVTYPE_RELIC:
|
||||
case INVTYPE_SHIELD:
|
||||
case INVTYPE_HOLDABLE:
|
||||
return true;
|
||||
}
|
||||
|
||||
switch(Class)
|
||||
{
|
||||
case ITEM_CLASS_WEAPON:
|
||||
case ITEM_CLASS_PROJECTILE:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetMaxStackSize() const
|
||||
{
|
||||
return (Stackable == 2147483647 || Stackable <= 0 || Stackable == 1000) ? uint32(0x7FFFFFFF-1) : uint32(Stackable);
|
||||
}
|
||||
|
||||
float getDPS() const
|
||||
{
|
||||
if (Delay == 0)
|
||||
return 0;
|
||||
float temp = 0;
|
||||
for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||
temp+=Damage[i].DamageMin + Damage[i].DamageMax;
|
||||
return temp*500/Delay;
|
||||
}
|
||||
|
||||
int32 getFeralBonus(int32 extraDPS = 0) const
|
||||
{
|
||||
// 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc
|
||||
if (Class == ITEM_CLASS_WEAPON && (1<<SubClass)&0x02A5F3)
|
||||
{
|
||||
int32 bonus = int32((extraDPS + getDPS())*14.0f) - 767;
|
||||
if (bonus < 0)
|
||||
return 0;
|
||||
return bonus;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; }
|
||||
bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; }
|
||||
bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; }
|
||||
bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAGS_CONJURED); }
|
||||
};
|
||||
|
||||
struct ItemLocale
|
||||
{
|
||||
std::vector<std::string> Name;
|
||||
std::vector<std::string> Description;
|
||||
};
|
||||
|
||||
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
|
||||
#if defined(__GNUC__)
|
||||
#pragma pack()
|
||||
#else
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user