fix for nameplates and castbars

Removed SuperWoW dependency from castbar and nameplate cast detection. Cast interrupts (sidestep, spell failed) now correctly stop the castbar by setting event = "FAIL" / event = "CAST" on the libdebuff cache entry instead of nil-ing it — preventing stale local references from keeping the castbar alive. UnitCastingInfo fallback is retained for non-Nampower environments but no longer overrides Nampower cast state.
This commit is contained in:
Meow
2026-02-28 10:18:30 +01:00
parent b32d8568dd
commit 988dfc7079
2 changed files with 35 additions and 35 deletions
+15 -18
View File
@@ -1,5 +1,4 @@
pfUI:RegisterModule("castbar", "vanilla", function ()
local superwow_active = HasSuperWoW()
local font = C.castbar.use_unitfonts == "1" and pfUI.font_unit or pfUI.font_default
local font_size = C.castbar.use_unitfonts == "1" and C.global.font_unit_size or C.global.font_size
@@ -108,43 +107,41 @@ pfUI:RegisterModule("castbar", "vanilla", function ()
local focusGuid = nil
if this.unitstr and string.find(this.unitstr, "^0x") then
focusGuid = this.unitstr
elseif this.unitstr and this.unitstr ~= "player" then
local _, guid = UnitExists(this.unitstr)
if guid then focusGuid = guid end
end
-- Try libdebuff_casts first for GUID-based units (works with Turtle GUID + Nampower events)
local cast, nameSubtext, text, texture, startTime, endTime
local castBlocked = false
if focusGuid and pfUI.libdebuff_casts and pfUI.libdebuff_casts[focusGuid] then
local castData = pfUI.libdebuff_casts[focusGuid]
if castData.event == "START" and castData.endTime and castData.endTime > GetTime() then
if castData.event == "CAST" or castData.event == "FAIL" then
castBlocked = true
pfUI.libdebuff_casts[focusGuid] = nil
elseif castData.event == "START" and castData.endTime and castData.endTime > GetTime() then
cast = castData.spellName
texture = castData.icon
startTime = castData.startTime * 1000 -- libdebuff uses seconds, castbar expects milliseconds
startTime = castData.startTime * 1000
endTime = castData.endTime * 1000
nameSubtext = "" -- Rank info not available in libdebuff_casts
nameSubtext = ""
end
end
-- Fallback: transform unitstrings to unit guids when SuperWoW is active
-- SuperWoW stores cast data by GUID for all units INCLUDING player
-- BUT: For player casts, we need to use libcast data because it handles pushback correctly
local useLibcastForPlayer = this.unitstr == "player"
if not cast and superwow_active and this.unitstr and not useLibcastForPlayer then
local _, guid = UnitExists(this.unitstr)
query = guid or query
end
-- For player: use player name to query libcast.db directly
if not cast and useLibcastForPlayer then
query = UnitName("player")
end
-- Fallback: Try UnitCastingInfo if we haven't found cast data yet
if not cast and UnitCastingInfo then
-- Fallback: UnitCastingInfo only when no focusGuid (Nampower not available for this unit)
if not cast and not castBlocked and not focusGuid and UnitCastingInfo then
cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(query)
end
if not cast and UnitChannelInfo then
-- scan for channel spells if no cast was found
if not cast and not castBlocked and not focusGuid and UnitChannelInfo then
channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(this.unitstr or this.unitname)
cast = channel
end
+20 -17
View File
@@ -1505,10 +1505,14 @@ nameplates:RegisterEvent("ZONE_CHANGED_NEW_AREA")
-- Get GUID for CastEvents lookup - use cached GUID when available
if isTargetPlate then
targetGUID = state and state.targetGuid
if not targetGUID then
local _, guid = UnitExists("target")
targetGUID = guid
end
end
-- Use cached GUID for non-target plates
if superwow_active and not isTargetPlate then
if not isTargetPlate then
unitstr = nameplate.cachedGuid
end
@@ -1557,32 +1561,32 @@ nameplates:RegisterEvent("ZONE_CHANGED_NEW_AREA")
nameplate.castbar:Show()
end
else
-- Fallback to API calls if no event data (for non-SuperWoW or target)
-- Fallback to API calls only when no GUID available (Nampower not tracking this unit)
local channel, cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
-- Try to get cast info for target plates
if isTargetPlate and UnitExists("target") then
if targetGUID then
-- We have a GUID = Nampower is authority, no cast means no cast
nameplate.castbar:Hide()
elseif isTargetPlate and UnitExists("target") then
cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo("target")
if not cast then
if not cast then
channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo("target")
end
-- NAMPOWER: For non-target plates, use GUID or mobName
elseif unitstr then
-- unitstr is GUID from Nampower
cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(unitstr)
local _, guid = UnitExists(unitstr)
local q = guid or unitstr
cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(q)
if not cast then
channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(unitstr)
channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(q)
end
elseif name then
-- Fallback to mob name (for CHAT_MSG castbars)
cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(name)
if not cast then
channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(name)
end
end
if not cast and not channel then
-- No cast data = hide castbar (fixes stuck castbar on FAIL for non-target plates)
nameplate.castbar:Hide()
else
local effect = cast or channel
@@ -1594,21 +1598,20 @@ nameplates:RegisterEvent("ZONE_CHANGED_NEW_AREA")
nameplate.castbar:SetMinMaxValues(0, duration/1000)
nameplate.castbar:SetValue(cur)
-- Show remaining time (countdown), not elapsed time
local remaining = max - cur
if channel then remaining = cur end -- Channel already counts down
if channel then remaining = cur end
if C.unitframes.castbardecimals == "1" then
nameplate.castbar.text:SetText(floor(remaining * 10) / 10)
else
nameplate.castbar.text:SetText(string.format("%.2f", remaining))
end
if C.nameplates.spellname == "1" then
nameplate.castbar.spell:SetText(effect)
else
nameplate.castbar.spell:SetText("")
end
nameplate.castbar:Show()
if texture then