SuperWoW dependency fully removed

Read the Readme for more informations please.
This commit is contained in:
Meow
2026-03-02 13:05:22 +01:00
parent c7aca0de99
commit b91ef05a96
8 changed files with 87 additions and 94 deletions
+15
View File
@@ -14,6 +14,21 @@ This version includes significant performance improvements, DLL-enhanced feature
---
## 🎯 What's New in Version 8.0.0
* **Nampower 3.0.0+ now required** — minimum version bumped from 2.41.0
* **SuperWoW dependency fully removed** — all SuperWoW-specific code paths eliminated:
* `UNIT_CASTEVENT` replaced with `SPELL_GO_SELF` hook for Druid Prowl detection
* `UnitCastingInfo`/`UnitChannelInfo` SuperWoW fallbacks removed from libcast
* `SpellInfo()` (SuperWoW) replaced with `GetSpellRecField()` (Nampower) throughout
* `SPELL_HEAL_BY_SELF` CVar (`NP_EnableSpellHealEvents`) now auto-enabled by libdebuff
* **`GetUnitGUID()` migration** — replaced all `local _, guid = UnitExists(unit)` with `GetUnitGUID(unit)` across 11 files (Nampower 3.0.0 API)
* **Player castbar icon fix** — icons for custom Turtle WoW spells (e.g. Swift Travel Form) now correctly resolved via `GetSpellRecField`/`GetSpellIconTexture` instead of falling back to the previous spell's icon
* **Castbar timer rounding** — 1-decimal mode now rounds correctly to match the Blizzard spellbook display (e.g. 2798ms → 2.8s instead of 2.7s)
* **Nampower warning popup** — updated to be more prominent (`!!!WARNING!!!` in red, non-dismissable via Escape, uses pfUI URL copy frame for download link)
---
## 🎯 What's New in Version 7.8.0
### 🔗 libdebuff External Hook System (libs/libdebuff.lua)
+38 -37
View File
@@ -53,9 +53,6 @@ local scanner = libtipscan:GetScanner("libcast")
local libcast = CreateFrame("Frame", "pfEnemyCast")
local player = UnitName("player")
-- Store original SuperWoW UnitChannelInfo if it exists
local SuperWoW_UnitChannelInfo = _G.UnitChannelInfo
UnitChannelInfo = function(unit)
-- convert to name if unitstring was given
local unitName = pfValidUnits[unit] and UnitName(unit) or unit
@@ -100,11 +97,7 @@ UnitChannelInfo = function(unit)
return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
end
-- For non-player units: use SuperWoW if available, otherwise use libcast.db
if SuperWoW_UnitChannelInfo then
return SuperWoW_UnitChannelInfo(unit)
end
-- For non-player units: use libdebuff GUID-based tracking or libcast.db
-- Try GUID-based lookup first (from libdebuff's SPELL_START tracking)
local db = nil
if guid and pfUI.libdebuff_casts and pfUI.libdebuff_casts[guid] then
@@ -152,9 +145,6 @@ UnitChannelInfo = function(unit)
return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
end
-- Store original SuperWoW UnitCastingInfo if it exists
local SuperWoW_UnitCastingInfo = _G.UnitCastingInfo
UnitCastingInfo = function(unit)
-- convert to name if unitstring was given
local unitName = pfValidUnits[unit] and UnitName(unit) or unit
@@ -172,7 +162,6 @@ UnitCastingInfo = function(unit)
end
-- For player: ALWAYS use libcast.db because it handles pushback correctly
-- SuperWoW's UnitCastingInfo doesn't track SPELLCAST_DELAYED events
local isPlayer = unit == "player" or unitName == player
if isPlayer then
@@ -200,11 +189,7 @@ UnitCastingInfo = function(unit)
return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
end
-- For non-player units: use SuperWoW if available, otherwise use libcast.db
if SuperWoW_UnitCastingInfo then
return SuperWoW_UnitCastingInfo(unit)
end
-- For non-player units: use libdebuff GUID-based tracking or libcast.db
-- Try GUID-based lookup first (from libdebuff's SPELL_START tracking)
local db = nil
if guid and pfUI.libdebuff_casts and pfUI.libdebuff_casts[guid] then
@@ -321,30 +306,34 @@ libcast:RegisterEvent("SPELLCAST_CHANNEL_STOP")
libcast:RegisterEvent("SPELLCAST_CHANNEL_UPDATE")
local mob, spell, icon, _
local lastSpellId = nil -- spellId cached from SPELL_START_SELF (Nampower)
libcast:SetScript("OnEvent", function()
-- Fill database with player casts
if event == "SPELLCAST_START" then
icon = L["spells"][arg1] and L["spells"][arg1].icon and string.format("%s%s", "Interface\\Icons\\", L["spells"][arg1].icon) or lastcasttex
-- Check if SuperWoW already set the cast data (with correct haste-adjusted casttime)
-- If so, only update icon if needed, don't overwrite casttime
local superWowAlreadySet = this.db[player].cast == arg1 and this.db[player].casttime and this.db[player].casttime > 0
if superWowAlreadySet then
-- SuperWoW already set correct casttime, only update icon if better
if icon and not this.db[player].icon then
this.db[player].icon = icon
-- Get icon from Nampower using spellId cached from SPELL_START_SELF
icon = nil
if lastSpellId and GetSpellRecField and GetSpellIconTexture then
local iconId = GetSpellRecField(lastSpellId, "spellIconID")
if iconId then
icon = GetSpellIconTexture(iconId)
if icon and not string.find(icon, "\\") then
icon = "Interface\\Icons\\" .. icon
end
end
else
-- No SuperWoW data, use SPELLCAST_START data
this.db[player].cast = arg1
this.db[player].rank = lastrank
this.db[player].start = GetTime()
this.db[player].casttime = arg2
this.db[player].icon = icon
this.db[player].channel = nil
end
-- fallback to L["spells"] / lastcasttex if Nampower didn't provide icon
if not icon then
icon = L["spells"][arg1] and L["spells"][arg1].icon and string.format("%s%s", "Interface\\Icons\\", L["spells"][arg1].icon) or lastcasttex
end
lastSpellId = nil
this.db[player].cast = arg1
this.db[player].rank = lastrank
this.db[player].start = GetTime()
this.db[player].casttime = arg2
this.db[player].icon = icon
this.db[player].channel = nil
if not L["spells"][arg1] or not L["spells"][arg1].icon or not L["spells"][arg1].t then
L["spells"][arg1] = L["spells"][arg1] or { }
@@ -353,6 +342,7 @@ libcast:SetScript("OnEvent", function()
end
lastcasttex, lastrank = nil, nil
elseif event == "SPELLCAST_STOP" or event == "SPELLCAST_FAILED" or event == "SPELLCAST_INTERRUPTED" then
lastSpellId = nil
if this.db[player] and not this.db[player].channel then
-- remove cast action to the database
this.db[player].cast = nil
@@ -530,7 +520,12 @@ libcast.customcast[strlower(multishot)] = function(begin, duration)
end
local function CastCustom(id, bookType, rawSpellName, rank, texture, castingTime)
if not id or not rawSpellName or not castingTime then return end -- ignore if the spell is not found or if it is instant-cast
if not id or not rawSpellName then return end -- ignore if the spell is not found
if not castingTime or castingTime == 0 then
-- instant-cast: clear lastcasttex so next cast doesn't inherit this icon
lastcasttex, lastrank = nil, nil
return
end
lastrank = rank
lastcasttex = texture
@@ -571,5 +566,11 @@ hooksecurefunc("UseAction", function(slot, target, button)
CastCustom(cachedSpellId, cachedBookType, cachedRawSpellName, cachedRank, cachedTexture, cachedCastingTime)
end)
-- Cache spellId from SPELL_START_SELF so SPELLCAST_START can use it for icon lookup
pfUI.libdebuff_spell_start_self_hooks = pfUI.libdebuff_spell_start_self_hooks or {}
pfUI.libdebuff_spell_start_self_hooks["libcast_icon"] = function(spellId)
lastSpellId = spellId
end
-- add libcast to pfUI API
pfUI.api.libcast = libcast
pfUI.api.libcast = libcast
+8 -21
View File
@@ -384,11 +384,6 @@ function libdebuff:GetSpellIcon(spellId)
end
end
if not texture and SpellInfo then
local _, _, spellTexture = SpellInfo(spellId)
texture = spellTexture
end
if not texture then
texture = "Interface\\Icons\\INV_Misc_QuestionMark"
end
@@ -459,7 +454,7 @@ local function GetDebuffSlotMap(guid)
local spellId = auras[auraSlot]
if spellId and spellId > 0 then
displaySlot = displaySlot + 1
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name") or SpellInfo(spellId)
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
local texture = libdebuff:GetSpellIcon(spellId)
-- Get stacks from auraApplications (0-indexed, so +1 for display)
@@ -1215,9 +1210,7 @@ if hasNampower then
local rec = GetSpellRec(spellId)
spellName = rec and rec.name or nil
end
if not spellName and SpellInfo then
spellName = SpellInfo(spellId)
end
local icon = libdebuff:GetSpellIcon(spellId)
@@ -1282,12 +1275,8 @@ if hasNampower then
if numMissed > 0 or numHit == 0 then return end
local spellName, spellRankString
if SpellInfo then
spellName, spellRankString = SpellInfo(spellId)
elseif GetSpellRecField then
spellName = GetSpellRecField(spellId, "name")
end
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
local spellRankString
if not spellName then return end
local castRank = 0
@@ -1377,9 +1366,7 @@ if hasNampower then
local rec = GetSpellRec(spellId)
spellName = rec and rec.name or nil
end
if not spellName and SpellInfo then
spellName = SpellInfo(spellId)
end
-- Store pending cast info for libpredict (heal prediction target tracking)
-- This allows libpredict to resolve the correct target for Nampower queued casts,
@@ -1424,7 +1411,7 @@ if hasNampower then
if not spellId then return end
if not targetGuid or targetGuid == "" or targetGuid == "0x0000000000000000" then return end
local spellName = SpellInfo and SpellInfo(spellId) or (GetSpellRecField and GetSpellRecField(spellId, "name"))
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
if not spellName then return end
-- Deduplicate: Ignore if we processed this exact cast recently (within 100ms)
@@ -1680,7 +1667,7 @@ if hasNampower then
-- Invalidate slot map cache for this GUID
slotMapCache[guid] = nil
local spellName = SpellInfo and SpellInfo(spellId)
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
if not spellName then return end
if debugStats.enabled then
@@ -1816,7 +1803,7 @@ if hasNampower then
-- Invalidate slot map cache for this GUID
slotMapCache[guid] = nil
local spellName = SpellInfo and SpellInfo(spellId) or "?"
local spellName = (GetSpellRecField and GetSpellRecField(spellId, "name")) or "?"
if debugStats.enabled then
debugStats.debuff_removed = debugStats.debuff_removed + 1
+1 -3
View File
@@ -1,8 +1,6 @@
-- load pfUI environment
setfenv(1, pfUI:GetEnvironment())
local superwow_active = HasSuperWoW()
--[[ librange ]]--
-- A pfUI library that detects and caches distance to units.
--
@@ -197,7 +195,7 @@ librange:SetScript("OnUpdate", function()
end
-- try to read distance via superwow second
if superwow_active then
if HasSuperWoW() and UnitPosition then
local x1, y1, z1 = UnitPosition("player")
local x2, y2, z2 = UnitPosition(unit)
-- only continue if we got position values
+21 -25
View File
@@ -984,7 +984,6 @@ pfUI:RegisterModule("actionbar", "vanilla", function ()
local pageswitch = CreateFrame("Frame", "pfActionBarPageSwitch", UIParent)
pageswitch:RegisterEvent("PLAYER_AURAS_CHANGED")
pageswitch:RegisterEvent("PLAYER_ENTERING_WORLD")
pageswitch:RegisterEvent("UNIT_CASTEVENT")
pageswitch:RegisterEvent("PLAYER_LOGOUT")
pageswitch:SetScript("OnEvent", function()
-- Handle shutdown to prevent crash 132
@@ -994,34 +993,15 @@ pfUI:RegisterModule("actionbar", "vanilla", function ()
this:SetScript("OnUpdate", nil)
return
end
if class ~= "DRUID" then return end
-- On login/reload: full scan
if event == "PLAYER_ENTERING_WORLD" then
prowling = FullScan()
return
end
-- UNIT_CASTEVENT: detect Prowl cast instantly
-- Prowl Spell IDs: 5215 (Rank 1), 6783 (Rank 2), 9913 (Rank 3)
if event == "UNIT_CASTEVENT" then
local guid, target, cEvent, spellId = arg1, arg2, arg3, arg4
local playerGuid = GetUnitGUID("player")
if guid == playerGuid and cEvent == "CAST" then
if spellId == 5215 or spellId == 6783 or spellId == 9913 then
-- Prowl cast detected
inCatForm = true
prowlActive = true
prowling = true
elseif spellId == 768 then
-- Cat Form cast (Spell ID 768)
inCatForm = true
end
end
return
end
-- PLAYER_AURAS_CHANGED: smart scanning
if event == "PLAYER_AURAS_CHANGED" then
if prowlActive then
@@ -1047,9 +1027,25 @@ pfUI:RegisterModule("actionbar", "vanilla", function ()
-- Not in cat form, do a full scan (might have just shifted)
prowling = FullScan()
end
-- If inCatForm but not prowlActive, no scan needed (wait for UNIT_CASTEVENT)
-- If inCatForm but not prowlActive, no scan needed (wait for SPELL_GO_SELF hook)
end
end)
-- Prowl/CatForm detection via Nampower SPELL_GO_SELF hook (replaces UNIT_CASTEVENT)
-- Prowl Spell IDs: 5215 (Rank 1), 6783 (Rank 2), 9913 (Rank 3)
-- Cat Form Spell ID: 768
local PROWL_IDS = { [5215] = true, [6783] = true, [9913] = true }
pfUI.libdebuff_spell_go_hooks = pfUI.libdebuff_spell_go_hooks or {}
pfUI.libdebuff_spell_go_hooks["actionbar_prowl"] = function(spellId)
if class ~= "DRUID" then return end
if PROWL_IDS[spellId] then
inCatForm = true
prowlActive = true
prowling = true
elseif spellId == 768 then
inCatForm = true
end
end
pageswitch:SetScript("OnUpdate", function()
-- switch actionbar page depending on meta key that is pressed
if C.bars.pagemastershift == "1" and IsShiftKeyDown() then
@@ -1756,4 +1752,4 @@ pfUI:RegisterModule("actionbar", "vanilla", function ()
return reagent_counts[reagent_slots[slot]]
end
end
end)
end)
+2 -6
View File
@@ -67,14 +67,11 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
local spellId = arg2
if eventCode == NORMAL_QUEUED or eventCode == NON_GCD_QUEUED or eventCode == ON_SWING_QUEUED then
-- Get spell texture from GetSpellRec (Nampower) or SpellInfo (SuperWoW fallback)
-- Get spell texture from GetSpellRec (Nampower)
local texture
if GetSpellRec then
local rec = GetSpellRec(spellId)
texture = rec and rec.spellIconID and GetSpellIconTexture(rec.spellIconID) or nil
elseif SpellInfo then
local _, _, tex = SpellInfo(spellId)
texture = tex
end
if texture then
@@ -112,8 +109,7 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
local iconID = rec.spellIconID
texture = iconID and GetSpellIconTexture(iconID) or nil
end
elseif SpellInfo then
name, rank, texture = SpellInfo(spellId)
end
if not name then
name, rank = SafeGetSpellNameAndRank(spellId)
+1 -1
View File
@@ -3,7 +3,7 @@
## Author: Shagu - modfied by me0wg4ming
## Notes: A complete user interface replacement.
## Notes-ruRU: Полная замена пользовательского интерфейса.
## Version: 7.8.0
## Version: 8.0.0
## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
+1 -1
View File
@@ -3,7 +3,7 @@
## Author: Shagu - modfied by me0wg4ming
## Notes: A complete user interface replacement.
## Notes-ruRU: Полная замена пользовательского интерфейса.
## Version: 7.8.0
## Version: 8.0.0
## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB