You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

630 lines
20 KiB

AzeriteTooltip = LibStub("AceAddon-3.0"):NewAddon("AzeriteTooltip", "AceEvent-3.0", "AceHook-3.0")
local locationIDs = {
["Head"] = 1,
["Shoulder"] = 3,
["Chest"] = 5,
}
local itemEquipLocToSlot = {
["INVTYPE_HEAD"] = 1,
["INVTYPE_SHOULDER"] = 3,
["INVTYPE_CHEST"] = 5,
["INVTYPE_ROBE"] = 5
}
local rings = {
1,
2,
}
local addText = ""
StaticPopupDialogs["ReloadUI_Popup"] = {
text = "Reload your UI to apply changes?",
button1 = "Reload",
button2 = "Later",
OnAccept = function()
ReloadUI()
end,
timeout = 0,
whileDead = true,
hideOnEscape = true,
preferredIndex = 3,
}
local defaults_settings = {
profile = {
removeblizzard = true,
onlyspec = false,
compact = false,
bags = true,
icon_anchor = "BOTTOMLEFT",
paperdoll = true,
}
}
function AzeriteTooltip:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("AzeriteTooltipDB", defaults_settings, true)
self.settings = self.db.profile
self:SetupOptions()
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("AzeriteTooltip", "AzeriteTooltip")
end
function AzeriteTooltip:SetupOptions()
self.options = {
name = "AzeriteTooltip",
descStyle = "inline",
type = "group",
childGroups = "tab",
args = {
desc = {
type = "description",
name = "Lightweight addon that shows azerite traits on tooltip/gear.",
fontSize = "medium",
order = 1
},
author = {
type = "description",
name = "\n|cffffd100Author: |r Kygo @ EU-Hyjal",
order = 2
},
version = {
type = "description",
name = "|cffffd100Version: |r" .. GetAddOnMetadata("AzeriteTooltip", "Version") .."\n",
order = 3
},
removeblizzard = {
name = "Remove Blizzard Text",
desc = "|cffaaaaaaReplace blizzard's default text. |r",
descStyle = "inline",
width = "full",
type = "toggle",
order = 4,
set = function(info,val)
self.settings.removeblizzard = val
end,
get = function(info) return self.settings.removeblizzard end
},
onlyspec = {
name = "Only Spec",
desc = "|cffaaaaaaShow only traits for your current specialization. |r",
descStyle = "inline",
width = "full",
type = "toggle",
order = 5,
set = function(info,val)
self.settings.onlyspec = val
end,
get = function(info) return self.settings.onlyspec end
},
compact = {
name = "Compact Mode",
desc = "|cffaaaaaaTraits will show in a more compact layout. |r",
descStyle = "inline",
width = "full",
type = "toggle",
order = 6,
set = function(info,val)
self.settings.compact = val
end,
get = function(info) return self.settings.compact end
},
bags = {
name = "Show traits in bags",
desc = "|cffaaaaaaShow two main traits on gear in bags (works only with Blizzard Bags and Bagnon). |r",
descStyle = "inline",
width = "full",
type = "toggle",
order = 7,
set = function(info,val)
StaticPopup_Show("ReloadUI_Popup")
self.settings.bags = val
end,
get = function(info) return self.settings.bags end
},
paperdoll = {
name = "Show traits in character frame",
desc = "|cffaaaaaaShow two main traits on gear on character frame. |r",
descStyle = "inline",
width = "full",
type = "toggle",
order = 8,
set = function(info,val)
StaticPopup_Show("ReloadUI_Popup")
self.settings.paperdoll = val
end,
get = function(info) return self.settings.paperdoll end
},
icon_anchor = {
type = "select",
name = "Icon Anchor",
style = "dropdown",
values = {
["TOPLEFT"] = "TOP", -- 0
["BOTTOMLEFT"] = "BOTTOM", -- 1
},
order = 9,
set = function(info,val)
self.settings.icon_anchor = val
end,
get = function(info)
return self.settings.icon_anchor
end
},
}
}
LibStub("AceConfig-3.0"):RegisterOptionsTable("AzeriteTooltip", self.options)
end
function AzeriteTooltip:OnEnable()
self:SecureHook('PaperDollItemSlotButton_Update')
self:SecureHook('EquipmentFlyout_DisplayButton')
self:SecureHook('ContainerFrame_Update')
if IsAddOnLoaded("Bagnon") then
hooksecurefunc(Bagnon.Item, "Update", function(self)
if not AzeriteTooltip.db.profile.bags then return end
AzeriteTooltip:SetContainerAzerite(self)
end)
end
self:SecureHookScript(GameTooltip, 'OnTooltipSetItem', 'OnTooltipSetItem')
self:SecureHookScript(ItemRefTooltip, 'OnTooltipSetItem', 'OnTooltipSetItem')
self:SecureHookScript(ShoppingTooltip1, 'OnTooltipSetItem', 'OnTooltipSetItem')
self:SecureHookScript(EmbeddedItemTooltip, 'OnTooltipSetItem', 'OnTooltipSetItem')
end
function AzeriteTooltip:GetSpellID(powerID)
local powerInfo = C_AzeriteEmpoweredItem.GetPowerInfo(powerID)
if (powerInfo) then
local azeriteSpellID = powerInfo["spellID"]
return azeriteSpellID
end
end
function AzeriteTooltip:HasUnselectedPower(tooltip)
local AzeriteUnlock = strsplit("%d", AZERITE_POWER_UNLOCKED_AT_LEVEL)
for i = 8, tooltip:NumLines() do
local left = _G[tooltip:GetName().."TextLeft"..i]
local text = left:GetText()
if text and ( text:find(AzeriteUnlock) or text:find(NEW_AZERITE_POWER_AVAILABLE) ) then
return true
end
end
end
function AzeriteTooltip:ScanSelectedTraits(tooltip, powerName)
local empowered = GetSpellInfo(263978)
for i = 8, tooltip:NumLines() do
local left = _G[tooltip:GetName().."TextLeft"..i]
local text = left:GetText()
local newText
local newPowerName
if text and text:find("-") then
newText = string.gsub(text, "-", " ")
end
if powerName:find("-") then
newPowerName = string.gsub(powerName, "-", " ")
end
if text and text:find(powerName) then
return true
elseif (newText and newPowerName and newText:match(newPowerName)) then
return true
elseif (powerName == empowered and not self:HasUnselectedPower(tooltip)) then
return true
end
end
end
function AzeriteTooltip:GetAzeriteLevel()
local level
local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem()
if azeriteItemLocation then
level = C_AzeriteItem.GetPowerLevel(azeriteItemLocation)
else
level = 0
end
return level
end
function AzeriteTooltip:ClearBlizzardText(tooltip)
local textLeft = tooltip.textLeft
if not textLeft then
local tooltipName = tooltip:GetName()
textLeft = setmetatable({}, { __index = function(t, i)
local line = _G[tooltipName .. "TextLeft" .. i]
t[i] = line
return line
end })
tooltip.textLeft = textLeft
end
for i = 7, tooltip:NumLines() do
if textLeft then
local line = textLeft[i]
local text = line:GetText()
local r, g, b = line:GetTextColor()
if text then
local ActiveAzeritePowers = strsplit("(%d/%d)", CURRENTLY_SELECTED_AZERITE_POWERS) -- Active Azerite Powers (%d/%d)
local AzeritePowers = strsplit("(0/%d)", TOOLTIP_AZERITE_UNLOCK_LEVELS) -- Azerite Powers (0/%d)
local AzeriteUnlock = strsplit("%d", AZERITE_POWER_UNLOCKED_AT_LEVEL) -- Unlocked at Heart of Azeroth Level %d
local Durability = strsplit("%d / %d", DURABILITY_TEMPLATE)
local ReqLevel = strsplit("%d", ITEM_MIN_LEVEL)
if text:match(NEW_AZERITE_POWER_AVAILABLE) then
line:SetText("")
end
if text:find(AzeriteUnlock) then
line:SetText("")
end
if text:find(Durability) or text:find(ReqLevel) then
textLeft[i-1]:SetText("")
end
if text:find(ActiveAzeritePowers) then
textLeft[i-1]:SetText("")
line:SetText("")
textLeft[i+1]:SetText(addText)
elseif (text:find(AzeritePowers) and not text:find(">")) then
textLeft[i-1]:SetText("")
line:SetText("")
textLeft[i+1]:SetText(addText)
-- 8.1 FIX --
elseif text:find(AZERITE_EMPOWERED_ITEM_FULLY_UPGRADED) then
textLeft[i-1]:SetText("")
line:SetText(addText)
textLeft[i+1]:SetText("")
end
end
end
end
end
function AzeriteTooltip:RemovePowerText(tooltip, powerName)
local textLeft = tooltip.textLeft
if not textLeft then
local tooltipName = tooltip:GetName()
textLeft = setmetatable({}, { __index = function(t, i)
local line = _G[tooltipName .. "TextLeft" .. i]
t[i] = line
return line
end })
tooltip.textLeft = textLeft
end
for i = 7, tooltip:NumLines() do
if textLeft then
local enchanted = strsplit("%d", ENCHANTED_TOOLTIP_LINE)
local use = strsplit("%d", ITEM_SPELL_TRIGGER_ONUSE)
local line = textLeft[i]
local text = line:GetText()
local r, g, b = line:GetTextColor()
local newText
local newPowerName
if text and text:find("-") then
newText = string.gsub(text, "-", " ")
end
if powerName:find("-") then
newPowerName = string.gsub(powerName, "-", " ")
end
if text then
if text:match(CURRENTLY_SELECTED_AZERITE_POWERS_INSPECT) then return end
if text:find("- "..powerName) then
line:SetText("")
elseif (newText and newPowerName and newText:match(newPowerName)) then
line:SetText("")
end
if ( r < 0.1 and g > 0.9 and b < 0.1 and not text:find(">") and not text:find(ITEM_SPELL_TRIGGER_ONEQUIP) and not text:find(enchanted) and not text:find(use) ) then
line:SetText("")
end
end
end
end
end
function AzeriteTooltip:BuildTooltip(self)
local name, link = self:GetItem()
if not name then return end
if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItemByID(link) then
addText = ""
local currentLevel = AzeriteTooltip:GetAzeriteLevel()
local specID = GetSpecializationInfo(GetSpecialization())
local allTierInfo = C_AzeriteEmpoweredItem.GetAllTierInfoByItemID(link)
if not allTierInfo then return end
local activePowers = {}
local activeAzeriteTrait = false
if AzeriteTooltip.db.profile.compact then
for j=1, 5 do
if not allTierInfo[j] then break end
local tierLevel = allTierInfo[j]["unlockLevel"]
local azeritePowerID = allTierInfo[j]["azeritePowerIDs"][1]
if not allTierInfo[1]["azeritePowerIDs"][1] then return end
local azeriteTooltipText = " "
for i, _ in pairs(allTierInfo[j]["azeritePowerIDs"]) do
local azeritePowerID = allTierInfo[j]["azeritePowerIDs"][i]
local azeriteSpellID = AzeriteTooltip:GetSpellID(azeritePowerID)
local azeritePowerName, _, icon = GetSpellInfo(azeriteSpellID)
if tierLevel <= currentLevel then
if AzeriteTooltip:ScanSelectedTraits(self, azeritePowerName) then
local azeriteIcon = '|T'..icon..':24:24:0:0:64:64:4:60:4:60:255:255:255|t'
azeriteTooltipText = azeriteTooltipText.." >"..azeriteIcon.."<"
tinsert(activePowers, {name = azeritePowerName})
activeAzeriteTrait = true
elseif C_AzeriteEmpoweredItem.IsPowerAvailableForSpec(azeritePowerID, specID) then
local azeriteIcon = '|T'..icon..':24:24:0:0:64:64:4:60:4:60:255:255:255|t'
azeriteTooltipText = azeriteTooltipText.." "..azeriteIcon
elseif not AzeriteTooltip.db.profile.onlyspec or IsControlKeyDown() then
local azeriteIcon = '|T'..icon..':24:24:0:0:64:64:4:60:4:60:150:150:150|t'
azeriteTooltipText = azeriteTooltipText.." "..azeriteIcon
end
elseif C_AzeriteEmpoweredItem.IsPowerAvailableForSpec(azeritePowerID, specID) then
local azeriteIcon = '|T'..icon..':24:24:0:0:64:64:4:60:4:60:150:150:150|t'
azeriteTooltipText = azeriteTooltipText.." "..azeriteIcon
elseif not AzeriteTooltip.db.profile.onlyspec or IsControlKeyDown() then
local azeriteIcon = '|T'..icon..':24:24:0:0:64:64:4:60:4:60:150:150:150|t'
azeriteTooltipText = azeriteTooltipText.." "..azeriteIcon
end
end
if tierLevel <= currentLevel then
if j > 1 then
addText = addText.."\n \n|cFFffcc00Level "..tierLevel..azeriteTooltipText.."|r"
else
addText = addText.."\n|cFFffcc00Level "..tierLevel..azeriteTooltipText.."|r"
end
else
if j > 1 then
addText = addText.."\n \n|cFF7a7a7aLevel "..tierLevel..azeriteTooltipText.."|r"
else
addText = addText.."\n|cFF7a7a7aLevel "..tierLevel..azeriteTooltipText.."|r"
end
end
end
else
for j=1, 5 do
if not allTierInfo[j] then break end
local tierLevel = allTierInfo[j]["unlockLevel"]
local azeritePowerID = allTierInfo[j]["azeritePowerIDs"][1]
if not allTierInfo[1]["azeritePowerIDs"][1] then return end
local r, g, b
if tierLevel <= currentLevel then
r, g, b = 1, 0.8, 0
else
r, g, b = 0.5, 0.5, 0.5
end
local rgb = ("ff%.2x%.2x%.2x"):format(r*255, g*255, b*255)
if j > 1 then
addText = addText.. "\n\n|c" .. rgb .. format(" Level %d", tierLevel) .. "|r\n"
else
addText = addText.. "\n|c" .. rgb .. format(" Level %d", tierLevel) .. "|r\n"
end
for i, v in pairs(allTierInfo[j]["azeritePowerIDs"]) do
local azeritePowerID = allTierInfo[j]["azeritePowerIDs"][i]
local azeriteSpellID = AzeriteTooltip:GetSpellID(azeritePowerID)
local azeritePowerName, _, icon = GetSpellInfo(azeriteSpellID)
local azeriteIcon = '|T'..icon..':20:20:0:0:64:64:4:60:4:60|t'
local azeriteTooltipText = " "..azeriteIcon.." "..azeritePowerName
if tierLevel <= currentLevel then
if AzeriteTooltip:ScanSelectedTraits(self, azeritePowerName) then
tinsert(activePowers, {name = azeritePowerName})
activeAzeriteTrait = true
addText = addText.."\n|cFF00FF00"..azeriteTooltipText.."|r"
elseif C_AzeriteEmpoweredItem.IsPowerAvailableForSpec(azeritePowerID, specID) then
addText = addText.."\n|cFFFFFFFF"..azeriteTooltipText.."|r"
elseif not AzeriteTooltip.db.profile.onlyspec or IsControlKeyDown() then
addText = addText.."\n|cFF7a7a7a"..azeriteTooltipText.."|r"
end
elseif C_AzeriteEmpoweredItem.IsPowerAvailableForSpec(azeritePowerID, specID) then
addText = addText.."\n|cFF7a7a7a"..azeriteTooltipText.."|r"
elseif not AzeriteTooltip.db.profile.onlyspec or IsControlKeyDown() then
addText = addText.."\n|cFF7a7a7a"..azeriteTooltipText.."|r"
end
end
end
end
if AzeriteTooltip.db.profile.removeblizzard then
if activeAzeriteTrait then
for k, v in pairs(activePowers) do
AzeriteTooltip:RemovePowerText(self, v.name)
end
end
AzeriteTooltip:ClearBlizzardText(self)
else
self:AddLine(addText)
self:AddLine(" ")
end
wipe(activePowers)
end
end
function AzeriteTooltip:CreateAzeriteIcons(button, azeriteEmpoweredItemLocation)
if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(azeriteEmpoweredItemLocation) then
if not button.azerite then
button.azerite = CreateFrame("Frame", "$parent.azerite", button);
button.azerite:SetPoint(AzeriteTooltip.db.profile.icon_anchor, button, AzeriteTooltip.db.profile.icon_anchor)
button.azerite:SetSize(37, 18)
else
button.azerite:ClearAllPoints()
button.azerite:SetPoint(AzeriteTooltip.db.profile.icon_anchor, button, AzeriteTooltip.db.profile.icon_anchor)
button.azerite:Show()
end
local allTierInfo = C_AzeriteEmpoweredItem.GetAllTierInfo(azeriteEmpoweredItemLocation)
local noneSelected = true
for j, k in ipairs(rings) do
if not allTierInfo[j] then break end
local azeritePowerID = allTierInfo[k]["azeritePowerIDs"][1]
if not allTierInfo[1]["azeritePowerIDs"][1] then return end
for i, _ in pairs(allTierInfo[k]["azeritePowerIDs"]) do
local azeritePowerID = allTierInfo[k]["azeritePowerIDs"][i]
local azeriteSpellID = AzeriteTooltip:GetSpellID(azeritePowerID)
local azeritePowerName, _, icon = GetSpellInfo(azeriteSpellID)
if C_AzeriteEmpoweredItem.IsPowerSelected(azeriteEmpoweredItemLocation, azeritePowerID) then
noneSelected = false
if not button.azerite[j] then
button.azerite[j] = button.azerite:CreateTexture("$parent."..j, "OVERLAY", nil, button.azerite)
if j == 1 then
button.azerite[j]:SetPoint(AzeriteTooltip.db.profile.icon_anchor, button, AzeriteTooltip.db.profile.icon_anchor)
else
button.azerite[j]:SetPoint("BOTTOMLEFT", button.azerite[j-1], "BOTTOMRIGHT", 4, 0)
end
button.azerite[j]:SetSize(16, 16)
button.azerite[j]:SetTexture(icon)
-- Border
button.azerite[j].overlay = button.azerite:CreateTexture(nil, "ARTWORK", nil, 7)
button.azerite[j].overlay:SetTexture([[Interface\TargetingFrame\UI-TargetingFrame-Stealable]])
button.azerite[j].overlay:SetVertexColor(0.7,0.7,0.7,0.8)
button.azerite[j].overlay:SetPoint("TOPLEFT", button.azerite[j], -3, 3)
button.azerite[j].overlay:SetPoint("BOTTOMRIGHT", button.azerite[j], 3, -3)
button.azerite[j].overlay:SetBlendMode("ADD")
else
if j == 1 then
button.azerite[j]:ClearAllPoints()
button.azerite[j]:SetPoint(AzeriteTooltip.db.profile.icon_anchor, button, AzeriteTooltip.db.profile.icon_anchor)
end
button.azerite[j]:SetTexture(icon)
end
end
end
end
if noneSelected then button.azerite:Hide() end
else
if button.azerite then
button.azerite:Hide()
end
end
end
function AzeriteTooltip:SetContainerAzerite(self)
local name = self:GetName();
for i = 1, self.size or 1 do
local button = self.size and _G[name .. "Item" .. i] or self;
local self = self.size and self or button:GetParent()
local link = GetContainerItemLink(self:GetID(), button:GetID())
if not button then
return
end;
if link then
local azeriteEmpoweredItemLocation = ItemLocation:CreateFromBagAndSlot(self:GetID(), button:GetID())
AzeriteTooltip:CreateAzeriteIcons(button, azeriteEmpoweredItemLocation)
else
if button.azerite then
button.azerite:Hide()
end
end
end
end
function AzeriteTooltip:SetPaperDollAzerite(self)
local button = self
local id = self:GetID();
local textureName = GetInventoryItemTexture("player", id);
local hasItem = textureName ~= nil;
if (id == 1 or id == 3 or id == 5) and hasItem then
local azeriteEmpoweredItemLocation = ItemLocation:CreateFromEquipmentSlot(id)
AzeriteTooltip:CreateAzeriteIcons(button, azeriteEmpoweredItemLocation)
else
if button.azerite then
button.azerite:Hide()
end
end
end
function AzeriteTooltip:SetFlyoutAzerite(self)
if self.azerite then
self.azerite:Hide()
end
if ( not self.location ) then
return;
end
if ( self.location >= EQUIPMENTFLYOUT_FIRST_SPECIAL_LOCATION ) then
return;
end
local _, _, _, _, slot, bag = EquipmentManager_UnpackLocation(self.location)
local azeriteEmpoweredItemLocation = ItemLocation:CreateFromBagAndSlot(bag, slot)
local button = self
if not bag then return end
if not button then
return
end;
AzeriteTooltip:CreateAzeriteIcons(button, azeriteEmpoweredItemLocation)
end
-- HOOKS
function AzeriteTooltip:ContainerFrame_Update(frame)
if not AzeriteTooltip.db.profile.bags then return end
self:SetContainerAzerite(frame)
end
function AzeriteTooltip:PaperDollItemSlotButton_Update(frame)
if not AzeriteTooltip.db.profile.paperdoll then return end
self:SetPaperDollAzerite(frame)
end
function AzeriteTooltip:EquipmentFlyout_DisplayButton(frame)
if not AzeriteTooltip.db.profile.paperdoll then return end
self:SetFlyoutAzerite(frame)
end
function AzeriteTooltip:OnTooltipSetItem(frame)
self:BuildTooltip(frame)
end
SLASH_AZERITETOOLTIP1 = "/azeritetooltip"
SLASH_AZERITETOOLTIP2 = "/at"
SlashCmdList["AZERITETOOLTIP"] = function()
InterfaceOptionsFrame_OpenToCategory("AzeriteTooltip")
InterfaceOptionsFrame_OpenToCategory("AzeriteTooltip")
end