aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none>2009-02-15 11:58:27 -0600
committermegamage <none@none>2009-02-15 11:58:27 -0600
commit97ac3aba05cfc56c6c8a7c5dbfb7071b02239181 (patch)
tree283dc5898154b7b1654e193657d32ea1f94bdfcf /src
parent419b74952002c0605ca829227f55a6354d8bd1c8 (diff)
Implemented limit category check for item/gem at equip or gem inserting. Author: VladimirMangos
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/game/Item.cpp27
-rw-r--r--src/game/Item.h1
-rw-r--r--src/game/ItemHandler.cpp94
-rw-r--r--src/game/ObjectMgr.cpp8
-rw-r--r--src/game/Player.cpp160
-rw-r--r--src/game/Player.h6
-rw-r--r--src/shared/Database/DBCStores.cpp4
-rw-r--r--src/shared/Database/DBCStores.h1
-rw-r--r--src/shared/Database/DBCStructure.h9
-rw-r--r--src/shared/Database/DBCfmt.cpp1
10 files changed, 245 insertions, 66 deletions
diff --git a/src/game/Item.cpp b/src/game/Item.cpp
index e8280711143..2cb1fe3caa4 100644
--- a/src/game/Item.cpp
+++ b/src/game/Item.cpp
@@ -806,7 +806,7 @@ void Item::ClearEnchantment(EnchantmentSlot slot)
bool Item::GemsFitSockets() const
{
bool fits = true;
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
{
uint8 SocketColor = GetProto()->Socket[enchant_slot-SOCK_ENCHANTMENT_SLOT].Color;
@@ -846,7 +846,7 @@ bool Item::GemsFitSockets() const
uint8 Item::GetGemCountWithID(uint32 GemID) const
{
uint8 count = 0;
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
{
uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
if(!enchant_id)
@@ -862,6 +862,29 @@ uint8 Item::GetGemCountWithID(uint32 GemID) const
return count;
}
+uint8 Item::GetGemCountWithLimitCategory(uint32 limitCategory) const
+{
+ uint8 count = 0;
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
+ {
+ uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
+ if(!enchant_id)
+ continue;
+
+ SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!enchantEntry)
+ continue;
+
+ ItemPrototype const* gemProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID);
+ if(!gemProto)
+ continue;
+
+ if(gemProto->ItemLimitCategory==limitCategory)
+ ++count;
+ }
+ return count;
+}
+
bool Item::IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const
{
ItemPrototype const* proto = GetProto();
diff --git a/src/game/Item.h b/src/game/Item.h
index 8869f2ac013..4f901302105 100644
--- a/src/game/Item.h
+++ b/src/game/Item.h
@@ -236,6 +236,7 @@ class TRINITY_DLL_SPEC Item : public Object
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 GetSlot() const {return m_slot;}
Bag *GetContainer() { return m_container; }
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 6b896e502f9..522539b6bab 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -1186,41 +1186,91 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
// check unique-equipped conditions
for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
{
- if (Gems[i] && (Gems[i]->GetProto()->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED))
+ if(!Gems[i])
+ continue;
+
+ // continue check for case when attempt add 2 similar unique equipped gems in one item.
+ ItemPrototype const* iGemProto = Gems[i]->GetProto();
+
+ // unique item (for new and already placed bit removed enchantments
+ if (iGemProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
{
- // for equipped item check all equipment for duplicate equipped gems
- if(itemTarget->IsEquipped())
+ for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
{
- if(GetPlayer()->GetItemOrItemWithGemEquipped(Gems[i]->GetEntry()))
+ if(i==j) // skip self
+ continue;
+
+ if (Gems[j])
{
- _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE, itemTarget, NULL );
- return;
+ if (iGemProto->ItemId == Gems[j]->GetEntry())
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
+ return;
+ }
+ }
+ else if(OldEnchants[j])
+ {
+ if(SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
+ {
+ if (iGemProto->ItemId == enchantEntry->GemID)
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
+ return;
+ }
+ }
}
+
}
+ }
- // continue check for case when attempt add 2 similar unique equipped gems in one item.
- for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
+ // unique limit type item
+ int32 limit_newcount = 0;
+ if (iGemProto->ItemLimitCategory)
+ {
+ if(ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->ItemLimitCategory))
{
- if ((i != j) && (Gems[j]) && (Gems[i]->GetProto()->ItemId == Gems[j]->GetProto()->ItemId))
+ for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
+ {
+ if (Gems[j])
+ {
+ // destroyed gem
+ if (OldEnchants[j])
+ {
+ if(SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
+ if(ItemPrototype const* jProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID))
+ if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
+ --limit_newcount;
+ }
+
+ // new gem
+ if (iGemProto->ItemLimitCategory == Gems[j]->GetProto()->ItemLimitCategory)
+ ++limit_newcount;
+ }
+ // existed gem
+ else if(OldEnchants[j])
+ {
+ if(SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
+ if(ItemPrototype const* jProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID))
+ if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
+ ++limit_newcount;
+ }
+ }
+
+ if(limit_newcount > 0 && uint32(limit_newcount) > limitEntry->maxCount)
{
_player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
return;
}
}
- for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
- {
- if (OldEnchants[j])
- {
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]);
- if(!enchantEntry)
- continue;
+ }
- if ((enchantEntry->GemID == Gems[i]->GetProto()->ItemId) && (i != j))
- {
- _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
- return;
- }
- }
+ // for equipped item check all equipment for duplicate equipped gems
+ if(itemTarget->IsEquipped())
+ {
+ if(uint8 res = _player->CanEquipUniqueItem(Gems[i],slot,limit_newcount >= 0 ? limit_newcount : 0))
+ {
+ _player->SendEquipError( res, itemTarget, NULL );
+ return;
}
}
}
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index a981e06bc31..32be0e9ca41 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -1777,6 +1777,12 @@ void ObjectMgr::LoadItemPrototypes()
sLog.outErrorDb("Item (Entry: %u) has wrong FoodType value (%u)",i,proto->FoodType);
const_cast<ItemPrototype*>(proto)->FoodType = 0;
}
+
+ if(proto->ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(proto->ItemLimitCategory))
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong LimitCategory value (%u)",i,proto->ItemLimitCategory);
+ const_cast<ItemPrototype*>(proto)->ItemLimitCategory = 0;
+ }
}
}
@@ -6668,7 +6674,7 @@ bool PlayerCondition::Meets(Player const * player) const
case CONDITION_ITEM:
return player->HasItemCount(value1, value2);
case CONDITION_ITEM_EQUIPPED:
- return player->GetItemOrItemWithGemEquipped(value1) != NULL;
+ return player->HasItemOrGemWithIdEquipped(value1,1);
case CONDITION_ZONEID:
return player->GetZoneId() == value1;
case CONDITION_REPUTATION_RANK:
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 123b9dd6057..4a68b6539c8 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -9099,31 +9099,76 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const
return false;
}
-Item* Player::GetItemOrItemWithGemEquipped( uint32 item ) const
+bool Player::HasItemOrGemWithIdEquipped( uint32 item, uint32 count, uint8 except_slot ) const
{
- Item *pItem;
- for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
+ uint32 tempcount = 0;
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetEntry() == item )
- return pItem;
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if( pItem && pItem->GetEntry() == item)
+ {
+ tempcount += pItem->GetCount();
+ if( tempcount >= count )
+ return true;
+ }
}
ItemPrototype const *pProto = objmgr.GetItemPrototype(item);
if (pProto && pProto->GemProperties)
{
- for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetProto()->Socket[0].Color )
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if( pItem && pItem->GetProto()->Socket[0].Color)
{
- if (pItem->GetGemCountWithID(item) > 0 )
- return pItem;
+ tempcount += pItem->GetGemCountWithID(item);
+ if( tempcount >= count )
+ return true;
}
}
}
- return NULL;
+ return false;
+}
+
+bool Player::HasItemOrGemWithLimitCategoryEquipped( uint32 limitCategory, uint32 count, uint8 except_slot ) const
+{
+ uint32 tempcount = 0;
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
+ {
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if (!pItem)
+ continue;
+
+ ItemPrototype const *pProto = pItem->GetProto();
+ if (!pProto)
+ continue;
+
+ if (pProto->ItemLimitCategory == limitCategory)
+ {
+ tempcount += pItem->GetCount();
+ if( tempcount >= count )
+ return true;
+ }
+
+ if( pProto->Socket[0].Color)
+ {
+ tempcount += pItem->GetGemCountWithLimitCategory(limitCategory);
+ if( tempcount >= count )
+ return true;
+ }
+ }
+
+ return false;
}
uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count ) const
@@ -10210,33 +10255,9 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if( !swap && GetItemByPos( INVENTORY_SLOT_BAG_0, eslot ) )
return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE;
- // check unique-equipped on item
- if (pProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
- {
- // there is an equip limit on this item
- Item* tItem = GetItemOrItemWithGemEquipped(pProto->ItemId);
- if (tItem && (!swap || tItem->GetSlot() != eslot ) )
- return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
- }
-
- // check unique-equipped on gems
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
- {
- uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if(!enchant_id)
- continue;
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if(!enchantEntry)
- continue;
-
- ItemPrototype const* pGem = objmgr.GetItemPrototype(enchantEntry->GemID);
- if(pGem && (pGem->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED))
- {
- Item* tItem = GetItemOrItemWithGemEquipped(enchantEntry->GemID);
- if(tItem && (!swap || tItem->GetSlot() != eslot ))
- return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
- }
- }
+ // if swap ignore item (equipped also)
+ if(uint8 res = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT))
+ return res;
// check unique-equipped special item classes
if (pProto->Class == ITEM_CLASS_QUIVER)
@@ -20373,3 +20394,64 @@ uint32 Player::GetPhaseMaskForSpawn() const
return PHASEMASK_NORMAL;
}
+
+uint8 Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const
+{
+ ItemPrototype const* pProto = pItem->GetProto();
+
+ // proto based limitations
+ if(uint8 res = CanEquipUniqueItem(pProto,eslot,limit_count))
+ return res;
+
+ // check unique-equipped on gems
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ {
+ uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot));
+ if(!enchant_id)
+ continue;
+ SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!enchantEntry)
+ continue;
+
+ ItemPrototype const* pGem = objmgr.GetItemPrototype(enchantEntry->GemID);
+ if(!pGem)
+ continue;
+
+ // include for check equip another gems with same limit category for not equipped item (and then not counted)
+ uint32 gem_limit_count = !pItem->IsEquipped() && pGem->ItemLimitCategory
+ ? pItem->GetGemCountWithLimitCategory(pGem->ItemLimitCategory) : 1;
+
+ if(uint8 res = CanEquipUniqueItem(pGem, eslot,gem_limit_count))
+ return res;
+ }
+
+ return EQUIP_ERR_OK;
+}
+
+uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_slot, uint32 limit_count) const
+{
+ // check unique-equipped on item
+ if (itemProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
+ {
+ // there is an equip limit on this item
+ if(HasItemOrGemWithIdEquipped(itemProto->ItemId,1,except_slot))
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+ }
+
+ // check unique-equipped limit
+ if (itemProto->ItemLimitCategory)
+ {
+ ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(itemProto->ItemLimitCategory);
+ if(!limitEntry)
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+
+ if(limit_count > limitEntry->maxCount)
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE; // attempt add too many limit category items (gems)
+
+ // there is an equip limit on this item
+ if(HasItemOrGemWithLimitCategoryEquipped(itemProto->ItemLimitCategory,limitEntry->maxCount-limit_count+1,except_slot))
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+ }
+
+ return EQUIP_ERR_OK;
+}
diff --git a/src/game/Player.h b/src/game/Player.h
index dbcfcd558ac..bfc99bb1cd1 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1084,7 +1084,8 @@ class TRINITY_DLL_SPEC Player : public Unit
bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const;
bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL);
bool CanNoReagentCast(SpellEntry const* spellInfo) const;
- Item* GetItemOrItemWithGemEquipped( uint32 item ) const;
+ bool HasItemOrGemWithIdEquipped( uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const;
+ bool HasItemOrGemWithLimitCategoryEquipped( uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const;
uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); }
uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); }
uint8 CanStoreNewItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL ) const
@@ -1102,6 +1103,9 @@ class TRINITY_DLL_SPEC Player : public Unit
uint8 CanStoreItems( Item **pItem,int count) const;
uint8 CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, bool swap ) const;
uint8 CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading = true ) const;
+
+ uint8 CanEquipUniqueItem( Item * pItem, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1 ) const;
+ uint8 CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1 ) const;
uint8 CanUnequipItems( uint32 item, uint32 count ) const;
uint8 CanUnequipItem( uint16 src, bool swap ) const;
uint8 CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, Item *pItem, bool swap, bool not_loading = true ) const;
diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp
index b4fb79f2dd0..6e49a344b1a 100644
--- a/src/shared/Database/DBCStores.cpp
+++ b/src/shared/Database/DBCStores.cpp
@@ -81,6 +81,7 @@ DBCStorage <ItemEntry> sItemStore(Itemfmt);
//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
//DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently
DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt);
+DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt);
DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt);
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
@@ -194,7 +195,7 @@ void LoadDBCStores(const std::string& dataPath)
{
std::string dbcPath = dataPath+"dbc/";
- const uint32 DBCFilesCount = 71;
+ const uint32 DBCFilesCount = 72;
barGoLink bar( DBCFilesCount );
@@ -271,6 +272,7 @@ void LoadDBCStores(const std::string& dataPath)
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc");
diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h
index 6aec6db3bed..4a67164a773 100644
--- a/src/shared/Database/DBCStores.h
+++ b/src/shared/Database/DBCStores.h
@@ -172,6 +172,7 @@ extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
extern DBCStorage <ItemEntry> sItemStore;
//extern DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore; -- not used currently
extern DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore;
+extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
extern DBCStorage <ItemSetEntry> sItemSetStore;
diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h
index 86079fb417a..4be24d9e24b 100644
--- a/src/shared/Database/DBCStructure.h
+++ b/src/shared/Database/DBCStructure.h
@@ -877,6 +877,15 @@ struct ItemExtendedCostEntry
uint32 reqpersonalarenarating; // 13 required personal arena rating
};
+struct ItemLimitCategoryEntry
+{
+ uint32 ID; // 0 Id
+ //char* name[16] // 1-16 m_name_lang
+ // 17 name flags
+ uint32 maxCount; // max allowed equipped as item or in gem slot
+ //uint32 unk; // 1 for prismatic gems only...
+};
+
struct ItemRandomPropertiesEntry
{
uint32 ID; // 0 m_ID
diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp
index 481303406b1..0420c2b9a85 100644
--- a/src/shared/Database/DBCfmt.cpp
+++ b/src/shared/Database/DBCfmt.cpp
@@ -59,6 +59,7 @@ const char Itemfmt[]="nixiiiii";
//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
//const char ItemCondExtCostsEntryfmt[]="xiii";
const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix";
+const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxix";
const char ItemRandomPropertiesfmt[]="nxiiiiixxxxxxxxxxxxxxxxx";
const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiiiiiii";
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";