Add files via upload

This commit is contained in:
totalllyswede
2026-02-14 07:45:42 -08:00
committed by GitHub
parent 09125cee61
commit bceec38bac
3 changed files with 763 additions and 8 deletions
+711
View File
@@ -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()
+9
View File
@@ -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
+43 -8
View File
@@ -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