266 lines
6.9 KiB
Lua
266 lines
6.9 KiB
Lua
local addonName = ...
|
|
|
|
local EquippedItemLevel = CreateFrame("Frame")
|
|
_G[addonName] = EquippedItemLevel
|
|
|
|
local slots = {
|
|
{ id = 1, frame = "CharacterHeadSlot" },
|
|
{ id = 2, frame = "CharacterNeckSlot" },
|
|
{ id = 3, frame = "CharacterShoulderSlot" },
|
|
{ id = 5, frame = "CharacterChestSlot" },
|
|
{ id = 6, frame = "CharacterWaistSlot" },
|
|
{ id = 7, frame = "CharacterLegsSlot" },
|
|
{ id = 8, frame = "CharacterFeetSlot" },
|
|
{ id = 9, frame = "CharacterWristSlot" },
|
|
{ id = 10, frame = "CharacterHandsSlot" },
|
|
{ id = 11, frame = "CharacterFinger0Slot" },
|
|
{ id = 12, frame = "CharacterFinger1Slot" },
|
|
{ id = 13, frame = "CharacterTrinket0Slot" },
|
|
{ id = 14, frame = "CharacterTrinket1Slot" },
|
|
{ id = 15, frame = "CharacterBackSlot" },
|
|
{ id = 16, frame = "CharacterMainHandSlot" },
|
|
{ id = 17, frame = "CharacterSecondaryHandSlot" },
|
|
}
|
|
|
|
local itemLevels = {}
|
|
local updateQueued = false
|
|
local characterFrameHooked = false
|
|
local bagFrameHooks = {}
|
|
local equippedLowest, equippedHighest
|
|
|
|
local function GetCachedItemInfo(itemLink)
|
|
if C_Item and C_Item.GetItemInfo then
|
|
return C_Item.GetItemInfo(itemLink)
|
|
end
|
|
|
|
if GetItemInfo then
|
|
return GetItemInfo(itemLink)
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function GetItemLevel(itemLink)
|
|
if not itemLink then
|
|
return nil
|
|
end
|
|
|
|
if C_Item and C_Item.GetDetailedItemLevelInfo then
|
|
local level = C_Item.GetDetailedItemLevelInfo(itemLink)
|
|
if level and level > 0 then
|
|
return level
|
|
end
|
|
end
|
|
|
|
local _, _, _, level = GetCachedItemInfo(itemLink)
|
|
return level
|
|
end
|
|
|
|
local function GetGradientColor(level, lowest, highest)
|
|
if lowest == highest then
|
|
return 0, 1, 0
|
|
end
|
|
|
|
local progress = (level - lowest) / (highest - lowest)
|
|
progress = math.max(0, math.min(1, progress))
|
|
if progress <= 0.5 then
|
|
return 1, progress * 2, 0
|
|
end
|
|
|
|
return 2 - progress * 2, 1, 0
|
|
end
|
|
|
|
local function IsGearItem(itemLink)
|
|
if not itemLink then
|
|
return false
|
|
end
|
|
|
|
local _, _, _, _, _, _, _, _, equipLocation = GetCachedItemInfo(itemLink)
|
|
return equipLocation
|
|
and equipLocation ~= ""
|
|
and equipLocation ~= "INVTYPE_NON_EQUIP"
|
|
and equipLocation ~= "INVTYPE_NON_EQUIP_IGNORE"
|
|
and equipLocation ~= "INVTYPE_BAG"
|
|
and equipLocation ~= "INVTYPE_TABARD"
|
|
end
|
|
|
|
local function CreateLabel(slot)
|
|
local button = _G[slot.frame]
|
|
if not button or button.EquippedItemLevelLabel then
|
|
return
|
|
end
|
|
|
|
local label = button:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
label:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 2)
|
|
label:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE")
|
|
label:SetJustifyH("RIGHT")
|
|
label:Hide()
|
|
button.EquippedItemLevelLabel = label
|
|
end
|
|
|
|
function EquippedItemLevel:Update()
|
|
updateQueued = false
|
|
|
|
local lowest, highest
|
|
for _, slot in ipairs(slots) do
|
|
CreateLabel(slot)
|
|
|
|
local itemLink = GetInventoryItemLink("player", slot.id)
|
|
local level = GetItemLevel(itemLink)
|
|
itemLevels[slot.id] = level
|
|
|
|
if level then
|
|
lowest = not lowest and level or math.min(lowest, level)
|
|
highest = not highest and level or math.max(highest, level)
|
|
end
|
|
end
|
|
|
|
equippedLowest, equippedHighest = lowest, highest
|
|
|
|
for _, slot in ipairs(slots) do
|
|
local button = _G[slot.frame]
|
|
local label = button and button.EquippedItemLevelLabel
|
|
local level = itemLevels[slot.id]
|
|
|
|
if label and level and lowest and highest then
|
|
local red, green, blue = GetGradientColor(level, lowest, highest)
|
|
label:SetText(string.format("%.0f", level))
|
|
label:SetTextColor(red, green, blue)
|
|
label:Show()
|
|
elseif label then
|
|
label:Hide()
|
|
end
|
|
end
|
|
|
|
self:UpdateBagLabels()
|
|
end
|
|
|
|
function EquippedItemLevel:QueueUpdate()
|
|
if updateQueued then
|
|
return
|
|
end
|
|
|
|
updateQueued = true
|
|
C_Timer.After(0.1, function()
|
|
EquippedItemLevel:Update()
|
|
end)
|
|
end
|
|
|
|
function EquippedItemLevel:HookCharacterFrame()
|
|
if characterFrameHooked or not CharacterFrame then
|
|
return
|
|
end
|
|
|
|
CharacterFrame:HookScript("OnShow", function()
|
|
EquippedItemLevel:QueueUpdate()
|
|
end)
|
|
characterFrameHooked = true
|
|
end
|
|
|
|
function EquippedItemLevel:UpdateBagButton(button)
|
|
if not button or not button.GetBagID then
|
|
return
|
|
end
|
|
|
|
local label = button.EquippedItemLevelBagLabel
|
|
if not label then
|
|
label = button:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
label:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 2)
|
|
label:SetFont("Fonts\\FRIZQT__.TTF", 11, "OUTLINE")
|
|
label:SetJustifyH("RIGHT")
|
|
button.EquippedItemLevelBagLabel = label
|
|
end
|
|
|
|
local bag, slot = button:GetBagID(), button:GetID()
|
|
local itemLink = bag and slot and C_Container.GetContainerItemLink(bag, slot)
|
|
local level = GetItemLevel(itemLink)
|
|
if not level or not IsGearItem(itemLink) or not equippedLowest or not equippedHighest then
|
|
label:Hide()
|
|
return
|
|
end
|
|
|
|
local red, green, blue = GetGradientColor(level, equippedLowest, equippedHighest)
|
|
label:SetText(string.format("%.0f", level))
|
|
label:SetTextColor(red, green, blue)
|
|
label:Show()
|
|
end
|
|
|
|
function EquippedItemLevel:UpdateContainerFrame(frame)
|
|
if not frame then
|
|
return
|
|
end
|
|
|
|
if frame.EnumerateValidItems then
|
|
for _, button in frame:EnumerateValidItems() do
|
|
self:UpdateBagButton(button)
|
|
end
|
|
elseif frame.Items then
|
|
for _, button in ipairs(frame.Items) do
|
|
self:UpdateBagButton(button)
|
|
end
|
|
end
|
|
end
|
|
|
|
function EquippedItemLevel:HookBagFrame(frame)
|
|
if not frame or bagFrameHooks[frame] or not frame.Update then
|
|
return
|
|
end
|
|
|
|
hooksecurefunc(frame, "Update", function(updatedFrame)
|
|
EquippedItemLevel:UpdateContainerFrame(updatedFrame)
|
|
end)
|
|
bagFrameHooks[frame] = true
|
|
end
|
|
|
|
function EquippedItemLevel:UpdateBagLabels()
|
|
local index = 1
|
|
local frame = _G["ContainerFrame" .. index]
|
|
while frame do
|
|
self:HookBagFrame(frame)
|
|
self:UpdateContainerFrame(frame)
|
|
index = index + 1
|
|
frame = _G["ContainerFrame" .. index]
|
|
end
|
|
|
|
if ContainerFrameCombinedBags then
|
|
self:HookBagFrame(ContainerFrameCombinedBags)
|
|
self:UpdateContainerFrame(ContainerFrameCombinedBags)
|
|
end
|
|
end
|
|
|
|
local function AddTooltipItemLevel(tooltip, data)
|
|
-- The same data is supplied for normal and comparison tooltips, including
|
|
-- comparison panes that do not implement GameTooltip:GetItem().
|
|
local itemReference = data and (data.hyperlink or data.id)
|
|
if not itemReference or not IsGearItem(itemReference) then
|
|
return
|
|
end
|
|
|
|
local level = GetItemLevel(itemReference)
|
|
if not level then
|
|
return
|
|
end
|
|
|
|
local red, green, blue = GetGradientColor(level, equippedLowest or level, equippedHighest or level)
|
|
tooltip:AddDoubleLine("Item level", string.format("%.0f", level), 1, 0.82, 0, red, green, blue)
|
|
tooltip:Show()
|
|
end
|
|
|
|
function EquippedItemLevel:OnEvent(event)
|
|
if event == "PLAYER_LOGIN" then
|
|
TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, AddTooltipItemLevel)
|
|
|
|
end
|
|
|
|
self:HookCharacterFrame()
|
|
self:QueueUpdate()
|
|
end
|
|
|
|
EquippedItemLevel:RegisterEvent("PLAYER_LOGIN")
|
|
EquippedItemLevel:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
|
|
EquippedItemLevel:RegisterEvent("GET_ITEM_INFO_RECEIVED")
|
|
EquippedItemLevel:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
EquippedItemLevel:RegisterEvent("ADDON_LOADED")
|
|
EquippedItemLevel:RegisterEvent("BAG_UPDATE_DELAYED")
|
|
EquippedItemLevel:SetScript("OnEvent", EquippedItemLevel.OnEvent)
|