更新配置相关显示等
This commit is contained in:
156
Units/Pet.lua
156
Units/Pet.lua
@@ -137,6 +137,8 @@ function SFrames.Pet:Initialize()
|
||||
self.frame.unit = "pet"
|
||||
f:Hide()
|
||||
|
||||
self:CreateCastbar()
|
||||
|
||||
SFrames:RegisterEvent("UNIT_PET", function() if arg1 == "player" then self:UpdateAll() end end)
|
||||
SFrames:RegisterEvent("PET_BAR_UPDATE", function() self:UpdateAll() end)
|
||||
SFrames:RegisterEvent("UNIT_HEALTH", function() if arg1 == "pet" then self:UpdateHealth() end end)
|
||||
@@ -785,3 +787,157 @@ function SFrames.Pet:UpdateFoodButton()
|
||||
if self.foodPanel then self.foodPanel:Hide() end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Pet Castbar
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function SFrames.Pet:CreateCastbar()
|
||||
local f = self.frame
|
||||
local cbHeight = SFrames.Config.castbarHeight
|
||||
|
||||
local cb = SFrames:CreateStatusBar(f, "SFramesPetCastbar")
|
||||
cb:SetHeight(cbHeight)
|
||||
cb:SetPoint("BOTTOMLEFT", f, "TOPLEFT", 0, 4)
|
||||
cb:SetPoint("BOTTOMRIGHT", f, "TOPRIGHT", -(cbHeight + 6), 4)
|
||||
|
||||
local cbbg = CreateFrame("Frame", nil, f)
|
||||
cbbg:SetPoint("TOPLEFT", cb, "TOPLEFT", -1, 1)
|
||||
cbbg:SetPoint("BOTTOMRIGHT", cb, "BOTTOMRIGHT", 1, -1)
|
||||
cbbg:SetFrameLevel(cb:GetFrameLevel() - 1)
|
||||
SFrames:CreateUnitBackdrop(cbbg)
|
||||
|
||||
cb.bg = cb:CreateTexture(nil, "BACKGROUND")
|
||||
cb.bg:SetAllPoints()
|
||||
cb.bg:SetTexture(SFrames:GetTexture())
|
||||
cb.bg:SetVertexColor(_A.slotBg[1], _A.slotBg[2], _A.slotBg[3], _A.slotBg[4] or 1)
|
||||
cb:SetStatusBarColor(1, 0.7, 0)
|
||||
|
||||
cb.text = SFrames:CreateFontString(cb, 10, "LEFT")
|
||||
cb.text:SetPoint("LEFT", cb, "LEFT", 4, 0)
|
||||
|
||||
cb.time = SFrames:CreateFontString(cb, 10, "RIGHT")
|
||||
cb.time:SetPoint("RIGHT", cb, "RIGHT", -4, 0)
|
||||
|
||||
cb.icon = cb:CreateTexture(nil, "ARTWORK")
|
||||
cb.icon:SetWidth(cbHeight + 2)
|
||||
cb.icon:SetHeight(cbHeight + 2)
|
||||
cb.icon:SetPoint("LEFT", cb, "RIGHT", 4, 0)
|
||||
cb.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)
|
||||
|
||||
local ibg = CreateFrame("Frame", nil, f)
|
||||
ibg:SetPoint("TOPLEFT", cb.icon, "TOPLEFT", -1, 1)
|
||||
ibg:SetPoint("BOTTOMRIGHT", cb.icon, "BOTTOMRIGHT", 1, -1)
|
||||
ibg:SetFrameLevel(cb:GetFrameLevel() - 1)
|
||||
SFrames:CreateUnitBackdrop(ibg)
|
||||
|
||||
cb:Hide()
|
||||
cbbg:Hide()
|
||||
cb.icon:Hide()
|
||||
ibg:Hide()
|
||||
|
||||
f.castbar = cb
|
||||
f.castbar.cbbg = cbbg
|
||||
f.castbar.ibg = ibg
|
||||
|
||||
f.castbarUpdater = CreateFrame("Frame", nil, f)
|
||||
f.castbarUpdater:SetScript("OnUpdate", function() SFrames.Pet:CastbarOnUpdate() end)
|
||||
end
|
||||
|
||||
function SFrames.Pet:CastbarOnUpdate()
|
||||
local cb = self.frame.castbar
|
||||
if not UnitExists("pet") then
|
||||
cb:Hide()
|
||||
cb.cbbg:Hide()
|
||||
cb.icon:Hide()
|
||||
cb.ibg:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local cast, texture, startTime, endTime, channel
|
||||
|
||||
-- 1) Try native UnitCastingInfo / UnitChannelInfo (TurtleWoW extended API)
|
||||
local _UnitCastingInfo = UnitCastingInfo or (ShaguTweaks and ShaguTweaks.UnitCastingInfo)
|
||||
if _UnitCastingInfo then
|
||||
local c, _, _, tex, st, et = _UnitCastingInfo("pet")
|
||||
if c then
|
||||
cast, texture, startTime, endTime = c, tex, st, et
|
||||
end
|
||||
end
|
||||
|
||||
if not cast then
|
||||
local _UnitChannelInfo = UnitChannelInfo or (ShaguTweaks and ShaguTweaks.UnitChannelInfo)
|
||||
if _UnitChannelInfo then
|
||||
local c, _, _, tex, st, et = _UnitChannelInfo("pet")
|
||||
if c then
|
||||
cast, texture, startTime, endTime = c, tex, st, et
|
||||
channel = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 2) Fallback: SuperWoW castdb (GUID-based)
|
||||
if not cast and SFrames.castdb and UnitGUID then
|
||||
local guid = UnitGUID("pet")
|
||||
if guid then
|
||||
local entry = SFrames.castdb[guid]
|
||||
if entry and entry.cast and entry.start and entry.casttime then
|
||||
local elapsed = GetTime() - entry.start
|
||||
local duration = entry.casttime / 1000
|
||||
if elapsed < duration + 0.5 then
|
||||
cast = entry.cast
|
||||
texture = entry.icon
|
||||
startTime = entry.start * 1000
|
||||
endTime = (entry.start + duration) * 1000
|
||||
channel = entry.channel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if cast and startTime and endTime then
|
||||
local duration = (endTime - startTime) / 1000
|
||||
local cur = GetTime() - (startTime / 1000)
|
||||
|
||||
if channel then
|
||||
cur = duration + (startTime / 1000) - GetTime()
|
||||
end
|
||||
|
||||
if cur > duration then cur = duration end
|
||||
if cur < 0 then cur = 0 end
|
||||
|
||||
cb:SetMinMaxValues(0, duration)
|
||||
cb:SetValue(cur)
|
||||
cb.text:SetText(cast)
|
||||
cb.time:SetText(string.format("%.1f", channel and cur or math.max(duration - cur, 0)))
|
||||
|
||||
if texture then
|
||||
cb.icon:SetTexture(texture)
|
||||
end
|
||||
|
||||
cb:SetAlpha(1)
|
||||
cb.cbbg:SetAlpha(1)
|
||||
cb.icon:SetAlpha(1)
|
||||
cb.ibg:SetAlpha(1)
|
||||
|
||||
cb:Show()
|
||||
cb.cbbg:Show()
|
||||
cb.icon:Show()
|
||||
cb.ibg:Show()
|
||||
else
|
||||
if cb:IsShown() then
|
||||
local alpha = cb:GetAlpha() - 0.05
|
||||
if alpha > 0 then
|
||||
cb:SetAlpha(alpha)
|
||||
cb.cbbg:SetAlpha(alpha)
|
||||
cb.icon:SetAlpha(alpha)
|
||||
cb.ibg:SetAlpha(alpha)
|
||||
else
|
||||
cb:Hide()
|
||||
cb.cbbg:Hide()
|
||||
cb.icon:Hide()
|
||||
cb.ibg:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1418,30 +1418,35 @@ function SFrames.Player:CreateAuras()
|
||||
end
|
||||
|
||||
function SFrames.Player:UpdateAuras()
|
||||
local timeNow = GetTime()
|
||||
for i = 1, 16 do
|
||||
local b = self.frame.buffs[i]
|
||||
local buffIndex, untilCancelled = GetPlayerBuff(i - 1, "HELPFUL")
|
||||
if buffIndex >= 0 then
|
||||
local texture = GetPlayerBuffTexture(buffIndex)
|
||||
if texture then
|
||||
b.icon:SetTexture(texture)
|
||||
b.buffIndex = buffIndex
|
||||
b:Show()
|
||||
|
||||
local timeLeft = GetPlayerBuffTimeLeft(buffIndex)
|
||||
if timeLeft and timeLeft > 0 and timeLeft < 9999 then
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
local slotIdx = 0
|
||||
for i = 0, 31 do
|
||||
local buffIndex, untilCancelled = GetPlayerBuff(i, "HELPFUL")
|
||||
if buffIndex and buffIndex >= 0 then
|
||||
if not SFrames:IsBuffHidden(buffIndex) then
|
||||
slotIdx = slotIdx + 1
|
||||
if slotIdx > 16 then break end
|
||||
local b = self.frame.buffs[slotIdx]
|
||||
local texture = GetPlayerBuffTexture(buffIndex)
|
||||
if texture then
|
||||
b.icon:SetTexture(texture)
|
||||
b.buffIndex = buffIndex
|
||||
b:Show()
|
||||
|
||||
local timeLeft = GetPlayerBuffTimeLeft(buffIndex)
|
||||
if timeLeft and timeLeft > 0 and timeLeft < 9999 then
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
else
|
||||
b.cdText:SetText("")
|
||||
end
|
||||
else
|
||||
b.cdText:SetText("")
|
||||
b:Hide()
|
||||
end
|
||||
else
|
||||
b:Hide()
|
||||
end
|
||||
else
|
||||
b:Hide()
|
||||
end
|
||||
end
|
||||
for j = slotIdx + 1, 16 do
|
||||
self.frame.buffs[j]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialization Hook for Auras and Castbar
|
||||
@@ -1455,8 +1460,8 @@ function SFrames.Player:Initialize()
|
||||
self.auraUpdater.timer = 0
|
||||
self.auraUpdater:SetScript("OnUpdate", function()
|
||||
this.timer = this.timer + arg1
|
||||
SFrames.Player:UpdateFiveSecondRule()
|
||||
if this.timer >= 0.2 then
|
||||
SFrames.Player:UpdateFiveSecondRule()
|
||||
SFrames.Player:UpdateAuras()
|
||||
SFrames.Player:UpdatePower()
|
||||
SFrames.Player:UpdateHealPrediction()
|
||||
|
||||
@@ -935,36 +935,86 @@ function SFrames.TalentTree:ApplyVirtualPoints()
|
||||
return
|
||||
end
|
||||
|
||||
if not self.applyQueue then self.applyQueue = {} end
|
||||
self.applyQueue = {}
|
||||
|
||||
for tb = 1, GetNumTalentTabs() do
|
||||
local treeTalents = {}
|
||||
for idx = 1, GetNumTalents(tb) do
|
||||
local name, icon, tier, column, realRank = GetTalentInfo(tb, idx)
|
||||
local virtRank = self:GetVirtualRank(tb, idx)
|
||||
local diff = virtRank - realRank
|
||||
if diff > 0 then
|
||||
for i = 1, diff do
|
||||
table.insert(self.applyQueue, {tab = tb, index = idx})
|
||||
table.insert(treeTalents, {tab = tb, index = idx, tier = tier or 1})
|
||||
end
|
||||
end
|
||||
end
|
||||
table.sort(treeTalents, function(a, b) return a.tier < b.tier end)
|
||||
for _, entry in ipairs(treeTalents) do
|
||||
table.insert(self.applyQueue, entry)
|
||||
end
|
||||
end
|
||||
|
||||
if table.getn(self.applyQueue) > 0 then
|
||||
self.frame:SetScript("OnUpdate", function()
|
||||
if table.getn(SFrames.TalentTree.applyQueue) > 0 then
|
||||
local t = table.remove(SFrames.TalentTree.applyQueue, 1)
|
||||
LearnTalent(t.tab, t.index)
|
||||
else
|
||||
this:SetScript("OnUpdate", nil)
|
||||
SFrames.TalentTree.simMode = false
|
||||
SFrames.TalentTree:UpdateSimModeLabel()
|
||||
end
|
||||
end)
|
||||
else
|
||||
if table.getn(self.applyQueue) == 0 then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|c" .. GetHex() .. "Nanami:|r 没有新的天赋点数需要应用。")
|
||||
return
|
||||
end
|
||||
|
||||
local total = table.getn(self.applyQueue)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|c" .. GetHex() .. "Nanami:|r 开始应用 " .. total .. " 个天赋点...")
|
||||
|
||||
if not self.applyEventFrame then
|
||||
self.applyEventFrame = CreateFrame("Frame", "NanamiTalentApplyFrame")
|
||||
end
|
||||
self.applyEventFrame:UnregisterAllEvents()
|
||||
|
||||
self.applyStallTimer = 0
|
||||
self.applyWaiting = false
|
||||
|
||||
local function FinishApply()
|
||||
self.applyEventFrame:UnregisterAllEvents()
|
||||
self.applyEventFrame:SetScript("OnUpdate", nil)
|
||||
self.applyQueue = {}
|
||||
self.applyWaiting = false
|
||||
self.simMode = false
|
||||
self:UpdateSimModeLabel()
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|c" .. GetHex() .. "Nanami:|r 天赋应用完成。")
|
||||
end
|
||||
|
||||
local function TryNextTalent()
|
||||
if table.getn(self.applyQueue) == 0 then
|
||||
FinishApply()
|
||||
return
|
||||
end
|
||||
local t = table.remove(self.applyQueue, 1)
|
||||
LearnTalent(t.tab, t.index)
|
||||
self.applyWaiting = true
|
||||
self.applyStallTimer = 0
|
||||
end
|
||||
|
||||
self.applyEventFrame:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
self.applyEventFrame:SetScript("OnEvent", function()
|
||||
if not SFrames.TalentTree.applyWaiting then return end
|
||||
SFrames.TalentTree.applyWaiting = false
|
||||
SFrames.TalentTree.applyStallTimer = 0
|
||||
TryNextTalent()
|
||||
end)
|
||||
|
||||
self.applyEventFrame:SetScript("OnUpdate", function()
|
||||
if not SFrames.TalentTree.applyWaiting then return end
|
||||
SFrames.TalentTree.applyStallTimer = (SFrames.TalentTree.applyStallTimer or 0) + (arg1 or 0)
|
||||
if SFrames.TalentTree.applyStallTimer >= 2.0 then
|
||||
SFrames.TalentTree.applyStallTimer = 0
|
||||
SFrames.TalentTree.applyWaiting = false
|
||||
if table.getn(SFrames.TalentTree.applyQueue) > 0 then
|
||||
TryNextTalent()
|
||||
else
|
||||
FinishApply()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
TryNextTalent()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
112
Units/Target.lua
112
Units/Target.lua
@@ -819,27 +819,69 @@ end
|
||||
|
||||
function SFrames.Target:TickAuras()
|
||||
if not UnitExists("target") then return end
|
||||
|
||||
|
||||
local timeNow = GetTime()
|
||||
|
||||
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, 16 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
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
if npFormat then
|
||||
local text, r, g, bc, a = npFormat(timeLeft)
|
||||
b.cdText:SetText(text)
|
||||
if r then b.cdText:SetTextColor(r, g, bc, a or 1) end
|
||||
else
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
end
|
||||
else
|
||||
b.cdText:SetText("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Debuffs: re-query SpellDB for live-accurate timers
|
||||
for i = 1, 16 do
|
||||
local b = self.frame.debuffs[i]
|
||||
if b:IsShown() and b.expirationTime then
|
||||
local timeLeft = b.expirationTime - timeNow
|
||||
if timeLeft > 0 and timeLeft < 3600 then
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
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
|
||||
|
||||
if timeLeft and timeLeft > 0 and timeLeft < 3600 then
|
||||
if npFormat then
|
||||
local text, r, g, bc, a = npFormat(timeLeft)
|
||||
b.cdText:SetText(text)
|
||||
if r then b.cdText:SetTextColor(r, g, bc, a or 1) end
|
||||
else
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
end
|
||||
else
|
||||
b.cdText:SetText("")
|
||||
end
|
||||
@@ -895,29 +937,65 @@ 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, 16 do
|
||||
local texture = UnitDebuff("target", i)
|
||||
local b = self.frame.debuffs[i]
|
||||
b:SetID(i) -- Ensure ID is set for tooltips
|
||||
b:SetID(i)
|
||||
if texture then
|
||||
b.icon:SetTexture(texture)
|
||||
|
||||
-- Scrape tooltip for duration
|
||||
SFrames.Tooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
SFrames.Tooltip:ClearLines()
|
||||
SFrames.Tooltip:SetUnitDebuff("target", i)
|
||||
local timeLeft = SFrames:GetAuraTimeLeft("target", i, false)
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
if timeLeft and timeLeft > 0 then
|
||||
b.expirationTime = GetTime() + timeLeft
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
b.effectName = effectName
|
||||
if npFormat then
|
||||
local text, r, g, bc, a = npFormat(timeLeft)
|
||||
b.cdText:SetText(text)
|
||||
if r then b.cdText:SetTextColor(r, g, bc, a or 1) end
|
||||
else
|
||||
b.cdText:SetText(SFrames:FormatTime(timeLeft))
|
||||
end
|
||||
else
|
||||
b.expirationTime = nil
|
||||
b.effectName = nil
|
||||
b.cdText:SetText("")
|
||||
end
|
||||
|
||||
|
||||
b:Show()
|
||||
else
|
||||
b.expirationTime = nil
|
||||
b.effectName = nil
|
||||
b.cdText:SetText("")
|
||||
b:Hide()
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user