Files
Nanami-UI/Tooltip.lua
2026-03-20 14:04:51 +08:00

1363 lines
52 KiB
Lua

SFrames.FloatingTooltip = {}
--------------------------------------------------------------------------------
-- Class colors for tooltip unit-name coloring
--------------------------------------------------------------------------------
local TT_CLASS_COLORS = {
["WARRIOR"] = { 0.78, 0.61, 0.43 },
["MAGE"] = { 0.41, 0.80, 0.94 },
["ROGUE"] = { 1.00, 0.96, 0.41 },
["DRUID"] = { 1.00, 0.49, 0.04 },
["HUNTER"] = { 0.67, 0.83, 0.45 },
["SHAMAN"] = { 0.14, 0.35, 1.00 },
["PRIEST"] = { 1.00, 1.00, 1.00 },
["WARLOCK"] = { 0.58, 0.51, 0.79 },
["PALADIN"] = { 0.96, 0.55, 0.73 },
}
local TT_CLASS_REVERSE = {}
local ttClassReverseDone = false
local function TT_BuildClassReverse()
if ttClassReverseDone then return end
ttClassReverseDone = true
if LOCALIZED_CLASS_NAMES_MALE then
for en, loc in pairs(LOCALIZED_CLASS_NAMES_MALE) do
TT_CLASS_REVERSE[loc] = en
end
end
if LOCALIZED_CLASS_NAMES_FEMALE then
for en, loc in pairs(LOCALIZED_CLASS_NAMES_FEMALE) do
TT_CLASS_REVERSE[loc] = en
end
end
local zh = {
["战士"]="WARRIOR", ["法师"]="MAGE", ["盗贼"]="ROGUE",
["德鲁伊"]="DRUID", ["猎人"]="HUNTER", ["萨满祭司"]="SHAMAN",
["牧师"]="PRIEST", ["术士"]="WARLOCK", ["圣骑士"]="PALADIN",
}
for loc, en in pairs(zh) do
if not TT_CLASS_REVERSE[loc] then TT_CLASS_REVERSE[loc] = en end
end
for en, _ in pairs(TT_CLASS_COLORS) do
TT_CLASS_REVERSE[en] = en
TT_CLASS_REVERSE[string.lower(en)] = en
end
end
local function TT_GetClassToken(unit)
if not UnitExists(unit) then return nil end
local className, classEN = UnitClass(unit)
if classEN and classEN ~= "" then return string.upper(classEN) end
if className then
TT_BuildClassReverse()
return TT_CLASS_REVERSE[className]
end
return nil
end
local function TT_GetClassColor(classToken)
if not classToken then return nil, nil, nil end
if CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[classToken] then
local c = CUSTOM_CLASS_COLORS[classToken]
return c.r, c.g, c.b
end
if RAID_CLASS_COLORS and RAID_CLASS_COLORS[classToken] then
local c = RAID_CLASS_COLORS[classToken]
return c.r, c.g, c.b
end
local c = TT_CLASS_COLORS[classToken]
if c then return c[1], c[2], c[3] end
return nil, nil, nil
end
local function TT_ClassHex(classToken)
local r, g, b = TT_GetClassColor(classToken)
if not r then return "|cffffffff" end
return string.format("|cff%02x%02x%02x", r * 255, g * 255, b * 255)
end
--------------------------------------------------------------------------------
-- Backdrop helper (applied once, not every frame)
--------------------------------------------------------------------------------
local TT_BACKDROP = {
bgFile = "Interface\\Buttons\\WHITE8X8",
insets = { left = 0, right = 0, top = 0, bottom = 0 },
}
local function TT_ApplyBackdrop(frame)
frame:SetBackdrop(TT_BACKDROP)
local _A = SFrames.ActiveTheme
if _A and _A.panelBg then
frame:SetBackdropColor(_A.panelBg[1], _A.panelBg[2], _A.panelBg[3], 0.95)
else
frame:SetBackdropColor(0.08, 0.08, 0.08, 0.95)
end
end
--------------------------------------------------------------------------------
-- Level difficulty color (fallback if GetDifficultyColor is unavailable)
--------------------------------------------------------------------------------
local function TT_DifficultyColor(unitLevel)
local playerLevel = UnitLevel("player") or 1
if unitLevel < 0 then return 1, 0, 0 end
local diff = unitLevel - playerLevel
if diff >= 5 then
return 1, 0.1, 0.1
elseif diff >= 3 then
return 1, 0.5, 0.25
elseif diff >= -2 then
return 1, 1, 0
elseif diff >= -8 then
return 0.25, 0.75, 0.25
else
return 0.5, 0.5, 0.5
end
end
--------------------------------------------------------------------------------
-- Initialize
--------------------------------------------------------------------------------
function SFrames.FloatingTooltip:Initialize()
TT_ApplyBackdrop(GameTooltip)
--------------------------------------------------------------------------
-- Standalone backdrop frame: a SIBLING of GameTooltip (parented to
-- UIParent, not GameTooltip) at the same TOOLTIP strata but one frame-
-- level below. This guarantees it renders directly behind the tooltip
-- text and is completely immune to C++ SetBackdrop resets.
--------------------------------------------------------------------------
if not GameTooltip._nanamiBG then
GameTooltip._nanamiBG = true
local bgFrame = CreateFrame("Frame", "NanamiTooltipBG", UIParent)
bgFrame:SetFrameStrata("TOOLTIP")
bgFrame:SetFrameLevel(math.max(1, GameTooltip:GetFrameLevel()) - 1)
bgFrame:Hide()
GameTooltip._nanamiBGFrame = bgFrame
local bg = bgFrame:CreateTexture(nil, "ARTWORK")
bg:SetTexture("Interface\\Buttons\\WHITE8X8")
local _Abg = SFrames.ActiveTheme
if _Abg and _Abg.panelBg then
bg:SetVertexColor(_Abg.panelBg[1], _Abg.panelBg[2], _Abg.panelBg[3], 0.95)
else
bg:SetVertexColor(0.08, 0.08, 0.08, 0.95)
end
bg:SetAllPoints(bgFrame)
GameTooltip._nanamiBGTex = bg
end
--------------------------------------------------------------------------
-- Health bar: position, backdrop, texture, health text
--------------------------------------------------------------------------
local barFont = (SFrames and SFrames.GetFont and SFrames:GetFont()) or "Fonts\\ARIALN.TTF"
GameTooltipStatusBar:SetHeight(10)
GameTooltipStatusBar:ClearAllPoints()
GameTooltipStatusBar:SetPoint("BOTTOMLEFT", GameTooltip, "TOPLEFT", 4, 2)
GameTooltipStatusBar:SetPoint("BOTTOMRIGHT", GameTooltip, "TOPRIGHT", -4, 2)
GameTooltipStatusBar:SetStatusBarTexture(SFrames:GetTexture())
GameTooltipStatusBar.bg = GameTooltipStatusBar.bg or GameTooltipStatusBar:CreateTexture(nil, "BACKGROUND")
GameTooltipStatusBar.bg:SetTexture("Interface\\TARGETINGFRAME\\UI-StatusBar")
GameTooltipStatusBar.bg:SetVertexColor(.1, .1, 0, .8)
GameTooltipStatusBar.bg:SetAllPoints(true)
if not GameTooltipStatusBar.backdrop then
local bd = CreateFrame("Frame", "SFramesTooltipStatusBarBD", GameTooltipStatusBar)
bd:SetPoint("TOPLEFT", GameTooltipStatusBar, "TOPLEFT", -3, 3)
bd:SetPoint("BOTTOMRIGHT", GameTooltipStatusBar, "BOTTOMRIGHT", 3, -3)
bd:SetBackdrop({
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 8, edgeSize = 12,
insets = { left = 3, right = 3, top = 3, bottom = 3 },
})
bd:SetBackdropBorderColor(.8, .8, .8, 1)
GameTooltipStatusBar.backdrop = bd
end
if not GameTooltipStatusBar.healthText then
local ht = GameTooltipStatusBar.backdrop:CreateFontString(nil, "DIALOG", "GameFontWhite")
ht:SetFont(barFont, 12, "OUTLINE")
ht:SetPoint("TOP", 0, 4)
ht:SetNonSpaceWrap(false)
GameTooltipStatusBar.healthText = ht
end
if not GameTooltipStatusBar._origSetColor then
GameTooltipStatusBar._origSetColor = GameTooltipStatusBar.SetStatusBarColor
GameTooltipStatusBar.SetStatusBarColor = function() return end
end
--------------------------------------------------------------------------
-- Track mouseover name/level for health estimation
--------------------------------------------------------------------------
local ttMouseName, ttMouseLevel
local barEvents = CreateFrame("Frame", nil, GameTooltipStatusBar)
barEvents:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
barEvents:SetScript("OnEvent", function()
ttMouseName = UnitName("mouseover")
ttMouseLevel = UnitLevel("mouseover")
end)
local function TT_Abbreviate(val)
if val >= 1000000 then
return string.format("%.1fM", val / 1000000)
elseif val >= 10000 then
return string.format("%.1fK", val / 1000)
end
return tostring(math.floor(val))
end
local barThrottle = 0
barEvents:SetScript("OnUpdate", function()
barThrottle = barThrottle + arg1
if barThrottle < 0.1 then return end
barThrottle = 0
local hp = GameTooltipStatusBar:GetValue()
local _, hpmax = GameTooltipStatusBar:GetMinMaxValues()
if hpmax and hpmax > 0 then
if hpmax > 100 then
GameTooltipStatusBar.healthText:SetText(
TT_Abbreviate(hp) .. " / " .. TT_Abbreviate(hpmax))
else
GameTooltipStatusBar.healthText:SetText(
string.format("%d%%", math.ceil(hp / hpmax * 100)))
end
else
GameTooltipStatusBar.healthText:SetText("")
end
end)
local linesFormatted = false
--------------------------------------------------------------------------
-- Track tooltip owner to skip styling for world-map / pfQuest markers
--------------------------------------------------------------------------
local ttOwner = nil
local orig_SetOwner = GameTooltip.SetOwner
GameTooltip.SetOwner = function(self, owner, anchor, xOff, yOff)
ttOwner = owner
return orig_SetOwner(self, owner, anchor, xOff, yOff)
end
local function TT_IsMapMarkerTooltip()
if not ttOwner then return false end
if WorldMapFrame and WorldMapFrame:IsShown() then
local name = ttOwner.GetName and ttOwner:GetName()
if name and (string.find(name, "^pf") or string.find(name, "^WorldMap")) then
return true
end
local parent = ttOwner.GetParent and ttOwner:GetParent()
while parent do
if parent == WorldMapFrame or parent == WorldMapButton then
return true
end
parent = parent.GetParent and parent:GetParent()
end
end
return false
end
local function TT_ShowBar(show)
if not GameTooltipStatusBar then return end
GameTooltipStatusBar:SetStatusBarTexture(SFrames:GetTexture())
if show then
GameTooltipStatusBar:SetAlpha(1)
GameTooltipStatusBar:Show()
if GameTooltipStatusBar.backdrop then
GameTooltipStatusBar.backdrop:SetAlpha(1)
GameTooltipStatusBar.backdrop:Show()
end
else
GameTooltipStatusBar:SetAlpha(0)
if GameTooltipStatusBar.backdrop then
GameTooltipStatusBar.backdrop:SetAlpha(0)
end
if GameTooltipStatusBar.healthText then GameTooltipStatusBar.healthText:SetText("") end
end
end
-- Sync the standalone bg frame to match GameTooltip's position/size
local function TT_SyncBGFrame()
local bf = GameTooltip._nanamiBGFrame
if not bf then return end
local w = GameTooltip:GetWidth()
local h = GameTooltip:GetHeight()
if w and h and w > 0 and h > 0 then
bf:SetWidth(w)
bf:SetHeight(h)
bf:ClearAllPoints()
bf:SetPoint("TOPLEFT", GameTooltip, "TOPLEFT", 0, 0)
bf:SetFrameLevel(math.max(1, GameTooltip:GetFrameLevel()) - 1)
bf:Show()
end
end
-- OnShow: apply backdrop, sync bg frame, reset formatting flag
local orig_OnShow = GameTooltip:GetScript("OnShow")
local ttIsMapMarker = false
GameTooltip:SetScript("OnShow", function()
if orig_OnShow then orig_OnShow() end
linesFormatted = false
ttIsMapMarker = TT_IsMapMarkerTooltip()
TT_ApplyBackdrop(this)
TT_SyncBGFrame()
if not ttIsMapMarker then
TT_ShowBar(UnitExists("mouseover"))
end
end)
-- OnUpdate: throttled backdrop/bar refresh and cursor tracking
local orig_OnUpdate = GameTooltip:GetScript("OnUpdate")
local ttThrottle = 0
GameTooltip:SetScript("OnUpdate", function()
if orig_OnUpdate then orig_OnUpdate() end
ttThrottle = ttThrottle + arg1
if ttThrottle < 0.05 then return end
ttThrottle = 0
TT_ApplyBackdrop(this)
TT_SyncBGFrame()
if not ttIsMapMarker then
TT_ShowBar(UnitExists("mouseover"))
end
if not linesFormatted then
linesFormatted = true
if not ttIsMapMarker and UnitExists("mouseover") then
SFrames.FloatingTooltip:FormatLines(this)
end
end
if SFramesDB and SFramesDB.tooltipMode == "CURSOR" and not ttIsMapMarker then
local x, y = GetCursorPosition()
local scale = UIParent:GetEffectiveScale()
if scale and scale > 0 then
this:ClearAllPoints()
this:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", (x / scale) + 16, (y / scale) - 16)
end
end
end)
-- OnHide: hide bg frame, reset flag and owner tracking
local orig_OnHide = GameTooltip:GetScript("OnHide")
GameTooltip:SetScript("OnHide", function()
linesFormatted = false
ttOwner = nil
if GameTooltip._nanamiBGFrame then
GameTooltip._nanamiBGFrame:Hide()
end
if orig_OnHide then orig_OnHide() end
end)
-- Tooltip Positioning logic
if not SFrames.FloatingTooltip.anchor then
local anchor = CreateFrame("Button", "SFramesTooltipAnchor", UIParent)
anchor:SetWidth(180)
anchor:SetHeight(60)
anchor:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -20, 100)
anchor:SetFrameStrata("HIGH")
anchor:EnableMouse(true)
anchor:SetMovable(true)
anchor:RegisterForDrag("LeftButton")
anchor:SetScript("OnDragStart", function() this:StartMoving() end)
anchor:SetScript("OnDragStop", function()
this:StopMovingOrSizing()
if SFramesDB then
local _, _, _, x, y = this:GetPoint()
SFramesDB.tooltipX = x
SFramesDB.tooltipY = y
end
end)
anchor:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8x8",
edgeFile = "Interface\\Buttons\\WHITE8x8",
edgeSize = 1,
insets = {left=1, right=1, top=1, bottom=1}
})
anchor:SetBackdropColor(0.08, 0.08, 0.08, 0.95)
anchor:SetBackdropBorderColor(0.4, 0.8, 0.4, 1)
local font = (SFrames and SFrames.GetFont and SFrames:GetFont()) or "Fonts\\ARIALN.TTF"
anchor.title = anchor:CreateFontString(nil, "OVERLAY")
anchor.title:SetFont(font, 13, "OUTLINE")
anchor.title:SetPoint("TOPLEFT", anchor, "TOPLEFT", 8, -8)
anchor.title:SetText("Tooltip 模拟位置")
anchor.title:SetTextColor(1, 1, 1)
anchor.desc = anchor:CreateFontString(nil, "OVERLAY")
anchor.desc:SetFont(font, 11, "OUTLINE")
anchor.desc:SetPoint("TOPLEFT", anchor.title, "BOTTOMLEFT", 0, -4)
anchor.desc:SetText("拖拽我以调整[自定义]锚点。")
anchor.desc:SetTextColor(1, 0.82, 0)
anchor.desc:SetJustifyH("LEFT")
anchor:Hide()
SFrames.FloatingTooltip.anchor = anchor
end
if not SFrames.FloatingTooltip.hookedAnchor then
SFrames.FloatingTooltip.hookedAnchor = true
local orig_GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor
function GameTooltip_SetDefaultAnchor(tooltip, parent)
if SFramesDB and SFramesDB.tooltipMode == "CURSOR" then
tooltip:SetOwner(parent, "ANCHOR_NONE")
elseif SFramesDB and SFramesDB.tooltipMode == "CUSTOM" then
tooltip:SetOwner(parent, "ANCHOR_NONE")
tooltip:ClearAllPoints()
tooltip:SetPoint("BOTTOMRIGHT", "SFramesTooltipAnchor", "BOTTOMRIGHT", 0, 0)
else
orig_GameTooltip_SetDefaultAnchor(tooltip, parent)
end
end
end
SFrames.FloatingTooltip:ApplyConfig()
-- WorldMapTooltip: raw textures on a child frame (SetBackdrop is unreliable)
if WorldMapTooltip and not WorldMapTooltip._nanamiBG then
WorldMapTooltip._nanamiBG = true
local wmtBgFrame = CreateFrame("Frame", nil, WorldMapTooltip)
wmtBgFrame:SetAllPoints(WorldMapTooltip)
wmtBgFrame:SetFrameLevel(math.max(0, WorldMapTooltip:GetFrameLevel()))
local bg = wmtBgFrame:CreateTexture(nil, "BACKGROUND")
bg:SetTexture("Interface\\Buttons\\WHITE8X8")
bg:SetVertexColor(0.05, 0.05, 0.05, 1)
bg:SetAllPoints(wmtBgFrame)
local function WMTEdge(p1, r1, p2, r2, w, h)
local t = wmtBgFrame:CreateTexture(nil, "BORDER")
t:SetTexture("Interface\\Buttons\\WHITE8X8")
t:SetVertexColor(0.20, 0.20, 0.20, 1)
t:SetPoint(p1, WorldMapTooltip, r1)
t:SetPoint(p2, WorldMapTooltip, r2)
if w then t:SetWidth(w) end
if h then t:SetHeight(h) end
end
WMTEdge("TOPLEFT","TOPLEFT","TOPRIGHT","TOPRIGHT", nil, 1)
WMTEdge("BOTTOMLEFT","BOTTOMLEFT","BOTTOMRIGHT","BOTTOMRIGHT", nil, 1)
WMTEdge("TOPLEFT","TOPLEFT","BOTTOMLEFT","BOTTOMLEFT", 1, nil)
WMTEdge("TOPRIGHT","TOPRIGHT","BOTTOMRIGHT","BOTTOMRIGHT", 1, nil)
end
if SFrames.ItemCompare and SFrames.ItemCompare.HookTooltips then
SFrames.ItemCompare:HookTooltips()
end
end
function SFrames.FloatingTooltip:ApplyConfig()
if SFramesDB and SFramesDB.tooltipX and SFramesDB.tooltipY and self.anchor then
self.anchor:ClearAllPoints()
self.anchor:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", SFramesDB.tooltipX, SFramesDB.tooltipY)
end
end
function SFrames.FloatingTooltip:ToggleAnchor(show)
if not self.anchor then return end
if show then
self.anchor:Show()
else
self.anchor:Hide()
end
end
function SFrames.FloatingTooltip:FormatLines(tooltip)
local unit = "mouseover"
if not UnitExists(unit) then return end
local nameLine = GameTooltipTextLeft1
if not nameLine then return end
local nameText = nameLine:GetText()
if nameText and string.find(nameText, "\n") then
nameText = string.gsub(nameText, "\n", " ")
nameLine:SetText(nameText)
end
--------------------------------------------------------------------------
-- Player units
--------------------------------------------------------------------------
if UnitIsPlayer(unit) then
local classToken = TT_GetClassToken(unit)
-- Class-color the name
if classToken then
local r, g, b = TT_GetClassColor(classToken)
if r then
nameLine:SetTextColor(r, g, b)
if GameTooltipStatusBar and GameTooltipStatusBar._origSetColor then
GameTooltipStatusBar._origSetColor(GameTooltipStatusBar, r, g, b)
end
end
end
-- Fetch guild info for this player
local ttGuild, ttRankStr, ttRankIdx
if GetGuildInfo then
ttGuild, ttRankStr, ttRankIdx = GetGuildInfo(unit)
end
-- Iterate existing lines: enhance guild line + color level
local numLines = tooltip:NumLines()
for i = 2, numLines do
local left = getglobal("GameTooltipTextLeft" .. i)
if left then
local txt = left:GetText()
if txt then
-- Guild line <GuildName> — append rank
if string.find(txt, "^<.*>$") then
if ttRankStr and ttRankStr ~= "" then
left:SetText(txt .. " - " .. ttRankStr)
end
left:SetTextColor(0.30, 0.90, 0.30)
end
-- Level line
local _, _, lvlStr = string.find(txt, "^Level (%d+)")
if not lvlStr then
_, _, lvlStr = string.find(txt, "^等级 (%d+)")
end
local lvlNum = tonumber(lvlStr)
if lvlNum then
local lr, lg, lb = TT_DifficultyColor(lvlNum)
left:SetTextColor(lr, lg, lb)
end
end
end
end
-----------------------------------------------------------------------
-- Extra info lines (appended below existing content)
-----------------------------------------------------------------------
-- Guild info (if player is in a guild but Blizzard didn't show it)
if ttGuild and ttRankStr then
local foundGuild = false
for i = 2, numLines do
local left = getglobal("GameTooltipTextLeft" .. i)
if left then
local txt = left:GetText() or ""
if string.find(txt, "^<.*>") then
foundGuild = true
break
end
end
end
if not foundGuild then
tooltip:AddLine("<" .. ttGuild .. "> - " .. ttRankStr, 0.30, 0.90, 0.30)
end
end
-- PvP Rank (text only; |T...|t inline textures not supported in 1.12)
if UnitPVPRank and GetPVPRankInfo then
local rank = UnitPVPRank(unit)
if rank and rank > 0 then
local rankName = GetPVPRankInfo(rank)
if rankName and rankName ~= "" then
tooltip:AddLine("军衔: " .. rankName, 1, 0.85, 0.35)
end
end
end
-- PvP flag + faction
if UnitIsPVP and UnitIsPVP(unit) then
local fTag = UnitFactionGroup and UnitFactionGroup(unit)
if fTag then
local pvpHex = (fTag == "Horde") and "|cffff4444" or "|cff44bbff"
tooltip:AddLine(pvpHex .. "PvP " .. fTag .. "|r")
end
end
-- Turtle WoW challenge modes (defensive checks)
if IsHardcore and IsHardcore(unit) then
tooltip:AddLine("|cffff3333[Hardcore]|r")
end
if C_TurtleWoW then
if C_TurtleWoW.IsHardcore and C_TurtleWoW.IsHardcore(unit) then
tooltip:AddLine("|cffff3333[Hardcore]|r")
end
if C_TurtleWoW.IsSurvivalist and C_TurtleWoW.IsSurvivalist(unit) then
tooltip:AddLine("|cff33ff33[Survivalist]|r")
end
if C_TurtleWoW.IsIronMan and C_TurtleWoW.IsIronMan(unit) then
tooltip:AddLine("|cffaaaaaa[Iron Man]|r")
end
end
if UnitIsTrivial and UnitIsTrivial(unit) then
tooltip:AddLine("|cff888888[休闲模式]|r")
end
--------------------------------------------------------------------------
-- NPC / Creature units: color health bar by reaction
--------------------------------------------------------------------------
else
local reaction = UnitReaction(unit, "player")
if reaction then
local color = UnitReactionColor and UnitReactionColor[reaction]
if color and GameTooltipStatusBar and GameTooltipStatusBar._origSetColor then
GameTooltipStatusBar._origSetColor(GameTooltipStatusBar, color.r, color.g, color.b)
end
end
end
--------------------------------------------------------------------------
-- Target of mouseover (all units)
--------------------------------------------------------------------------
local tgtUnit = unit .. "target"
if UnitExists(tgtUnit) then
local tgtName = UnitName(tgtUnit)
if tgtName then
local line
if UnitIsUnit(tgtUnit, "player") then
local _At = SFrames.ActiveTheme
local _accentHex = "ff6699"
if _At and _At.accentHex then _accentHex = _At.accentHex end
line = "|cffffd700目标: |r|cff" .. _accentHex .. ">> 你 <<|r"
elseif UnitIsPlayer(tgtUnit) then
local hex = TT_ClassHex(TT_GetClassToken(tgtUnit))
line = "|cffffd700目标: |r" .. hex .. tgtName .. "|r"
else
line = "|cffffd700目标: |r|cffffffff" .. tgtName .. "|r"
end
tooltip:AddLine(line)
end
end
tooltip:Show()
end
--------------------------------------------------------------------------------
-- Item Compare: show stat differences vs currently equipped item
--------------------------------------------------------------------------------
SFrames.ItemCompare = {}
local IC = SFrames.ItemCompare
local IC_STAT_ORDER = {
"STR","AGI","STA","INT","SPI",
"CRIT","TOHIT","RANGEDCRIT",
"SPELLCRIT","SPELLTOHIT",
"ATTACKPOWER","RANGEDATTACKPOWER",
"DMG","HEAL",
"DEFENSE","DODGE","PARRY","BLOCK","BLOCKVALUE",
"ARMOR",
"HEALTHREG","MANAREG",
"HEALTH","MANA",
}
local IC_STAT_NAMES = {
STR="力量", AGI="敏捷", STA="耐力", INT="智力", SPI="精神",
CRIT="暴击%", TOHIT="命中%", RANGEDCRIT="远程暴击%",
SPELLCRIT="法术暴击%", SPELLTOHIT="法术命中%",
ATTACKPOWER="攻强", RANGEDATTACKPOWER="远程攻强",
DMG="法伤", HEAL="治疗",
DEFENSE="防御", DODGE="闪避%", PARRY="招架%", BLOCK="格挡%", BLOCKVALUE="格挡值",
ARMOR="护甲",
HEALTHREG="生命/5秒", MANAREG="法力/5秒",
HEALTH="生命值", MANA="法力值",
}
local IC_EQUIP_LOC_TO_SLOT = {
INVTYPE_HEAD = 1, INVTYPE_NECK = 2, INVTYPE_SHOULDER = 3,
INVTYPE_BODY = 4, INVTYPE_CHEST = 5, INVTYPE_ROBE = 5,
INVTYPE_WAIST = 6, INVTYPE_LEGS = 7, INVTYPE_FEET = 8,
INVTYPE_WRIST = 9, INVTYPE_HAND = 10,
INVTYPE_FINGER = 11, INVTYPE_TRINKET = 13,
INVTYPE_CLOAK = 15,
INVTYPE_WEAPON = 16, INVTYPE_2HWEAPON = 16, INVTYPE_WEAPONMAINHAND = 16,
INVTYPE_SHIELD = 17, INVTYPE_WEAPONOFFHAND = 17, INVTYPE_HOLDABLE = 17,
INVTYPE_RANGED = 18, INVTYPE_RANGEDRIGHT = 18, INVTYPE_THROWN = 18,
INVTYPE_RELIC = 18, INVTYPE_TABARD = 19,
}
local function IC_GetLib()
if AceLibrary and AceLibrary.HasInstance and AceLibrary:HasInstance("ItemBonusLib-1.0") then
return AceLibrary("ItemBonusLib-1.0")
end
return nil
end
local function IC_GetEquipSlot(link)
if not link then return nil end
local _, _, _, _, _, _, _, equipLoc = GetItemInfo(link)
if not equipLoc or equipLoc == "" then return nil end
return IC_EQUIP_LOC_TO_SLOT[equipLoc]
end
local function IC_ScanBonuses(lib, link)
if not lib or not link then return nil end
local ok, result = pcall(function() return lib:ScanItem(link, true) end)
if ok and result then return result end
return nil
end
local function IC_AppendCompare(tooltip, newBonuses, oldBonuses)
if not newBonuses then return end
local hasAny = false
local lines = {}
for _, key in ipairs(IC_STAT_ORDER) do
local nv = newBonuses[key] or 0
local ov = (oldBonuses and oldBonuses[key]) or 0
local diff = nv - ov
if diff ~= 0 then
local name = IC_STAT_NAMES[key] or key
local text
if diff > 0 then
text = "|cff00ff00+" .. diff .. " " .. name .. "|r"
else
text = "|cffff4444" .. diff .. " " .. name .. "|r"
end
table.insert(lines, text)
hasAny = true
end
end
if hasAny then
tooltip:AddLine(" ")
tooltip:AddLine("与当前装备对比:", 0.6, 0.8, 1)
for _, l in ipairs(lines) do
tooltip:AddLine(l)
end
tooltip:Show()
end
end
local function IC_GetItemLevel(link)
if not link or not LibItem_Level then return nil end
local _, _, itemId = string.find(link, "item:(%d+)")
if itemId then return LibItem_Level[tonumber(itemId)] end
return nil
end
local function IC_AppendItemLevel(tooltip, link)
if SFramesDB and SFramesDB.showItemLevel == false then return end
local ilvl = IC_GetItemLevel(link)
if ilvl and ilvl > 0 then
tooltip:AddLine("物品等级: " .. ilvl, 1, 0.82, 0)
end
end
--------------------------------------------------------------------------------
-- Sell Price Infrastructure
--------------------------------------------------------------------------------
local function IC_GetItemIdFromLink(link)
if not link then return nil end
local _, _, id = string.find(link, "item:(%d+)")
if id then return tonumber(id) end
return nil
end
local function IC_CacheSellPrice(itemId, copper)
if not itemId or not copper or copper <= 0 then return end
if not SFramesGlobalDB then SFramesGlobalDB = {} end
if not SFramesGlobalDB.sellPriceCache then SFramesGlobalDB.sellPriceCache = {} end
SFramesGlobalDB.sellPriceCache[itemId] = copper
end
local function IC_GetSellPrice(itemId)
if not itemId then return nil end
if NanamiSellPriceDB then
local price = NanamiSellPriceDB[itemId]
if price and price > 0 then return price end
end
if ShaguTweaks and ShaguTweaks.SellValueDB then
local price = ShaguTweaks.SellValueDB[itemId]
if price and price > 0 then return price end
end
if SFramesGlobalDB and SFramesGlobalDB.sellPriceCache then
local price = SFramesGlobalDB.sellPriceCache[itemId]
if price and price > 0 then return price end
end
return nil
end
local function IC_TryGetItemInfoSellPrice(link)
if not link then return nil end
local r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11 = GetItemInfo(link)
if r11 and type(r11) == "number" and r11 > 0 then
return r11
end
return nil
end
local function IC_ExtractLinkFromTooltipName(tooltip)
if not tooltip then return nil end
local left1 = _G[tooltip:GetName() .. "TextLeft1"]
if not left1 then return nil end
local name = left1:GetText()
if not name or name == "" then return nil end
if GetItemLinkByName then
local link = GetItemLinkByName(name)
if link then return link end
end
if ShaguTweaks and ShaguTweaks.GetItemLinkByName then
local link = ShaguTweaks.GetItemLinkByName(name)
if link then return link end
end
return nil
end
local function IC_AddSellPrice(tooltip, link, count)
if not link then return end
if tooltip._nanamiSellPriceAdded then return end
if MerchantFrame and MerchantFrame:IsShown() then return end
local itemId = IC_GetItemIdFromLink(link)
local price = IC_GetSellPrice(itemId)
if not price then
price = IC_TryGetItemInfoSellPrice(link)
if price and itemId then IC_CacheSellPrice(itemId, price) end
end
if price and price > 0 then
count = count or 1
if count < 1 then count = 1 end
tooltip._nanamiSellPriceAdded = true
SetTooltipMoney(tooltip, price * count)
tooltip:Show()
end
end
--------------------------------------------------------------------------------
local function IC_AppendItemId(tooltip, link)
if SFramesDB and SFramesDB.showTooltipIDs == false then return end
local itemId = IC_GetItemIdFromLink(link)
if itemId then
tooltip:AddLine("物品ID: " .. itemId, 0.55, 0.55, 0.70)
end
end
local function IC_EnhanceTooltip(tooltip, link, count, skipSellPrice)
if not link then return end
IC_AppendItemLevel(tooltip, link)
IC_AppendItemId(tooltip, link)
if not SFramesDB or SFramesDB.itemCompare ~= false then
local lib = IC_GetLib()
if lib then
local eslot = IC_GetEquipSlot(link)
if eslot then
local newB = IC_ScanBonuses(lib, link)
local eqLink = GetInventoryItemLink("player", eslot)
local oldB = IC_ScanBonuses(lib, eqLink)
IC_AppendCompare(tooltip, newB, oldB)
end
end
end
if SFrames.GearScore and SFrames.GearScore.AddScoreToTooltip then
pcall(function() SFrames.GearScore:AddScoreToTooltip(tooltip, link) end)
end
if not skipSellPrice then
IC_AddSellPrice(tooltip, link, count)
end
tooltip:Show()
end
function IC:HookTooltips()
if self.hooked then return end
self.hooked = true
---------------------------------------------------------------------------
-- OnHide cleanup: reset sell-price tracking flag
---------------------------------------------------------------------------
local orig_OnHide_IC = GameTooltip:GetScript("OnHide")
GameTooltip:SetScript("OnHide", function()
this._nanamiSellPriceAdded = nil
if orig_OnHide_IC then orig_OnHide_IC() end
end)
---------------------------------------------------------------------------
-- Passive sell-price caching: intercept SetTooltipMoney calls while
-- processing a bag item at a merchant so we learn the unit price.
---------------------------------------------------------------------------
local IC_PendingBagLink = nil
local IC_PendingBagCount = nil
local orig_SetTooltipMoney = SetTooltipMoney
SetTooltipMoney = function(frame, money, a1, a2, a3)
if orig_SetTooltipMoney then
orig_SetTooltipMoney(frame, money, a1, a2, a3)
end
if IC_PendingBagLink and money and money > 0 then
if frame == GameTooltip or frame == SFramesScanTooltip then
local itemId = IC_GetItemIdFromLink(IC_PendingBagLink)
local count = IC_PendingBagCount or 1
if count < 1 then count = 1 end
if itemId then
IC_CacheSellPrice(itemId, math.floor(money / count))
end
end
end
end
---------------------------------------------------------------------------
-- MERCHANT_SHOW: proactively scan all bag items to cache sell prices.
---------------------------------------------------------------------------
local scanFrame = CreateFrame("Frame")
scanFrame:RegisterEvent("MERCHANT_SHOW")
scanFrame:SetScript("OnEvent", function()
for bag = 0, 4 do
local numSlots = GetContainerNumSlots(bag) or 0
for slot = 1, numSlots do
local link = GetContainerItemLink(bag, slot)
if link then
local itemId = IC_GetItemIdFromLink(link)
if itemId and not IC_GetSellPrice(itemId) then
local infoPrice = IC_TryGetItemInfoSellPrice(link)
if infoPrice then
IC_CacheSellPrice(itemId, infoPrice)
elseif SFramesScanTooltip then
local _, cnt = GetContainerItemInfo(bag, slot)
cnt = cnt or 1
IC_PendingBagLink = link
IC_PendingBagCount = cnt
pcall(function()
SFramesScanTooltip:SetOwner(UIParent, "ANCHOR_NONE")
SFramesScanTooltip:ClearLines()
SFramesScanTooltip:SetBagItem(bag, slot)
SFramesScanTooltip:Hide()
end)
IC_PendingBagLink = nil
IC_PendingBagCount = nil
end
end
end
end
end
end)
---------------------------------------------------------------------------
-- GameTooltip.SetBagItem
---------------------------------------------------------------------------
local orig_SetBagItem = GameTooltip.SetBagItem
GameTooltip.SetBagItem = function(self, bag, slot)
self._nanamiSellPriceAdded = nil
local link = GetContainerItemLink(bag, slot)
local _, cnt = GetContainerItemInfo(bag, slot)
IC_PendingBagLink = link
IC_PendingBagCount = cnt or 1
local hasItem, hasCooldown, repairCost = orig_SetBagItem(self, bag, slot)
IC_PendingBagLink = nil
IC_PendingBagCount = nil
local moneyAlreadyShown = self.hasMoney
pcall(function()
if link then
IC_EnhanceTooltip(GameTooltip, link, cnt, moneyAlreadyShown)
end
end)
return hasItem, hasCooldown, repairCost
end
---------------------------------------------------------------------------
-- GameTooltip.SetInventoryItem
---------------------------------------------------------------------------
local orig_SetInvItem = GameTooltip.SetInventoryItem
GameTooltip.SetInventoryItem = function(self, unit, slotId)
self._nanamiSellPriceAdded = nil
local hasItem, hasCooldown, repairCost = orig_SetInvItem(self, unit, slotId)
local moneyAlreadyShown = self.hasMoney
pcall(function()
if unit == "player" and slotId then
local link = GetInventoryItemLink("player", slotId)
if link then
IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown)
end
end
end)
return hasItem, hasCooldown, repairCost
end
---------------------------------------------------------------------------
-- GameTooltip.SetMerchantItem
---------------------------------------------------------------------------
local orig_SetMerchantItem = GameTooltip.SetMerchantItem
if orig_SetMerchantItem then
GameTooltip.SetMerchantItem = function(self, idx)
self._nanamiSellPriceAdded = nil
orig_SetMerchantItem(self, idx)
pcall(function()
local link = GetMerchantItemLink and GetMerchantItemLink(idx)
if link then IC_EnhanceTooltip(GameTooltip, link) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetQuestItem — with fallback link extraction
---------------------------------------------------------------------------
local orig_SetQuestItem = GameTooltip.SetQuestItem
if orig_SetQuestItem then
GameTooltip.SetQuestItem = function(self, qtype, idx)
self._nanamiSellPriceAdded = nil
orig_SetQuestItem(self, qtype, idx)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link
if GetQuestItemLink then link = GetQuestItemLink(qtype, idx) end
if not link then link = IC_ExtractLinkFromTooltipName(GameTooltip) end
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetQuestLogItem — with fallback link extraction
---------------------------------------------------------------------------
local orig_SetQuestLogItem = GameTooltip.SetQuestLogItem
if orig_SetQuestLogItem then
GameTooltip.SetQuestLogItem = function(self, itype, idx)
self._nanamiSellPriceAdded = nil
orig_SetQuestLogItem(self, itype, idx)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link
if GetQuestLogItemLink then link = GetQuestLogItemLink(itype, idx) end
if not link then link = IC_ExtractLinkFromTooltipName(GameTooltip) end
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetLootItem
---------------------------------------------------------------------------
local orig_SetLootItem = GameTooltip.SetLootItem
if orig_SetLootItem then
GameTooltip.SetLootItem = function(self, idx)
self._nanamiSellPriceAdded = nil
orig_SetLootItem(self, idx)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link = GetLootSlotLink and GetLootSlotLink(idx)
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetLootRollItem
---------------------------------------------------------------------------
local orig_SetLootRollItem = GameTooltip.SetLootRollItem
if orig_SetLootRollItem then
GameTooltip.SetLootRollItem = function(self, rollId)
self._nanamiSellPriceAdded = nil
orig_SetLootRollItem(self, rollId)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link = GetLootRollItemLink and GetLootRollItemLink(rollId)
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetCraftItem
---------------------------------------------------------------------------
local orig_SetCraftItem = GameTooltip.SetCraftItem
if orig_SetCraftItem then
GameTooltip.SetCraftItem = function(self, skill, slot)
self._nanamiSellPriceAdded = nil
orig_SetCraftItem(self, skill, slot)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link = GetCraftReagentItemLink and GetCraftReagentItemLink(skill, slot)
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetTradeSkillItem
---------------------------------------------------------------------------
local orig_SetTradeSkillItem = GameTooltip.SetTradeSkillItem
if orig_SetTradeSkillItem then
GameTooltip.SetTradeSkillItem = function(self, skillIndex, reagentIndex)
self._nanamiSellPriceAdded = nil
orig_SetTradeSkillItem(self, skillIndex, reagentIndex)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link
if reagentIndex then
if GetTradeSkillReagentItemLink then
link = GetTradeSkillReagentItemLink(skillIndex, reagentIndex)
end
else
if GetTradeSkillItemLink then
link = GetTradeSkillItemLink(skillIndex)
end
end
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetAuctionItem
---------------------------------------------------------------------------
local orig_SetAuctionItem = GameTooltip.SetAuctionItem
if orig_SetAuctionItem then
GameTooltip.SetAuctionItem = function(self, atype, idx)
self._nanamiSellPriceAdded = nil
orig_SetAuctionItem(self, atype, idx)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local _, _, cnt = GetAuctionItemInfo and GetAuctionItemInfo(atype, idx)
local link = GetAuctionItemLink and GetAuctionItemLink(atype, idx)
if link then IC_EnhanceTooltip(GameTooltip, link, cnt, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetTradePlayerItem
---------------------------------------------------------------------------
local orig_SetTradePlayerItem = GameTooltip.SetTradePlayerItem
if orig_SetTradePlayerItem then
GameTooltip.SetTradePlayerItem = function(self, idx)
self._nanamiSellPriceAdded = nil
orig_SetTradePlayerItem(self, idx)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link = GetTradePlayerItemLink and GetTradePlayerItemLink(idx)
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetTradeTargetItem
---------------------------------------------------------------------------
local orig_SetTradeTargetItem = GameTooltip.SetTradeTargetItem
if orig_SetTradeTargetItem then
GameTooltip.SetTradeTargetItem = function(self, idx)
self._nanamiSellPriceAdded = nil
orig_SetTradeTargetItem(self, idx)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link = GetTradeTargetItemLink and GetTradeTargetItemLink(idx)
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- GameTooltip.SetInboxItem
---------------------------------------------------------------------------
local orig_SetInboxItem = GameTooltip.SetInboxItem
if orig_SetInboxItem then
GameTooltip.SetInboxItem = function(self, mailID, attachIdx)
self._nanamiSellPriceAdded = nil
orig_SetInboxItem(self, mailID, attachIdx)
local moneyAlreadyShown = self.hasMoney
pcall(function()
local link = IC_ExtractLinkFromTooltipName(GameTooltip)
if link then IC_EnhanceTooltip(GameTooltip, link, nil, moneyAlreadyShown) end
end)
end
end
---------------------------------------------------------------------------
-- SetItemRef (chat item links)
---------------------------------------------------------------------------
local orig_SetItemRef = SetItemRef
if orig_SetItemRef then
SetItemRef = function(link, text, button)
orig_SetItemRef(link, text, button)
if IsAltKeyDown() or IsShiftKeyDown() or IsControlKeyDown() then return end
pcall(function()
local _, _, itemStr = string.find(link or "", "(item:[%-?%d:]+)")
if itemStr then
ItemRefTooltip._nanamiSellPriceAdded = nil
local itemId = IC_GetItemIdFromLink(itemStr)
local price = IC_GetSellPrice(itemId)
if not price then
price = IC_TryGetItemInfoSellPrice(itemStr)
if price and itemId then IC_CacheSellPrice(itemId, price) end
end
if price and price > 0 and not ItemRefTooltip.hasMoney then
SetTooltipMoney(ItemRefTooltip, price)
ItemRefTooltip:Show()
end
if itemId then
ItemRefTooltip:AddLine("物品ID: " .. itemId, 0.55, 0.55, 0.70)
ItemRefTooltip:Show()
end
end
end)
end
end
---------------------------------------------------------------------------
-- Spell ID display
---------------------------------------------------------------------------
local spellIdCache = {}
local function TT_AddSpellIdLine(tooltip, sid)
if not tooltip or not sid then return end
if SFramesDB and SFramesDB.showTooltipIDs == false then return end
tooltip:AddLine("法术ID: " .. sid, 0.55, 0.55, 0.70)
tooltip:Show()
end
local function TT_ExtractSpellId(link)
if not link then return nil end
local _, _, id = string.find(link, "spell:(%d+)")
return id
end
local function TT_CleanName(text)
if not text then return nil end
text = string.gsub(text, "|c%x%x%x%x%x%x%x%x", "")
text = string.gsub(text, "|r", "")
text = string.gsub(text, "|H.-|h", "")
text = string.gsub(text, "|h", "")
text = string.gsub(text, "^%s+", "")
text = string.gsub(text, "%s+$", "")
return text
end
local function TT_BuildSpellCache()
spellIdCache = {}
local function ScanBook(bookType, count)
if not GetSpellLink or count == 0 then return end
for i = 1, count do
local name, rank = GetSpellName(i, bookType)
if name then
local link = GetSpellLink(i, bookType)
local sid = TT_ExtractSpellId(link)
if sid then
spellIdCache[name] = sid
local clean = TT_CleanName(name)
if clean and clean ~= name then
spellIdCache[clean] = sid
end
end
end
end
end
local bookType = BOOKTYPE_SPELL or "spell"
local numTabs = GetNumSpellTabs and GetNumSpellTabs() or 0
local total = 0
for t = 1, numTabs do
local _, _, _, count = GetSpellTabInfo(t)
total = total + (count or 0)
end
ScanBook(bookType, total)
if HasPetSpells then
local numPet = HasPetSpells() or 0
if numPet > 0 then
ScanBook(BOOKTYPE_PET or "pet", numPet)
end
end
end
local spellCacheFrame = CreateFrame("Frame")
spellCacheFrame:RegisterEvent("SPELLS_CHANGED")
spellCacheFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
spellCacheFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
spellCacheFrame:RegisterEvent("PET_BAR_UPDATE")
spellCacheFrame:SetScript("OnEvent", function()
TT_BuildSpellCache()
end)
local function TT_LookupSpellId(spellBookIdx, bookType)
if GetSpellLink then
local link = GetSpellLink(spellBookIdx, bookType)
local sid = TT_ExtractSpellId(link)
if sid then return sid end
end
local name = GetSpellName(spellBookIdx, bookType)
if name then
if spellIdCache[name] then return spellIdCache[name] end
local clean = TT_CleanName(name)
if clean and spellIdCache[clean] then return spellIdCache[clean] end
end
return nil
end
local function TT_LookupByTooltipName(tooltip)
local ttName = tooltip and tooltip:GetName()
if not ttName then return nil end
local left1 = _G[ttName .. "TextLeft1"]
if not left1 then return nil end
local raw = left1:GetText()
if not raw or raw == "" then return nil end
if spellIdCache[raw] then return spellIdCache[raw] end
local clean = TT_CleanName(raw)
if clean and spellIdCache[clean] then return spellIdCache[clean] end
local noRank = string.gsub(clean or raw, "%s*%(.-%)%s*$", "")
if noRank ~= (clean or raw) and spellIdCache[noRank] then
return spellIdCache[noRank]
end
return nil
end
local orig_SetSpell = GameTooltip.SetSpell
if orig_SetSpell then
GameTooltip.SetSpell = function(self, id, bookType)
orig_SetSpell(self, id, bookType)
pcall(function()
local sid = TT_LookupSpellId(id, bookType)
if sid then
TT_AddSpellIdLine(self, sid)
end
end)
end
end
local orig_SetUnitBuff = GameTooltip.SetUnitBuff
if orig_SetUnitBuff then
GameTooltip.SetUnitBuff = function(self, unit, idx, filter)
orig_SetUnitBuff(self, unit, idx, filter)
pcall(function()
local sid = TT_LookupByTooltipName(self)
if sid then TT_AddSpellIdLine(self, sid) end
end)
end
end
local orig_SetUnitDebuff = GameTooltip.SetUnitDebuff
if orig_SetUnitDebuff then
GameTooltip.SetUnitDebuff = function(self, unit, idx, filter)
orig_SetUnitDebuff(self, unit, idx, filter)
pcall(function()
local sid = TT_LookupByTooltipName(self)
if sid then TT_AddSpellIdLine(self, sid) end
end)
end
end
local orig_SetCraftSpell = GameTooltip.SetCraftSpell
if orig_SetCraftSpell then
GameTooltip.SetCraftSpell = function(self, idx)
orig_SetCraftSpell(self, idx)
pcall(function()
local sid = TT_LookupByTooltipName(self)
if sid then TT_AddSpellIdLine(self, sid) end
end)
end
end
local orig_SetTrackingSpell = GameTooltip.SetTrackingSpell
if orig_SetTrackingSpell then
GameTooltip.SetTrackingSpell = function(self)
orig_SetTrackingSpell(self)
pcall(function()
local sid = TT_LookupByTooltipName(self)
if sid then TT_AddSpellIdLine(self, sid) end
end)
end
end
end