Files
GearSetTooltips/ItemSetTooltip.lua
T
2026-02-14 06:10:26 -08:00

337 lines
12 KiB
Lua

-- ItemSetTooltip: Shows which ItemRack/Outfitter sets an item belongs to
ItemSetTooltip = {}
-- Cache of set item IDs for performance
ItemSetTooltip.SetItems = {}
-- Initialization flag
ItemSetTooltip.Initialized = false
-- Initialize addon
function ItemSetTooltip:Initialize()
-- Wait for ItemRack or Outfitter to load
self:RegisterEvents()
end
-- Register events
function ItemSetTooltip:RegisterEvents()
local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function()
if not ItemSetTooltip.Initialized then
if IsAddOnLoaded("ItemRack") or IsAddOnLoaded("Outfitter") then
ItemSetTooltip:OnAddonsLoaded()
end
end
end)
end
function ItemSetTooltip:OnAddonsLoaded()
-- Prevent multiple initializations
if self.Initialized then
return
end
self.Initialized = true
-- Update set items cache
self:UpdateSetItems()
-- Hook ItemRack functions to update cache
if ItemRack and ItemRack.SaveSet then
self:HookFunction(ItemRack, "SaveSet")
end
if ItemRack and ItemRack.DeleteSet then
self:HookFunction(ItemRack, "DeleteSet")
end
-- Hook tooltips
self:HookTooltips()
-- Delay the load message to ensure chat frame is ready
local msgFrame = CreateFrame("Frame")
local elapsed = 0
msgFrame:SetScript("OnUpdate", function()
elapsed = elapsed + arg1
if elapsed >= 0.5 then
local msg = "ItemSetTooltip loaded"
if IsAddOnLoaded("ItemRack") and IsAddOnLoaded("Outfitter") then
msg = msg .. " - Tracking ItemRack and Outfitter sets"
elseif IsAddOnLoaded("ItemRack") then
msg = msg .. " - Tracking ItemRack sets"
elseif IsAddOnLoaded("Outfitter") then
msg = msg .. " - Tracking Outfitter sets"
end
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00" .. msg .. "|r")
msgFrame:SetScript("OnUpdate", nil)
end
end)
-- Schedule a delayed update
self:ScheduleUpdate(2)
end
-- Simple function hooking
function ItemSetTooltip:HookFunction(table, funcName)
if not table or not table[funcName] then return end
local original = table[funcName]
table[funcName] = function(...)
local result = original(unpack(arg))
ItemSetTooltip:UpdateSetItems()
return result
end
end
-- Schedule a delayed update
function ItemSetTooltip:ScheduleUpdate(delay)
local frame = CreateFrame("Frame")
local elapsed = 0
frame:SetScript("OnUpdate", function()
elapsed = elapsed + arg1
if elapsed >= delay then
ItemSetTooltip:UpdateSetItems()
frame:SetScript("OnUpdate", nil)
end
end)
end
-- Build cache of all items in ItemRack and Outfitter sets
function ItemSetTooltip:UpdateSetItems()
local success, errorMsg = pcall(function()
local oldCount = 0
for _ in pairs(ItemSetTooltip.SetItems) do
oldCount = oldCount + 1
end
ItemSetTooltip.SetItems = {}
local count = 0
-- Read ItemRack sets
if IsAddOnLoaded("ItemRack") then
local userData = Rack_User or ItemRack_Users
if userData then
local user = UnitName("player") .. " of " .. GetCVar("realmName")
if userData[user] and userData[user].Sets then
for setName, setData in pairs(userData[user].Sets) do
if not string.find(setName, "^ItemRack%-") and not string.find(setName, "^Rack%-") then
for slot = 0, 19 do
local itemData = setData[slot]
if itemData and type(itemData) == "table" then
local itemID = itemData.id
if itemID and itemID ~= 0 then
if type(itemID) == "string" then
local _, _, extractedID = string.find(itemID, "^(%d+)")
itemID = tonumber(extractedID)
end
if itemID and itemID > 0 then
if not ItemSetTooltip.SetItems[itemID] then
count = count + 1
end
ItemSetTooltip.SetItems[itemID] = true
end
end
end
end
end
end
end
end
end
-- Read Outfitter sets
if IsAddOnLoaded("Outfitter") and gOutfitter_Settings and gOutfitter_Settings.Outfits then
for cat, outfits in pairs(gOutfitter_Settings.Outfits) do
if table.getn(outfits) > 0 then
for _, outfit in ipairs(outfits) do
if outfit.Items then
for slot, item in pairs(outfit.Items) do
local itemID = tonumber(item.Code)
if itemID and itemID > 0 then
if not ItemSetTooltip.SetItems[itemID] then
count = count + 1
end
ItemSetTooltip.SetItems[itemID] = true
end
end
end
end
end
end
end
-- Show message if count changed
if count ~= oldCount then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Item Set Change Detected - Tooltips Updated|r")
end
end)
if not success then
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000ItemSetTooltip: Error updating cache - " .. tostring(errorMsg) .. "|r")
end
end
-- Get which sets an item belongs to (from both ItemRack and Outfitter)
function ItemSetTooltip:GetItemSets(itemID)
if not itemID then return nil end
-- Only process if item is in our cache
if not self.SetItems[itemID] then return nil end
local sets = {}
-- Check ItemRack sets
if IsAddOnLoaded("ItemRack") then
local userData = Rack_User or ItemRack_Users
if userData then
local user = UnitName("player") .. " of " .. GetCVar("realmName")
if userData[user] and userData[user].Sets then
for setName, setData in pairs(userData[user].Sets) do
if not string.find(setName, "^ItemRack%-") and not string.find(setName, "^Rack%-") then
for slot = 0, 19 do
local itemData = setData[slot]
if itemData and type(itemData) == "table" then
local slotItemID = itemData.id
if slotItemID and slotItemID ~= 0 then
if type(slotItemID) == "string" then
local _, _, extractedID = string.find(slotItemID, "^(%d+)")
slotItemID = tonumber(extractedID)
end
if slotItemID and slotItemID == itemID then
table.insert(sets, setName)
break
end
end
end
end
end
end
end
end
end
-- Check Outfitter sets
if IsAddOnLoaded("Outfitter") and gOutfitter_Settings and gOutfitter_Settings.Outfits then
for cat, outfits in pairs(gOutfitter_Settings.Outfits) do
if table.getn(outfits) > 0 then
for _, outfit in ipairs(outfits) do
if outfit.Items and outfit.Name then
for slot, item in pairs(outfit.Items) do
local outfitItemID = tonumber(item.Code)
if outfitItemID and outfitItemID == itemID then
table.insert(sets, outfit.Name)
break
end
end
end
end
end
end
end
if table.getn(sets) > 0 then
return sets
else
return nil
end
end
-- Hook all tooltip events
function ItemSetTooltip:HookTooltips()
-- Store a reference to the last item we added info for to prevent duplicates
self.lastItemProcessed = nil
-- Hook GameTooltip SetBagItem for bag items only
local orig_SetBagItem = GameTooltip.SetBagItem
GameTooltip.SetBagItem = function(this, bag, slot)
orig_SetBagItem(this, bag, slot)
local itemLink = GetContainerItemLink(bag, slot)
if itemLink then
ItemSetTooltip:AddSetsToTooltip(this, itemLink)
end
end
-- Hook OnHide to clear the last processed item
local orig_OnHide = GameTooltip:GetScript("OnHide")
GameTooltip:SetScript("OnHide", function()
if orig_OnHide then
orig_OnHide()
end
ItemSetTooltip.lastItemProcessed = nil
end)
end
-- Add set information directly to the game tooltip
function ItemSetTooltip:AddSetsToTooltip(tooltip, itemLink)
if not itemLink then
return
end
-- Prevent adding the same item multiple times
if self.lastItemProcessed == itemLink then
return
end
self.lastItemProcessed = itemLink
local _, _, itemID = string.find(itemLink, "item:(%d+)")
itemID = tonumber(itemID)
if not itemID then
return
end
local sets = self:GetItemSets(itemID)
if sets then
-- Limit to 5 sets
local totalSets = table.getn(sets)
local displayCount = math.min(5, totalSets)
-- Build the set names string
local setString = ""
for i = 1, displayCount do
if i > 1 then
setString = setString .. ", "
end
setString = setString .. sets[i]
end
-- If there are more than 5, add count
if totalSets > 5 then
setString = setString .. " (+" .. (totalSets - 5) .. " more)"
end
-- Add the line in blue text (RGB: 0.5, 0.5, 1.0 for a nice blue)
tooltip:AddLine("Sets: " .. setString, 0.5, 0.5, 1.0)
end
end
-- Slash commands
SLASH_ITEMSETTOOLTIP1 = "/itemsettooltip"
SLASH_ITEMSETTOOLTIP2 = "/ist"
SlashCmdList["ITEMSETTOOLTIP"] = function(msg)
msg = string.lower(msg or "")
if msg == "update" or msg == "refresh" then
ItemSetTooltip:UpdateSetItems()
else
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00ItemSetTooltip commands:|r")
DEFAULT_CHAT_FRAME:AddMessage("/ist update - Refresh set items cache")
end
end
-- Initialize on load
ItemSetTooltip:Initialize()