From 7d6f5b0b4a95f8eab111a017cbafb19d70983f43 Mon Sep 17 00:00:00 2001 From: higurush Date: Fri, 4 Jun 2021 00:55:20 +0200 Subject: [PATCH 01/11] Add Stat Filter --- AtlasLoot/Core/Search.lua | 215 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index 13588ba..bffec9d 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -11,6 +11,125 @@ local modules = { "AtlasLoot_BurningCrusade", "AtlasLoot_Crafting", "AtlasLoot_O local currentPage = 1; local SearchResult = nil; +-- Supported Operators +local BINARYOPERATORS = { "&" }; +local OPERATORS = { "<>", "<=", ">=", "=", "<", ">" }; + +-- Supported Stat Filters +local STATFILTERS = { + -- Base Stats + ["stamina"] = "ITEM_MOD_STAMINA_SHORT", + ["stam"] = "ITEM_MOD_STAMINA_SHORT", + ["sta"] = "ITEM_MOD_STAMINA_SHORT", + + ["strength"] = "ITEM_MOD_STRENGTH_SHORT", + ["str"] = "ITEM_MOD_STRENGTH_SHORT", + + ["agility"] = "ITEM_MOD_AGILITY_SHORT", + ["agi"] = "ITEM_MOD_AGILITY_SHORT", + + ["intellect"] = "ITEM_MOD_INTELLECT_SHORT", + ["int"] = "ITEM_MOD_INTELLECT_SHORT", + + ["spirit"] = "ITEM_MOD_SPIRIT_SHORT", + ["spir"] = "ITEM_MOD_SPIRIT_SHORT", + ["spi"] = "ITEM_MOD_SPIRIT_SHORT", + + ["health"] = "ITEM_MOD_HEALTH_SHORT", + ["mana"] = "ITEM_MOD_MANA_SHORT", + + ["mp5"] = "ITEM_MOD_POWER_REGEN0_SHORT", + ["mpr"] = "ITEM_MOD_POWER_REGEN0_SHORT", + + ["hp5"] = "ITEM_MOD_HEALTH_REGEN_SHORT", + ["hpr"] = "ITEM_MOD_HEALTH_REGEN_SHORT", + + --Sockets + ["socketblue"] = "EMPTY_SOCKET_BLUE", + ["socketred"] = "EMPTY_SOCKET_RED", + ["socketyellow"] = "EMPTY_SOCKET_YELLOW", + + ["socketmeta"] = "EMPTY_SOCKET_META", + ["meta"] = "EMPTY_SOCKET_META", + + --Secondary Stats + ["attackpowerferal"] = "ITEM_MOD_FERAL_ATTACK_POWER_SHORT", + ["attackpowferal"] = "ITEM_MOD_FERAL_ATTACK_POWER_SHORT", + ["apferal"] = "ITEM_MOD_FERAL_ATTACK_POWER_SHORT", + + ["attackpower"] = "ITEM_MOD_ATTACK_POWER_SHORT", + ["attackpow"] = "ITEM_MOD_ATTACK_POWER_SHORT", + ["ap"] = "ITEM_MOD_ATTACK_POWER_SHORT", + + ["spellpower"] = "ITEM_MOD_SPELL_POWER_SHORT", + ["spellpow"] = "ITEM_MOD_SPELL_POWER_SHORT", + ["sp"] = "ITEM_MOD_SPELL_POWER_SHORT", + + ["spellpenetration"] = "ITEM_MOD_SPELL_PENETRATION_SHORT", + ["spellpen"] = "ITEM_MOD_SPELL_PENETRATION_SHORT", + ["spp"] = "ITEM_MOD_SPELL_PENETRATION_SHORT", + + ["crit"] = "ITEM_MOD_CRIT_RATING_SHORT", + ["haste"] = "ITEM_MOD_HASTE_RATING_SHORT", + + ["hit"] = "ITEM_MOD_HIT_RATING_SHORT", + + ["armorpenetration"] = "ITEM_MOD_ARMOR_PENETRATION_RATING_SHOR", + ["armorpen"] = "ITEM_MOD_ARMOR_PENETRATION_RATING_SHOR", + ["arp"] = "ITEM_MOD_ARMOR_PENETRATION_RATING_SHOR", + + ["expertise"] = "ITEM_MOD_EXPERTISE_RATING_SHORT", + ["exp"] = "ITEM_MOD_EXPERTISE_RATING_SHORT", + + ["dps"] = "ITEM_MOD_DAMAGE_PER_SECOND_SHORT", + + ["resilience"] = "ITEM_MOD_RESILIENCE_RATING", + ["resil"] = "ITEM_MOD_RESILIENCE_RATING", + ["res"] = "ITEM_MOD_RESILIENCE_RATING", + + ["defense"] = "ITEM_MOD_DEFENSE_SKILL_RATING_SHORT", + ["def"] = "ITEM_MOD_DEFENSE_SKILL_RATING_SHORT", + + ["dodge"] = "ITEM_MOD_DODGE_RATING_SHORT", + ["dod"] = "ITEM_MOD_DODGE_RATING_SHORT", + + ["block"] = "ITEM_MOD_BLOCK_RATING_SHORT", + + ["blockvalue"] = "ITEM_MOD_BLOCK_VALUE_SHORT", + ["blockval"] = "ITEM_MOD_BLOCK_VALUE_SHORT", + ["bv"] = "ITEM_MOD_BLOCK_VALUE_SHORT", + + ["parry"] = "ITEM_MOD_PARRY_RATING_SHORT", + + --Resistances + ["armor"] = "RESISTANCE0_NAME", + ["arm"] = "RESISTANCE0_NAME", + ["resistancephysical"] = "RESISTANCE0_NAME", + ["resistancephys"] = "RESISTANCE0_NAME", + ["resphys"] = "RESISTANCE0_NAME", + + ["resistanceholy"] = "RESISTANCE1_NAME", + ["resholy"] = "RESISTANCE1_NAME", + + ["resistancefire"] = "RESISTANCE2_NAME", + ["resfire"] = "RESISTANCE2_NAME", + + ["resistancenature"] = "RESISTANCE3_NAME", + ["resnature"] = "RESISTANCE3_NAME", + ["resnat"] = "RESISTANCE3_NAME", + + ["resistanceforst"] = "RESISTANCE4_NAME", + ["resfrost"] = "RESISTANCE4_NAME", + + ["resistanceshadow"] = "RESISTANCE5_NAME", + ["resshadow"] = "RESISTANCE5_NAME", + ["resshad"] = "RESISTANCE5_NAME", + + ["resistancearcane"] = "RESISTANCE6_NAME", + ["resarcane"] = "RESISTANCE6_NAME", + ["resarc"] = "RESISTANCE6_NAME", +}; + function AtlasLoot:ShowSearchResult() AtlasLoot_ShowItemsFrame("SearchResult", "SearchResultPage"..currentPage, (AL["Search Result: %s"]):format(AtlasLootCharDB.LastSearchedText or ""), pFrame); end @@ -52,12 +171,108 @@ function AtlasLoot:Search(Text) local module = AtlasLoot_GetLODModule(dataSource); if not module or self.db.profile.SearchOn[module] ~= true then return end end]] + + local function HaveBinaryOperator (textValue) + for index, operator in ipairs(BINARYOPERATORS) do + if string.find(textValue, operator) then + return operator; + end + end + return nil; + end + + local function HaveOperator (textValue) + for index, operator in ipairs(OPERATORS) do + if string.find(textValue, operator) then + return operator; + end + end + return nil; + end + + local function SplitString(str, delimiter) + result = {}; + for match in (str..delimiter):gmatch("(.-)"..delimiter) do + table.insert(result, match); + end + return result; + end + + local function HaveStat (textValue) + for index, statItem in pairs(STATFILTERS) do + if string.find(textValue, index) then + return STATFILTERS[index]; + end + end + return nil; + end + + local function IsStatsMatch(operator, statValue, searchedStat) + if searchedStat ~= nil and statValue ~= nil + and ((operator == "<>") and (statValue ~= searchedStat) + or (operator == "<=") and (statValue <= searchedStat) + or (operator == ">=") and (statValue >= searchedStat) + or (operator == "=") and (statValue == searchedStat) + or (operator == "<") and (statValue < searchedStat) + or (operator == ">") and (statValue > searchedStat)) + then + return true; + end + return false; + end + + local function IsItemMatch(searchTextItem, stats, operator) + if stats then + local statFilterFound = HaveStat(searchTextItem); + if statFilterFound then + local statValue = tonumber(stats[statFilterFound]); + local searchedStat = tonumber(string.match(searchTextItem, "%d+")); + if IsStatsMatch(operator, statValue, searchedStat) then + return true; + end + end + end + return false; + end + local partial = self.db.profile.PartialMatching; for dataID, data in pairs(AtlasLoot_Data) do for _, v in ipairs(data) do if type(v[2]) == "number" and v[2] > 0 then local itemName = GetItemInfo(v[2]); if not itemName then itemName = gsub(v[4], "=q%d=", "") end + + -- Checks for Stat Filter by searching for an Operator in the search text + local operator = HaveOperator(text); + if operator ~= nil then + + -- Stat Filter + local stats = GetItemStats("item:"..tostring(v[2])); + if stats then + -- Currently only supports "&" + local binaryOperator = HaveBinaryOperator(text); + if binaryOperator ~= nil then + + local searchItems = SplitString(text, binaryOperator); + local searchConditionsMet = true; + for _, searchTextItem in ipairs(searchItems) do + local localOperator = HaveOperator(searchTextItem); + if not localOperator or not IsItemMatch(searchTextItem, stats, localOperator) then + searchConditionsMet = false; + end; + end + table.wipe(searchItems); + + if searchConditionsMet then + table.insert(AtlasLootCharDB["SearchResult"], { 0, v[2], v[3], itemName, lootpage, "", "", dataID.."|".."\"\"" }); + end + elseif IsItemMatch(text, stats, operator) then + table.insert(AtlasLootCharDB["SearchResult"], { 0, v[2], v[3], itemName, lootpage, "", "", dataID.."|".."\"\"" }); + end + table.wipe(stats); + end + end + local found; if partial then found = string.find(string.lower(itemName), text); From 80d18456b405edfdb9d6988c29edafd693c04f76 Mon Sep 17 00:00:00 2001 From: higurush Date: Fri, 4 Jun 2021 02:48:20 +0200 Subject: [PATCH 02/11] Rename IsStatsMatch for reusability --- AtlasLoot/Core/Search.lua | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index bffec9d..d104d41 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -206,15 +206,15 @@ function AtlasLoot:Search(Text) end return nil; end - - local function IsStatsMatch(operator, statValue, searchedStat) - if searchedStat ~= nil and statValue ~= nil - and ((operator == "<>") and (statValue ~= searchedStat) - or (operator == "<=") and (statValue <= searchedStat) - or (operator == ">=") and (statValue >= searchedStat) - or (operator == "=") and (statValue == searchedStat) - or (operator == "<") and (statValue < searchedStat) - or (operator == ">") and (statValue > searchedStat)) + + local function CompareNumbersByOperator (operator, baseValue, valueToCompare) + if baseValue ~= nil and valueToCompare ~= nil + and ((operator == "<>") and (baseValue ~= valueToCompare) + or (operator == "<=") and (baseValue <= valueToCompare) + or (operator == ">=") and (baseValue >= valueToCompare) + or (operator == "=") and (baseValue == valueToCompare) + or (operator == "<") and (baseValue < valueToCompare) + or (operator == ">") and (baseValue > valueToCompare)) then return true; end @@ -227,7 +227,7 @@ function AtlasLoot:Search(Text) if statFilterFound then local statValue = tonumber(stats[statFilterFound]); local searchedStat = tonumber(string.match(searchTextItem, "%d+")); - if IsStatsMatch(operator, statValue, searchedStat) then + if CompareNumbersByOperator(operator, statValue, searchedStat) then return true; end end @@ -246,8 +246,10 @@ function AtlasLoot:Search(Text) local operator = HaveOperator(text); if operator ~= nil then + local itemId = tostring(v[2]); + -- Stat Filter - local stats = GetItemStats("item:"..tostring(v[2])); + local stats = GetItemStats("item:"..itemId); if stats then -- Currently only supports "&" local binaryOperator = HaveBinaryOperator(text); From 29982384f0c0980cba17191279f9171bfc6461bf Mon Sep 17 00:00:00 2001 From: higurush Date: Fri, 4 Jun 2021 02:49:34 +0200 Subject: [PATCH 03/11] Add Base Item Info Filter Tables and Functions --- AtlasLoot/Core/Search.lua | 98 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index d104d41..e18bef3 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -127,7 +127,66 @@ local STATFILTERS = { ["resistancearcane"] = "RESISTANCE6_NAME", ["resarcane"] = "RESISTANCE6_NAME", - ["resarc"] = "RESISTANCE6_NAME", + ["resarc"] = "RESISTANCE6_NAME" +}; + +local ITEMINFOFILTERS = { + ["ilvl"] = "ilvl", + ["minlvl"] = "minlvl", + ["type"] = "type", + ["subtype"] = "subtype", + ["quality"] = "quality" +}; + +local ITEMINFOVALUEFILTERS = { + ["poor"] = 0, + ["common"] = 1, + ["uncommon"] = 2, + ["rare"] = 3, + ["epic"] = 4, + ["legendary"] = 5, + ["artifact"] = 6, + ["heirloom"] = 7 +}; + +local ITEMINFOEQUIPMENTLOC = { + ["INVTYPE_NON_EQUIP"] = "INVTYPE_NON_EQUIP", + ["INVTYPE_HEAD"] = "INVTYPE_HEAD", + ["INVTYPE_NECK"] = "INVTYPE_NECK", + ["INVTYPE_SHOULDER"] = "INVTYPE_SHOULDER", + ["INVTYPE_BODY"] = "INVTYPE_BODY", + ["INVTYPE_CHEST"] = "INVTYPE_CHEST", + ["INVTYPE_WAIST"] = "INVTYPE_WAIST", + ["INVTYPE_LEGS"] = "INVTYPE_LEGS", + ["INVTYPE_FEET"] = "INVTYPE_FEET", + ["INVTYPE_WRIST"] = "INVTYPE_WRIST", + ["INVTYPE_HAND"] = "INVTYPE_HAND", + ["INVTYPE_FINGER"] = "INVTYPE_FINGER", + ["INVTYPE_TRINKET"] = "INVTYPE_TRINKET", + ["INVTYPE_WEAPON"] = "INVTYPE_WEAPON", + ["INVTYPE_SHIELD"] = "INVTYPE_SHIELD", + ["INVTYPE_RANGED"] = "INVTYPE_RANGED", + ["INVTYPE_CLOAK"] = "INVTYPE_CLOAK", + ["INVTYPE_2HWEAPON"] = "INVTYPE_2HWEAPON", + ["INVTYPE_BAG"] = "INVTYPE_BAG", + ["INVTYPE_TABARD"] = "INVTYPE_TABARD", + ["INVTYPE_ROBE"] = "INVTYPE_ROBE", + ["INVTYPE_WEAPONMAINHAND"] = "INVTYPE_WEAPONMAINHAND", + ["INVTYPE_WEAPONOFFHAND"] = "INVTYPE_WEAPONOFFHAND", + ["INVTYPE_HOLDABLE"] = "INVTYPE_HOLDABLE", + ["INVTYPE_AMMO"] = "INVTYPE_AMMO", + ["INVTYPE_THROWN"] = "INVTYPE_THROWN", + ["INVTYPE_RANGEDRIGHT"] = "INVTYPE_RANGEDRIGHT", + ["INVTYPE_QUIVER"] = "INVTYPE_QUIVER", + ["INVTYPE_RELIC"] = "INVTYPE_RELIC" +}; + +local ITEMLEVELGEAREQUIPFILTER = { + ["INVTYPE_NON_EQUIP"] = "INVTYPE_NON_EQUIP", + ["INVTYPE_BODY"] = "INVTYPE_BODY", + ["INVTYPE_BAG"] = "INVTYPE_BAG", + ["INVTYPE_AMMO"] = "INVTYPE_AMMO", + ["INVTYPE_QUIVER"] = "INVTYPE_QUIVER" }; function AtlasLoot:ShowSearchResult() @@ -235,6 +294,35 @@ function AtlasLoot:Search(Text) return false; end + local function HaveItemInfoFilter (textValue) + for index, itemInfoFilter in pairs(ITEMINFOFILTERS) do + if string.find(textValue, index) then + return index; + end + end + return nil; + end + + local function IsItemLevelFilter (textValue) + local itemLevelFilter = ITEMINFOFILTERS["ilvl"]; + if string.match(textValue, itemLevelFilter) then + return true; + end + return false; + end + + local function IsEquipableGear (textValue) + if textValue == nil or textValue == "" then + return false; + end + for index, equipLoc in ipairs(ITEMLEVELGEAREQUIPFILTER) do + if string.find(textValue, equipLoc) then + return false; + end + end + return true; + end + local partial = self.db.profile.PartialMatching; for dataID, data in pairs(AtlasLoot_Data) do for _, v in ipairs(data) do @@ -273,6 +361,14 @@ function AtlasLoot:Search(Text) end table.wipe(stats); end + + -- Item Info Filter + local itemInfoFilter = HaveItemInfoFilter(text); + if itemInfoFilter then + -- Name, Link, Quality(num), iLvl(num), minLvl(num), itemType(localized string), itemSubType(localized string), stackCount(num), itemEquipLoc(enum), texture(link to a file), displayId(num) + local _, _, itemQuality, itemLvl, minLvl, _, _, _, itemEquipLoc = GetItemInfo(itemId); + end + end local found; From 13693de045bb5205ff7099e51400c62caddec7cc Mon Sep 17 00:00:00 2001 From: higurush Date: Fri, 4 Jun 2021 02:50:38 +0200 Subject: [PATCH 04/11] Add Item Level Filter for single Filter - Can only filter for iLvl by searching only for iLvl, eg: "ilvl<10" - memo TODOs --- AtlasLoot/Core/Search.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index e18bef3..30a65cf 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -367,6 +367,23 @@ function AtlasLoot:Search(Text) if itemInfoFilter then -- Name, Link, Quality(num), iLvl(num), minLvl(num), itemType(localized string), itemSubType(localized string), stackCount(num), itemEquipLoc(enum), texture(link to a file), displayId(num) local _, _, itemQuality, itemLvl, minLvl, _, _, _, itemEquipLoc = GetItemInfo(itemId); + + -- Currently only supports "&" + local binaryOperator = HaveBinaryOperator(text); + if binaryOperator ~= nil then + -- TODO + else + -- Item Level Filter + if itemLvl ~= nil and itemLvl > 0 and IsEquipableGear(itemEquipLoc) and IsItemLevelFilter(itemInfoFilter) then + local searchedItemLevel = tonumber(string.match(text, "%d+")); + if CompareNumbersByOperator(operator, itemLvl, searchedItemLevel) then + table.insert(AtlasLootCharDB["SearchResult"], { 0, v[2], v[3], itemName, lootpage, "", "", dataID.."|".."\"\"" }); + end + end + -- TODO itemQuality + -- TODO minLvl + -- TODO itemEquipLoc + end end end From 0612f2388cbca3bd67142e6d9a45eeab96aa762e Mon Sep 17 00:00:00 2001 From: higurush Date: Sat, 5 Jun 2021 15:13:08 +0200 Subject: [PATCH 05/11] Add iLvL Filter Added item level filter Reorder and Refactor of some methods and variables --- AtlasLoot/Core/Search.lua | 147 +++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 67 deletions(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index 30a65cf..4aad053 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -257,15 +257,6 @@ function AtlasLoot:Search(Text) return result; end - local function HaveStat (textValue) - for index, statItem in pairs(STATFILTERS) do - if string.find(textValue, index) then - return STATFILTERS[index]; - end - end - return nil; - end - local function CompareNumbersByOperator (operator, baseValue, valueToCompare) if baseValue ~= nil and valueToCompare ~= nil and ((operator == "<>") and (baseValue ~= valueToCompare) @@ -280,7 +271,17 @@ function AtlasLoot:Search(Text) return false; end - local function IsItemMatch(searchTextItem, stats, operator) + -- Region: Stat Filter + local function HaveStat (textValue) + for index, statItem in pairs(STATFILTERS) do + if string.find(textValue, index) then + return STATFILTERS[index]; + end + end + return nil; + end + + local function IsItemStatMatch(searchTextItem, stats, operator) if stats then local statFilterFound = HaveStat(searchTextItem); if statFilterFound then @@ -293,7 +294,9 @@ function AtlasLoot:Search(Text) end return false; end + -- EndRegion + -- Region: Item Level Filter local function HaveItemInfoFilter (textValue) for index, itemInfoFilter in pairs(ITEMINFOFILTERS) do if string.find(textValue, index) then @@ -303,14 +306,6 @@ function AtlasLoot:Search(Text) return nil; end - local function IsItemLevelFilter (textValue) - local itemLevelFilter = ITEMINFOFILTERS["ilvl"]; - if string.match(textValue, itemLevelFilter) then - return true; - end - return false; - end - local function IsEquipableGear (textValue) if textValue == nil or textValue == "" then return false; @@ -323,70 +318,88 @@ function AtlasLoot:Search(Text) return true; end + local function IsItemLevelFilter (textValue) + local itemLevelFilter = ITEMINFOFILTERS["ilvl"]; + if string.match(textValue, itemLevelFilter) then + return true; + end + return false; + end + local function IsItemLevelFilterMatch(searchText, itemLvl, itemEquipLoc, operator) + local itemInfoFilter = HaveItemInfoFilter(searchText); + if itemInfoFilter and itemLvl ~= nil and itemLvl > 0 and IsEquipableGear(itemEquipLoc) and IsItemLevelFilter(itemInfoFilter) then + local searchedItemLevel = tonumber(string.match(searchText, "%d+")); + if CompareNumbersByOperator(operator, itemLvl, searchedItemLevel) then + return true; + end + end + return false; + end + -- EndRegion + + -- Add item to Search Result + local function AddItemToSearchResult(itemId, itemType, itemName, lootPage, dataId) + table.insert(AtlasLootCharDB["SearchResult"], { 0, itemId, itemType, itemName, lootPage, "", "", dataId.."|".."\"\"" }); + end + local partial = self.db.profile.PartialMatching; for dataID, data in pairs(AtlasLoot_Data) do for _, v in ipairs(data) do if type(v[2]) == "number" and v[2] > 0 then - local itemName = GetItemInfo(v[2]); + -- Name, Link, Quality(num), iLvl(num), minLvl(num), itemType(localized string), itemSubType(localized string), stackCount(num), itemEquipLoc(enum), texture(link to a local file), displayId(num) + local itemName, _, itemQuality, itemLvl, minLvl, _, _, _, itemEquipLoc = GetItemInfo(v[2]); + if not itemName then itemName = gsub(v[4], "=q%d=", "") end - - -- Checks for Stat Filter by searching for an Operator in the search text - local operator = HaveOperator(text); - if operator ~= nil then - - local itemId = tostring(v[2]); + + -- Checks for Item Filters by searching for an Operator in the search text + local operator = HaveOperator(text); + if operator ~= nil then + local stats = GetItemStats("item:"..tostring(v[2])); - -- Stat Filter - local stats = GetItemStats("item:"..itemId); - if stats then - -- Currently only supports "&" - local binaryOperator = HaveBinaryOperator(text); - if binaryOperator ~= nil then + -- Currently only supports "&" + local binaryOperator = HaveBinaryOperator(text); + if binaryOperator ~= nil then + local searchConditionsMet = true; + local searchItems = SplitString(text, binaryOperator); - local searchItems = SplitString(text, binaryOperator); - local searchConditionsMet = true; + if searchItems and searchItems ~= nil then for _, searchTextItem in ipairs(searchItems) do local localOperator = HaveOperator(searchTextItem); - if not localOperator or not IsItemMatch(searchTextItem, stats, localOperator) then + if not localOperator + or not ( + -- Stat Filter + (stats and IsItemStatMatch(searchTextItem, stats, localOperator)) + -- Item Level Filter + or (IsItemLevelFilterMatch(searchTextItem, itemLvl, itemEquipLoc, localOperator)) + ) + then searchConditionsMet = false; - end; - end - table.wipe(searchItems); - - if searchConditionsMet then - table.insert(AtlasLootCharDB["SearchResult"], { 0, v[2], v[3], itemName, lootpage, "", "", dataID.."|".."\"\"" }); - end - elseif IsItemMatch(text, stats, operator) then - table.insert(AtlasLootCharDB["SearchResult"], { 0, v[2], v[3], itemName, lootpage, "", "", dataID.."|".."\"\"" }); - end - table.wipe(stats); - end - - -- Item Info Filter - local itemInfoFilter = HaveItemInfoFilter(text); - if itemInfoFilter then - -- Name, Link, Quality(num), iLvl(num), minLvl(num), itemType(localized string), itemSubType(localized string), stackCount(num), itemEquipLoc(enum), texture(link to a file), displayId(num) - local _, _, itemQuality, itemLvl, minLvl, _, _, _, itemEquipLoc = GetItemInfo(itemId); - - -- Currently only supports "&" - local binaryOperator = HaveBinaryOperator(text); - if binaryOperator ~= nil then - -- TODO - else - -- Item Level Filter - if itemLvl ~= nil and itemLvl > 0 and IsEquipableGear(itemEquipLoc) and IsItemLevelFilter(itemInfoFilter) then - local searchedItemLevel = tonumber(string.match(text, "%d+")); - if CompareNumbersByOperator(operator, itemLvl, searchedItemLevel) then - table.insert(AtlasLootCharDB["SearchResult"], { 0, v[2], v[3], itemName, lootpage, "", "", dataID.."|".."\"\"" }); + break; end end - -- TODO itemQuality - -- TODO minLvl - -- TODO itemEquipLoc + + if searchConditionsMet then + AddItemToSearchResult(v[2], v[3], itemName, lootpage, dataID); + end end + else + -- Stat Filter + if (stats and IsItemStatMatch(text, stats, operator)) + -- Item Level Filter + or IsItemLevelFilterMatch(text, itemLvl, itemEquipLoc, operator) + then + AddItemToSearchResult(v[2], v[3], itemName, lootpage, dataID); + end + -- TODO itemQuality + -- TODO minLvl + -- TODO itemEquipLoc end - end + -- Stat Table Cleanup + if stats then + table.wipe(stats); + end + end local found; if partial then From 97efb5e480bc8a5db7a8e0f1d39ebb524186bf68 Mon Sep 17 00:00:00 2001 From: higurush Date: Sat, 5 Jun 2021 16:25:03 +0200 Subject: [PATCH 06/11] Disable Equipable Gear on Item Level Search out of scope for now --- AtlasLoot/Core/Search.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index 4aad053..1937aad 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -327,7 +327,10 @@ function AtlasLoot:Search(Text) end local function IsItemLevelFilterMatch(searchText, itemLvl, itemEquipLoc, operator) local itemInfoFilter = HaveItemInfoFilter(searchText); - if itemInfoFilter and itemLvl ~= nil and itemLvl > 0 and IsEquipableGear(itemEquipLoc) and IsItemLevelFilter(itemInfoFilter) then + if itemInfoFilter and itemLvl ~= nil and itemLvl > 0 + --and IsEquipableGear(itemEquipLoc) + and IsItemLevelFilter(itemInfoFilter) + then local searchedItemLevel = tonumber(string.match(searchText, "%d+")); if CompareNumbersByOperator(operator, itemLvl, searchedItemLevel) then return true; From 79dd5b08015835e30488202ba55fbf7359c12dc3 Mon Sep 17 00:00:00 2001 From: higurush Date: Sat, 5 Jun 2021 22:59:09 +0200 Subject: [PATCH 07/11] Extend Not found error message -operator search outside for loot -on not found message print some more useful info -Added slash command that displays all used item filter keys --- AtlasLoot/Core/Search.lua | 41 +++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index 1937aad..e1ee5c4 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -130,6 +130,28 @@ local STATFILTERS = { ["resarc"] = "RESISTANCE6_NAME" }; +-- Slash command that prints out all used item filter keys +SLASH_ATLASLOOTITEMINFOFILTERS1 = "/atlaslootfilterkeys"; +SlashCmdList["ATLASLOOTITEMINFOFILTERS"] = function(msg, editBox) + local sortedTable = { "socket", "sockets", "gem", "gems", "ilvl" }; + for index, statItem in pairs(STATFILTERS) do + table.insert(sortedTable, index); + end + table.sort(sortedTable, function(a,b) return a < b; end) + + local filterKeys = "Filter keys: [ "; + for i, filterIndex in pairs(sortedTable) do + if i == 1 then + filterKeys = filterKeys..filterIndex; + else + filterKeys = filterKeys..", "..filterIndex; + end + end + filterKeys = filterKeys.." ]"; + + print(filterKeys); +end + local ITEMINFOFILTERS = { ["ilvl"] = "ilvl", ["minlvl"] = "minlvl", @@ -325,9 +347,11 @@ function AtlasLoot:Search(Text) end return false; end + local function IsItemLevelFilterMatch(searchText, itemLvl, itemEquipLoc, operator) local itemInfoFilter = HaveItemInfoFilter(searchText); if itemInfoFilter and itemLvl ~= nil and itemLvl > 0 + --TODO Equipment filter patch --and IsEquipableGear(itemEquipLoc) and IsItemLevelFilter(itemInfoFilter) then @@ -345,7 +369,12 @@ function AtlasLoot:Search(Text) table.insert(AtlasLootCharDB["SearchResult"], { 0, itemId, itemType, itemName, lootPage, "", "", dataId.."|".."\"\"" }); end + -- Checks for Partial Matching local partial = self.db.profile.PartialMatching; + + -- Checks for Item Filters by searching for an Operator in the search text + local operator = HaveOperator(text); + for dataID, data in pairs(AtlasLoot_Data) do for _, v in ipairs(data) do if type(v[2]) == "number" and v[2] > 0 then @@ -353,9 +382,7 @@ function AtlasLoot:Search(Text) local itemName, _, itemQuality, itemLvl, minLvl, _, _, _, itemEquipLoc = GetItemInfo(v[2]); if not itemName then itemName = gsub(v[4], "=q%d=", "") end - - -- Checks for Item Filters by searching for an Operator in the search text - local operator = HaveOperator(text); + if operator ~= nil then local stats = GetItemStats("item:"..tostring(v[2])); @@ -441,7 +468,13 @@ function AtlasLoot:Search(Text) end if #AtlasLootCharDB["SearchResult"] == 0 then - DEFAULT_CHAT_FRAME:AddMessage(RED..AL["AtlasLoot"]..": "..WHITE..AL["No match found for"].." \""..Text.."\"."); + local itemFilterErrorMessage = ""; + if operator then + itemFilterErrorMessage = [[ +Please check if you have a typo in the filter, to check filter keys, type \"/atlaslootfilterkeys\". +You might also have to query the server for item informations to load them into your client's Cache.]]; + end + DEFAULT_CHAT_FRAME:AddMessage(RED..AL["AtlasLoot"]..": "..WHITE..AL["No match found for"].." \""..Text.."\"."..itemFilterErrorMessage); else currentPage = 1; SearchResult = AtlasLoot_CategorizeWishList(AtlasLootCharDB["SearchResult"]); From 3951b0a17649915b32450a98f952701499dc2da9 Mon Sep 17 00:00:00 2001 From: higurush Date: Sat, 5 Jun 2021 23:00:21 +0200 Subject: [PATCH 08/11] Added general socket filter Added a filter that lets the user search by total number of sockets. Sockets have only been filtered by specific color. --- AtlasLoot/Core/Search.lua | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index e1ee5c4..48be708 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -49,6 +49,9 @@ local STATFILTERS = { ["socketred"] = "EMPTY_SOCKET_RED", ["socketyellow"] = "EMPTY_SOCKET_YELLOW", + ["socketnocolor"] = "EMPTY_SOCKET_NO_COLOR", + ["socketwhite"] = "EMPTY_SOCKET_NO_COLOR", + ["socketmeta"] = "EMPTY_SOCKET_META", ["meta"] = "EMPTY_SOCKET_META", @@ -152,6 +155,14 @@ SlashCmdList["ATLASLOOTITEMINFOFILTERS"] = function(msg, editBox) print(filterKeys); end +local ITEMSOCKETSTATFILTERS = { + "EMPTY_SOCKET_BLUE", + "EMPTY_SOCKET_RED", + "EMPTY_SOCKET_YELLOW", + "EMPTY_SOCKET_META", + "EMPTY_SOCKET_NO_COLOR" +}; + local ITEMINFOFILTERS = { ["ilvl"] = "ilvl", ["minlvl"] = "minlvl", @@ -294,6 +305,54 @@ function AtlasLoot:Search(Text) end -- Region: Stat Filter + local function IsSocketTermInSearchText(searchText) + if string.find(searchText, "socket") + or string.find(searchText, "sockets") + or string.find(searchText, "gem") + or string.find(searchText, "gems") + then + return true; + end + return false; + end + + local function IsSocketTermEqualsSearchText(searchText) + if searchText == "socket" + or searchText == "sockets" + or searchText == "gem" + or searchText == "gems" + then + return true; + end + return false; + end + + local function FilterSockets(searchTextItem, stats, operator) + if stats then + if IsSocketTermInSearchText(searchTextItem) then + local searchedStatValue = tonumber(string.match(searchTextItem, "%d+")); + local searchTerm = string.gsub(searchTextItem, tostring(searchedStatValue), ""); + searchTerm = string.gsub(searchTerm, operator, ""); + + if IsSocketTermEqualsSearchText(searchTerm) then + local socketCount = 0; + for _, socketType in pairs(ITEMSOCKETSTATFILTERS) do + if socketType then + local statValue = tonumber(stats[socketType]); + if statValue then + socketCount = socketCount + statValue; + end + end + end + if CompareNumbersByOperator(operator, socketCount, searchedStatValue) then + return true; + end + end + end + end + return false; + end + local function HaveStat (textValue) for index, statItem in pairs(STATFILTERS) do if string.find(textValue, index) then @@ -312,6 +371,8 @@ function AtlasLoot:Search(Text) if CompareNumbersByOperator(operator, statValue, searchedStat) then return true; end + else + return FilterSockets(searchTextItem, stats, operator); end end return false; From 6b9d73e6043339a1706258b07955646b99f450f4 Mon Sep 17 00:00:00 2001 From: higurush Date: Sat, 5 Jun 2021 23:01:38 +0200 Subject: [PATCH 09/11] Fix Stat Filter Key Matching Fixed an issues where stat filter key was partially matching the filter key. Now it matches for the exact key defined in the filter tables. --- AtlasLoot/Core/Search.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index 48be708..0c07a2f 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -355,7 +355,7 @@ function AtlasLoot:Search(Text) local function HaveStat (textValue) for index, statItem in pairs(STATFILTERS) do - if string.find(textValue, index) then + if textValue == index then return STATFILTERS[index]; end end @@ -364,10 +364,13 @@ function AtlasLoot:Search(Text) local function IsItemStatMatch(searchTextItem, stats, operator) if stats then - local statFilterFound = HaveStat(searchTextItem); + local searchedStat = tonumber(string.match(searchTextItem, "%d+")); + local searchTerm = searchTextItem.gsub(searchTextItem, tostring(searchedStat), ""); + searchTerm = string.gsub(searchTerm, operator, ""); + + local statFilterFound = HaveStat(searchTerm); if statFilterFound then local statValue = tonumber(stats[statFilterFound]); - local searchedStat = tonumber(string.match(searchTextItem, "%d+")); if CompareNumbersByOperator(operator, statValue, searchedStat) then return true; end @@ -453,15 +456,15 @@ function AtlasLoot:Search(Text) local searchConditionsMet = true; local searchItems = SplitString(text, binaryOperator); - if searchItems and searchItems ~= nil then + if searchItems then for _, searchTextItem in ipairs(searchItems) do local localOperator = HaveOperator(searchTextItem); if not localOperator or not ( -- Stat Filter - (stats and IsItemStatMatch(searchTextItem, stats, localOperator)) + IsItemStatMatch(searchTextItem, stats, localOperator) -- Item Level Filter - or (IsItemLevelFilterMatch(searchTextItem, itemLvl, itemEquipLoc, localOperator)) + or IsItemLevelFilterMatch(searchTextItem, itemLvl, itemEquipLoc, localOperator) ) then searchConditionsMet = false; @@ -475,7 +478,7 @@ function AtlasLoot:Search(Text) end else -- Stat Filter - if (stats and IsItemStatMatch(text, stats, operator)) + if IsItemStatMatch(text, stats, operator) -- Item Level Filter or IsItemLevelFilterMatch(text, itemLvl, itemEquipLoc, operator) then From 954e7e4dd9375ced800fde55cdb7a4e3c6727ae0 Mon Sep 17 00:00:00 2001 From: higurush Date: Sat, 5 Jun 2021 23:10:08 +0200 Subject: [PATCH 10/11] Fixed Item Info Filter partial matching Fixed an issue where item info filter was partially matching. --- AtlasLoot/Core/Search.lua | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index 0c07a2f..62f8001 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -385,7 +385,7 @@ function AtlasLoot:Search(Text) -- Region: Item Level Filter local function HaveItemInfoFilter (textValue) for index, itemInfoFilter in pairs(ITEMINFOFILTERS) do - if string.find(textValue, index) then + if textValue == index then return index; end end @@ -413,13 +413,16 @@ function AtlasLoot:Search(Text) end local function IsItemLevelFilterMatch(searchText, itemLvl, itemEquipLoc, operator) - local itemInfoFilter = HaveItemInfoFilter(searchText); + local searchedItemLevel = tonumber(string.match(searchText, "%d+")); + local searchTerm = searchText.gsub(searchText, tostring(searchedItemLevel), ""); + searchTerm = string.gsub(searchTerm, operator, ""); + + local itemInfoFilter = HaveItemInfoFilter(searchTerm); if itemInfoFilter and itemLvl ~= nil and itemLvl > 0 --TODO Equipment filter patch --and IsEquipableGear(itemEquipLoc) and IsItemLevelFilter(itemInfoFilter) then - local searchedItemLevel = tonumber(string.match(searchText, "%d+")); if CompareNumbersByOperator(operator, itemLvl, searchedItemLevel) then return true; end @@ -535,7 +538,7 @@ function AtlasLoot:Search(Text) local itemFilterErrorMessage = ""; if operator then itemFilterErrorMessage = [[ -Please check if you have a typo in the filter, to check filter keys, type \"/atlaslootfilterkeys\". +Please check if you have a typo in the filter, to check filter keys, type "/atlaslootfilterkeys". You might also have to query the server for item informations to load them into your client's Cache.]]; end DEFAULT_CHAT_FRAME:AddMessage(RED..AL["AtlasLoot"]..": "..WHITE..AL["No match found for"].." \""..Text.."\"."..itemFilterErrorMessage); From 30ed539a4780f0355f4718ac095e6d08027b6b04 Mon Sep 17 00:00:00 2001 From: higurush Date: Sat, 5 Jun 2021 23:23:15 +0200 Subject: [PATCH 11/11] Added slash commad for filter examples --- AtlasLoot/Core/Search.lua | 55 +++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/AtlasLoot/Core/Search.lua b/AtlasLoot/Core/Search.lua index 62f8001..3222307 100644 --- a/AtlasLoot/Core/Search.lua +++ b/AtlasLoot/Core/Search.lua @@ -133,28 +133,6 @@ local STATFILTERS = { ["resarc"] = "RESISTANCE6_NAME" }; --- Slash command that prints out all used item filter keys -SLASH_ATLASLOOTITEMINFOFILTERS1 = "/atlaslootfilterkeys"; -SlashCmdList["ATLASLOOTITEMINFOFILTERS"] = function(msg, editBox) - local sortedTable = { "socket", "sockets", "gem", "gems", "ilvl" }; - for index, statItem in pairs(STATFILTERS) do - table.insert(sortedTable, index); - end - table.sort(sortedTable, function(a,b) return a < b; end) - - local filterKeys = "Filter keys: [ "; - for i, filterIndex in pairs(sortedTable) do - if i == 1 then - filterKeys = filterKeys..filterIndex; - else - filterKeys = filterKeys..", "..filterIndex; - end - end - filterKeys = filterKeys.." ]"; - - print(filterKeys); -end - local ITEMSOCKETSTATFILTERS = { "EMPTY_SOCKET_BLUE", "EMPTY_SOCKET_RED", @@ -222,6 +200,35 @@ local ITEMLEVELGEAREQUIPFILTER = { ["INVTYPE_QUIVER"] = "INVTYPE_QUIVER" }; +-- Slash command that prints out all used item filter keys +SLASH_ATLASLOOTITEMINFOFILTERS1 = "/atlaslootfilterkeys"; +SlashCmdList["ATLASLOOTITEMINFOFILTERS"] = function(msg, editBox) + local sortedTable = { "socket", "sockets", "gem", "gems", "ilvl" }; + for index, statItem in pairs(STATFILTERS) do + table.insert(sortedTable, index); + end + table.sort(sortedTable, function(a,b) return a < b; end) + + local filterKeys = "Filter keys: [ "; + for i, filterIndex in pairs(sortedTable) do + if i == 1 then + filterKeys = filterKeys..filterIndex; + else + filterKeys = filterKeys..", "..filterIndex; + end + end + filterKeys = filterKeys.." ]"; + + print(filterKeys); +end + +-- Slash command that prints filter examples +SLASH_ATLASLOOTITEMINFOFILTEREXAMPLE1 = "/atlaslootfilterexample"; +SlashCmdList["ATLASLOOTITEMINFOFILTEREXAMPLE"] = function(msg, editBox) + print("Single search example: str>40"); + print("Multi search example: str>40&ilvl<140&ilvl>=120&int>0&socket>2"); +end + function AtlasLoot:ShowSearchResult() AtlasLoot_ShowItemsFrame("SearchResult", "SearchResultPage"..currentPage, (AL["Search Result: %s"]):format(AtlasLootCharDB.LastSearchedText or ""), pFrame); end @@ -538,7 +545,9 @@ function AtlasLoot:Search(Text) local itemFilterErrorMessage = ""; if operator then itemFilterErrorMessage = [[ -Please check if you have a typo in the filter, to check filter keys, type "/atlaslootfilterkeys". +Please check if you have a typo in the filter. +To check filter keys, type "/atlaslootfilterkeys". +To check filter examples, type "/atlaslootfilterexample". You might also have to query the server for item informations to load them into your client's Cache.]]; end DEFAULT_CHAT_FRAME:AddMessage(RED..AL["AtlasLoot"]..": "..WHITE..AL["No match found for"].." \""..Text.."\"."..itemFilterErrorMessage);