From ef05e1f113c38ddfe3c01ac45f756a3e234b3e80 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 18 Apr 2018 19:43:29 -0400 Subject: [PATCH] Core/Items: Implemented ItemLimitCategoryCondition.db2 --- .../Database/Databases/HotfixDatabase.cs | 6 +++++ Source/Game/DataStorage/CliDB.cs | 2 ++ Source/Game/DataStorage/DB2Manager.cs | 9 +++++++ Source/Game/DataStorage/Structs/I_Records.cs | 8 ++++++ Source/Game/Entities/Player/Player.Items.cs | 27 ++++++++++++++----- Source/Game/Handlers/ItemHandler.cs | 2 +- .../master/2018_04_18_00_hotfixes.sql | 12 +++++++++ 7 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 sql/updates/hotfixes/master/2018_04_18_00_hotfixes.sql diff --git a/Source/Framework/Database/Databases/HotfixDatabase.cs b/Source/Framework/Database/Databases/HotfixDatabase.cs index 44f824f0d..e609df22d 100644 --- a/Source/Framework/Database/Databases/HotfixDatabase.cs +++ b/Source/Framework/Database/Databases/HotfixDatabase.cs @@ -503,6 +503,10 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_ITEM_LIMIT_CATEGORY, "SELECT ID, Name, Quantity, Flags FROM item_limit_category ORDER BY ID DESC"); PrepareStatement(HotfixStatements.SEL_ITEM_LIMIT_CATEGORY_LOCALE, "SELECT ID, Name_lang FROM item_limit_category_locale WHERE locale = ?"); + // ItemLimitCategoryCondition.db2 + PrepareStatement(HotfixStatements.SEL_ITEM_LIMIT_CATEGORY_CONDITION, "SELECT ID, AddQuantity, PlayerConditionID, ParentItemLimitCategoryID " + + " FROM item_limit_category_condition ORDER BY ID DESC"); + // ItemModifiedAppearance.db2 PrepareStatement(HotfixStatements.SEL_ITEM_MODIFIED_APPEARANCE, "SELECT ItemID, ID, ItemAppearanceModifierID, ItemAppearanceID, OrderIndex, " + "TransmogSourceTypeEnum FROM item_modified_appearance ORDER BY ID DESC"); @@ -1305,6 +1309,8 @@ namespace Framework.Database SEL_ITEM_LIMIT_CATEGORY, SEL_ITEM_LIMIT_CATEGORY_LOCALE, + SEL_ITEM_LIMIT_CATEGORY_CONDITION, + SEL_ITEM_MODIFIED_APPEARANCE, SEL_ITEM_PRICE_BASE, diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 5cb7fb163..a23186e1f 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -144,6 +144,7 @@ namespace Game.DataStorage ItemLevelSelectorQualityStorage = DBReader.Read("ItemLevelSelectorQuality.db2", HotfixStatements.SEL_ITEM_LEVEL_SELECTOR_QUALITY); ItemLevelSelectorQualitySetStorage = DBReader.Read("ItemLevelSelectorQualitySet.db2", HotfixStatements.SEL_ITEM_LEVEL_SELECTOR_QUALITY_SET); ItemLimitCategoryStorage = DBReader.Read("ItemLimitCategory.db2", HotfixStatements.SEL_ITEM_LIMIT_CATEGORY, HotfixStatements.SEL_ITEM_LIMIT_CATEGORY_LOCALE); + ItemLimitCategoryConditionStorage = DBReader.Read("ItemLimitCategoryCondition.db2", HotfixStatements.SEL_ITEM_LIMIT_CATEGORY_CONDITION); ItemModifiedAppearanceStorage = DBReader.Read("ItemModifiedAppearance.db2", HotfixStatements.SEL_ITEM_MODIFIED_APPEARANCE); ItemPriceBaseStorage = DBReader.Read("ItemPriceBase.db2", HotfixStatements.SEL_ITEM_PRICE_BASE); ItemRandomPropertiesStorage = DBReader.Read("ItemRandomProperties.db2", HotfixStatements.SEL_ITEM_RANDOM_PROPERTIES, HotfixStatements.SEL_ITEM_RANDOM_PROPERTIES_LOCALE); @@ -476,6 +477,7 @@ namespace Game.DataStorage public static DB6Storage ItemLevelSelectorQualityStorage; public static DB6Storage ItemLevelSelectorQualitySetStorage; public static DB6Storage ItemLimitCategoryStorage; + public static DB6Storage ItemLimitCategoryConditionStorage; public static DB6Storage ItemModifiedAppearanceStorage; public static DB6Storage ItemPriceBaseStorage; public static DB6Storage ItemRandomPropertiesStorage; diff --git a/Source/Game/DataStorage/DB2Manager.cs b/Source/Game/DataStorage/DB2Manager.cs index 266e1d01b..40fda7423 100644 --- a/Source/Game/DataStorage/DB2Manager.cs +++ b/Source/Game/DataStorage/DB2Manager.cs @@ -227,6 +227,9 @@ namespace Game.DataStorage CliDB.ItemCurrencyCostStorage.Clear(); + foreach (ItemLimitCategoryConditionRecord condition in CliDB.ItemLimitCategoryConditionStorage.Values) + _itemCategoryConditions.Add((uint)condition.ParentItemLimitCategoryID, condition); + foreach (ItemLevelSelectorQualityRecord itemLevelSelectorQuality in CliDB.ItemLevelSelectorQualityStorage.Values) _itemLevelQualitySelectorQualities.Add(itemLevelSelectorQuality.ParentILSQualitySetID, itemLevelSelectorQuality); @@ -944,6 +947,11 @@ namespace Game.DataStorage return _itemClassByOldEnum[(int)itemClass]; } + public List GetItemLimitCategoryConditions(uint categoryId) + { + return _itemCategoryConditions.LookupByKey(categoryId); + } + public uint GetItemDisplayId(uint itemId, uint appearanceModId) { ItemModifiedAppearanceRecord modifiedAppearance = GetItemModifiedAppearance(itemId, appearanceModId); @@ -1511,6 +1519,7 @@ namespace Game.DataStorage Dictionary _itemChildEquipment = new Dictionary(); Array _itemClassByOldEnum = new Array(19); List _itemsWithCurrencyCost = new List(); + MultiMap _itemCategoryConditions = new MultiMap(); MultiMap _itemLevelQualitySelectorQualities = new MultiMap(); Dictionary _itemModifiedAppearancesByItem = new Dictionary(); MultiMap _itemToBonusTree = new MultiMap(); diff --git a/Source/Game/DataStorage/Structs/I_Records.cs b/Source/Game/DataStorage/Structs/I_Records.cs index 6f3d407a1..078e494d1 100644 --- a/Source/Game/DataStorage/Structs/I_Records.cs +++ b/Source/Game/DataStorage/Structs/I_Records.cs @@ -233,6 +233,14 @@ namespace Game.DataStorage public byte Flags; } + public sealed class ItemLimitCategoryConditionRecord + { + public uint Id; + public sbyte AddQuantity; + public uint PlayerConditionID; + public int ParentItemLimitCategoryID; + } + public sealed class ItemModifiedAppearanceRecord { public uint ItemID; diff --git a/Source/Game/Entities/Player/Player.Items.cs b/Source/Game/Entities/Player/Player.Items.cs index ea0cc5b18..27c9083d3 100644 --- a/Source/Game/Entities/Player/Player.Items.cs +++ b/Source/Game/Entities/Player/Player.Items.cs @@ -1375,7 +1375,6 @@ namespace Game.Entities // check unique-equipped limit if (pProto.GetItemLimitCategory() != 0) { - ItemLimitCategoryRecord limitEntry = CliDB.ItemLimitCategoryStorage.LookupByKey(pProto.GetItemLimitCategory()); if (limitEntry == null) { @@ -1385,10 +1384,11 @@ namespace Game.Entities if (limitEntry.Flags == 0) { + byte limitQuantity = GetItemLimitCategoryQuantity(limitEntry); uint curcount = GetItemCountWithLimitCategory(pProto.GetItemLimitCategory(), pItem); - if (curcount + count > limitEntry.Quantity) + if (curcount + count > limitQuantity) { - no_space_count = count + curcount - limitEntry.Quantity; + no_space_count = count + curcount - limitQuantity; offendingItemId = pProto.GetId(); return InventoryResult.ItemMaxLimitCategoryCountExceededIs; } @@ -3221,6 +3221,20 @@ namespace Game.Entities return count; } + public byte GetItemLimitCategoryQuantity(ItemLimitCategoryRecord limitEntry) + { + byte limit = limitEntry.Quantity; + + var limitConditions = Global.DB2Mgr.GetItemLimitCategoryConditions(limitEntry.Id); + foreach (ItemLimitCategoryConditionRecord limitCondition in limitConditions) + { + PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(limitCondition.PlayerConditionID); + if (playerCondition == null || ConditionManager.IsPlayerMeetingCondition(this, playerCondition)) + limit += (byte)limitCondition.AddQuantity; + } + + return limit; + } public void DestroyConjuredItems(bool update) { @@ -5340,14 +5354,15 @@ namespace Game.Entities return InventoryResult.NotEquippable; // NOTE: limitEntry.mode not checked because if item have have-limit then it applied and to equip case + byte limitQuantity = GetItemLimitCategoryQuantity(limitEntry); - if (limit_count > limitEntry.Quantity) + if (limit_count > limitQuantity) return InventoryResult.ItemMaxLimitCategoryEquippedExceededIs; // 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 InventoryResult.ItemMaxLimitCategoryEquippedExceededIs; - else if (HasGemWithLimitCategoryEquipped(itemProto.GetItemLimitCategory(), limitEntry.Quantity - limit_count + 1, except_slot)) + else if (HasGemWithLimitCategoryEquipped(itemProto.GetItemLimitCategory(), limitQuantity - limit_count + 1, except_slot)) return InventoryResult.ItemMaxCountEquippedSocketed; } diff --git a/Source/Game/Handlers/ItemHandler.cs b/Source/Game/Handlers/ItemHandler.cs index 8c03a601b..93727baa3 100644 --- a/Source/Game/Handlers/ItemHandler.cs +++ b/Source/Game/Handlers/ItemHandler.cs @@ -903,7 +903,7 @@ namespace Game } } - if (limit_newcount > 0 && limit_newcount > limitEntry.Quantity) + if (limit_newcount > 0 && limit_newcount > _player.GetItemLimitCategoryQuantity(limitEntry)) { GetPlayer().SendEquipError(InventoryResult.ItemUniqueEquippableSocketed, itemTarget); return; diff --git a/sql/updates/hotfixes/master/2018_04_18_00_hotfixes.sql b/sql/updates/hotfixes/master/2018_04_18_00_hotfixes.sql new file mode 100644 index 000000000..669723989 --- /dev/null +++ b/sql/updates/hotfixes/master/2018_04_18_00_hotfixes.sql @@ -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;