From 2f61716858f5aa8e47d13df711fe9f5760e8820a Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 12:46:44 +0100 Subject: [PATCH 1/8] fixed castbar not showing properly for abilitys like Hunter Volley --- libs/libdebuff.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/libdebuff.lua b/libs/libdebuff.lua index 452f1cdc..8e358100 100644 --- a/libs/libdebuff.lua +++ b/libs/libdebuff.lua @@ -1201,8 +1201,12 @@ if hasNampower then local spellId = arg2 local casterGuid = arg3 local spellType = arg8 or 0 -- 0=Normal, 1=Channel, 2=Autorepeating - local isChannel = spellType == 1 - local castTime = isChannel and arg7 or arg6 -- arg6=castTime (normal), arg7=duration (channel) + -- arg6=castTime, arg7=channel duration + -- prefer arg6 if present — some spells (e.g. Volley post-rework) still send + -- arg8=1 but now have a real cast time in arg6, so we only fall back to arg7 + -- when arg6 is nil (true channels like Blizzard) + local castTime = arg6 or arg7 + local isChannel = spellType == 1 and not arg6 if not casterGuid or not spellId then return end From 956582ff0801f9877ad463f233610fa74b21e169 Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 12:59:44 +0100 Subject: [PATCH 2/8] Fixed missing ranks. - Added a new method to display spellrank when casting spells (nampower GetSpellRecField) --- modules/castbar.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/castbar.lua b/modules/castbar.lua index 8b498daa..0fc927e9 100644 --- a/modules/castbar.lua +++ b/modules/castbar.lua @@ -127,7 +127,12 @@ pfUI:RegisterModule("castbar", "vanilla", function () texture = castData.icon startTime = castData.startTime * 1000 endTime = castData.endTime * 1000 - nameSubtext = "" + -- Try to get rank from spell DB via spellID (nameSubtext is not stored in libdebuff_casts) + if castData.spellID and GetSpellRecField then + nameSubtext = GetSpellRecField(castData.spellID, "rank") or "" + else + nameSubtext = "" + end if castData.event == "CHANNEL" then channel = cast end @@ -390,4 +395,4 @@ pfUI:RegisterModule("castbar", "vanilla", function () UpdateMovable(pfUI.castbar.focus) end -end) +end) \ No newline at end of file From 462f087ece8e9acd645f09a629f46b1191fe2ec7 Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 14:31:37 +0100 Subject: [PATCH 3/8] fixed fake castbar showing up for some hunter spells/abilitys. --- modules/castbar.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/castbar.lua b/modules/castbar.lua index 0fc927e9..7bd66c01 100644 --- a/modules/castbar.lua +++ b/modules/castbar.lua @@ -146,12 +146,14 @@ pfUI:RegisterModule("castbar", "vanilla", function () query = UnitName("player") end - -- Fallback: pfGetCastInfo only when no focusGuid or no cast found via libdebuff - if not cast and not castBlocked and pfGetCastInfo then + -- Fallback: pfGetCastInfo only when no focusGuid (Nampower not available for this unit). + -- If we have a focusGuid, libdebuff is authoritative - don't fall back to libcast + -- even if no cast is active (prevents false positives e.g. spellbook clicks on CD spells). + if not cast and not castBlocked and not focusGuid and pfGetCastInfo then cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = pfGetCastInfo(query) end - if not cast and not castBlocked and pfGetChannelInfo then + if not cast and not castBlocked and not focusGuid and pfGetChannelInfo then channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = pfGetChannelInfo(this.unitstr or this.unitname) cast = channel end From ef9495bf884f33e6b32b005bc80793ededd0f5bc Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 14:46:15 +0100 Subject: [PATCH 4/8] version push and readme update --- README.md | 37 ++++++++++++++++++++++++++++++++++++- pfUI-tbc.toc | 2 +- pfUI.toc | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2b65c97d..d9d58e63 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # pfUI - Turtle WoW Edition -[![Version](https://img.shields.io/badge/version-8.1.0-blue.svg)](https://github.com/me0wg4ming/pfUI) +[![Version](https://img.shields.io/badge/version-8.3.0-blue.svg)](https://github.com/me0wg4ming/pfUI) [![Turtle WoW](https://img.shields.io/badge/Turtle%20WoW-1.18.0-brightgreen.svg)](https://turtlecraft.gg/) [![SuperWoW](https://img.shields.io/badge/SuperWoW-Optional-yellow.svg)](https://github.com/balakethelock/SuperWoW) [![Nampower](https://img.shields.io/badge/Nampower-Required-purple.svg)](https://gitea.com/avitasia/nampower) @@ -14,6 +14,41 @@ This version includes significant performance improvements, DLL-enhanced feature --- +8.3.0 (March 28, 2026) +Nameplate castbars (nameplates.lua, castbar.lua) +the target nameplate castbar was kinda janky compared to the unit frame castbar, so i basically rewrote how it works. it now runs on its own dedicated OnUpdate frame, same as the castbar.lua target castbar does - completly decoupled from the main nameplate loop. also fixed that the castbar throttle setting in the options did literally nothing for the target plate (the comparison was always false lol). non-target plate castbars get their own throttle now too, and during big pulls (20+ plates) they get capped even more to keep things smooth +on top of that the nameplate castbar now uses the same texture + color config as the player/target castbar instead of the hp bar texture and hardcoded yellow. and SetMinMaxValues only gets called once per cast now instead of every single tick +also fixed a bunch of stuff in castbar.lua: + +GetTime() was called like 4 times per tick which caused the throttle to slowly drift, cached it as now once instead +"Show Rank" wasnt working at all when nampower was active because nameSubtext got hardcoded to "" in the libdebuff path. its now fetched via GetSpellRecField +clicking a spell thats on cooldown in the spellbook was showing a fake 3sec castbar. fixed by not falling back to libcast when we already have a focusGuid (libdebuff handles it) + +Map stuff (map.lua, turtle-wow.lua) +added a "switch to current zone" toggle button directly on the worldmap - when its off, opening the map wont auto-jump to your current zone anymore so you can actually browse around freely +also redid all the zone overlay coords for 1.18.1, they were pretty far off before. new zone added: Moonwhisper. removed the UpperKarazhan2f placeholder that wasnt doing anything +Hunter bar (hunterbar.lua) +the melee/ranged page swap now uses IsSpellInRange with Wing Clip and Arcane Shot as range indicators instead of scanning actionbar slots. added hysteresis so it doesnt flip back and forth rapidly in the transition zone +New skins + +Transmog frame skinned (transmog.lua) +Turtle Shop skinned (turtle_shop.lua) + +GroupUI (turtle-wow.lua) +rewrote the turtle GroupUI management logic, it was kind of a mess. now its documented and handles the party/raid cases correctly without interfering when pfUI UF is disabled +misc fixes + +GetColorGradient now handles NaN input without erroring +GetNoNameObject nil check before GetRegions call +UnitInRange was referencing librange as a local that didnt exist, fixed +energy tick spark no longer restarts when mana is already full +macrotweak disables itself if Supermacro/SuperCleveRoidMacros/UltimaMacros are loaded +xpbar rested tooltip shows a warning if exh% goes over 112 (twow display bug) +libthrottle: added nameplates_castbar and swingtimer defaults +talents skin: nil guard for MAX_NUM_TALENTS + +--- + ## 🎯 What's New in Version 8.1.0 (March 03, 2026) 🗡️ Swing Timer Bug Fixes (swingtimer.lua) diff --git a/pfUI-tbc.toc b/pfUI-tbc.toc index 6dbd9968..2d69341a 100644 --- a/pfUI-tbc.toc +++ b/pfUI-tbc.toc @@ -3,7 +3,7 @@ ## Author: Shagu - modfied by me0wg4ming ## Notes: A complete user interface replacement. ## Notes-ruRU: Полная замена пользовательского интерфейса. -## Version: 8.2.0 +## Version: 8.3.0 ## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle ## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB diff --git a/pfUI.toc b/pfUI.toc index b484d19d..133d2472 100644 --- a/pfUI.toc +++ b/pfUI.toc @@ -3,7 +3,7 @@ ## Author: Shagu - modfied by me0wg4ming ## Notes: A complete user interface replacement. ## Notes-ruRU: Полная замена пользовательского интерфейса. -## Version: 8.2.0 +## Version: 8.3.0 ## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle ## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB From df0d73f7e64d0faceb5627fb72cf11d57be8f23e Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 14:47:07 +0100 Subject: [PATCH 5/8] readme update --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d9d58e63..6b45d48a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ This version includes significant performance improvements, DLL-enhanced feature --- -8.3.0 (March 28, 2026) +## 🎯 Whats new in 8.3.0 (March 28, 2026) + Nameplate castbars (nameplates.lua, castbar.lua) the target nameplate castbar was kinda janky compared to the unit frame castbar, so i basically rewrote how it works. it now runs on its own dedicated OnUpdate frame, same as the castbar.lua target castbar does - completly decoupled from the main nameplate loop. also fixed that the castbar throttle setting in the options did literally nothing for the target plate (the comparison was always false lol). non-target plate castbars get their own throttle now too, and during big pulls (20+ plates) they get capped even more to keep things smooth on top of that the nameplate castbar now uses the same texture + color config as the player/target castbar instead of the hp bar texture and hardcoded yellow. and SetMinMaxValues only gets called once per cast now instead of every single tick From c5c669ad3ecd570d5da8ea4c02760f5165d25009 Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 14:51:00 +0100 Subject: [PATCH 6/8] updated readme formating --- README.md | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 6b45d48a..cc50ea71 100644 --- a/README.md +++ b/README.md @@ -16,37 +16,47 @@ This version includes significant performance improvements, DLL-enhanced feature ## 🎯 Whats new in 8.3.0 (March 28, 2026) -Nameplate castbars (nameplates.lua, castbar.lua) +**Nameplate castbars** (nameplates.lua, castbar.lua) + the target nameplate castbar was kinda janky compared to the unit frame castbar, so i basically rewrote how it works. it now runs on its own dedicated OnUpdate frame, same as the castbar.lua target castbar does - completly decoupled from the main nameplate loop. also fixed that the castbar throttle setting in the options did literally nothing for the target plate (the comparison was always false lol). non-target plate castbars get their own throttle now too, and during big pulls (20+ plates) they get capped even more to keep things smooth + on top of that the nameplate castbar now uses the same texture + color config as the player/target castbar instead of the hp bar texture and hardcoded yellow. and SetMinMaxValues only gets called once per cast now instead of every single tick + also fixed a bunch of stuff in castbar.lua: +- GetTime() was called like 4 times per tick which caused the throttle to slowly drift, cached it as `now` once instead +- "Show Rank" wasnt working at all when nampower was active because nameSubtext got hardcoded to "" in the libdebuff path. its now fetched via GetSpellRecField +- clicking a spell thats on cooldown in the spellbook was showing a fake 3sec castbar. fixed by not falling back to libcast when we already have a focusGuid (libdebuff handles it) -GetTime() was called like 4 times per tick which caused the throttle to slowly drift, cached it as now once instead -"Show Rank" wasnt working at all when nampower was active because nameSubtext got hardcoded to "" in the libdebuff path. its now fetched via GetSpellRecField -clicking a spell thats on cooldown in the spellbook was showing a fake 3sec castbar. fixed by not falling back to libcast when we already have a focusGuid (libdebuff handles it) +**Map stuff** (map.lua, turtle-wow.lua) -Map stuff (map.lua, turtle-wow.lua) added a "switch to current zone" toggle button directly on the worldmap - when its off, opening the map wont auto-jump to your current zone anymore so you can actually browse around freely + also redid all the zone overlay coords for 1.18.1, they were pretty far off before. new zone added: Moonwhisper. removed the UpperKarazhan2f placeholder that wasnt doing anything -Hunter bar (hunterbar.lua) + +**Hunter bar** (hunterbar.lua) + the melee/ranged page swap now uses IsSpellInRange with Wing Clip and Arcane Shot as range indicators instead of scanning actionbar slots. added hysteresis so it doesnt flip back and forth rapidly in the transition zone -New skins -Transmog frame skinned (transmog.lua) -Turtle Shop skinned (turtle_shop.lua) +**New skins** + +- Transmog frame skinned (transmog.lua) +- Turtle Shop skinned (turtle_shop.lua) + +**GroupUI** (turtle-wow.lua) -GroupUI (turtle-wow.lua) rewrote the turtle GroupUI management logic, it was kind of a mess. now its documented and handles the party/raid cases correctly without interfering when pfUI UF is disabled -misc fixes -GetColorGradient now handles NaN input without erroring -GetNoNameObject nil check before GetRegions call -UnitInRange was referencing librange as a local that didnt exist, fixed -energy tick spark no longer restarts when mana is already full -macrotweak disables itself if Supermacro/SuperCleveRoidMacros/UltimaMacros are loaded -xpbar rested tooltip shows a warning if exh% goes over 112 (twow display bug) -libthrottle: added nameplates_castbar and swingtimer defaults -talents skin: nil guard for MAX_NUM_TALENTS +**misc fixes** + +- GetColorGradient now handles NaN input without erroring +- GetNoNameObject nil check before GetRegions call +- UnitInRange was referencing librange as a local that didnt exist, fixed +- energy tick spark no longer restarts when mana is already full +- macrotweak disables itself if Supermacro/SuperCleveRoidMacros/UltimaMacros are loaded +- xpbar rested tooltip shows a warning if exh% goes over 112 (twow display bug) +- libthrottle: added nameplates_castbar and swingtimer defaults +- talents skin: nil guard for MAX_NUM_TALENTS +- added github issue templates --- From 4fe7795f2488a1ebe8317967cb5df74e70028149 Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 15:01:32 +0100 Subject: [PATCH 7/8] Branch-aware update notifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Master and experiment users no longer cross-notify each other about updates. The version message now includes a branch tag (master or exp) derived from the toc version string at runtime — only players on the same branch trigger the update notification. No config needed, works automatically. --- modules/updatenotify.lua | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/modules/updatenotify.lua b/modules/updatenotify.lua index a88730dd..e901a38a 100644 --- a/modules/updatenotify.lua +++ b/modules/updatenotify.lua @@ -5,17 +5,26 @@ pfUI:RegisterModule("updatenotify", "vanilla:tbc", function () local loginchannels = { "BATTLEGROUND", "RAID", "GUILD" } local groupchannels = { "BATTLEGROUND", "RAID" } + -- Determine branch from toc version string. + -- experiment toc has "9.x.x (experiment version)", master does not. + -- Only notify players on the same branch about updates. + local tocversion = GetAddOnMetadata(pfUI.name, "Version") or "" + local localbranch = strfind(tocversion, "experiment") and "exp" or "master" + local versionmsg = "VERSION:" .. localversion .. ":" .. localbranch + pfUI.updater = CreateFrame("Frame") pfUI.updater:RegisterEvent("CHAT_MSG_ADDON") pfUI.updater:RegisterEvent("PLAYER_ENTERING_WORLD") pfUI.updater:RegisterEvent("PARTY_MEMBERS_CHANGED") pfUI.updater:SetScript("OnEvent", function() if event == "CHAT_MSG_ADDON" and arg1 == "pfUI" then - local v, remoteversion = pfUI.api.strsplit(":", arg2) - local remoteversion = tonumber(remoteversion) - if v == "VERSION" and remoteversion then - if remoteversion > localversion then - pfUI_init.updateavailable = remoteversion + local v, rv, branch = pfUI.api.strsplit(":", arg2) + local rv = tonumber(rv) + -- only process VERSION messages from the same branch + -- messages without a branch tag (old versions) are ignored + if v == "VERSION" and rv and branch == localbranch then + if rv > localversion then + pfUI_init.updateavailable = rv end end end @@ -24,7 +33,7 @@ pfUI:RegisterModule("updatenotify", "vanilla:tbc", function () local groupsize = GetNumRaidMembers() > 0 and GetNumRaidMembers() or GetNumPartyMembers() > 0 and GetNumPartyMembers() or 0 if ( this.group or 0 ) < groupsize then for _, chan in pairs(groupchannels) do - SendAddonMessage("pfUI", "VERSION:" .. localversion, chan) + SendAddonMessage("pfUI", versionmsg, chan) end end this.group = groupsize @@ -39,7 +48,7 @@ pfUI:RegisterModule("updatenotify", "vanilla:tbc", function () end for _, chan in pairs(loginchannels) do - SendAddonMessage("pfUI", "VERSION:" .. localversion, chan) + SendAddonMessage("pfUI", versionmsg, chan) end end end) From c0c3f9a21ccbc4f13ca268d0f06140d0bdeb0aad Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Sat, 28 Mar 2026 19:19:45 +0100 Subject: [PATCH 8/8] Fix for other channels to have a castbar again --- libs/libdebuff.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/libdebuff.lua b/libs/libdebuff.lua index 8e358100..5dbad640 100644 --- a/libs/libdebuff.lua +++ b/libs/libdebuff.lua @@ -1205,8 +1205,12 @@ if hasNampower then -- prefer arg6 if present — some spells (e.g. Volley post-rework) still send -- arg8=1 but now have a real cast time in arg6, so we only fall back to arg7 -- when arg6 is nil (true channels like Blizzard) - local castTime = arg6 or arg7 - local isChannel = spellType == 1 and not arg6 + -- arg6=castTime (ms), arg7=channel duration (ms), arg8=spellType + -- For channels: arg6=0 (no cast time), arg7=duration, spellType=1 + -- For normal casts: arg6=castTime, arg7=0, spellType=0 + -- Note: "not arg6" is wrong in Lua since 0 is truthy - use arg6 == 0 or nil + local castTime = (arg6 and arg6 > 0) and arg6 or arg7 + local isChannel = spellType == 1 and (not arg6 or arg6 == 0) if not casterGuid or not spellId then return end