mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Items: Implemented ItemLimitCategoryCondition.db2 (#21835)
This commit is contained in:
12
sql/updates/hotfixes/master/2018_04_18_00_hotfixes.sql
Normal file
12
sql/updates/hotfixes/master/2018_04_18_00_hotfixes.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
--
|
||||
-- Table structure for table `item_limit_category_condition`
|
||||
--
|
||||
DROP TABLE IF EXISTS `item_limit_category_condition`;
|
||||
CREATE TABLE `item_limit_category_condition` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`AddQuantity` tinyint(3) NOT NULL DEFAULT '0',
|
||||
`PlayerConditionID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`ParentItemLimitCategoryID` int(10) NOT NULL DEFAULT '0',
|
||||
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
@@ -513,6 +513,10 @@ void HotfixDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(HOTFIX_SEL_ITEM_LIMIT_CATEGORY, "SELECT ID, Name, Quantity, Flags FROM item_limit_category ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_LIMIT_CATEGORY, "SELECT ID, Name_lang FROM item_limit_category_locale WHERE locale = ?", CONNECTION_SYNCH);
|
||||
|
||||
// ItemLimitCategoryCondition.db2
|
||||
PrepareStatement(HOTFIX_SEL_ITEM_LIMIT_CATEGORY_CONDITION, "SELECT ID, AddQuantity, PlayerConditionID, ParentItemLimitCategoryID "
|
||||
" FROM item_limit_category_condition ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
// ItemModifiedAppearance.db2
|
||||
PrepareStatement(HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE, "SELECT ItemID, ID, ItemAppearanceModifierID, ItemAppearanceID, OrderIndex, "
|
||||
"TransmogSourceTypeEnum FROM item_modified_appearance ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
@@ -281,6 +281,8 @@ enum HotfixDatabaseStatements : uint32
|
||||
HOTFIX_SEL_ITEM_LIMIT_CATEGORY,
|
||||
HOTFIX_SEL_ITEM_LIMIT_CATEGORY_LOCALE,
|
||||
|
||||
HOTFIX_SEL_ITEM_LIMIT_CATEGORY_CONDITION,
|
||||
|
||||
HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE,
|
||||
|
||||
HOTFIX_SEL_ITEM_PRICE_BASE,
|
||||
|
||||
@@ -2427,6 +2427,22 @@ struct ItemLimitCategoryLoadInfo
|
||||
}
|
||||
};
|
||||
|
||||
struct ItemLimitCategoryConditionLoadInfo
|
||||
{
|
||||
static DB2LoadInfo const* Instance()
|
||||
{
|
||||
static DB2FieldMeta const fields[] =
|
||||
{
|
||||
{ false, FT_INT, "ID" },
|
||||
{ true, FT_BYTE, "AddQuantity" },
|
||||
{ false, FT_INT, "PlayerConditionID" },
|
||||
{ true, FT_INT, "ParentItemLimitCategoryID" },
|
||||
};
|
||||
static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, ItemLimitCategoryConditionMeta::Instance(), HOTFIX_SEL_ITEM_LIMIT_CATEGORY_CONDITION);
|
||||
return &loadInfo;
|
||||
}
|
||||
};
|
||||
|
||||
struct ItemModifiedAppearanceLoadInfo
|
||||
{
|
||||
static DB2LoadInfo const* Instance()
|
||||
|
||||
@@ -144,6 +144,7 @@ DB2Storage<ItemLevelSelectorEntry> sItemLevelSelectorStore("ItemLev
|
||||
DB2Storage<ItemLevelSelectorQualityEntry> sItemLevelSelectorQualityStore("ItemLevelSelectorQuality.db2", ItemLevelSelectorQualityLoadInfo::Instance());
|
||||
DB2Storage<ItemLevelSelectorQualitySetEntry> sItemLevelSelectorQualitySetStore("ItemLevelSelectorQualitySet.db2", ItemLevelSelectorQualitySetLoadInfo::Instance());
|
||||
DB2Storage<ItemLimitCategoryEntry> sItemLimitCategoryStore("ItemLimitCategory.db2", ItemLimitCategoryLoadInfo::Instance());
|
||||
DB2Storage<ItemLimitCategoryConditionEntry> sItemLimitCategoryConditionStore("ItemLimitCategoryCondition.db2", ItemLimitCategoryConditionLoadInfo::Instance());
|
||||
DB2Storage<ItemModifiedAppearanceEntry> sItemModifiedAppearanceStore("ItemModifiedAppearance.db2", ItemModifiedAppearanceLoadInfo::Instance());
|
||||
DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore("ItemPriceBase.db2", ItemPriceBaseLoadInfo::Instance());
|
||||
DB2Storage<ItemRandomPropertiesEntry> sItemRandomPropertiesStore("ItemRandomProperties.db2", ItemRandomPropertiesLoadInfo::Instance());
|
||||
@@ -301,6 +302,7 @@ typedef std::unordered_map<int16, uint32> ItemBonusListLevelDeltaContainer;
|
||||
typedef std::unordered_multimap<uint32 /*itemId*/, uint32 /*bonusTreeId*/> ItemToBonusTreeContainer;
|
||||
typedef std::unordered_map<uint32 /*itemId*/, ItemChildEquipmentEntry const*> ItemChildEquipmentContainer;
|
||||
typedef std::array<ItemClassEntry const*, 19> ItemClassByOldEnumContainer;
|
||||
typedef std::unordered_map<uint32, std::vector<ItemLimitCategoryConditionEntry const*>> ItemLimitCategoryConditionContainer;
|
||||
typedef std::set<ItemLevelSelectorQualityEntry const*, ItemLevelSelectorQualityEntryComparator> ItemLevelSelectorQualities;
|
||||
typedef std::unordered_map<uint32 /*itemId | appearanceMod << 24*/, ItemModifiedAppearanceEntry const*> ItemModifiedAppearanceByItemContainer;
|
||||
typedef std::unordered_map<uint32, std::set<ItemBonusTreeNodeEntry const*>> ItemBonusTreeContainer;
|
||||
@@ -353,6 +355,7 @@ namespace
|
||||
ItemChildEquipmentContainer _itemChildEquipment;
|
||||
ItemClassByOldEnumContainer _itemClassByOldEnum;
|
||||
std::unordered_set<uint32> _itemsWithCurrencyCost;
|
||||
ItemLimitCategoryConditionContainer _itemCategoryConditions;
|
||||
std::unordered_map<uint32 /*itemLevelSelectorQualitySetId*/, ItemLevelSelectorQualities> _itemLevelQualitySelectorQualities;
|
||||
ItemModifiedAppearanceByItemContainer _itemModifiedAppearancesByItem;
|
||||
ItemToBonusTreeContainer _itemToBonusTree;
|
||||
@@ -578,6 +581,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
|
||||
LOAD_DB2(sItemLevelSelectorQualityStore);
|
||||
LOAD_DB2(sItemLevelSelectorQualitySetStore);
|
||||
LOAD_DB2(sItemLimitCategoryStore);
|
||||
LOAD_DB2(sItemLimitCategoryConditionStore);
|
||||
LOAD_DB2(sItemModifiedAppearanceStore);
|
||||
LOAD_DB2(sItemPriceBaseStore);
|
||||
LOAD_DB2(sItemRandomPropertiesStore);
|
||||
@@ -861,6 +865,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
|
||||
for (ItemCurrencyCostEntry const* itemCurrencyCost : sItemCurrencyCostStore)
|
||||
_itemsWithCurrencyCost.insert(itemCurrencyCost->ItemID);
|
||||
|
||||
for (ItemLimitCategoryConditionEntry const* condition : sItemLimitCategoryConditionStore)
|
||||
_itemCategoryConditions[condition->ParentItemLimitCategoryID].push_back(condition);
|
||||
|
||||
for (ItemLevelSelectorQualityEntry const* itemLevelSelectorQuality : sItemLevelSelectorQualityStore)
|
||||
_itemLevelQualitySelectorQualities[itemLevelSelectorQuality->ParentILSQualitySetID].insert(itemLevelSelectorQuality);
|
||||
|
||||
@@ -1668,6 +1675,15 @@ bool DB2Manager::HasItemCurrencyCost(uint32 itemId) const
|
||||
return _itemsWithCurrencyCost.count(itemId) > 0;
|
||||
}
|
||||
|
||||
std::vector<ItemLimitCategoryConditionEntry const*> const* DB2Manager::GetItemLimitCategoryConditions(uint32 categoryId) const
|
||||
{
|
||||
auto itr = _itemCategoryConditions.find(categoryId);
|
||||
if (itr != _itemCategoryConditions.end())
|
||||
return &itr->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32 DB2Manager::GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const
|
||||
{
|
||||
if (ItemModifiedAppearanceEntry const* modifiedAppearance = GetItemModifiedAppearance(itemId, appearanceModId))
|
||||
|
||||
@@ -285,6 +285,7 @@ public:
|
||||
ItemChildEquipmentEntry const* GetItemChildEquipment(uint32 itemId) const;
|
||||
ItemClassEntry const* GetItemClassByOldEnum(uint32 itemClass) const;
|
||||
bool HasItemCurrencyCost(uint32 itemId) const;
|
||||
std::vector<ItemLimitCategoryConditionEntry const*> const* GetItemLimitCategoryConditions(uint32 categoryId) const;
|
||||
uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const;
|
||||
ItemModifiedAppearanceEntry const* GetItemModifiedAppearance(uint32 itemId, uint32 appearanceModId) const;
|
||||
ItemModifiedAppearanceEntry const* GetDefaultItemModifiedAppearance(uint32 itemId) const;
|
||||
|
||||
@@ -1500,6 +1500,14 @@ struct ItemLimitCategoryEntry
|
||||
uint8 Flags;
|
||||
};
|
||||
|
||||
struct ItemLimitCategoryConditionEntry
|
||||
{
|
||||
uint32 ID;
|
||||
int8 AddQuantity;
|
||||
uint32 PlayerConditionID;
|
||||
int32 ParentItemLimitCategoryID;
|
||||
};
|
||||
|
||||
struct ItemModifiedAppearanceEntry
|
||||
{
|
||||
int32 ItemID;
|
||||
|
||||
@@ -10190,11 +10190,12 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
|
||||
|
||||
if (limitEntry->Flags == ITEM_LIMIT_CATEGORY_MODE_HAVE)
|
||||
{
|
||||
uint8 limitQuantity = GetItemLimitCategoryQuantity(limitEntry);
|
||||
uint32 curcount = GetItemCountWithLimitCategory(pProto->GetItemLimitCategory(), pItem);
|
||||
if (curcount + count > uint32(limitEntry->Quantity))
|
||||
if (curcount + count > uint32(limitQuantity))
|
||||
{
|
||||
if (no_space_count)
|
||||
*no_space_count = count + curcount - limitEntry->Quantity;
|
||||
*no_space_count = count + curcount - limitQuantity;
|
||||
if (offendingItemId)
|
||||
*offendingItemId = pProto->GetId();
|
||||
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS;
|
||||
@@ -25979,14 +25980,15 @@ InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8
|
||||
return EQUIP_ERR_NOT_EQUIPPABLE;
|
||||
|
||||
// NOTE: limitEntry->mode not checked because if item have have-limit then it applied and to equip case
|
||||
uint8 limitQuantity = GetItemLimitCategoryQuantity(limitEntry);
|
||||
|
||||
if (limit_count > limitEntry->Quantity)
|
||||
if (limit_count > limitQuantity)
|
||||
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS;
|
||||
|
||||
// there is an equip limit on this item
|
||||
if (HasItemWithLimitCategoryEquipped(itemProto->GetItemLimitCategory(), limitEntry->Quantity - limit_count + 1, except_slot))
|
||||
if (HasItemWithLimitCategoryEquipped(itemProto->GetItemLimitCategory(), limitQuantity - limit_count + 1, except_slot))
|
||||
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS;
|
||||
else if (HasGemWithLimitCategoryEquipped(itemProto->GetItemLimitCategory(), limitEntry->Quantity - limit_count + 1, except_slot))
|
||||
else if (HasGemWithLimitCategoryEquipped(itemProto->GetItemLimitCategory(), limitQuantity - limit_count + 1, except_slot))
|
||||
return EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED;
|
||||
}
|
||||
|
||||
@@ -28291,3 +28293,20 @@ void Player::UpdateItemLevelAreaBasedScaling()
|
||||
}
|
||||
// @todo other types of power scaling such as timewalking
|
||||
}
|
||||
|
||||
uint8 Player::GetItemLimitCategoryQuantity(ItemLimitCategoryEntry const* limitEntry) const
|
||||
{
|
||||
uint8 limit = limitEntry->Quantity;
|
||||
|
||||
if (std::vector<ItemLimitCategoryConditionEntry const*> const* limitConditions = sDB2Manager.GetItemLimitCategoryConditions(limitEntry->ID))
|
||||
{
|
||||
for (ItemLimitCategoryConditionEntry const* limitCondition : *limitConditions)
|
||||
{
|
||||
PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(limitCondition->PlayerConditionID);
|
||||
if (!playerCondition || ConditionMgr::IsPlayerMeetingCondition(this, playerCondition))
|
||||
limit += limitCondition->AddQuantity;
|
||||
}
|
||||
}
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ struct CreatureTemplate;
|
||||
struct CurrencyTypesEntry;
|
||||
struct FactionEntry;
|
||||
struct ItemExtendedCostEntry;
|
||||
struct ItemLimitCategoryEntry;
|
||||
struct ItemSetEffect;
|
||||
struct ItemTemplate;
|
||||
struct Loot;
|
||||
@@ -2223,6 +2224,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void SendMovieStart(uint32 movieId);
|
||||
|
||||
uint32 DoRandomRoll(uint32 minimum, uint32 maximum);
|
||||
uint8 GetItemLimitCategoryQuantity(ItemLimitCategoryEntry const* limitEntry) const;
|
||||
|
||||
void UpdateItemLevelAreaBasedScaling();
|
||||
void ActivatePvpItemLevels(bool activate) { _usePvpItemLevels = activate; }
|
||||
|
||||
@@ -1044,7 +1044,7 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems)
|
||||
}
|
||||
}
|
||||
|
||||
if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->Quantity)
|
||||
if (limit_newcount > 0 && uint32(limit_newcount) > _player->GetItemLimitCategoryQuantity(limitEntry))
|
||||
{
|
||||
_player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user