Files
coa-elvui/ElvUI/Libraries/LibItemSearch-1.2/LibItemSearch-1.2.lua
T

336 lines
7.4 KiB
Lua

--[[
ItemSearch
An item text search engine of some sort
--]]
local Search = LibStub("CustomSearch-1.0")
local Unfit = LibStub("Unfit-1.0")
local Lib = LibStub:NewLibrary("LibItemSearch-1.2-ElvUI", 17)
if Lib then
Lib.Scanner = LibItemSearchTooltipScanner or CreateFrame("GameTooltip", "LibItemSearchTooltipScanner", UIParent, "GameTooltipTemplate")
Lib.Filters = {}
else
return
end
--[[ User API ]]--
function Lib:Matches(link, search)
return Search(link, search, self.Filters)
end
function Lib:Tooltip(link, search)
return link and self.Filters.tip:match(link, nil, search)
end
function Lib:TooltipPhrase(link, search)
return link and self.Filters.tipPhrases:match(link, nil, search)
end
function Lib:InSet(link, search)
if IsEquippableItem(link) then
local id = tonumber(link:match("item:(%-?%d+)"))
return self:BelongsToSet(id, (search or ""):lower())
end
end
--[[ Internal API ]]--
local function LibItemRack(id, search)
for name, set in pairs(ItemRackUser.Sets) do
if search == "any" or name:sub(1,1) ~= "" and Search:Find(search, name) then
for _, item in pairs(set.equip) do
if sameID(id, item) then
return true
end
end
end
end
end
local function LibWardrobe(id, search)
for _, outfit in ipairs(Wardrobe.CurrentConfig.Outfit) do
local name = outfit.OutfitName
if search == "any" or Search:Find(search, name) then
for _, item in pairs(outfit.Item) do
if item.IsSlotUsed == 1 and item.ItemID == id then
return true
end
end
end
end
end
local function LibOutfitter(id, search)
for _, group in pairs(Outfitter.Settings.Outfits) do
for _, set in ipairs(group) do
if search == "any" or Search:Find(search, set["Name"]) then
for _, base in pairs(set["Items"]) do
if base["Code"] == id then
return true
end
end
end
end
end
end
local function LibDefault(id, search)
for i = 1, GetNumEquipmentSets() do
local name = GetEquipmentSetInfo(i)
if search == "any" or Search:Find(search, name) then
local items = GetEquipmentSetItemIDs(name)
for _, item in pairs(items) do
if id == item then
return true
end
end
end
end
end
local outfit_addons = {LibDefault}
function Lib:BelongsToSet(id, search)
for g, funct in ipairs(outfit_addons) do
if funct(id, search) then
return true
end
end
end
--[[ General ]]--
Lib.Filters.name = {
tags = {"n", "name"},
canSearch = function(self, operator, search)
return not operator and search
end,
match = function(self, item, _, search)
local name = item:match("%[(.-)%]")
return Search:Find(search, name)
end
}
Lib.Filters.type = {
tags = {"t", "type", "s", "slot"},
canSearch = function(self, operator, search)
return not operator and search
end,
match = function(self, item, _, search)
local type, subType, _, equipSlot = select(6, GetItemInfo(item))
return Search:Find(search, type, subType, equipSlot and equipSlot ~= "" and _G[equipSlot])
end
}
Lib.Filters.level = {
tags = {"l", "level", "lvl", "ilvl"},
canSearch = function(self, _, search)
return tonumber(search)
end,
match = function(self, link, operator, num)
local lvl = select(4, GetItemInfo(link))
if lvl then
return Search:Compare(operator, lvl, num)
end
end
}
Lib.Filters.requiredlevel = {
tags = {"r", "req", "rl", "reql", "reqlvl"},
canSearch = function(self, _, search)
return tonumber(search)
end,
match = function(self, link, operator, num)
local lvl = select(5, GetItemInfo(link))
if lvl then
return Search:Compare(operator, lvl, num)
end
end
}
Lib.Filters.sets = {
tags = {"s", "set"},
canSearch = function(self, operator, search)
return not operator and search
end,
match = function(self, link, _, search)
return Lib:InSet(link, search)
end,
}
Lib.Filters.quality = {
tags = {"q", "quality"},
keywords = {},
canSearch = function(self, _, search)
for quality, name in pairs(self.keywords) do
if name:find(search) then
return quality
end
end
end,
match = function(self, link, operator, num)
local quality = select(3, GetItemInfo(link))
return Search:Compare(operator, quality, num)
end,
}
--[[
0 Poor 9d9d9d
1 Common ffffff
2 Uncommon 1eff00
3 Rare 0070dd
4 Epic a335ee
5 Legendary ff8000
6 Artifact e6cc80
7 Heirloom 00ccff
]]
for i = 0, 7 do -- Ascension change: was `#ITEM_QUALITY_COLORS` now `7`
Lib.Filters.quality.keywords[i] = _G["ITEM_QUALITY" .. i .. "_DESC"]:lower()
end
--[[ Classic Keywords ]]--
Lib.Filters.items = {
keyword = ITEMS:lower(),
canSearch = function(self, operator, search)
return not operator and self.keyword:find(search)
end,
match = function(self, link)
return true
end
}
Lib.Filters.usable = {
keyword = USABLE_ITEMS:lower(),
canSearch = function(self, operator, search)
return not operator and self.keyword:find(search)
end,
match = function(self, link)
if not Unfit:IsItemUnusable(link) then
local lvl = select(5, GetItemInfo(link))
return lvl and (lvl ~= 0 and lvl <= UnitLevel("player"))
end
end
}
--[[ Tooltips ]]--
Lib.Filters.tip = {
tags = {"tt", "tip", "tooltip"},
onlyTags = true,
canSearch = function(self, _, search)
return search
end,
match = function(self, link, _, search)
if link:find("item:") then
Lib.Scanner:SetOwner(UIParent, "ANCHOR_NONE")
Lib.Scanner:SetHyperlink(link)
for i = 1, Lib.Scanner:NumLines() do
if Search:Find(search, _G[Lib.Scanner:GetName() .. "TextLeft" .. i]:GetText()) then
return true
end
end
end
end
}
Lib.Filters.tipPhrases = {
canSearch = function(self, _, search)
if #search >= 3 then
for key, query in pairs(self.keywords) do
if key:find(search) then
return query
end
end
end
end,
match = function(self, link, _, search)
local id = link:match("item:(%d+)")
if not id then
return
end
local cached = self.cache[search][id]
if cached ~= nil then
return cached
end
Lib.Scanner:SetOwner(UIParent, "ANCHOR_NONE")
Lib.Scanner:SetHyperlink(link)
local matches = false
for i = 1, Lib.Scanner:NumLines() do
if search == _G[Lib.Scanner:GetName() .. "TextLeft" .. i]:GetText() then
matches = true
break
end
end
self.cache[search][id] = matches
return matches
end,
cache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end}),
keywords = {
[ITEM_SOULBOUND:lower()] = ITEM_BIND_ON_PICKUP,
[QUESTS_LABEL:lower()] = ITEM_BIND_QUEST,
["bound"] = ITEM_BIND_ON_PICKUP,
["bop"] = ITEM_BIND_ON_PICKUP,
["boe"] = ITEM_BIND_ON_EQUIP,
["bou"] = ITEM_BIND_ON_USE,
["boa"] = ITEM_BIND_TO_ACCOUNT,
}
}
-- keep track of which function handles which addon
local equipmentAddons = {
["ItemRack"] = LibItemRack,
["Wardrobe"] = LibWardrobe,
["Outfitter"] = LibOutfitter,
}
local loadedOutfitAddons = {} -- keep track of which set management addons are loaded
-- check if any addons are already loaded
for addon, funct in pairs(equipmentAddons) do
if IsAddOnLoaded(addon) then
loadedOutfitAddons[addon] = true
outfit_addons[#outfit_addons + 1] = funct
end
end
local frame, events = CreateFrame("Frame"), {}
-- watch loading addons for ones we care about
function events:ADDON_LOADED(name)
if equipmentAddons[name] and not loadedOutfitAddons[name] then
outfit_addons[#outfit_addons + 1] = equipmentAddons[name]
loadedOutfitAddons[name] = true
end
end
frame:SetScript("OnEvent", function(self, event, ...)
events[event](self, ...)
end)
for k, v in pairs(events) do
frame:RegisterEvent(k) -- Register all events for which handlers have been defined
end