diff options
author | Roc13x <roc13x@gmail.com> | 2018-04-18 16:41:23 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2018-04-18 18:41:23 +0300 |
commit | cd5a704fc1629d5f606535b3756195fb311b5ef2 (patch) | |
tree | 9c547af43db7b5c20156ffc2a9034cbb4ff9e850 /src | |
parent | 3ee4c58176e85d461d9f9fd8dacd11a216a57783 (diff) |
Core/Items: Implemented ItemLimitCategoryCondition.db2 (#21835)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.cpp | 4 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2LoadInfo.h | 16 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 16 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 1 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 29 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 2 |
9 files changed, 74 insertions, 6 deletions
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp index 2eb4beb7a32..73f48f1285a 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp @@ -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); diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index bb56844ddae..42e65d96261 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -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, diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h index 244bfa1a685..c0f6a4a7452 100644 --- a/src/server/game/DataStores/DB2LoadInfo.h +++ b/src/server/game/DataStores/DB2LoadInfo.h @@ -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() diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 0dee96c82ce..3d5ec4531af 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -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)) diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 35b0456ea4a..a7b070d5492 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -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; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 02d458d6de1..915a88b9c4f 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -1500,6 +1500,14 @@ struct ItemLimitCategoryEntry uint8 Flags; }; +struct ItemLimitCategoryConditionEntry +{ + uint32 ID; + int8 AddQuantity; + uint32 PlayerConditionID; + int32 ParentItemLimitCategoryID; +}; + struct ItemModifiedAppearanceEntry { int32 ItemID; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ae12ddc303d..27db6496e84 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -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; +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ebe275a0f0a..7c161440207 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -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; } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 50ff418d108..ce83e861e6d 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -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; |