From bceec38bac1fddc3db9d4973f55aa2c3e4a225b7 Mon Sep 17 00:00:00 2001 From: totalllyswede Date: Sat, 14 Feb 2026 07:45:42 -0800 Subject: [PATCH] Add files via upload --- GearSetTooltips.lua | 711 ++++++++++++++++++++++++++++++++++++++++++++ GearSetTooltips.toc | 9 + README.md | 51 +++- 3 files changed, 763 insertions(+), 8 deletions(-) create mode 100644 GearSetTooltips.lua create mode 100644 GearSetTooltips.toc diff --git a/GearSetTooltips.lua b/GearSetTooltips.lua new file mode 100644 index 0000000..e4a4f80 --- /dev/null +++ b/GearSetTooltips.lua @@ -0,0 +1,711 @@ +-- GearSetTooltips: Shows which ItemRack/Outfitter sets an item belongs to + +GearSetTooltips = {} + +-- Cache of set item IDs for performance +GearSetTooltips.SetItems = {} + +-- Initialization flag +GearSetTooltips.Initialized = false + +-- Settings frame reference +GearSetTooltips.SettingsFrame = nil + +-- Default settings +local defaults = { + setColors = {} -- Individual colors per set +} + +-- Color presets +local colorPresets = { + ["Blue"] = {r = 0.5, g = 0.5, b = 1.0}, + ["Light Blue"] = {r = 0.5, g = 0.8, b = 1.0}, + ["Green"] = {r = 0.5, g = 1.0, b = 0.5}, + ["Yellow"] = {r = 1.0, g = 1.0, b = 0.5}, + ["Orange"] = {r = 1.0, g = 0.6, b = 0.2}, + ["Red"] = {r = 1.0, g = 0.3, b = 0.3}, + ["Purple"] = {r = 0.8, g = 0.5, b = 1.0}, + ["White"] = {r = 1.0, g = 1.0, b = 1.0} +} + +-- Get current color based on per-set color +function GearSetTooltips:GetCurrentColor(setName) + -- Safety check - ensure setColors exists + if not GearSetTooltipsDB or not GearSetTooltipsDB.setColors then + return 0.5, 0.5, 1.0 -- fallback to blue + end + + if setName and GearSetTooltipsDB.setColors[setName] then + -- Use per-set color if defined + local preset = GearSetTooltipsDB.setColors[setName] + local color = colorPresets[preset] + if color then + return color.r, color.g, color.b + end + end + + -- Default to Blue + return 0.5, 0.5, 1.0 +end + +-- Initialize addon +function GearSetTooltips:Initialize() + -- Initialize saved variables + if not GearSetTooltipsDB then + GearSetTooltipsDB = {} + end + + -- Apply defaults + for k, v in pairs(defaults) do + if GearSetTooltipsDB[k] == nil then + GearSetTooltipsDB[k] = v + end + end + + -- Ensure setColors is a table + if type(GearSetTooltipsDB.setColors) ~= "table" then + GearSetTooltipsDB.setColors = {} + end + + -- Wait for ItemRack or Outfitter to load + self:RegisterEvents() +end + +-- Register events +function GearSetTooltips:RegisterEvents() + local frame = CreateFrame("Frame") + frame:RegisterEvent("ADDON_LOADED") + + frame:SetScript("OnEvent", function() + if not GearSetTooltips.Initialized then + if IsAddOnLoaded("ItemRack") or IsAddOnLoaded("Outfitter") then + GearSetTooltips:OnAddonsLoaded() + end + end + end) +end + +function GearSetTooltips: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 = "GearSetTooltips 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 GearSetTooltips: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)) + GearSetTooltips:UpdateSetItems() + return result + end +end + +-- Schedule a delayed update +function GearSetTooltips:ScheduleUpdate(delay) + local frame = CreateFrame("Frame") + local elapsed = 0 + + frame:SetScript("OnUpdate", function() + elapsed = elapsed + arg1 + if elapsed >= delay then + GearSetTooltips:UpdateSetItems() + frame:SetScript("OnUpdate", nil) + end + end) +end + +-- Build cache of all items in ItemRack and Outfitter sets +function GearSetTooltips:UpdateSetItems() + local success, errorMsg = pcall(function() + local oldCount = 0 + for _ in pairs(GearSetTooltips.SetItems) do + oldCount = oldCount + 1 + end + + GearSetTooltips.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 " .. GetRealmName() + + 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 GearSetTooltips.SetItems[itemID] then + count = count + 1 + end + GearSetTooltips.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 GearSetTooltips.SetItems[itemID] then + count = count + 1 + end + GearSetTooltips.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("|cffff0000GearSetTooltips: Error updating cache - " .. tostring(errorMsg) .. "|r") + end +end + +-- Get which sets an item belongs to (from both ItemRack and Outfitter) +function GearSetTooltips: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 " .. GetRealmName() + + 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 GearSetTooltips: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 + GearSetTooltips: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 + GearSetTooltips.lastItemProcessed = nil + end) +end + +-- Add set information directly to the game tooltip +function GearSetTooltips: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) + + -- Add 'Gear Sets:' label in white + tooltip:AddLine("Gear Sets:", 1.0, 1.0, 1.0) + + -- Add each set on its own line with its individual color, indented + for i = 1, displayCount do + local setName = sets[i] + local r, g, b = GearSetTooltips:GetCurrentColor(setName) + tooltip:AddLine(" " .. setName, r, g, b) + end + + -- If there are more than 5, show count + if totalSets > 5 then + tooltip:AddLine(" (+" .. (totalSets - 5) .. " more)", 0.5, 0.5, 0.5) + end + end +end + +-- Create settings frame +function GearSetTooltips:CreateSettingsFrame() + if self.SettingsFrame then + return self.SettingsFrame + end + + local frame = CreateFrame("Frame", "GearSetTooltipsSettings", UIParent) + frame:SetWidth(400) + frame:SetHeight(280) + frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0) + frame:SetBackdrop({ + bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", + edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", + tile = true, + tileSize = 16, + edgeSize = 32, + insets = { left = 11, right = 12, top = 12, bottom = 11 } + }) + frame:SetBackdropColor(0.1, 0.1, 0.1, 1.0) + frame:SetMovable(true) + frame:EnableMouse(true) + frame:RegisterForDrag("LeftButton") + frame:SetScript("OnDragStart", function() this:StartMoving() end) + frame:SetScript("OnDragStop", function() this:StopMovingOrSizing() end) + frame:Hide() + + -- Make ESC key close the window + table.insert(UISpecialFrames, "GearSetTooltipsSettings") + + -- Title + local title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge") + title:SetPoint("TOP", 0, -20) + title:SetText("GearSet Tooltips") + + -- Close button + local closeBtn = CreateFrame("Button", nil, frame, "UIPanelCloseButton") + closeBtn:SetPoint("TOPRIGHT", -5, -5) + + -- Sets label + local setsLabel = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge") + setsLabel:SetPoint("TOPLEFT", 20, -50) + setsLabel:SetText("Detected Sets:") + setsLabel:SetTextColor(1.0, 1.0, 1.0) + + -- Column headings + local nameHeading = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") + nameHeading:SetPoint("TOPLEFT", 25, -75) + nameHeading:SetText("Set Name") + nameHeading:SetTextColor(1.0, 0.82, 0) + + local colorHeading = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") + colorHeading:SetPoint("TOPLEFT", 265, -75) + colorHeading:SetText("Color") + colorHeading:SetTextColor(1.0, 0.82, 0) + + -- Scrollable sets list + local scrollFrame = CreateFrame("ScrollFrame", "GearSetTooltipsScrollFrame", frame, "UIPanelScrollFrameTemplate") + scrollFrame:SetPoint("TOPLEFT", 20, -97) + scrollFrame:SetPoint("BOTTOMRIGHT", -40, 60) + + local scrollChild = CreateFrame("Frame", nil, scrollFrame) + scrollChild:SetWidth(310) + scrollChild:SetHeight(1) + scrollFrame:SetScrollChild(scrollChild) + + frame.scrollChild = scrollChild + + -- Horizontal divider line between column headings and list + local divider = frame:CreateTexture(nil, "ARTWORK") + divider:SetHeight(1) + divider:SetPoint("LEFT", 15, 50) + divider:SetPoint("RIGHT", -15, 50) + divider:SetTexture(0.5, 0.5, 0.5, 1.0) + + -- Detect Set Changes button (left) + local updateBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate") + updateBtn:SetWidth(130) + updateBtn:SetHeight(25) + updateBtn:SetPoint("BOTTOMLEFT", 10, 15) + updateBtn:SetText("Detect Set Changes") + updateBtn:SetScript("OnClick", function() + GearSetTooltips:UpdateSetItems() + GearSetTooltips:RefreshSettingsFrame() + DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Sets updated!|r") + end) + + -- Save & Close button (center) + local saveBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate") + saveBtn:SetWidth(100) + saveBtn:SetHeight(25) + saveBtn:SetPoint("BOTTOM", 0, 15) + saveBtn:SetText("Save & Close") + saveBtn:SetScript("OnClick", function() + frame:Hide() + DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00GearSetTooltips settings saved!|r") + end) + + -- Reset All Colors button (right) + local resetBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate") + resetBtn:SetWidth(130) + resetBtn:SetHeight(25) + resetBtn:SetPoint("BOTTOMRIGHT", -10, 15) + resetBtn:SetText("Reset All Colors") + resetBtn:SetScript("OnClick", function() + GearSetTooltipsDB.setColors = {} + GearSetTooltips:RefreshSettingsFrame() + DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00All set colors reset to blue!|r") + end) + + self.SettingsFrame = frame + return frame +end + +-- Create color selection dialog for a specific set +function GearSetTooltips:ShowColorDialog(setName) + -- Create or reuse dialog frame + if not self.ColorDialog then + local dialog = CreateFrame("Frame", "GearSetTooltipsColorDialog", UIParent) + dialog:SetWidth(200) + dialog:SetHeight(280) + dialog:SetPoint("CENTER", UIParent, "CENTER", 0, 0) + dialog:SetBackdrop({ + bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", + edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", + tile = true, + tileSize = 16, + edgeSize = 32, + insets = { left = 11, right = 12, top = 12, bottom = 11 } + }) + dialog:SetBackdropColor(0.1, 0.1, 0.1, 1.0) + dialog:SetFrameStrata("DIALOG") + dialog:Hide() + + -- Make ESC key close the color dialog + table.insert(UISpecialFrames, "ItemSetTooltipColorDialog") + + -- Title + dialog.title = dialog:CreateFontString(nil, "OVERLAY", "GameFontNormal") + dialog.title:SetPoint("TOP", 0, -15) + + -- Close button + local closeBtn = CreateFrame("Button", nil, dialog, "UIPanelCloseButton") + closeBtn:SetPoint("TOPRIGHT", -5, -5) + + -- Color buttons + dialog.colorButtons = {} + local buttonY = -45 + local buttonIndex = 0 + + for presetName, color in pairs(colorPresets) do + local btn = CreateFrame("Button", nil, dialog) + btn:SetWidth(170) + btn:SetHeight(26) + btn:SetPoint("TOP", 0, buttonY) + + -- Highlight only (no background texture) + btn:SetHighlightTexture("Interface\\Buttons\\UI-Panel-Button-Highlight") + + -- Color preview square + btn.colorBox = btn:CreateTexture(nil, "OVERLAY") + btn.colorBox:SetWidth(14) + btn.colorBox:SetHeight(14) + btn.colorBox:SetPoint("LEFT", 8, 0) + btn.colorBox:SetTexture(color.r, color.g, color.b, 1) + + -- Text + btn.text = btn:CreateFontString(nil, "OVERLAY", "GameFontNormal") + btn.text:SetPoint("LEFT", 28, 0) + btn.text:SetText(presetName) + + btn.presetName = presetName + btn:SetScript("OnClick", function() + -- Ensure setColors table exists + if not GearSetTooltipsDB.setColors then + GearSetTooltipsDB.setColors = {} + end + GearSetTooltipsDB.setColors[dialog.currentSet] = this.presetName + GearSetTooltips:RefreshSettingsFrame() + dialog:Hide() + end) + + table.insert(dialog.colorButtons, btn) + buttonY = buttonY - 28 + buttonIndex = buttonIndex + 1 + end + + self.ColorDialog = dialog + end + + self.ColorDialog.currentSet = setName + self.ColorDialog.title:SetText("Color for: " .. setName) + self.ColorDialog:Show() +end + +-- Refresh settings frame with current set list +function GearSetTooltips:RefreshSettingsFrame() + if not self.SettingsFrame then return end + + -- Clear existing rows + if self.SettingsFrame.setRows then + for _, row in ipairs(self.SettingsFrame.setRows) do + row:Hide() + end + else + self.SettingsFrame.setRows = {} + end + + local setList = {} + + -- Get ItemRack sets + if IsAddOnLoaded("ItemRack") then + local userData = Rack_User or ItemRack_Users + if userData then + local user = UnitName("player") .. " of " .. GetRealmName() + if userData[user] and userData[user].Sets then + for setName, _ in pairs(userData[user].Sets) do + if not string.find(setName, "^ItemRack%-") and not string.find(setName, "^Rack%-") then + table.insert(setList, {name = setName, addon = "ItemRack"}) + end + end + end + end + end + + -- Get 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.Name and outfit.Items then + table.insert(setList, {name = outfit.Name, addon = "Outfitter"}) + end + end + end + end + end + + -- Sort alphabetically by name + table.sort(setList, function(a, b) return a.name < b.name end) + + -- Create or update rows + local rowHeight = 16 + local yOffset = -5 + + for i, setData in ipairs(setList) do + local row = self.SettingsFrame.setRows[i] + + if not row then + -- Create new row + row = CreateFrame("Button", nil, self.SettingsFrame.scrollChild) + row:SetHeight(rowHeight) + row:SetWidth(320) + + -- Highlight texture + row:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") + + -- Set name text + row.nameText = row:CreateFontString(nil, "OVERLAY", "GameFontNormal") + row.nameText:SetPoint("LEFT", 5, 0) + row.nameText:SetJustifyH("LEFT") + row.nameText:SetWidth(220) + + -- Color indicator (small colored square) + row.colorBox = row:CreateTexture(nil, "OVERLAY") + row.colorBox:SetWidth(12) + row.colorBox:SetHeight(12) + row.colorBox:SetPoint("LEFT", 256, 0) + + -- Click handler + row:SetScript("OnClick", function() + GearSetTooltips:ShowColorDialog(this.setName) + end) + + table.insert(self.SettingsFrame.setRows, row) + end + + row:SetPoint("TOPLEFT", 0, yOffset) + row.nameText:SetText(setData.name .. " (" .. setData.addon .. ")") + row.setName = setData.name + + -- Set color box to this set's individual color + local r, g, b = self:GetCurrentColor(setData.name) + row.colorBox:SetTexture(r, g, b, 1) + + row:Show() + yOffset = yOffset - rowHeight + end + + -- Show "No sets found" if empty + if table.getn(setList) == 0 then + local row = self.SettingsFrame.setRows[1] + if not row then + row = CreateFrame("Frame", nil, self.SettingsFrame.scrollChild) + row:SetHeight(16) + row:SetWidth(320) + row.nameText = row:CreateFontString(nil, "OVERLAY", "GameFontNormal") + row.nameText:SetPoint("LEFT", 5, 0) + row.nameText:SetJustifyH("LEFT") + table.insert(self.SettingsFrame.setRows, row) + end + row:SetPoint("TOPLEFT", 0, -5) + row.nameText:SetText("No sets found") + row:Show() + end + + -- Update scroll child height + local totalHeight = math.max(1, table.getn(setList) * rowHeight + 30) + self.SettingsFrame.scrollChild:SetHeight(totalHeight) +end + +-- Show settings frame +function GearSetTooltips:ShowSettings() + local frame = self:CreateSettingsFrame() + self:RefreshSettingsFrame() + frame:Show() +end + +-- Slash commands +SLASH_GEARSETTOOLTIPS1 = "/gearsettooltips" +SLASH_GEARSETTOOLTIPS2 = "/gst" +SlashCmdList["GEARSETTOOLTIPS"] = function(msg) + msg = string.lower(msg or "") + + if msg == "update" or msg == "refresh" then + GearSetTooltips:UpdateSetItems() + elseif msg == "options" or msg == "config" or msg == "settings" then + GearSetTooltips:ShowSettings() + else + DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00GearSetTooltips commands:|r") + DEFAULT_CHAT_FRAME:AddMessage("/gst options - Open settings window") + DEFAULT_CHAT_FRAME:AddMessage("/gst update - Refresh set items cache") + end +end + +-- Initialize on load +GearSetTooltips:Initialize() diff --git a/GearSetTooltips.toc b/GearSetTooltips.toc new file mode 100644 index 0000000..366d986 --- /dev/null +++ b/GearSetTooltips.toc @@ -0,0 +1,9 @@ +## Interface: 11200 +## Title: GearSet Tooltips +## Notes: Shows which ItemRack/Outfitter sets an item belongs to +## Author: Olzon +## Version: 1.1 +## OptionalDeps: ItemRack, Outfitter +## SavedVariables: GearSetTooltipsDB + +GearSetTooltips.lua diff --git a/README.md b/README.md index 1eb2571..af54ec3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ItemSetTooltip +# GearSetTooltips A simple addon for World of Warcraft (Vanilla 1.12) that displays which ItemRack and/or Outfitter sets an item belongs to when you hover over items in your bags. @@ -8,11 +8,14 @@ A simple addon for World of Warcraft (Vanilla 1.12) that displays which ItemRack - Supports both ItemRack and Outfitter addons - Automatically updates when you modify your sets - Displays up to 5 sets per item (with count if more) -- Blue text for easy visibility +- Individual color customization per set +- 8 color presets available (Blue, Light Blue, Green, Yellow, Orange, Red, Purple, White) +- Easy-to-use settings window with dark theme +- Displays each set on its own line with custom colors ## Installation -1. Extract the `ItemSetTooltip` folder to your `World of Warcraft\Interface\AddOns\` directory +1. Extract the `GearSetTooltips` folder to your `World of Warcraft\Interface\AddOns\` directory 2. Restart WoW or reload UI (`/reload`) 3. The addon will automatically detect ItemRack and/or Outfitter @@ -25,27 +28,59 @@ A simple addon for World of Warcraft (Vanilla 1.12) that displays which ItemRack ## Usage -Simply hover over any item in your bags. If the item is part of any gear sets, you'll see a blue line at the bottom of the tooltip showing which sets it belongs to. +Simply hover over any item in your bags. If the item is part of any gear sets, you'll see a white "Gear Sets:" label followed by the set names, each in their custom color. Example: ``` -Sets: PvP, Healing, Tank +Gear Sets: + PvP (in blue) + Healing (in green) + Tank (in red) ``` ## Commands -- `/ist` or `/itemsettooltip` - Show available commands -- `/ist update` - Manually refresh the set items cache +- `/gst` or `/gearsettooltips` - Show available commands +- `/gst options` - Open settings window +- `/gst update` - Manually refresh the set items cache + +## Settings Window + +Access the settings with `/gst options` to: +- View all detected sets from ItemRack and Outfitter +- Click any set to choose a custom color (8 presets available) +- Detect set changes manually +- Reset all set colors back to default blue +- Modern dark-themed interface +- Press ESC to close ## Notes - Only shows tooltips for items in bags (not equipped items or other locations) - Automatically updates when you create, modify, or delete sets - Ignores ItemRack internal sets (those starting with "ItemRack-" or "Rack-") +- Each set can have its own color for easy visual identification +- "Gear Sets:" label always appears in white +- Settings are saved per character ## Version -1.0 +1.1 + +## Changelog + +### Version 1.1 +- Added graphical settings window with dark theme +- Per-set color customization with 8 color presets +- Each set now displays on its own line in tooltips +- Added "Detect Set Changes" and "Reset All Colors" buttons +- Improved UI with dividers and better spacing +- ESC key closes all windows +- Changed command from `/ist` to `/gst` + +### Version 1.0 +- Initial release +- Basic tooltip display for ItemRack and Outfitter sets ## Author