Core/Items: Implemented ItemLimitCategoryCondition.db2 (#21835)

This commit is contained in:
Roc13x
2018-04-18 16:41:23 +01:00
committed by Shauren
parent 3ee4c58176
commit cd5a704fc1
10 changed files with 86 additions and 6 deletions

View 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;

View File

@@ -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);

View File

@@ -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,

View File

@@ -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()

View File

@@ -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))

View File

@@ -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;

View File

@@ -1500,6 +1500,14 @@ struct ItemLimitCategoryEntry
uint8 Flags;
};
struct ItemLimitCategoryConditionEntry
{
uint32 ID;
int8 AddQuantity;
uint32 PlayerConditionID;
int32 ParentItemLimitCategoryID;
};
struct ItemModifiedAppearanceEntry
{
int32 ItemID;

View File

@@ -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;
}

View File

@@ -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; }

View File

@@ -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;