聊天重做前缓存

This commit is contained in:
rucky
2026-04-09 09:46:47 +08:00
parent 6e18269bfd
commit e915bbd74a
39 changed files with 8501 additions and 2308 deletions

View File

@@ -182,6 +182,17 @@ local function Clamp(value, minValue, maxValue)
return value
end
local function SetTextureIfPresent(region, texturePath)
if region and region.SetTexture and texturePath then
region:SetTexture(texturePath)
end
end
local function ApplyFontIfPresent(fs, size, fontKey, fallbackFontKey)
if not fs then return end
SFrames:ApplyFontString(fs, size, fontKey, fallbackFontKey)
end
local DIST_BASE_WIDTH = 80
local DIST_BASE_HEIGHT = 24
local DIST_BASE_FONTSIZE = 14
@@ -232,6 +243,33 @@ function SFrames.Target:GetConfig()
local powerHeight = tonumber(db.targetPowerHeight) or 9
powerHeight = Clamp(math.floor(powerHeight + 0.5), 6, 40)
local showPortrait = db.targetShowPortrait ~= false
local gradientStyle = SFrames:IsGradientStyle()
local classicDefaultPowerWidth = width - (showPortrait and portraitWidth or 0) - 2
if classicDefaultPowerWidth < 60 then
classicDefaultPowerWidth = 60
end
local rawPowerWidth = tonumber(db.targetPowerWidth)
local legacyFullWidth = tonumber(db.targetFrameWidth) or width
local defaultPowerWidth = gradientStyle and width or classicDefaultPowerWidth
local maxPowerWidth = gradientStyle and width or (width - 2)
local powerWidth
if gradientStyle then
-- 渐变风格:能量条始终与血条等宽(全宽)
powerWidth = width
elseif not rawPowerWidth
or math.abs(rawPowerWidth - legacyFullWidth) < 0.5
or math.abs(rawPowerWidth - classicDefaultPowerWidth) < 0.5 then
powerWidth = defaultPowerWidth
else
powerWidth = rawPowerWidth
end
powerWidth = Clamp(math.floor(powerWidth + 0.5), 60, maxPowerWidth)
local powerOffsetX = Clamp(math.floor((tonumber(db.targetPowerOffsetX) or 0) + 0.5), -120, 120)
local powerOffsetY = Clamp(math.floor((tonumber(db.targetPowerOffsetY) or 0) + 0.5), -80, 80)
local height = healthHeight + powerHeight + 4
height = Clamp(height, 30, 140)
@@ -241,6 +279,12 @@ function SFrames.Target:GetConfig()
local valueFont = tonumber(db.targetValueFontSize) or 10
valueFont = Clamp(math.floor(valueFont + 0.5), 8, 18)
local healthFont = tonumber(db.targetHealthFontSize) or valueFont
healthFont = Clamp(math.floor(healthFont + 0.5), 8, 18)
local powerFont = tonumber(db.targetPowerFontSize) or valueFont
powerFont = Clamp(math.floor(powerFont + 0.5), 8, 18)
local frameScale = tonumber(db.targetFrameScale) or 1
frameScale = Clamp(frameScale, 0.7, 1.8)
@@ -250,8 +294,16 @@ function SFrames.Target:GetConfig()
portraitWidth = portraitWidth,
healthHeight = healthHeight,
powerHeight = powerHeight,
powerWidth = powerWidth,
powerOffsetX = powerOffsetX,
powerOffsetY = powerOffsetY,
powerOnTop = db.targetPowerOnTop == true,
nameFont = nameFont,
valueFont = valueFont,
healthFont = healthFont,
powerFont = powerFont,
healthTexture = SFrames:ResolveBarTexture("targetHealthTexture", "barTexture"),
powerTexture = SFrames:ResolveBarTexture("targetPowerTexture", "barTexture"),
scale = frameScale,
}
end
@@ -334,8 +386,8 @@ function SFrames.Target:ApplyConfig()
if f.power then
f.power:ClearAllPoints()
f.power:SetPoint("TOPLEFT", f.health, "BOTTOMLEFT", 0, -1)
f.power:SetPoint("TOPRIGHT", f.health, "BOTTOMRIGHT", 0, 0)
f.power:SetPoint("TOPLEFT", f.health, "BOTTOMLEFT", cfg.powerOffsetX, -1 + cfg.powerOffsetY)
f.power:SetWidth(cfg.powerWidth)
f.power:SetHeight(cfg.powerHeight)
end
@@ -345,19 +397,71 @@ function SFrames.Target:ApplyConfig()
f.powerBGFrame:SetPoint("BOTTOMRIGHT", f.power, "BOTTOMRIGHT", 1, -1)
end
local outline = (SFrames and SFrames.Media and SFrames.Media.fontOutline) or "OUTLINE"
local fontPath = SFrames:GetFont()
SFrames:ApplyStatusBarTexture(f.health, "targetHealthTexture", "barTexture")
SFrames:ApplyStatusBarTexture(f.power, "targetPowerTexture", "barTexture")
SetTextureIfPresent(f.health and f.health.bg, cfg.healthTexture)
SetTextureIfPresent(f.health and f.health.healPredMine, cfg.healthTexture)
SetTextureIfPresent(f.health and f.health.healPredOther, cfg.healthTexture)
SetTextureIfPresent(f.health and f.health.healPredOver, cfg.healthTexture)
SetTextureIfPresent(f.power and f.power.bg, cfg.powerTexture)
if f.nameText then
f.nameText:SetFont(fontPath, cfg.nameFont, outline)
end
if f.healthText then
f.healthText:SetFont(fontPath, cfg.valueFont, outline)
end
if f.powerText then
f.powerText:SetFont(fontPath, cfg.valueFont, outline)
-- Gradient style preset
if SFrames:IsGradientStyle() then
-- Hide portrait & its backdrop
if f.portrait then f.portrait:Hide() end
if f.portraitBG then f.portraitBG:Hide() end
-- Strip backdrops
SFrames:ClearBackdrop(f)
SFrames:ClearBackdrop(f.healthBGFrame)
SFrames:ClearBackdrop(f.powerBGFrame)
-- Health bar full width
if f.health then
f.health:ClearAllPoints()
f.health:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
f.health:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, 0)
f.health:SetHeight(cfg.healthHeight)
end
-- Power bar full width, below health
if f.power then
f.power:ClearAllPoints()
f.power:SetPoint("TOPLEFT", f.health, "BOTTOMLEFT", cfg.powerOffsetX, -2 + cfg.powerOffsetY)
f.power:SetWidth(cfg.powerWidth)
f.power:SetHeight(cfg.powerHeight)
end
-- Apply gradient overlays
SFrames:ApplyGradientStyle(f.health)
SFrames:ApplyGradientStyle(f.power)
-- Flush BG frames (no border padding)
if f.healthBGFrame then
f.healthBGFrame:ClearAllPoints()
f.healthBGFrame:SetPoint("TOPLEFT", f.health, "TOPLEFT", 0, 0)
f.healthBGFrame:SetPoint("BOTTOMRIGHT", f.health, "BOTTOMRIGHT", 0, 0)
end
if f.powerBGFrame then
f.powerBGFrame:ClearAllPoints()
f.powerBGFrame:SetPoint("TOPLEFT", f.power, "TOPLEFT", 0, 0)
f.powerBGFrame:SetPoint("BOTTOMRIGHT", f.power, "BOTTOMRIGHT", 0, 0)
end
-- Hide bar backgrounds (transparent)
if f.healthBGFrame then f.healthBGFrame:Hide() end
if f.powerBGFrame then f.powerBGFrame:Hide() end
if f.health and f.health.bg then f.health.bg:Hide() end
if f.power and f.power.bg then f.power.bg:Hide() end
else
-- Classic style: remove gradient overlays if they exist
SFrames:RemoveGradientStyle(f.health)
SFrames:RemoveGradientStyle(f.power)
-- Restore bar backgrounds
if f.healthBGFrame then f.healthBGFrame:Show() end
if f.powerBGFrame then f.powerBGFrame:Show() end
if f.health and f.health.bg then f.health.bg:Show() end
if f.power and f.power.bg then f.power.bg:Show() end
end
ApplyFontIfPresent(f.nameText, cfg.nameFont, "targetNameFontKey")
ApplyFontIfPresent(f.healthText, cfg.healthFont, "targetHealthFontKey")
ApplyFontIfPresent(f.powerText, cfg.powerFont, "targetPowerFontKey")
if f.castbar then
f.castbar:ClearAllPoints()
if showPortrait then
@@ -374,6 +478,24 @@ function SFrames.Target:ApplyConfig()
self:ApplyDistanceScale(dScale)
end
if f.distText then
local dfs = (db.targetDistanceFontSize and tonumber(db.targetDistanceFontSize)) or 10
dfs = Clamp(dfs, 8, 24)
SFrames:ApplyFontString(f.distText, dfs, "targetDistanceFontKey", "fontKey")
end
if f.health and f.power then
local healthLevel = f:GetFrameLevel() + 2
local powerLevel = cfg.powerOnTop and (healthLevel + 1) or (healthLevel - 1)
f.health:SetFrameLevel(healthLevel)
f.power:SetFrameLevel(powerLevel)
end
SFrames:ApplyConfiguredUnitBackdrop(f, "target")
if f.healthBGFrame then SFrames:ApplyConfiguredUnitBackdrop(f.healthBGFrame, "target") end
if f.powerBGFrame then SFrames:ApplyConfiguredUnitBackdrop(f.powerBGFrame, "target") end
if f.portraitBG then SFrames:ApplyConfiguredUnitBackdrop(f.portraitBG, "target", true) end
if UnitExists("target") then
self:UpdateAll()
end
@@ -386,8 +508,6 @@ function SFrames.Target:ApplyDistanceScale(scale)
f:SetWidth(DIST_BASE_WIDTH * scale)
f:SetHeight(DIST_BASE_HEIGHT * scale)
if f.text then
local fontPath = SFrames:GetFont()
local outline = (SFrames.Media and SFrames.Media.fontOutline) or "OUTLINE"
local customSize = SFramesDB and tonumber(SFramesDB.targetDistanceFontSize)
local fontSize
if customSize and customSize >= 8 and customSize <= 24 then
@@ -395,7 +515,7 @@ function SFrames.Target:ApplyDistanceScale(scale)
else
fontSize = math.max(8, math.floor(DIST_BASE_FONTSIZE * scale + 0.5))
end
f.text:SetFont(fontPath, fontSize, outline)
SFrames:ApplyFontString(f.text, fontSize, "targetDistanceFontKey", "fontKey")
end
end
@@ -437,54 +557,46 @@ function SFrames.Target:InitializeDistanceFrame()
f.text:SetShadowColor(0, 0, 0, 1)
f.text:SetShadowOffset(1, -1)
-- Behind indicator text (shown next to distance)
f.behindText = SFrames:CreateFontString(f, fontSize, "LEFT")
f.behindText:SetPoint("LEFT", f.text, "RIGHT", 4, 0)
f.behindText:SetShadowColor(0, 0, 0, 1)
f.behindText:SetShadowOffset(1, -1)
f.behindText:Hide()
SFrames.Target.distanceFrame = f
f:Hide()
f.timer = 0
f:SetScript("OnUpdate", function()
if SFramesDB and SFramesDB.targetDistanceEnabled == false then
if this:IsShown() then this:Hide() end
local ticker = CreateFrame("Frame", nil, UIParent)
ticker:SetWidth(1)
ticker:SetHeight(1)
ticker.timer = 0
ticker:Show()
ticker:SetScript("OnUpdate", function()
local distFrame = SFrames.Target.distanceFrame
if not distFrame then return end
local disabled = SFramesDB and SFramesDB.targetDistanceEnabled == false
local onFrame = not SFramesDB or SFramesDB.targetDistanceOnFrame ~= false
local tgtFrame = SFrames.Target and SFrames.Target.frame
local embeddedText = tgtFrame and tgtFrame.distText
if disabled then
if distFrame:IsShown() then distFrame:Hide() end
if embeddedText and embeddedText:IsShown() then embeddedText:Hide() end
return
end
if not UnitExists("target") then
if this:IsShown() then this:Hide() end
if this.behindText then this.behindText:Hide() end
if distFrame:IsShown() then distFrame:Hide() end
if embeddedText and embeddedText:IsShown() then embeddedText:Hide() end
return
end
this.timer = this.timer + (arg1 or 0)
if this.timer >= 0.4 then
this.timer = 0
local dist = SFrames.Target:GetDistance("target")
this.text:SetText(dist or "---")
if not this:IsShown() then this:Show() end
local distStr = dist or "---"
-- Behind indicator
if this.behindText then
local showBehind = not SFramesDB or SFramesDB.Tweaks == nil
or SFramesDB.Tweaks.behindIndicator ~= false
if showBehind and IsUnitXPAvailable() then
local ok, isBehind = pcall(UnitXP, "behind", "player", "target")
if ok and isBehind then
this.behindText:SetText("背后")
this.behindText:SetTextColor(0.2, 1.0, 0.3)
this.behindText:Show()
elseif ok then
this.behindText:SetText("正面")
this.behindText:SetTextColor(1.0, 0.35, 0.3)
this.behindText:Show()
else
this.behindText:Hide()
end
else
this.behindText:Hide()
end
if onFrame and embeddedText then
embeddedText:SetText(distStr)
if not embeddedText:IsShown() then embeddedText:Show() end
if distFrame:IsShown() then distFrame:Hide() end
else
distFrame.text:SetText(distStr)
if not distFrame:IsShown() then distFrame:Show() end
if embeddedText and embeddedText:IsShown() then embeddedText:Hide() end
end
end
end)
@@ -515,15 +627,23 @@ function SFrames.Target:Initialize()
local f = CreateFrame("Button", "SFramesTargetFrame", UIParent)
f:SetWidth(SFrames.Config.width)
f:SetHeight(SFrames.Config.height)
if SFramesDB and SFramesDB.Positions and SFramesDB.Positions["TargetFrame"] then
local pos = SFramesDB.Positions["TargetFrame"]
f:SetPoint(pos.point, UIParent, pos.relativePoint, pos.xOfs, pos.yOfs)
else
f:SetPoint("CENTER", UIParent, "CENTER", 200, -100) -- Mirrored from player
end
local frameScale = (SFramesDB and type(SFramesDB.targetFrameScale) == "number") and SFramesDB.targetFrameScale or 1
f:SetScale(frameScale)
if SFramesDB and SFramesDB.Positions and SFramesDB.Positions["TargetFrame"] then
local pos = SFramesDB.Positions["TargetFrame"]
local fScale = f:GetEffectiveScale() / UIParent:GetEffectiveScale()
if fScale > 0.01 and math.abs(fScale - 1) > 0.001 then
f:SetPoint(pos.point, UIParent, pos.relativePoint,
(pos.xOfs or 0) / fScale, (pos.yOfs or 0) / fScale)
else
f:SetPoint(pos.point, UIParent, pos.relativePoint, pos.xOfs or 0, pos.yOfs or 0)
end
else
f:SetPoint("CENTER", UIParent, "CENTER", 200, -100)
end
f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
@@ -533,25 +653,21 @@ function SFrames.Target:Initialize()
if not SFramesDB then SFramesDB = {} end
if not SFramesDB.Positions then SFramesDB.Positions = {} end
local point, relativeTo, relativePoint, xOfs, yOfs = f:GetPoint()
local fSc = f:GetEffectiveScale() / UIParent:GetEffectiveScale()
if fSc > 0.01 and math.abs(fSc - 1) > 0.001 then
xOfs = (xOfs or 0) * fSc
yOfs = (yOfs or 0) * fSc
end
SFramesDB.Positions["TargetFrame"] = { point = point, relativePoint = relativePoint, xOfs = xOfs, yOfs = yOfs }
end)
f:RegisterForClicks("LeftButtonUp", "RightButtonUp")
f:SetScript("OnClick", function()
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] OnClick fired: " .. tostring(arg1) .. "|r")
if arg1 == "LeftButton" then
-- Shift+左键 = 设为焦点
if IsShiftKeyDown() then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] Shift+LeftButton -> SetFocus|r")
if SFrames.Focus and SFrames.Focus.SetFromTarget then
local ok, err = pcall(SFrames.Focus.SetFromTarget, SFrames.Focus)
if ok then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] Focus set OK|r")
else
DEFAULT_CHAT_FRAME:AddMessage("|cffff4444[Nanami] Focus error: " .. tostring(err) .. "|r")
end
else
DEFAULT_CHAT_FRAME:AddMessage("|cffff4444[Nanami] SFrames.Focus missing!|r")
pcall(SFrames.Focus.SetFromTarget, SFrames.Focus)
end
return
end
@@ -562,31 +678,25 @@ function SFrames.Target:Initialize()
SpellTargetUnit(this.unit)
end
elseif arg1 == "RightButton" then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] RightButton hit|r")
if SpellIsTargeting and SpellIsTargeting() then
SpellStopTargeting()
return
end
if not UnitExists("target") then
DEFAULT_CHAT_FRAME:AddMessage("|cffff4444[Nanami] No target, abort|r")
return
end
if not SFrames.Target.dropDown then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] Creating dropdown...|r")
local ok1, err1 = pcall(function()
SFrames.Target.dropDown = CreateFrame("Frame", "SFramesTargetDropDown", UIParent, "UIDropDownMenuTemplate")
end)
if not ok1 then
DEFAULT_CHAT_FRAME:AddMessage("|cffff4444[Nanami] CreateFrame failed: " .. tostring(err1) .. "|r")
return
end
SFrames.Target.dropDown.displayMode = "MENU"
SFrames.Target.dropDown.initialize = function()
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] initialize() called|r")
local dd = SFrames.Target.dropDown
local name = dd.targetName
if not name then
DEFAULT_CHAT_FRAME:AddMessage("|cffff4444[Nanami] initialize: no targetName|r")
return
end
@@ -678,16 +788,9 @@ function SFrames.Target:Initialize()
-- 取消按钮不添加,点击菜单外部即可关闭(节省按钮位)
end
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] Dropdown created OK|r")
end
SFrames.Target.dropDown.targetName = UnitName("target")
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] Calling ToggleDropDownMenu...|r")
local ok3, err3 = pcall(ToggleDropDownMenu, 1, nil, SFrames.Target.dropDown, "cursor")
if not ok3 then
DEFAULT_CHAT_FRAME:AddMessage("|cffff4444[Nanami] ToggleDropDownMenu failed: " .. tostring(err3) .. "|r")
else
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nanami] ToggleDropDownMenu OK|r")
end
pcall(ToggleDropDownMenu, 1, nil, SFrames.Target.dropDown, "cursor")
end
end)
f:SetScript("OnReceiveDrag", function()
@@ -799,6 +902,19 @@ function SFrames.Target:Initialize()
f.comboText:SetTextColor(1, 0.8, 0)
f.comboText:SetText("")
-- Embedded distance text (high-level overlay so it's never covered)
local distOverlay = CreateFrame("Frame", nil, f)
distOverlay:SetFrameLevel((f:GetFrameLevel() or 0) + 20)
distOverlay:SetAllPoints(f.health)
local distFS = (SFramesDB and tonumber(SFramesDB.targetDistanceFontSize)) or 10
f.distText = SFrames:CreateFontString(distOverlay, distFS, "CENTER")
f.distText:SetPoint("CENTER", f.health, "TOP", 0, 0)
f.distText:SetTextColor(1, 0.82, 0.25)
f.distText:SetShadowColor(0, 0, 0, 1)
f.distText:SetShadowOffset(1, -1)
f.distText:SetText("")
f.distText:Hide()
-- Raid Target Icon (top center of health bar, half outside frame)
local raidIconSize = 22
local raidIconOvr = CreateFrame("Frame", nil, f)
@@ -864,7 +980,8 @@ function SFrames.Target:Initialize()
-- Register movers
if SFrames.Movers and SFrames.Movers.RegisterMover then
SFrames.Movers:RegisterMover("TargetFrame", f, "目标",
"CENTER", "UIParent", "CENTER", 200, -100)
"CENTER", "UIParent", "CENTER", 200, -100,
nil, { alwaysShowInLayout = true })
if SFrames.Target.distanceFrame then
SFrames.Movers:RegisterMover("TargetDistanceFrame", SFrames.Target.distanceFrame, "目标距离",
"CENTER", "UIParent", "CENTER", 0, 100)
@@ -1047,18 +1164,24 @@ function SFrames.Target:OnTargetChanged()
if UnitExists("target") then
self.frame:Show()
self:UpdateAll()
local enabled = not (SFramesDB and SFramesDB.targetDistanceEnabled == false)
local onFrame = not SFramesDB or SFramesDB.targetDistanceOnFrame ~= false
if SFrames.Target.distanceFrame then
local dist = self:GetDistance("target")
SFrames.Target.distanceFrame.text:SetText(dist or "---")
if not (SFramesDB and SFramesDB.targetDistanceEnabled == false) then
SFrames.Target.distanceFrame:Show()
else
if onFrame and self.frame.distText then
self.frame.distText:SetText(dist or "---")
if enabled then self.frame.distText:Show() else self.frame.distText:Hide() end
SFrames.Target.distanceFrame:Hide()
else
SFrames.Target.distanceFrame.text:SetText(dist or "---")
if enabled then SFrames.Target.distanceFrame:Show() else SFrames.Target.distanceFrame:Hide() end
if self.frame.distText then self.frame.distText:Hide() end
end
end
else
self.frame:Hide()
if SFrames.Target.distanceFrame then SFrames.Target.distanceFrame:Hide() end
if self.frame and self.frame.distText then self.frame.distText:Hide() end
end
end
@@ -1153,6 +1276,8 @@ function SFrames.Target:UpdateAll()
end
local useClassColor = not (SFramesDB and SFramesDB.classColorHealth == false)
-- Gradient style always uses class colors
if SFrames:IsGradientStyle() then useClassColor = true end
if UnitIsPlayer("target") and useClassColor then
local _, class = UnitClass("target")
@@ -1184,6 +1309,10 @@ function SFrames.Target:UpdateAll()
self.frame.nameText:SetText(formattedLevel .. name)
self.frame.nameText:SetTextColor(r, g, b)
end
-- Re-apply gradient after color change
if SFrames:IsGradientStyle() then
SFrames:ApplyBarGradient(self.frame.health)
end
end
function SFrames.Target:UpdateHealth()
@@ -1208,9 +1337,9 @@ function SFrames.Target:UpdateHealth()
end
if displayMax > 0 then
self.frame.healthText:SetText(displayHp .. " / " .. displayMax)
self.frame.healthText:SetText(SFrames:FormatCompactPair(displayHp, displayMax))
else
self.frame.healthText:SetText(displayHp)
self.frame.healthText:SetText(SFrames:FormatCompactNumber(displayHp))
end
self:UpdateHealPrediction()
@@ -1222,14 +1351,8 @@ function SFrames.Target:UpdateHealPrediction()
local predOther = self.frame.health.healPredOther
local predOver = self.frame.health.healPredOver
local function HidePredictions()
predMine:Hide()
predOther:Hide()
predOver:Hide()
end
if not UnitExists("target") then
HidePredictions()
predMine:Hide(); predOther:Hide(); predOver:Hide()
return
end
@@ -1251,7 +1374,7 @@ function SFrames.Target:UpdateHealPrediction()
end
if maxHp <= 0 then
HidePredictions()
predMine:Hide(); predOther:Hide(); predOver:Hide()
return
end
@@ -1268,7 +1391,7 @@ function SFrames.Target:UpdateHealPrediction()
end
local missing = maxHp - hp
if missing <= 0 and (mineIncoming <= 0 and othersIncoming <= 0) then
HidePredictions()
predMine:Hide(); predOther:Hide(); predOver:Hide()
return
end
@@ -1276,14 +1399,14 @@ function SFrames.Target:UpdateHealPrediction()
local remaining = missing - mineShown
local otherShown = math.min(math.max(0, othersIncoming), remaining)
if mineShown <= 0 and otherShown <= 0 and (mineIncoming <= 0 and othersIncoming <= 0) then
HidePredictions()
predMine:Hide(); predOther:Hide(); predOver:Hide()
return
end
local showPortrait = SFramesDB and SFramesDB.targetShowPortrait ~= false
local barWidth = self.frame:GetWidth() - (showPortrait and (self.frame.portrait:GetWidth() + 2) or 2)
if barWidth <= 0 then
HidePredictions()
predMine:Hide(); predOther:Hide(); predOver:Hide()
return
end
@@ -1293,7 +1416,7 @@ function SFrames.Target:UpdateHealPrediction()
local availableWidth = barWidth - currentWidth
if availableWidth <= 0 and (mineIncoming <= 0 and othersIncoming <= 0) then
HidePredictions()
predMine:Hide(); predOther:Hide(); predOver:Hide()
return
end
@@ -1359,6 +1482,9 @@ function SFrames.Target:UpdatePowerType()
else
self.frame.power:SetStatusBarColor(0, 0, 1)
end
if SFrames:IsGradientStyle() then
SFrames:ApplyBarGradient(self.frame.power)
end
end
function SFrames.Target:UpdatePower()
@@ -1367,10 +1493,11 @@ function SFrames.Target:UpdatePower()
self.frame.power:SetMinMaxValues(0, maxPower)
self.frame.power:SetValue(power)
if maxPower > 0 then
self.frame.powerText:SetText(power .. " / " .. maxPower)
self.frame.powerText:SetText(SFrames:FormatCompactPair(power, maxPower))
else
self.frame.powerText:SetText("")
end
SFrames:UpdateRainbowBar(self.frame.power, power, maxPower, "target")
end
function SFrames.Target:UpdateComboPoints()
@@ -1501,23 +1628,15 @@ end
function SFrames.Target:TickAuras()
if not UnitExists("target") then return end
local timeNow = GetTime()
local tracker = SFrames.AuraTracker
local npFormat = NanamiPlates_Auras and NanamiPlates_Auras.FormatTime
local hasNP = NanamiPlates_SpellDB and NanamiPlates_SpellDB.FindEffectData
local targetName, targetLevel, targetGUID
if hasNP then
targetName = UnitName("target")
targetLevel = UnitLevel("target") or 0
targetGUID = UnitGUID and UnitGUID("target")
end
-- Buffs
for i = 1, 32 do
local b = self.frame.buffs[i]
if b:IsShown() and b.expirationTime then
local timeLeft = b.expirationTime - timeNow
if timeLeft > 0 and timeLeft < 3600 then
if b:IsShown() then
local timeLeft = tracker and tracker:GetAuraTimeLeft("target", "buff", i)
if timeLeft and timeLeft > 0 and timeLeft < 3600 then
if npFormat then
local text, r, g, bc, a = npFormat(timeLeft)
b.cdText:SetText(text)
@@ -1531,30 +1650,11 @@ function SFrames.Target:TickAuras()
end
end
-- Debuffs: re-query SpellDB for live-accurate timers
-- Debuffs
for i = 1, 32 do
local b = self.frame.debuffs[i]
if b:IsShown() then
local timeLeft = nil
if hasNP and b.effectName then
local data = targetGUID and NanamiPlates_SpellDB:FindEffectData(targetGUID, targetLevel, b.effectName)
if not data and targetName then
data = NanamiPlates_SpellDB:FindEffectData(targetName, targetLevel, b.effectName)
end
if data and data.start and data.duration then
local remaining = data.duration + data.start - timeNow
if remaining > 0 then
timeLeft = remaining
b.expirationTime = timeNow + remaining
end
end
end
if not timeLeft and b.expirationTime then
timeLeft = b.expirationTime - timeNow
end
local timeLeft = tracker and tracker:GetAuraTimeLeft("target", "debuff", i)
if timeLeft and timeLeft > 0 and timeLeft < 3600 then
if npFormat then
local text, r, g, bc, a = npFormat(timeLeft)
@@ -1573,6 +1673,11 @@ end
function SFrames.Target:UpdateAuras()
if not UnitExists("target") then return end
local tracker = SFrames.AuraTracker
if tracker and tracker.HandleAuraSnapshot then
tracker:HandleAuraSnapshot("target")
end
local hasSuperWoW = SFrames.superwow_active and SpellInfo
local numBuffs = 0
-- Buffs
@@ -1584,12 +1689,9 @@ function SFrames.Target:UpdateAuras()
b.icon:SetTexture(texture)
-- Store aura ID when SuperWoW is available
b.auraID = hasSuperWoW and swAuraID or nil
SFrames.Tooltip:SetOwner(UIParent, "ANCHOR_NONE")
SFrames.Tooltip:ClearLines()
SFrames.Tooltip:SetUnitBuff("target", i)
local timeLeft = SFrames:GetAuraTimeLeft("target", i, true)
SFrames.Tooltip:Hide()
local state = tracker and tracker:GetAuraState("target", "buff", i)
local timeLeft = state and tracker:GetAuraTimeLeft("target", "buff", i)
if timeLeft and timeLeft > 0 then
b.expirationTime = GetTime() + timeLeft
b.cdText:SetText(SFrames:FormatTime(timeLeft))
@@ -1621,7 +1723,6 @@ function SFrames.Target:UpdateAuras()
end
-- Debuffs
local hasNP = NanamiPlates_SpellDB and NanamiPlates_SpellDB.UnitDebuff
local npFormat = NanamiPlates_Auras and NanamiPlates_Auras.FormatTime
for i = 1, 32 do
@@ -1633,39 +1734,12 @@ function SFrames.Target:UpdateAuras()
-- Store aura ID when SuperWoW is available
b.auraID = hasSuperWoW and swDebuffAuraID or nil
local timeLeft = 0
local effectName = nil
if hasNP then
local effect, rank, _, stacks, dtype, duration, npTimeLeft, isOwn = NanamiPlates_SpellDB:UnitDebuff("target", i)
effectName = effect
if npTimeLeft and npTimeLeft > 0 then
timeLeft = npTimeLeft
elseif effect and effect ~= "" and duration and duration > 0
and NanamiPlates_Auras and NanamiPlates_Auras.timers then
local unitKey = (UnitGUID and UnitGUID("target")) or UnitName("target") or ""
local cached = NanamiPlates_Auras.timers[unitKey .. "_" .. effect]
if not cached and UnitName("target") then
cached = NanamiPlates_Auras.timers[UnitName("target") .. "_" .. effect]
end
if cached and cached.startTime and cached.duration then
local remaining = cached.duration - (GetTime() - cached.startTime)
if remaining > 0 then timeLeft = remaining end
end
end
end
if timeLeft <= 0 then
SFrames.Tooltip:SetOwner(UIParent, "ANCHOR_NONE")
SFrames.Tooltip:ClearLines()
SFrames.Tooltip:SetUnitDebuff("target", i)
timeLeft = SFrames:GetAuraTimeLeft("target", i, false)
SFrames.Tooltip:Hide()
end
local state = tracker and tracker:GetAuraState("target", "debuff", i)
local timeLeft = state and tracker:GetAuraTimeLeft("target", "debuff", i)
if timeLeft and timeLeft > 0 then
b.expirationTime = GetTime() + timeLeft
b.effectName = effectName
b.effectName = state and state.name or nil
if npFormat then
local text, r, g, bc, a = npFormat(timeLeft)
b.cdText:SetText(text)