Files
ShaguTweaks-ClassicAPI/mods/equip-compare.lua
T

290 lines
9.5 KiB
Lua

local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API
local module = ShaguTweaks:register({
title = T["Equip Compare"],
description = T["Shows currently equipped items on tooltips while the shift key is pressed."],
expansions = { ["vanilla"] = true },
category = T["Tooltip & Items"],
enabled = true,
})
module.enable = function(self)
local sides = { "Left", "Right" }
local function AddHeader(tooltip)
local name = tooltip:GetName()
-- shift all entries one line down
for i=tooltip:NumLines(), 1, -1 do
for _, side in pairs(sides) do
local current = _G[name.."Text"..side..i]
local below = _G[name.."Text"..side..i+1]
if current and current:IsShown() then
local text = current:GetText()
local r, g, b = current:GetTextColor()
if text and text ~= "" then
if tooltip:NumLines() < i+1 then
-- add new line if required
tooltip:AddLine(text, r, g, b, true)
else
-- update existing lines
below:SetText(text)
below:SetTextColor(r, g, b)
below:Show()
-- hide processed line
current:Hide()
end
end
end
end
end
-- add label to first line
_G[name.."TextLeft1"]:SetTextColor(.5, .5, .5, 1)
_G[name.."TextLeft1"]:SetText(CURRENTLY_EQUIPPED)
_G[name.."TextLeft1"]:Show()
-- update tooltip sizes
tooltip:Show()
end
local itemtypes = {
["deDE"] = {
["INVTYPE_WAND"] = "Zauberstab",
["INVTYPE_THROWN"] = "Wurfwaffe",
["INVTYPE_GUN"] = "Schusswaffe",
["INVTYPE_CROSSBOW"] = "Armbrust",
["INVTYPE_PROJECTILE"] = "Projektil",
},
["enUS"] = {
["INVTYPE_WAND"] = "Wand",
["INVTYPE_THROWN"] = "Thrown",
["INVTYPE_GUN"] = "Gun",
["INVTYPE_CROSSBOW"] = "Crossbow",
["INVTYPE_PROJECTILE"] = "Projectile",
},
["esES"] = {
["INVTYPE_WAND"] = "Varita",
["INVTYPE_THROWN"] = "Arma arrojadiza",
["INVTYPE_GUN"] = "Arma de fuego",
["INVTYPE_CROSSBOW"] = "Ballesta",
["INVTYPE_PROJECTILE"] = "Proyectil",
},
["frFR"] = {
["INVTYPE_WAND"] = "Baguette",
["INVTYPE_THROWN"] = "Armes de jet",
["INVTYPE_GUN"] = "Arme à feu",
["INVTYPE_CROSSBOW"] = "Arbalète",
["INVTYPE_PROJECTILE"] = "Projectile",
},
["koKR"] = {
["INVTYPE_WAND"] = "마법봉",
["INVTYPE_THROWN"] = "투척 무기",
["INVTYPE_GUN"] = "총",
["INVTYPE_CROSSBOW"] = "석궁",
["INVTYPE_PROJECTILE"] = "투사체",
},
["ruRU"] = {
["INVTYPE_WAND"] = "Жезл",
["INVTYPE_THROWN"] = "Метательное",
["INVTYPE_GUN"] = "Огнестрельное",
["INVTYPE_CROSSBOW"] = "Арбалет",
["INVTYPE_PROJECTILE"] = "Боеприпасы",
},
["zhCN"] = {
["INVTYPE_WAND"] = "魔杖",
["INVTYPE_THROWN"] = "投掷武器",
["INVTYPE_GUN"] = "枪械",
["INVTYPE_CROSSBOW"] = "弩",
["INVTYPE_PROJECTILE"] = "弹药",
}
}
-- Vanilla misses a few inventory type labels in some locales.
local localeTypes = itemtypes[GetLocale()] or {}
for key, value in pairs(localeTypes) do setglobal(key, value) end
INVTYPE_WEAPON_OTHER = INVTYPE_WEAPON.."_other"
INVTYPE_FINGER_OTHER = INVTYPE_FINGER.."_other"
INVTYPE_TRINKET_OTHER = INVTYPE_TRINKET.."_other"
local slots = {
[INVTYPE_2HWEAPON] = "MainHandSlot",
[INVTYPE_BODY] = "ShirtSlot",
[INVTYPE_CHEST] = "ChestSlot",
[INVTYPE_CLOAK] = "BackSlot",
[INVTYPE_FEET] = "FeetSlot",
[INVTYPE_FINGER] = "Finger0Slot",
[INVTYPE_FINGER_OTHER] = "Finger1Slot",
[INVTYPE_HAND] = "HandsSlot",
[INVTYPE_HEAD] = "HeadSlot",
[INVTYPE_HOLDABLE] = "SecondaryHandSlot",
[INVTYPE_LEGS] = "LegsSlot",
[INVTYPE_NECK] = "NeckSlot",
[INVTYPE_RANGED] = "RangedSlot",
[INVTYPE_RELIC] = "RangedSlot",
[INVTYPE_ROBE] = "ChestSlot",
[INVTYPE_SHIELD] = "SecondaryHandSlot",
[INVTYPE_SHOULDER] = "ShoulderSlot",
[INVTYPE_TABARD] = "TabardSlot",
[INVTYPE_TRINKET] = "Trinket0Slot",
[INVTYPE_TRINKET_OTHER] = "Trinket1Slot",
[INVTYPE_WAIST] = "WaistSlot",
[INVTYPE_WEAPON] = "MainHandSlot",
[INVTYPE_WEAPON_OTHER] = "SecondaryHandSlot",
[INVTYPE_WEAPONMAINHAND] = "MainHandSlot",
[INVTYPE_WEAPONOFFHAND] = "SecondaryHandSlot",
[INVTYPE_WRIST] = "WristSlot",
[INVTYPE_WAND] = "RangedSlot",
[INVTYPE_GUN] = "RangedSlot",
[INVTYPE_PROJECTILE] = "AmmoSlot",
[INVTYPE_CROSSBOW] = "RangedSlot",
[INVTYPE_THROWN] = "RangedSlot",
}
ShoppingTooltip1:SetClampedToScreen(true)
ShoppingTooltip2:SetClampedToScreen(true)
local function IsCompareKeyDown()
if API and API.IsShiftKeyDown then
return API.IsShiftKeyDown()
end
return IsShiftKeyDown()
end
local function GetSlotType(tooltip)
-- Prefer ClassicAPI's cache-backed inventory type. This avoids depending on
-- localized tooltip text and works for Turtle WoW custom items when the
-- tooltip exposes its item link.
if API and tooltip.GetItem and API.GetItemIDFromLink
and API.GetItemInventoryTypeByID and API.GetItemInventorySlotKey then
local _, link = tooltip:GetItem()
local itemID = API.GetItemIDFromLink(link)
local inventoryType = itemID and API.GetItemInventoryTypeByID(itemID)
local slotKey = inventoryType and API.GetItemInventorySlotKey(inventoryType)
local slotType = slotKey and _G[slotKey]
if slotType and slots[slotType] then
return slotType
end
end
-- 1.12 fallback: find the localized inventory type in the tooltip text.
local tooltipName = tooltip:GetName()
for i=1,tooltip:NumLines() do
local tmpText = _G[tooltipName .. "TextLeft"..i]
local text = tmpText and tmpText:GetText()
if text and slots[text] then
return text
end
end
end
local function ShowCompare(tooltip)
if not tooltip then return end
-- Always clear previous comparisons first so switching from a ring/trinket
-- to a single-slot item cannot leave ShoppingTooltip2 behind.
ShoppingTooltip1:Hide()
ShoppingTooltip2:Hide()
if not IsCompareKeyDown() then return end
local slotType = GetSlotType(tooltip)
local slotName = slotType and slots[slotType]
if not slotName then return end
local slotID = GetInventorySlotInfo(slotName)
-- determine screen part
local x = GetCursorPosition() / UIParent:GetEffectiveScale()
local anchor = x < GetScreenWidth() / 2 and "TOPLEFT" or "TOPRIGHT"
local relative = x < GetScreenWidth() / 2 and "TOPRIGHT" or "TOPLEFT"
-- overwrite position for tooltips without owner
local pos, parent = tooltip:GetPoint()
if parent and parent == UIParent and pos == "TOPRIGHT" then
anchor = "TOPRIGHT"
relative = "TOPLEFT"
end
-- first tooltip
ShoppingTooltip1:SetOwner(tooltip, "ANCHOR_NONE")
ShoppingTooltip1:ClearAllPoints()
ShoppingTooltip1:SetPoint(anchor, tooltip, relative, 0, 0)
ShoppingTooltip1:SetInventoryItem("player", slotID)
ShoppingTooltip1:Show()
AddHeader(ShoppingTooltip1)
-- second tooltip for rings, trinkets and one-hand weapons
if slots[slotType .. "_other"] then
local slotID_other = GetInventorySlotInfo(slots[slotType .. "_other"])
ShoppingTooltip2:SetOwner(tooltip, "ANCHOR_NONE")
ShoppingTooltip2:ClearAllPoints()
if ShoppingTooltip1:IsShown() then
ShoppingTooltip2:SetPoint(anchor, ShoppingTooltip1, relative, 0, 0)
else
ShoppingTooltip2:SetPoint(anchor, tooltip, relative, 0, 0)
end
ShoppingTooltip2:SetInventoryItem("player", slotID_other)
ShoppingTooltip2:Show()
AddHeader(ShoppingTooltip2)
end
end
-- Recalculate only when a tooltip is actually shown/updated. The original
-- module scanned every tooltip line on every rendered frame.
local trackedTooltips = {}
local function TrackTooltip(tooltip)
if not tooltip or trackedTooltips[tooltip] then return end
trackedTooltips[tooltip] = true
ShaguTweaks.hooksecurefunc(tooltip, "Show", function()
ShowCompare(tooltip)
end)
end
TrackTooltip(GameTooltip)
-- ClassicAPI fires MODIFIER_STATE_CHANGED after updating its own L/R key
-- bitmap. Reading that bitmap here makes the comparison appear immediately
-- when Shift is pressed while an item tooltip is already visible.
local modifier = CreateFrame("Frame")
if API and API.modifierstate then
modifier:RegisterEvent("MODIFIER_STATE_CHANGED")
modifier:SetScript("OnEvent", function()
if arg1 == "LSHIFT" or arg1 == "RSHIFT" then
for tooltip in pairs(trackedTooltips) do
if tooltip:IsShown() then
ShowCompare(tooltip)
end
end
end
end)
else
-- Compatibility fallback for an older ClassicAPI build: poll only the
-- Shift boolean, not all tooltip lines every frame.
local previousShift = IsCompareKeyDown()
modifier:SetScript("OnUpdate", function()
local currentShift = IsCompareKeyDown()
if currentShift ~= previousShift then
previousShift = currentShift
for tooltip in pairs(trackedTooltips) do
if tooltip:IsShown() then
ShowCompare(tooltip)
end
end
end
end)
end
-- AtlasLoot uses its own tooltip frames; hook their Show calls the same way.
ShaguTweaks.HookAddonOrVariable("AtlasLoot", function()
TrackTooltip(AtlasLootTooltip)
TrackTooltip(AtlasLootTooltip2)
end)
end