diff --git a/modules/castbar.lua b/modules/castbar.lua index 2c0860b7..f5f04187 100644 --- a/modules/castbar.lua +++ b/modules/castbar.lua @@ -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 diff --git a/modules/nameplates.lua b/modules/nameplates.lua index a598afab..4e51a3f5 100644 --- a/modules/nameplates.lua +++ b/modules/nameplates.lua @@ -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