Untitled diff

Created Diff never expires
5 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
716 lines
35 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
744 lines
-- InspectEquip
-- InspectEquip


InspectEquip = LibStub("AceAddon-3.0"):NewAddon("InspectEquip", "AceConsole-3.0", "AceHook-3.0", "AceTimer-3.0", "AceEvent-3.0")
InspectEquip = LibStub("AceAddon-3.0"):NewAddon("InspectEquip", "AceConsole-3.0", "AceHook-3.0", "AceTimer-3.0", "AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("InspectEquip")
local L = LibStub("AceLocale-3.0"):GetLocale("InspectEquip")
local IE = InspectEquip
local IE = InspectEquip
local IS = InspectEquip_ItemSources --> ItemSources.lua
local IS = InspectEquip_ItemSources --> ItemSources.lua
local WIN = InspectEquip_InfoWindow --> InfoWindow.xml
local WIN = InspectEquip_InfoWindow --> InfoWindow.xml
local TITLE = InspectEquip_InfoWindowTitle
local TITLE = InspectEquip_InfoWindowTitle
local AVGIL = InspectEquip_InfoWindowAvgItemLevel
local AVGIL = InspectEquip_InfoWindowAvgItemLevel
local exMod = nil
local exMod = nil


local mop = select(4, GetBuildInfo()) >= 50000
local mop = select(4, GetBuildInfo()) >= 50000


local ItemUpgradeInfo = LibStub("LibItemUpgradeInfo-1.0")
local ItemUpgradeInfo = LibStub("LibItemUpgradeInfo-1.0")


local slots = { "HeadSlot", "NeckSlot", "ShoulderSlot", "BackSlot", "ChestSlot",
local slots = { "HeadSlot", "NeckSlot", "ShoulderSlot", "BackSlot", "ChestSlot",
"WristSlot", "HandsSlot", "WaistSlot", "LegsSlot", "FeetSlot",
"WristSlot", "HandsSlot", "WaistSlot", "LegsSlot", "FeetSlot",
"Finger0Slot", "Finger1Slot", "Trinket0Slot", "Trinket1Slot", "MainHandSlot",
"Finger0Slot", "Finger1Slot", "Trinket0Slot", "Trinket1Slot", "MainHandSlot",
"SecondaryHandSlot" } -- TabardSlot, ShirtSlot
"SecondaryHandSlot" } -- TabardSlot, ShirtSlot
local noEnchantWarningSlots = {
local noEnchantWarningSlots = {
["NeckSlot"] = true, ["WaistSlot"] = true, ["Finger0Slot"] = true, ["Finger1Slot"] = true,
["NeckSlot"] = true, ["WaistSlot"] = true, ["Finger0Slot"] = true, ["Finger1Slot"] = true,
["Trinket0Slot"] = true, ["Trinket1Slot"] = true, ["SecondaryHandSlot"] = true, ["RangedSlot"] = true,
["Trinket0Slot"] = true, ["Trinket1Slot"] = true, ["SecondaryHandSlot"] = true, ["RangedSlot"] = true,
}
}


local lines = {}
local lines = {}
local numlines = 0
local numlines = 0
local curline = 0
local curline = 0
local curUnit = nil
local curUnit = nil
local curUnitName = nil
local curUnitName = nil
local curUser = nil
local curUser = nil
local curGUID = nil
local curGUID = nil
local cached = false
local cached = false


local headers = {}
local headers = {}
local numheaders = 0
local numheaders = 0


local yoffset = -40
local yoffset = -40
local hooked = false
local hooked = false
local autoHidden = false
local autoHidden = false


local origInspectUnit
local origInspectUnit


local tonumber = tonumber
local tonumber = tonumber
local gmatch = string.gmatch
local gmatch = string.gmatch
local tinsert = table.insert
local tinsert = table.insert
local tsort = table.sort
local tsort = table.sort
local band = bit.band
local band = bit.band
local Examiner = Examiner
local Examiner = Examiner


--local _,_,_,gameToc = GetBuildInfo()
--local _,_,_,gameToc = GetBuildInfo()


local tooltipTimer = nil
local tooltipTimer = nil
local retryTimer = nil
local retryTimer = nil


if mop then
if mop then
noEnchantWarningSlots["HeadSlot"] = true
noEnchantWarningSlots["HeadSlot"] = true
else
else
tinsert(slots, "RangedSlot")
tinsert(slots, "RangedSlot")
end
end




--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------


InspectEquipConfig = {}
InspectEquipConfig = {}
local defaults = {
local defaults = {
tooltips = true,
tooltips = true,
showUnknown = true,
showUnknown = true,
inspectWindow = true,
inspectWindow = true,
charWindow = true,
charWindow = true,
checkEnchants = true,
checkEnchants = true,
listItemLevels = true,
listItemLevels = true,
showAvgItemLevel = true,
showAvgItemLevel = true,
ttR = 1.0,
ttR = 1.0,
ttG = 0.75,
ttG = 0.75,
ttB = 0.0,
ttB = 0.0,
maxSourceCount = 5,
maxSourceCount = 5,
}
}


local options = {
local options = {
name = "InspectEquip",
name = "InspectEquip",
type = "group",
type = "group",
args = {
args = {
tooltips = {
tooltips = {
order = 1, type = "toggle", width = "full",
order = 1, type = "toggle", width = "full",
name = L["Add drop information to tooltips"],
name = L["Add drop information to tooltips"],
desc = L["Add item drop information to all item tooltips"],
desc = L["Add item drop information to all item tooltips"],
get = function() return InspectEquipConfig.tooltips end,
get = function() return InspectEquipConfig.tooltips end,
set = function(_,v) InspectEquipConfig.tooltips = v; if v then IE:HookTooltips() end end,
set = function(_,v) InspectEquipConfig.tooltips = v; if v then IE:HookTooltips() end end,
},
},
showunknown = {
showunknown = {
order = 2, type = "toggle", width = "full",
order = 2, type = "toggle", width = "full",
name = L["Include unknown items in overview"],
name = L["Include unknown items in overview"],
desc = L["Show items that cannot be categorized in a seperate category"],
desc = L["Show items that cannot be categorized in a seperate category"],
get = function() return InspectEquipConfig.showUnknown end,
get = function() return InspectEquipConfig.showUnknown end,
set = function(_,v) InspectEquipConfig.showUnknown = v end,
set = function(_,v) InspectEquipConfig.showUnknown = v end,
},
},
inspectwindow = {
inspectwindow = {
order = 3, type = "toggle", width = "full",
order = 3, type = "toggle", width = "full",
name = L["Attach to inspect window"],
name = L["Attach to inspect window"],
desc = L["Show the equipment list when inspecting other characters"],
desc = L["Show the equipment list when inspecting other characters"],
get = function() return InspectEquipConfig.inspectWindow end,
get = function() return InspectEquipConfig.inspectWindow end,
set = function(_,v) InspectEquipConfig.inspectWindow = v end,
set = function(_,v) InspectEquipConfig.inspectWindow = v end,
},
},
charwindow = {
charwindow = {
order = 4, type = "toggle", width = "full",
order = 4, type = "toggle", width = "full",
name = L["Attach to character window"],
name = L["Attach to character window"],
desc = L["Also show the InspectEquip panel when opening the character window"],
desc = L["Also show the InspectEquip panel when opening the character window"],
get = function() return InspectEquipConfig.charWindow end,
get = function() return InspectEquipConfig.charWindow end,
set = function(_,v) InspectEquipConfig.charWindow = v end,
set = function(_,v) InspectEquipConfig.charWindow = v end,
},
},
checkenchants = {
checkenchants = {
order = 5, type = "toggle", width = "full",
order = 5, type = "toggle", width = "full",
name = L["Check for unenchanted items"],
name = L["Check for unenchanted items"],
desc = L["Display a warning for unenchanted items"],
desc = L["Display a warning for unenchanted items"],
get = function() return InspectEquipConfig.checkEnchants end,
get = function() return InspectEquipConfig.checkEnchants end,
set = function(_,v) InspectEquipConfig.checkEnchants = v end,
set = function(_,v) InspectEquipConfig.checkEnchants = v end,
},
},
listitemlevels = {
listitemlevels = {
order = 6, type = "toggle", width = "full",
order = 6, type = "toggle", width = "full",
name = L["Show item level in equipment list"],
name = L["Show item level in equipment list"],
desc = L["Show the item level of each item in the equipment panel"],
desc = L["Show the item level of each item in the equipment panel"],
get = function() return InspectEquipConfig.listItemLevels end,
get = function() return InspectEquipConfig.listItemLevels end,
set = function(_,v) InspectEquipConfig.listItemLevels = v end,
set = function(_,v) InspectEquipConfig.listItemLevels = v end,
},
},
showavgitemlevel = {
showavgitemlevel = {
order = 7, type = "toggle", width = "full",
order = 7, type = "toggle", width = "full",
name = L["Show average item level in equipment list"],
name = L["Show average item level in equipment list"],
desc = L["Show the average item level of all items in the equipment panel"],
desc = L["Show the average item level of all items in the equipment panel"],
get = function() return InspectEquipConfig.showAvgItemLevel end,
get = function() return InspectEquipConfig.showAvgItemLevel end,
set = function(_,v) InspectEquipConfig.showAvgItemLevel = v end,
set = function(_,v) InspectEquipConfig.showAvgItemLevel = v end,
},
},
tooltipcolor = {
tooltipcolor = {
order = 8, type = "color",
order = 8, type = "color",
name = L["Tooltip text color"],
name = L["Tooltip text color"],
width = "full",
width = "full",
get = function() return InspectEquipConfig.ttR, InspectEquipConfig.ttG, InspectEquipConfig.ttB, 1.0 end,
get = function() return InspectEquipConfig.ttR, InspectEquipConfig.ttG, InspectEquipConfig.ttB, 1.0 end,
set = function(_,r,g,b,a)
set = function(_,r,g,b,a)
InspectEquipConfig.ttR = r
InspectEquipConfig.ttR = r
InspectEquipConfig.ttG = g
InspectEquipConfig.ttG = g
InspectEquipConfig.ttB = b
InspectEquipConfig.ttB = b
end,
end,
},
},
maxsourcecount = {
maxsourcecount = {
order = 9, type = "range",
order = 9, type = "range",
min = 1, max = 20, softMax = 10, step = 1,
min = 1, max = 20, softMax = 10, step = 1,
width = "double",
width = "double",
name = L["Max. amount of sources in tooltips"],
name = L["Max. amount of sources in tooltips"],
desc = L["The maximum amount of sources that are displayed in item tooltips"],
desc = L["The maximum amount of sources that are displayed in item tooltips"],
get = function() return InspectEquipConfig.maxSourceCount end,
get = function() return InspectEquipConfig.maxSourceCount end,
set = function(_,v) InspectEquipConfig.maxSourceCount = v end,
set = function(_,v) InspectEquipConfig.maxSourceCount = v end,
},
},
database = {
database = {
order = 10, type = "group", inline = true,
order = 10, type = "group", inline = true,
name = L["Database"],
name = L["Database"],
args = {
args = {
resetdb = {
resetdb = {
order = 1, type = "execute",
order = 1, type = "execute",
width = "double",
width = "double",
name = L["Reset database"],
name = L["Reset database"],
desc = L["Recreate the database"],
desc = L["Recreate the database"],
func = function() IE:CreateLocalDatabase() end,
func = function() IE:CreateLocalDatabase() end,
},
},
},
},
}
}
},
},
}
}


LibStub("AceConfig-3.0"):RegisterOptionsTable("InspectEquip", options, "/inspectequip")
LibStub("AceConfig-3.0"):RegisterOptionsTable("InspectEquip", options, "/inspectequip")
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("InspectEquip")
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("InspectEquip")


--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------


function IE:OnInitialize()
function IE:OnInitialize()
setmetatable(InspectEquipConfig, {__index = defaults})
setmetatable(InspectEquipConfig, {__index = defaults})


self:SetParent(Examiner or InspectFrame)
self:SetParent(Examiner or InspectFrame)
WIN:Hide()
WIN:Hide()
TITLE:SetText("InspectEquip")
TITLE:SetText("InspectEquip")


if Examiner and Examiner.CreateModule then
if Examiner and Examiner.CreateModule then
exMod = Examiner:CreateModule("InspectEquip")
exMod = Examiner:CreateModule("InspectEquip")
exMod.OnCacheLoaded = function(s, entry, unit)
exMod.OnCacheLoaded = function(s, entry, unit)
if InspectEquipConfig.inspectWindow then
if InspectEquipConfig.inspectWindow then
IE:Inspect("cache", entry)
IE:Inspect("cache", entry)
end
end
end
end
exMod.OnClearInspect = function(s) WIN:Hide() end
exMod.OnClearInspect = function(s) WIN:Hide() end
exMod.OnInspect = function(s, unit)
exMod.OnInspect = function(s, unit)
if InspectEquipConfig.inspectWindow then
if InspectEquipConfig.inspectWindow then
IE:SetParent(Examiner); IE:Inspect(unit)
IE:SetParent(Examiner); IE:Inspect(unit)
end
end
end
end
end
end


self:RegisterEvent("PLAYER_ENTERING_WORLD")
self:RegisterEvent("PLAYER_ENTERING_WORLD")
self:RegisterEvent("ADDON_LOADED")
self:RegisterEvent("ADDON_LOADED")


--self:InitLocalDatabase()
--self:InitLocalDatabase()
end
end


function IE:OnEnable()
function IE:OnEnable()
origInspectUnit = origInspectUnit or InspectUnit
origInspectUnit = origInspectUnit or InspectUnit
InspectUnit = function(...) IE:InspectUnit(...) end
InspectUnit = function(...) IE:InspectUnit(...) end
self:SecureHookScript(PaperDollFrame, "OnShow", "PaperDollFrame_OnShow")
self:SecureHookScript(PaperDollFrame, "OnShow", "PaperDollFrame_OnShow")
self:SecureHookScript(PaperDollFrame, "OnHide", "PaperDollFrame_OnHide")
self:SecureHookScript(PaperDollFrame, "OnHide", "PaperDollFrame_OnHide")
if GearManagerDialog then -- 4.0
if GearManagerDialog then -- 4.0
self:SecureHookScript(GearManagerDialog, "OnShow", "GearManagerDialog_OnShow")
self:SecureHookScript(GearManagerDialog, "OnShow", "GearManagerDialog_OnShow")
self:SecureHookScript(GearManagerDialog, "OnHide", "GearManagerDialog_OnHide")
self:SecureHookScript(GearManagerDialog, "OnHide", "GearManagerDialog_OnHide")
end
end
if OutfitterFrame then
if OutfitterFrame then
self:SecureHookScript(OutfitterFrame, "OnShow", "GearManagerDialog_OnShow")
self:SecureHookScript(OutfitterFrame, "OnShow", "GearManagerDialog_OnShow")
self:SecureHookScript(OutfitterFrame, "OnHide", "GearManagerDialog_OnHide")
self:SecureHookScript(OutfitterFrame, "OnHide", "GearManagerDialog_OnHide")
end
end
self:RegisterEvent("UNIT_INVENTORY_CHANGED")
self:RegisterEvent("UNIT_INVENTORY_CHANGED")
self:RegisterEvent("INSPECT_READY")
self:RegisterEvent("INSPECT_READY")
end
end


function IE:OnDisable()
function IE:OnDisable()
InspectUnit = origInspectUnit
InspectUnit = origInspectUnit
if hooked then
if hooked then
hooked = false
hooked = false
self:Unhook("InspectFrame_UnitChanged")
self:Unhook("InspectFrame_UnitChanged")
end
end
self:UnhookAll()
self:UnhookAll()
self:UnregisterEvent("UNIT_INVENTORY_CHANGED")
self:UnregisterEvent("UNIT_INVENTORY_CHANGED")
self:UnregisterEvent("INSPECT_READY")
self:UnregisterEvent("INSPECT_READY")
self:CancelAllTimers()
self:CancelAllTimers()
WIN:Hide()
WIN:Hide()
end
end


local entered = false
local entered = false


function IE:PLAYER_ENTERING_WORLD()
function IE:PLAYER_ENTERING_WORLD()
entered = true
entered = true
self:ScheduleTooltipHook()
self:ScheduleTooltipHook()
self:InitLocalDatabase()
self:InitLocalDatabase()
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
end
end


function IE:ADDON_LOADED(e, name)
function IE:ADDON_LOADED(e, name)
if entered then
if entered then
self:ScheduleTooltipHook()
self:ScheduleTooltipHook()
end
end
end
end


-- Ugly hack, but some addons override the OnTooltipSetItem handler on
-- Ugly hack, but some addons override the OnTooltipSetItem handler on
-- ItemRefTooltip, breaking IE. Using this timer, IE hopefully hooks after them.
-- ItemRefTooltip, breaking IE. Using this timer, IE hopefully hooks after them.
function IE:ScheduleTooltipHook()
function IE:ScheduleTooltipHook()
if InspectEquipConfig.tooltips then
if InspectEquipConfig.tooltips then
if tooltipTimer then
if tooltipTimer then
self:CancelTimer(tooltipTimer, true)
self:CancelTimer(tooltipTimer, true)
end
end
tooltipTimer = self:ScheduleTimer('HookTooltips', 3)
tooltipTimer = self:ScheduleTimer('HookTooltips', 3)
end
end
end
end


function IE:SetParent(frame)
function IE:SetParent(frame)
WIN:SetParent(frame)
WIN:SetParent(frame)
WIN:ClearAllPoints()
WIN:ClearAllPoints()
if not (frame == Examiner) then
if not (frame == Examiner) then
WIN:SetPoint("TOPLEFT", frame, "TOPRIGHT", 5, 0)
WIN:SetPoint("TOPLEFT", frame, "TOPRIGHT", 5, 0)
else
else
WIN:SetPoint("TOPLEFT", frame, "TOPRIGHT", -25, -13)
WIN:SetPoint("TOPLEFT", frame, "TOPRIGHT", -25, -13)
end
end
end
end


function IE:NewLine()
function IE:NewLine()
local row = CreateFrame("Frame", nil, WIN)
local row = CreateFrame("Frame", nil, WIN)
row:SetHeight(12)
row:SetHeight(12)
row:SetWidth(200)
row:SetWidth(200)


local txt = row:CreateFontString(nil, "ARTWORK")
local txt = row:CreateFontString(nil, "ARTWORK")
txt:SetJustifyH("LEFT")
txt:SetJustifyH("LEFT")
txt:SetFontObject(GameFontHighlightSmall)
txt:SetFontObject(GameFontHighlightSmall)
txt:SetPoint("TOPLEFT", row, "TOPLEFT", 0, 0)
txt:SetPoint("TOPLEFT", row, "TOPLEFT", 0, 0)
row.text = txt
row.text = txt


row.yoffset = yoffset
row.yoffset = yoffset
IE:SetLinePadding(row, 0)
IE:SetLinePadding(row, 0)


yoffset = yoffset - 15
yoffset = yoffset - 15
numlines = numlines + 1
numlines = numlines + 1
lines[numlines] = row
lines[numlines] = row


row:EnableMouse(true)
row:EnableMouse(true)
row:SetScript("OnEnter", IE.Line_OnEnter)
row:SetScript("OnEnter", IE.Line_OnEnter)
row:SetScript("OnLeave", IE.Line_OnLeave)
row:SetScript("OnLeave", IE.Line_OnLeave)
row:SetScript("OnMouseDown", IE.Line_OnClick)
row:SetScript("OnMouseDown", IE.Line_OnClick)
end
end


function IE:SetLinePadding(line, padding)
function IE:SetLinePadding(line, padding)
local padWidth = select(2,line.text:GetFont()) * padding * 0.6
local padWidth = select(2,line.text:GetFont()) * padding * 0.6


line:SetPoint("TOPLEFT", WIN, "TOPLEFT", 15 + padWidth, line.yoffset)
line:SetPoint("TOPLEFT", WIN, "TOPLEFT", 15 + padWidth, line.yoffset)
line.padLeft = padWidth
line.padLeft = padWidth
end
end


function IE:ResetDisplay()
function IE:ResetDisplay()
for i = 1, numlines do
for i = 1, numlines do
lines[i].text:SetText("")
lines[i].text:SetText("")
IE:SetLinePadding(lines[i], 0)
IE:SetLinePadding(lines[i], 0)
lines[i]:Hide()
lines[i]:Hide()
end
end
curline = 0
curline = 0
end
end


function IE:AddLine(padding, text, link, item)
function IE:AddLine(padding, text, link, item)
curline = curline + 1
curline = curline + 1
if curline > numlines then
if curline > numlines then
self:NewLine()
self:NewLine()
end
end
local line = lines[curline]
local line = lines[curline]
line.link = link
line.link = link
line.item = item
line.item = item
line.text:SetText(text)
line.text:SetText(text)
line:SetWidth(line.text:GetStringWidth())
line:SetWidth(line.text:GetStringWidth())
IE:SetLinePadding(line, padding)
IE:SetLinePadding(line, padding)
line:SetFrameLevel(WIN:GetFrameLevel() + 1)
line:SetFrameLevel(WIN:GetFrameLevel() + 1)
line:Show()
line:Show()
end
end


function IE:FullUnitName(name, realm)
function IE:FullUnitName(name, realm)
if realm and realm ~= "" then
if realm and realm ~= "" then
return name .. "-" .. realm
return name .. "-" .. realm
else
else
return name
return name
end
end
end
end


function IE:GetExaminerCache(unit)
function IE:GetExaminerCache(unit)
local name, realm = UnitName(unit)
local name, realm = UnitName(unit)
return Examiner_Cache and Examiner_Cache[self:FullUnitName(name, realm)]
return Examiner_Cache and Examiner_Cache[self:FullUnitName(name, realm)]
end
end


function IE:InspectUnit(unit, ...)
function IE:InspectUnit(unit, ...)
origInspectUnit(unit, ...)
origInspectUnit(unit, ...)


if InspectEquipConfig.inspectWindow then
if InspectEquipConfig.inspectWindow then
self:SetParent(Examiner or InspectFrame)
self:SetParent(Examiner or InspectFrame)
WIN:Hide()
WIN:Hide()
if not hooked and InspectFrame_UnitChanged then
if not hooked and InspectFrame_UnitChanged then
hooked = true
hooked = true
self:SecureHook("InspectFrame_UnitChanged")
self:SecureHook("InspectFrame_UnitChanged")
end
end


self:Inspect(unit)
self:Inspect(unit)
end
end
end
end


function IE:InspectFrame_UnitChanged()
function IE:InspectFrame_UnitChanged()
if InspectFrame.unit and InspectEquipConfig.inspectWindow then
if InspectFrame.unit and InspectEquipConfig.inspectWindow then
self:InspectUnit(InspectFrame.unit)
self:InspectUnit(InspectFrame.unit)
else
else
WIN:Hide()
WIN:Hide()
end
end
end
end


function IE:PaperDollFrame_OnShow()
function IE:PaperDollFrame_OnShow()
if InspectEquipConfig.charWindow then
if InspectEquipConfig.charWindow then
IE:SetParent(CharacterFrame)
IE:SetParent(CharacterFrame)
IE:Inspect("player")
IE:Inspect("player")
end
end
end
end


function IE:PaperDollFrame_OnHide()
function IE:PaperDollFrame_OnHide()
if WIN:GetParent() == CharacterFrame then
if WIN:GetParent() == CharacterFrame then
WIN:Hide()
WIN:Hide()
autoHidden = false
autoHidden = false
end
end
end
end


function IE:GearManagerDialog_OnShow()
function IE:GearManagerDialog_OnShow()
if WIN:GetParent() == CharacterFrame and WIN:IsShown() then
if WIN:GetParent() == CharacterFrame and WIN:IsShown() then
WIN:Hide()
WIN:Hide()
autoHidden = true
autoHidden = true
end
end
end
end


function IE:GearManagerDialog_OnHide()
function IE:GearManagerDialog_OnHide()
if autoHidden and WIN:GetParent() == CharacterFrame then
if autoHidden and WIN:GetParent() == CharacterFrame then
WIN:Show()
WIN:Show()
autoHidden = false
autoHidden = false
end
end
end
end


function IE:UNIT_INVENTORY_CHANGED(event, unit)
function IE:UNIT_INVENTORY_CHANGED(event, unit)
if (unit == "player") and (WIN:IsVisible() or autoHidden) and (WIN:GetParent() == CharacterFrame) then
if (unit == "player") and (WIN:IsVisible() or autoHidden) and (WIN:GetParent() == CharacterFrame) then
IE:Inspect("player")
IE:Inspect("player")
elseif (unit == curUnit) and (UnitName(unit) == curUnitName) and (WIN:IsVisible()) then
elseif (unit == curUnit) and (UnitName(unit) == curUnitName) and (WIN:IsVisible()) then
IE:Inspect(curUnit)
IE:Inspect(curUnit)
end
end
end
end


function IE:INSPECT_READY(event, guid)
function IE:INSPECT_READY(event, guid)
if (guid == curGUID) and (UnitName(curUnit) == curUnitName) then
if (guid == curGUID) and (UnitName(curUnit) == curUnitName) then
IE:Inspect(curUnit)
IE:Inspect(curUnit)
else
else
-- probably mouseover changed... nothing we can do apparently :(
-- probably mouseover changed... nothing we can do apparently :(
-- (inspect by unit name / guid does not work)
-- (inspect by unit name / guid does not work)
end
end
end
end


function IE:Inspect(unit, entry)
function IE:Inspect(unit, entry)
local unitName, unitRealm
local unitName, unitRealm
cached = (unit == "cache")
cached = (unit == "cache")


if retryTimer then
if retryTimer then
-- stop retry timer if present
-- stop retry timer if present
self:CancelTimer(retryTimer, true)
self:CancelTimer(retryTimer, true)
retryTimer = nil
retryTimer = nil
end
end


if (cached and (not entry)) or (not self:IsEnabled()) then
if (cached and (not entry)) or (not self:IsEnabled()) then
WIN:Hide()
WIN:Hide()
return
return
end
end


local cacheItems = cached and entry.Items or nil
local cacheItems = cached and entry.Items or nil


if cached then
if cached then
unitName, unitRealm = entry.name, entry.realm
unitName, unitRealm = entry.name, entry.realm
curGUID = nil
curGUID = nil
else
else
if (not unit or not UnitExists(unit)) then
if (not unit or not UnitExists(unit)) then
unit = "player"
unit = "player"
end
end
unitName, unitRealm = UnitName(unit)
unitName, unitRealm = UnitName(unit)
curGUID = UnitGUID(unit)
curGUID = UnitGUID(unit)


if not CanInspect(unit) then
if not CanInspect(unit) then
entry = self:GetExaminerCache(unit)
entry = self:GetExaminerCache(unit)
if entry then
if entry then
cached = true
cached = true
cacheItems = entry.Items
cacheItems = entry.Items
end
end
else
else
--ClearInspectPlayer()
--ClearInspectPlayer()
--NotifyInspect(unit)
--NotifyInspect(unit)
end
end
end
end
if unitRealm == "" then unitRealm = nil end
if unitRealm == "" then unitRealm = nil end
curUnit = unit
curUnit = unit
curUnitName = unitName
curUnitName = unitName
curUser = self:FullUnitName(unitName, unitRealm)
curUser = self:FullUnitName(unitName, unitRealm)
TITLE:SetText("InspectEquip: " .. curUser .. (cached and " (Cache)" or ""))
TITLE:SetText("InspectEquip: " .. curUser .. (cached and " (Cache)" or ""))


self:ResetDisplay()
self:ResetDisplay()


local items = { cats = {}, items = {} }
local items = { cats = {}, items = {} }
local itemsFound = false
local itemsFound = false
local getItem
local getItem
if cached then
if cached then
getItem = function(slot)
getItem = function(slot)
local istr = cacheItems[slot]
local istr = cacheItems[slot]
if istr then
if istr then
local itemId = tonumber(istr:match("item:(%d+)"))
local itemId = tonumber(istr:match("item:(%d+)"))
return select(2, GetItemInfo(istr)) or ("[" .. itemId .. "]")
return select(2, GetItemInfo(istr)) or ("[" .. itemId .. "]")
else
else
return nil
return nil
end
end
end
end
else
else
getItem = function(slot) return GetInventoryItemLink(unit, GetInventorySlotInfo(slot)) end
getItem = function(slot) return GetInventoryItemLink(unit, GetInventorySlotInfo(slot)) end
end
end


local calciv = InspectEquipConfig.showAvgItemLevel
local calciv = InspectEquipConfig.showAvgItemLevel
local iLevelSum, iCount = 0,0
local iLevelSum, iCount = 0,0


local artifactLevel = 0
local artifactCount = 0

for _,slot in pairs(slots) do
for _,slot in pairs(slots) do
local itemLink = getItem(slot)
local itemLink = getItem(slot)
local isArtifact = false

if itemLink then
if itemLink then
-- get source
-- get source
local source = self:GetItemSourceCategories(itemLink)
local source = self:GetItemSourceCategories(itemLink)
if (not source) and InspectEquipConfig.showUnknown then
if (not source) and InspectEquipConfig.showUnknown then
local _,_,rar = GetItemInfo(itemLink)
local _,_,rar,ilvl = GetItemInfo(itemLink)
if rar and rar >= 2 then
if rar and rar >= 2 then
source = {L["Unknown"]}
if rar == 6 then
source = {L["Artifact"]}
else
source = {L["Unknown"]}
end
end
end

if slot == "MainHandSlot" or slot == "SecondaryHandSlot" then
local _,_,rar,ilvl = GetItemInfo(itemLink)

if rar and rar == 6 then -- artifact found
isArtifact = true
artifactCount = artifactCount + 1 -- count only count, lol. ilvl will be get as usual
end
end
end
end


if source then
if source then
local enchantId = tonumber(itemLink:match("Hitem:%d+:(%d+):"))
local enchantId = tonumber(itemLink:match("Hitem:%d+:(%d+):"))
itemsFound = true
itemsFound = true


-- find category
-- find category
local cat = items
local cat = items
local entry
local entry
for _, entry in pairs(source) do
for _, entry in pairs(source) do
if cat.cats[entry] == nil then
if cat.cats[entry] == nil then
cat.cats[entry] = { count = 0, cats = {}, items = {} }
cat.cats[entry] = { count = 0, cats = {}, items = {} }
end
end
cat = cat.cats[entry]
cat = cat.cats[entry]
cat.count = cat.count + 1
cat.count = cat.count + 1
end
end


-- add item to category
-- add item to category
cat.hasItems = true
cat.hasItems = true
cat.items[cat.count] = {link = itemLink, enchant = enchantId, slot = slot}
cat.items[cat.count] = {link = itemLink, enchant = enchantId, slot = slot}
end
end


-- calculate avg ilvl
-- calculate avg ilvl
if calciv then
if calciv then
local lvl = ItemUpgradeInfo:GetUpgradedItemLevel(itemLink)
local lvl = ItemUpgradeInfo:GetUpgradedItemLevel(itemLink)

if lvl then
if lvl then
iLevelSum = iLevelSum + lvl

iCount = iCount + 1
if isArtifact then
if lvl > artifactLevel then -- find out max artifact level from both items
artifactLevel = lvl
end
else
iLevelSum = iLevelSum + lvl
iCount = iCount + 1
end
end
end
end
end
elseif not cached then
elseif not cached then
local texture = GetInventoryItemTexture(unit, GetInventorySlotInfo(slot))
local texture = GetInventoryItemTexture(unit, GetInventorySlotInfo(slot))
if texture and not retryTimer then
if texture and not retryTimer then
-- item link is not yet available, but item texture is, i.e. the slot is not empty
-- item link is not yet available, but item texture is, i.e. the slot is not empty
-- item link data will become available shortly, so we just try it again in a sec
-- item link data will become available shortly, so we just try it again in a sec
retryTimer = self:ScheduleTimer("Inspect", 1, unit)
retryTimer = self:ScheduleTimer("Inspect", 1, unit)
end
end
end
end
end
end


if itemsFound then
if itemsFound then
self:AddCategory(items, 0)
self:AddCategory(items, 0)
if calciv and iCount > 0 then
if calciv and iCount > 0 then
iLevelSum = iLevelSum + artifactLevel * artifactCount
iCount = iCount + artifactCount

local avgLvl = iLevelSum / iCount
local avgLvl = iLevelSum / iCount
AVGIL:SetText(L["Avg. Item Level"] .. ": " .. string.format("%.2f", avgLvl))
AVGIL:SetText(L["Avg. Item Level"] .. ": " .. string.format("%.2f", avgLvl))
AVGIL:Show()
AVGIL:Show()
else
else
AVGIL:Hide()
AVGIL:Hide()
end
end
self:FixWindowSize()
self:FixWindowSize()
if WIN:GetParent() == CharacterFrame and ((GearManagerDialog and GearManagerDialog:IsVisible()) or (OutfitterFrame and OutfitterFrame:IsVisible())) then
if WIN:GetParent() == CharacterFrame and ((GearManagerDialog and GearManagerDialog:IsVisible()) or (OutfitterFrame and OutfitterFrame:IsVisible())) then
autoHidden = true
autoHidden = true
else
else
WIN:Show()
WIN:Show()
end
end
else
else
WIN:Hide()
WIN:Hide()
end
end
end
end


function IE:AddCategory(cat, padding)
function IE:AddCategory(cat, padding)
-- add items
-- add items
if cat.hasItems then
if cat.hasItems then
self:AddItems(cat.items, padding+1)
self:AddItems(cat.items, padding+1)
end
end


-- sort subcategories by item count
-- sort subcategories by item count
local t = {}
local t = {}
for name, subcat in pairs(cat.cats) do
for name, subcat in pairs(cat.cats) do
tinsert(t, {name = name, subcat = subcat})
tinsert(t, {name = name, subcat = subcat})
end
end
tsort(t, function(a,b) return a.subcat.count > b.subcat.count end)
tsort(t, function(a,b) return a.subcat.count > b.subcat.count end)


-- add subcategories
-- add subcategories
for i = 1, #t do
for i = 1, #t do
local name = t[i].name
local name = t[i].name
local subcat = t[i].subcat
local subcat = t[i].subcat
self:AddLine(padding, name .. " (" .. subcat.count .. ")")
self:AddLine(padding, name .. " (" .. subcat.count .. ")")
self:AddCategory(subcat, padding+1)
self:AddCategory(subcat, padding+1)
end
end
end
end


function IE:AddItems(tab, padding)
function IE:AddItems(tab, padding)
for _, item in pairs(tab) do
for _, item in pairs(tab) do
local suffix = ""
local suffix = ""
local prefix = ""
local prefix = ""
if InspectEquipConfig.listItemLevels then
if InspectEquipConfig.listItemLevels then
local ilvl = ItemUpgradeInfo:GetUpgradedItemLevel(item.link)
local ilvl = ItemUpgradeInfo:GetUpgradedItemLevel(item.link)
if ilvl then
if ilvl then
prefix = "|cffaaaaaa[" .. ilvl .. "]|r "
prefix = "|cffaaaaaa[" .. ilvl .. "]|r "
end
end
end
end
if InspectEquipConfig.checkEnchants and (item.enchant == 0) and (not noEnchantWarningSlots[item.slot]) then
if InspectEquipConfig.checkEnchants and (item.enchant == 0) and (not noEnchantWarningSlots[item.slot]) then
suffix = "|cffff0000*|r"
suffix = "|cffff0000*|r"
end
end
self:AddLine(padding, prefix .. item.link .. suffix, item.link, item)
self:AddLine(padding, prefix .. item.link .. suffix, item.link, item)
end
end
end
end


function IE:GetItemData(item)
function IE:GetItemData(item)
local id
local id
if type(item) == "number" then
if type(item) == "number" then
id = item
id = item
else -- item string/link
else -- item string/link
id = tonumber(item:match("item:(%d+)"))
id = tonumber(item:match("item:(%d+)"))
end
end


if id then
if id then
local isSrc = IS.Items[id]
local isSrc = IS.Items[id]
local locSrc = InspectEquipLocalDB.Items[id]
local locSrc = InspectEquipLocalDB.Items[id]
if isSrc and locSrc then
if isSrc and locSrc then
-- combine results
-- combine results
return locSrc .. ";" .. isSrc
return locSrc .. ";" .. isSrc
else
else
return isSrc or locSrc
return isSrc or locSrc
end
end
else
else
return nil
return nil
end
end
end
end


function IE:GetZoneName(id)
function IE:GetZoneName(id)
return IS.Zones[id] or InspectEquipLocalDB.Zones[id]
return IS.Zones[id] or InspectEquipLocalDB.Zones[id]
end
end


function IE:GetBossName(id)
function IE:GetBossName(id)
return IS.Bosses[id] or InspectEquipLocalDB.Bosses[id]
return IS.Bosses[id] or InspectEquipLocalDB.Bosses[id]
end
end


function IE:GetItemSourceCategories(itemLink)
function IE:GetItemSourceCategories(itemLink)
local data = IE:GetItemData(itemLink)
local data = IE:GetItemData(itemLink)
if data then
if data then
for entry in gmatch(data, "[^;]+") do
for entry in gmatch(data, "[^;]+") do
local next_field = gmatch(entry, "[^_]+")
local next_field = gmatch(entry, "[^_]+")
local cat = next_field()
local cat = next_field()


if cat == "r" or cat == "d" then
if cat == "r" or cat == "d" then
-- raid/dungeon
-- raid/dungeon
local zone = IE:GetZoneName(tonumber(next_field()))
local zone = IE:GetZoneName(tonumber(next_field()))
local mode = next_field()
local mode = next_field()
local zoneType
local zoneType
if cat == "r" then zoneType = L["Raid"] else zoneType = L["Instances"] end
if cat == "r" then zoneType = L["Raid"] else zoneType = L["Instances"] end
return {zoneType, zone}
return {zoneType, zone}
elseif cat == "v" or cat == "g" then
elseif cat == "v" or cat == "g" then
-- vendor
-- vendor
local mainCat
local mainCat
if cat == "v" then mainCat = L["Vendor"] else mainCat = L["Guild Vendor"] end
if cat == "v" then mainCat = L["Vendor"] else mainCat = L["Guild Vendor"] end
local typ = next_field()
local typ = next_field()
while typ do
while typ do
if typ == "c" then
if typ == "c" then
-- currency
-- currency
local currency = tonumber(next_field())
local currency = tonumber(next_field())
next_field()
next_field()
local curName = GetCurrencyInfo(currency)
local curName = GetCurrencyInfo(currency)
return {mainCat, curName}
return {mainCat, curName}
elseif typ == "i" then
elseif typ == "i" then
-- item
-- item
next_field()
next_field()
elseif typ == "m" then
elseif typ == "m" then
-- money
-- money
next_field()
next_field()
end
end
typ = next_field()
typ = next_field()
end
end
return {mainCat}
return {mainCat}
elseif cat == "f" then
elseif cat == "f" then
-- reputation rewards
-- reputation rewards
return {L["Reputation rewards"]}
return {L["Reputation rewards"]}
elseif cat == "m" then
elseif cat == "m" then
-- darkmoon cards
-- darkmoon cards
return {L["Darkmoon Faire"]}
return {L["Darkmoon Faire"]}
elseif cat == "w" then
elseif cat == "w" then
-- world drops
-- world drops
return {L["World drops"]}
return {L["World drops"]}
elseif cat == "c" then
elseif cat == "c" then
-- crafted
-- crafted
return {L["Crafted"]}
return {L["Crafted"]}
elseif cat == "q" then
elseif cat == "q" then
-- quest rewards
-- quest rewards
return {L["Quest Reward"]}
return {L["Quest Reward"]}
end
end


end
end
end
end
return nil
return nil
end
end


function IE:FixWindowSize()
function IE:FixWindowSize()
local maxwidth = TITLE:GetStringWidth()
local maxwidth = TITLE:GetStringWidth()
for i = 1, numlines do
for i = 1, numlines do
local width = lines[i].text:GetStringWidth() + lines[i].padLeft
local width = lines[i].text:GetStringWidth() + lines[i].padLeft
if maxwidth < width then maxwidth = width end
if maxwidth < width then maxwidth = width end
end
end
local height = (curline * 15) + 55
local height = (curline * 15) + 55
if InspectEquipConfig.showAvgItemLevel then
if InspectEquipConfig.showAvgItemLevel then
height = height + 15
height = height + 15
end
end
WIN:SetWidth(maxwidth + 40)
WIN:SetWidth(maxwidth + 40)
WIN:SetHeight(height)
WIN:SetHeight(height)
end
end


function IE.Line_OnEnter(row)
function IE.Line_OnEnter(row)
if row.link then
if row.link then
-- anchor on the correct side based on where there's more room
-- anchor on the correct side based on where there's more room
GameTooltip:SetOwner(row, "ANCHOR_NONE")
GameTooltip:SetOwner(row, "ANCHOR_NONE")
local ycenter = select(2, row:GetCenter()) * row:GetEffectiveScale()
local ycenter = select(2, row:GetCenter()) * row:GetEffectiveScale()
if ycenter > select(2, UIParent:GetCenter()) * UIParent:GetScale() then
if ycenter > select(2, UIParent:GetCenter()) * UIParent:GetScale() then
GameTooltip:SetPoint("TOPLEFT", row, "BOTTOMLEFT")
GameTooltip:SetPoint("TOPLEFT", row, "BOTTOMLEFT")
else
else
GameTooltip:SetPoint("BOTTOMLEFT", row, "TOPLEFT")
GameTooltip:SetPoint("BOTTOMLEFT", row, "TOPLEFT")
end
end
if (not cached) and (UnitName(curUnit) == curUnitName) then
if (not cached) and (UnitName(curUnit) == curUnitName) then
row.link = GetInventoryItemLink(curUnit, GetInventorySlotInfo(row.item.slot)) or row.link
row.link = GetInventoryItemLink(curUnit, GetInventorySlotInfo(row.item.slot)) or row.link
end
end
GameTooltip:SetHyperlink(row.link)
GameTooltip:SetHyperlink(row.link)
if row.item and InspectEquipConfig.checkEnchants and (row.item.enchant == 0) and (not noEnchantWarningSlots[row.item.slot]) then
if row.item and InspectEquipConfig.checkEnchants and (row.item.enchant == 0) and (not noEnchantWarningSlots[row.item.slot]) then
GameTooltip:AddLine(" ")
GameTooltip:AddLine(" ")
GameTooltip:AddLine("|cffff0000" .. L["Item is not enchanted"] .. "|r")
GameTooltip:AddLine("|cffff0000" .. L["Item is not enchanted"] .. "|r")
end
end
GameTooltip:Show()
GameTooltip:Show()
end
end
end
end


function IE.Line_OnLeave(row)
function IE.Line_OnLeave(row)
GameTooltip:Hide()
GameTooltip:Hide()
end
end


function IE.Line_OnClick(row, button)
function IE.Line_OnClick(row, button)
if row.link then
if row.link then
if IsControlKeyDown() then
if IsControlKeyDown() then
DressUpItemLink(row.link)
DressUpItemLink(row.link)
elseif IsShiftKeyDown() then
elseif IsShiftKeyDown() then
ChatEdit_InsertLink(row.link)
ChatEdit_InsertLink(row.link)
end
end
end
end
end
end