diff --git a/api/api.lua b/api/api.lua index b98a4e0b..878ed9c9 100644 --- a/api/api.lua +++ b/api/api.lua @@ -64,6 +64,10 @@ end -- Requires UnitXP_SP3 function pfUI.api.UnitInLineOfSight(unit1, unit2) if not pfUI.api.HasUnitXP() then return nil end + if not unit2 then + unit2 = unit1 + unit1 = "player" + end local success, inSight = pcall(UnitXP, "inSight", unit1, unit2) if success then return inSight end return nil @@ -74,6 +78,10 @@ end -- Requires UnitXP_SP3 function pfUI.api.UnitIsBehind(unit1, unit2) if not pfUI.api.HasUnitXP() then return nil end + if not unit2 then + unit2 = unit1 + unit1 = "player" + end local success, behind = pcall(UnitXP, "behind", unit1, unit2) if success then return behind end return nil @@ -84,17 +92,18 @@ gfind = string.gmatch or string.gfind mod = math.mod or mod -- [ strsplit ] --- Splits a string using a delimiter. +-- Splits a string using a delimiter. Thin wrapper that delegates to +-- ClassicAPI's C-level strsplit, kept as a pfUI.api entry point for +-- backwards compatibility with addons that call pfUI.api.strsplit. +-- Note: unlike the old Lua implementation, empty fields are preserved +-- (e.g. "a,,b" -> "a", "", "b"), matching real strsplit semantics. -- 'delimiter' [string] characters that will be interpreted as delimiter -- characters (bytes) in the string. -- 'subject' [string] String to split. -- return: [list] a list of strings. function pfUI.api.strsplit(delimiter, subject) if not subject then return nil end - local delimiter, fields = delimiter or ":", {} - local pattern = string.format("([^%s]+)", delimiter) - string.gsub(subject, pattern, function(c) fields[table.getn(fields)+1] = c end) - return unpack(fields) + return _G.strsplit(delimiter or ":", subject) end -- [ isempty ] @@ -131,7 +140,6 @@ end -- It takes care of the rangecheck module if existing. -- unit [string] A unit to query (string, unitID) -- return: [bool] "1" if in range otherwise "nil" -local RangeCache = {} function pfUI.api.UnitInRange(unit) if not UnitExists(unit) or not UnitIsVisible(unit) then return nil diff --git a/api/ui-widgets.lua b/api/ui-widgets.lua index 0de64bf6..46bc7fc0 100644 --- a/api/ui-widgets.lua +++ b/api/ui-widgets.lua @@ -21,8 +21,7 @@ do -- statusbars local handlers = { ["DisplayValue"] = function(self, val) - val = val > self.max and self.max or val - val = val < self.min and self.min or val + val = Clamp(val, self.min, self.max) -- remove animation queue if val == self.val_ then @@ -38,8 +37,7 @@ do -- statusbars point = height / (self.max - self.min) * (val - self.min) -- keep values in limits - point = math.min(height, point) - point = math.max(0, point) + point = Clamp(point, 0, height) -- set point to zero if value and max is zero if val == 0 then point = 0 end @@ -57,8 +55,7 @@ do -- statusbars point = width / (self.max - self.min) * (val - self.min) -- keep values in limits - point = math.min(width, point) - point = math.max(0, point) + point = Clamp(point, 0, width) -- set point to zero if value and max is zero if val == 0 then point = 0 end @@ -138,15 +135,8 @@ do -- statusbars end do -- dropdown - local _, class = UnitClass("player") - local color = PFUI_CLASS_COLORS[class] - local function ListEntryOnShow() - if this.parent.id == this.id then - this.icon:Show() - else - this.icon:Hide() - end + this.icon:SetShown(this.parent.id == this.id) end local function ListEntryOnClick() @@ -288,8 +278,7 @@ do -- dropdown frame.icon = frame:CreateTexture(nil, "OVERLAY") frame.icon:SetPoint("RIGHT", frame, "RIGHT", -2, 0) - frame.icon:SetHeight(16) - frame.icon:SetWidth(16) + frame.icon:SetSize(16, 16) frame.icon:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") frame.text = frame:CreateFontString(nil, "OVERLAY") @@ -329,8 +318,7 @@ do -- dropdown local button = CreateFrame("Button", nil, frame) button:SetPoint("RIGHT", frame, "RIGHT", -2, 0) - button:SetWidth(16) - button:SetHeight(16) + button:SetSize(16, 16) button:SetScript("OnClick", ListButtonOnClick) SkinArrowButton(button, "down") button.icon:SetVertexColor(1,.9,.1) @@ -380,8 +368,7 @@ function pfUI.api.CreateTabChild(self, title, bwidth, bheight, bottom, static) end -- set dimensions - b:SetHeight(button_height) - b:SetWidth(button_width) + b:SetSize(button_width, button_height) b:SetID(childcount) if not self.align or self.align == "LEFT" then @@ -516,13 +503,7 @@ function pfUI.api.CreateScrollFrame(name, parent) local max = f:GetVerticalScrollRange() local new = current - step - if new >= max then - f:SetVerticalScroll(max) - elseif new <= 0 then - f:SetVerticalScroll(0) - else - f:SetVerticalScroll(new) - end + f:SetVerticalScroll(Clamp(new, 0, max)) f:UpdateScrollState() end @@ -539,8 +520,7 @@ function pfUI.api.CreateScrollChild(name, parent) local f = CreateFrame("Frame", name, parent) -- dummy values required - f:SetWidth(1) - f:SetHeight(1) + f:SetSize(1, 1) f:SetAllPoints(parent) parent:SetScrollChild(f) @@ -607,8 +587,7 @@ end function pfUI.api.SetHighlight(frame, cr, cg, cb) if not frame then return end if not cr or not cg or not cb then - local _, class = UnitClass("player") - cr, cg, cb = GetClassColor(class) + cr, cg, cb = GetClassColor(UnitClassBase('player')) end frame.cr, frame.cg, frame.cb = cr, cg, cb, ca @@ -653,8 +632,7 @@ function pfUI.api.SkinButton(button, cr, cg, cb, icon, disableHighlight) if not b then b = button end if not b then return end if not cr or not cg or not cb then - local _, class = UnitClass("player") - cr, cg, cb = GetClassColor(class) + cr, cg, cb = GetClassColor(UnitClassBase('player')) end pfUI.api.CreateBackdrop(b, nil, true) b:SetNormalTexture("") @@ -702,8 +680,7 @@ function pfUI.api.SkinCollapseButton(button, all) b.icon = _G[name] or CreateFrame("Button", name, b) if all then size = 14 end - b.icon:SetWidth(size) - b.icon:SetHeight(size) + b.icon:SetSize(size, size) b.icon:SetPoint("LEFT", 2, 2) CreateBackdrop(b.icon) b.icon.text = b.icon:CreateFontString(nil, "OVERLAY") @@ -732,12 +709,10 @@ end function pfUI.api.SkinRotateButton(button) pfUI.api.CreateBackdrop(button) - local _, class = UnitClass("player") - local color = PFUI_CLASS_COLORS[class] - local cr, cg, cb = color.r , color.g, color.b + local cr, cg, cb = GetClassColor(UnitClassBase('player')) - button:SetWidth(button:GetWidth() - 18) - button:SetHeight(button:GetHeight() - 18) + local btnW, btnH = button:GetSize() + button:SetSize(btnW - 18, btnH - 18) button:GetNormalTexture():SetTexCoord(0.3, 0.29, 0.3, 0.65, 0.69, 0.29, 0.69, 0.65) button:GetPushedTexture():SetTexCoord(0.3, 0.29, 0.3, 0.65, 0.69, 0.29, 0.69, 0.65) @@ -759,8 +734,7 @@ function pfUI.api.SkinCloseButton(button, parentFrame, offsetX, offsetY) SkinButton(button, 1, .25, .25) - button:SetWidth(15) - button:SetHeight(15) + button:SetSize(15, 15) if parentFrame then button:ClearAllPoints() @@ -787,8 +761,7 @@ function pfUI.api.SkinArrowButton(button, dir, size) button:SetDisabledTexture(nil) if size then - button:SetWidth(size) - button:SetHeight(size) + button:SetSize(size, size) end if not button.icon then @@ -894,8 +867,7 @@ function pfUI.api.SkinCheckbox(frame, size) frame:SetPushedTexture("") frame:SetHighlightTexture("") if size then - frame:SetWidth(size) - frame:SetHeight(size) + frame:SetSize(size, size) end CreateBackdrop(frame) SetAllPointsOffset(frame.backdrop, frame, 4) @@ -936,9 +908,7 @@ function pfUI.api.SkinDropDown(frame, cr, cg, cb, useSmall) end if not cr or not cg or not cb then - local _, class = UnitClass("player") - local color = PFUI_CLASS_COLORS[class] - cr, cg, cb = color.r , color.g, color.b + cr, cg, cb = GetClassColor(UnitClassBase('player')) end SetHighlight(button, cr, cg, cb) @@ -1108,8 +1078,7 @@ function pfUI.api.CreateQuestionDialog(text, yes, no, editbox, onclose) -- buttons question.yes = CreateFrame("Button", "pfQuestionDialogYes", question, "UIPanelButtonTemplate") pfUI.api.SkinButton(question.yes) - question.yes:SetWidth(100) - question.yes:SetHeight(22) + question.yes:SetSize(100, 22) question.yes:SetText(yescap) question.yes:SetScript("OnClick", function() if yes then yes() end @@ -1124,8 +1093,7 @@ function pfUI.api.CreateQuestionDialog(text, yes, no, editbox, onclose) question.no = CreateFrame("Button", "pfQuestionDialogNo", question, "UIPanelButtonTemplate") pfUI.api.SkinButton(question.no) - question.no:SetWidth(100) - question.no:SetHeight(22) + question.no:SetSize(100, 22) question.no:SetText(nocap) question.no:SetScript("OnClick", function() if no then no() end @@ -1141,8 +1109,7 @@ function pfUI.api.CreateQuestionDialog(text, yes, no, editbox, onclose) question.close = CreateFrame("Button", "pfQuestionDialogClose", question) question.close:SetPoint("TOPRIGHT", -border, -border) pfUI.api.CreateBackdrop(question.close) - question.close:SetHeight(10) - question.close:SetWidth(10) + question.close:SetSize(10, 10) question.close.texture = question.close:CreateTexture("pfQuestionDialogCloseTex") question.close.texture:SetTexture(pfUI.media["img:close"]) question.close.texture:ClearAllPoints() @@ -1244,9 +1211,8 @@ function pfUI.api.CreateInfoBox(text, time, parent, height) infobox.duration = time infobox.lastshow = GetTime() - infobox:SetWidth(infobox.text:GetStringWidth() + 50) + infobox:SetSize(infobox.text:GetStringWidth() + 50, height) infobox:SetParent(parent) - infobox:SetHeight(height) infobox:SetFrameStrata("FULLSCREEN_DIALOG") infobox:Show() diff --git a/api/unitframes.lua b/api/unitframes.lua index 33c922aa..0e588f5a 100644 --- a/api/unitframes.lua +++ b/api/unitframes.lua @@ -21,6 +21,7 @@ end -- slash command to toggle unitframe test mode pfUI.api.RegisterSlashCommand("PFTEST", { "/pftest", "/pfuftest" }, function() pfUI.uf.showall = not pfUI.uf.showall + if pfUI.uf.raid and pfUI.uf.raid.LayoutPets then pfUI.uf.raid:LayoutPets() end end, true) -- HoT buff indicators that need name verification because their icons are @@ -126,75 +127,16 @@ visibilityscan:SetScript("OnUpdate", function() end) -- ============================================================================ --- GetUnitStats - Nampower Integration for Health + Power +-- GetUnitStats - health + power for a unit token. -- Returns: hp, maxHp, power, maxPower, powerType --- IMPORTANT: Uses _G.UnitExists directly to avoid conflicts with Nampower's --- use UnitGUID(unit) for GUID lookup (Nampower 3.0.0+) -- ============================================================================ - --- Cache für Stats-Tracking (nur Änderungen zählen) -pfUI.api.lastUnitStats = pfUI.api.lastUnitStats or {} - -function pfUI.api.GetUnitStats(unitstr, trackStats) - local hp, maxHp, power, maxPower, powerType - local usedNampower = false - - powerType = UnitPowerType(unitstr) or 0 - power = UnitPower(unitstr, powerType) - maxPower = UnitPowerMax(unitstr, powerType) - - -- Try GetUnitField first if available (for all units: players, pets, NPCs) - if GetUnitField then - -- Use the standard check first, then get guid separately - local exists = _G.UnitExists(unitstr) - if exists then - local guid = _G.UnitGUID(unitstr) - hp = GetUnitField(guid, "health") - maxHp = GetUnitField(guid, "maxHealth") - -- Check if Nampower gave valid health data - if hp and hp > 0 and maxHp and maxHp > 0 then - usedNampower = true - -- Track Nampower success - NUR bei echten Änderungen - if trackStats and pfUI.uf and pfUI.uf.stats and pfUI.uf.stats.enabled then - local lastStats = pfUI.api.lastUnitStats[unitstr] - if not lastStats or lastStats.hp ~= hp or lastStats.maxHp ~= maxHp or - lastStats.power ~= power or lastStats.maxPower ~= maxPower then - pfUI.uf.stats.nampowerUsed = (pfUI.uf.stats.nampowerUsed or 0) + 1 - pfUI.api.lastUnitStats[unitstr] = { - hp = hp, - maxHp = maxHp, - power = power, - maxPower = maxPower - } - end - end - return hp, maxHp, power or 0, maxPower or 1, powerType - end - end - end - - -- Fallback to standard API (for players when Nampower fails) - hp = UnitHealth(unitstr) or 0 - maxHp = UnitHealthMax(unitstr) or 1 - - -- Track Fallback usage - NUR bei echten Änderungen - if trackStats and not usedNampower then - if pfUI.uf and pfUI.uf.stats and pfUI.uf.stats.enabled then - local lastStats = pfUI.api.lastUnitStats[unitstr] - if not lastStats or lastStats.hp ~= hp or lastStats.maxHp ~= maxHp or - lastStats.power ~= power or lastStats.maxPower ~= maxPower then - pfUI.uf.stats.fallbackUsed = (pfUI.uf.stats.fallbackUsed or 0) + 1 - pfUI.api.lastUnitStats[unitstr] = { - hp = hp, - maxHp = maxHp, - power = power, - maxPower = maxPower - } - end - end - end - - return hp, maxHp, power, maxPower, powerType +function pfUI.api.GetUnitStats(unitstr) + local powerType = UnitPowerType(unitstr) or 0 + return UnitHealth(unitstr) or 0, + UnitHealthMax(unitstr) or 1, + UnitPower(unitstr, powerType) or 0, + UnitPowerMax(unitstr, powerType) or 1, + powerType end local aggrodata = { } @@ -378,19 +320,16 @@ function pfUI.uf:UpdateFrameSize() if self.config.portrait == "left" or self.config.portrait == "right" then if ptwidth == "-1" and ptheight == "-1" then -- align portrait size to frame - self.portrait:SetWidth(real_height) - self.portrait:SetHeight(real_height) + self.portrait:SetSize(real_height, real_height) portrait = real_height + spacing + 2*default_border else -- use custom portrait size - self.portrait:SetWidth(ptwidth) - self.portrait:SetHeight(ptheight) + self.portrait:SetSize(ptwidth, ptheight) portrait = ptwidth + spacing + 2*default_border end end - self:SetWidth(width + portrait) - self:SetHeight(real_height) + self:SetSize(width + portrait, real_height) end function pfUI.uf:UpdateConfig() @@ -427,8 +366,7 @@ function pfUI.uf:UpdateConfig() f.glow:SetScript("OnUpdate", pfUI.uf.glow.UpdateGlowAnimation) f.glow:Hide() - f.combat:SetWidth(tonumber(f.config.squaresize)) - f.combat:SetHeight(tonumber(f.config.squaresize)) + f.combat:SetSize(tonumber(f.config.squaresize), tonumber(f.config.squaresize)) f.combat:ClearAllPoints() f.combat:SetPoint(f.config.squarepos, 0, 0) f.combat:Hide() @@ -436,8 +374,7 @@ function pfUI.uf:UpdateConfig() f.hp:ClearAllPoints() f.hp:SetPoint("TOP", 0, 0) - f.hp:SetWidth(f.config.width) - f.hp:SetHeight(f.config.height) + f.hp:SetSize(f.config.width, f.config.height) if tonumber(f.config.height) < 0 then f.hp:Hide() end pfUI.api.CreateBackdrop(f.hp, default_border) @@ -589,11 +526,7 @@ function pfUI.uf:UpdateConfig() end if f.group then - if f.config.raidgrouplabel == "1" then - f.group:Show() - else - f.group:Hide() - end + f.group:SetShown(f.config.raidgrouplabel == "1") local xoff = tonumber(f.config.grouplabelxoff) or 0 local yoff = tonumber(f.config.grouplabelyoff) or 8 @@ -662,8 +595,7 @@ function pfUI.uf:UpdateConfig() f.powerCenterText:SetPoint("TOPLEFT",f.power.bar, "TOPLEFT", f.config.txtpowercenteroffx, 1 + tonumber(f.config.txtpowercenteroffy)) f.powerCenterText:SetPoint("BOTTOMRIGHT",f.power.bar, "BOTTOMRIGHT", f.config.txtpowercenteroffx, f.config.txtpowercenteroffy) - f.incHeal:SetHeight(f.config.height) - f.incHeal:SetWidth(f.config.width) + f.incHeal:SetSize(f.config.width, f.config.height) f.incHeal.texture:SetTexture(pfUI.media["img:bar"]) local cr, cg, cb, ca = GetStringColor(f.config.healcolor) cr, cg, cb, ca = tonumber(cr), tonumber(cg), tonumber(cb), tonumber(ca) @@ -679,53 +611,46 @@ function pfUI.uf:UpdateConfig() end f.ressIcon:SetFrameLevel(16) - f.ressIcon:SetWidth(32) - f.ressIcon:SetHeight(32) + f.ressIcon:SetSize(32, 32) f.ressIcon:SetPoint("CENTER", f, "CENTER", 0, 4) f.ressIcon.texture:SetTexture(pfUI.media["img:ress"]) f.ressIcon.texture:SetAllPoints(f.ressIcon) f.ressIcon:Hide() - f.leaderIcon:SetWidth(10) - f.leaderIcon:SetHeight(10) + f.leaderIcon:SetSize(10, 10) f.leaderIcon:SetPoint("CENTER", f, "TOPLEFT", 0, 0) f.leaderIcon.texture:SetTexture("Interface\\GROUPFRAME\\UI-Group-LeaderIcon") f.leaderIcon.texture:SetAllPoints(f.leaderIcon) f.leaderIcon:Hide() - f.lootIcon:SetWidth(10) - f.lootIcon:SetHeight(10) + f.lootIcon:SetSize(10, 10) f.lootIcon:SetPoint("CENTER", f, "LEFT", 0, 0) f.lootIcon.texture:SetTexture("Interface\\GROUPFRAME\\UI-Group-MasterLooter") f.lootIcon.texture:SetAllPoints(f.lootIcon) f.lootIcon:Hide() - f.pvpIcon:SetWidth(f.config.pvpiconsize) - f.pvpIcon:SetHeight(f.config.pvpiconsize) + f.pvpIcon:SetSize(f.config.pvpiconsize, f.config.pvpiconsize) f.pvpIcon:SetPoint(f.config.pvpiconalign, f, f.config.pvpiconalign, f.config.pvpiconoffx, f.config.pvpiconoffy) f.pvpIcon.texture:SetTexture(pfUI.media["img:pvp"]) f.pvpIcon.texture:SetAllPoints(f.pvpIcon) f.pvpIcon.texture:SetVertexColor(1,1,1,.5) f.pvpIcon:Hide() - f.raidIcon:SetWidth(f.config.raidiconsize) - f.raidIcon:SetHeight(f.config.raidiconsize) + f.raidIcon:SetSize(f.config.raidiconsize, f.config.raidiconsize) f.raidIcon:SetPoint("CENTER", f, f.config.raidiconalign, f.config.raidiconoffx, f.config.raidiconoffy) local raidIconTex = C.unitframes.blizzard_raidicons == "1" and "Interface\\TargetingFrame\\UI-RaidTargetingIcons" or pfUI.media["img:raidicons"] f.raidIcon.texture:SetTexture(raidIconTex) f.raidIcon.texture:SetAllPoints(f.raidIcon) f.raidIcon:Hide() - f.restIcon:SetWidth(16) - f.restIcon:SetHeight(16) + f.restIcon:SetSize(16, 16) f.restIcon:SetPoint("TOP", f, "TOPLEFT", 0, -1) f.restIcon.texture:SetTexture("Interface\\CharacterFrame\\UI-StateIcon", true) f.restIcon.texture:SetTexCoord(0, .5, 0, .421875) f.restIcon.texture:SetAllPoints(f.restIcon) f.restIcon:Hide() - f.happinessIcon:SetWidth(tonumber(C.unitframes.pet.happinesssize)) - f.happinessIcon:SetHeight(tonumber(C.unitframes.pet.happinesssize)) + f.happinessIcon:SetSize(tonumber(C.unitframes.pet.happinesssize), tonumber(C.unitframes.pet.happinesssize)) f.happinessIcon:SetPoint("CENTER", f, "TOPLEFT", default_border, -default_border) f.happinessIcon.texture:SetTexture(pfUI.media["img:neutral"]) f.happinessIcon.texture:SetAllPoints(f.happinessIcon) @@ -896,11 +821,7 @@ function pfUI.uf:UpdateConfig() -- immediately show/hide existing cooldown text if f.debuffs[i].cd.pfCooldownText then - if cooldown_text == 1 then - f.debuffs[i].cd.pfCooldownText:Show() - else - f.debuffs[i].cd.pfCooldownText:Hide() - end + f.debuffs[i].cd.pfCooldownText:SetShown(cooldown_text == 1) end f.debuffs[i].id = i @@ -1030,8 +951,6 @@ function pfUI.uf.OnEvent() this.update_full = true -- UNIT_XXX Events elseif arg1 and (arg1 == this.label .. this.id or (UnitGUID and arg1 == UnitGUID(this.label .. this.id))) then - this.lastEventUpdate = GetTime() - if event == "UNIT_PORTRAIT_UPDATE" or event == "UNIT_MODEL_CHANGED" then this.update_portrait = true elseif event == "UNIT_AURA" then @@ -1053,154 +972,19 @@ local _GetTime = GetTime pfUI.uf.now = 0 -- ============================================================================ --- GLOBAL FALLBACK THROTTLE - Limits total fallback updates across ALL frames --- ============================================================================ -pfUI.uf.fallbackThrottle = { - lastUpdate = 0, - interval = 0.1, -- 10 updates per second total (not per frame!) - updatesThisInterval = 0, - maxUpdatesPerInterval = 5 -- Max 5 frames can update per interval -} - --- ============================================================================ --- STATS SYSTEM - Performance tracking for Nampower vs Fallback --- ============================================================================ -pfUI.uf.stats = { - eventUpdates = 0, - heartbeatUpdates = 0, - earlyReturns = 0, - nampowerUsed = 0, - fallbackUsed = 0, - throttledSkips = 0, - startTime = 0, - enabled = true -} - --- Stats Frame (Live Display) -pfUI.uf.statsFrame = CreateFrame("Frame", "pfUIStatsFrame", UIParent) -pfUI.uf.statsFrame:SetWidth(200) -pfUI.uf.statsFrame:SetHeight(220) -pfUI.uf.statsFrame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -10, -200) -pfUI.uf.statsFrame:SetBackdrop({ - bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", - edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", - tile = true, tileSize = 16, edgeSize = 8, - insets = { left = 3, right = 3, top = 3, bottom = 3 } -}) -pfUI.uf.statsFrame:SetBackdropColor(0, 0, 0, 0.8) -pfUI.uf.statsFrame:EnableMouse(true) -pfUI.uf.statsFrame:SetMovable(true) -pfUI.uf.statsFrame:SetClampedToScreen(true) -pfUI.uf.statsFrame:RegisterForDrag("LeftButton") -pfUI.uf.statsFrame:SetScript("OnDragStart", function() this:StartMoving() end) -pfUI.uf.statsFrame:SetScript("OnDragStop", function() this:StopMovingOrSizing() end) -pfUI.uf.statsFrame:Hide() - --- Stats Title -pfUI.uf.statsFrame.title = pfUI.uf.statsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge") -pfUI.uf.statsFrame.title:SetPoint("TOP", pfUI.uf.statsFrame, "TOP", 0, -8) -pfUI.uf.statsFrame.title:SetText("Performance") - --- Stats Text (multi-line) -pfUI.uf.statsFrame.text = pfUI.uf.statsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") -pfUI.uf.statsFrame.text:SetPoint("TOPLEFT", pfUI.uf.statsFrame, "TOPLEFT", 10, -30) -pfUI.uf.statsFrame.text:SetWidth(180) -pfUI.uf.statsFrame.text:SetHeight(180) -pfUI.uf.statsFrame.text:SetJustifyH("LEFT") -pfUI.uf.statsFrame.text:SetJustifyV("TOP") -pfUI.uf.statsFrame.text:SetText("Initializing...") - --- Update function for stats display -pfUI.uf.UpdateStatsDisplay = function() - local elapsed = GetTime() - pfUI.uf.stats.startTime - if elapsed < 0.1 then return end - - local eventRate = pfUI.uf.stats.eventUpdates / elapsed - local heartbeatRate = pfUI.uf.stats.heartbeatUpdates / elapsed - local totalFrameUpdates = eventRate + heartbeatRate - - -- Calculate Nampower vs Fallback percentages (ONLY counts actual data changes!) - local totalDataChanges = pfUI.uf.stats.nampowerUsed + pfUI.uf.stats.fallbackUsed - local nampowerPct = totalDataChanges > 0 and math.floor((pfUI.uf.stats.nampowerUsed / totalDataChanges) * 100) or 0 - local fallbackPct = totalDataChanges > 0 and math.floor((pfUI.uf.stats.fallbackUsed / totalDataChanges) * 100) or 0 - - -- Calculate data change rate (how often HP/Mana actually changes) - local dataChangeRate = totalDataChanges / elapsed - - local statsText = string.format( - "Time: %.1fs\n" .. - "|cffaaaaaa--- Frame Updates ---|r\n" .. - "Event: %.1f/s (%d)\n" .. - "Heartbeat: %.1f/s (%d)\n" .. - "Total: %.1f/s\n" .. - "\n" .. - "|cffaaaaaa--- Data Changes ---|r\n" .. - "Rate: %.1f/s (%d)\n" .. - "|cff00ff00NP: %d%% (%d)|r\n" .. - "|cffff8800FB: %d%% (%d)|r", - elapsed, - eventRate, - pfUI.uf.stats.eventUpdates, - heartbeatRate, - pfUI.uf.stats.heartbeatUpdates, - totalFrameUpdates, - dataChangeRate, - totalDataChanges, - nampowerPct, - pfUI.uf.stats.nampowerUsed, - fallbackPct, - pfUI.uf.stats.fallbackUsed - ) - - pfUI.uf.statsFrame.text:SetText(statsText) -end - --- Stats update timer -pfUI.uf.statsUpdateTimer = 0 - --- Cache cleanup timer (clean lastUnitStats every 30s to prevent memory leak) -pfUI.uf.cacheCleanupTimer = 0 - --- ============================================================================ --- OnUpdate with Heartbeat Polling and Fallback +-- OnUpdate - eventless per-frame work (range check, aggro glow) and draining +-- the event-set update flags. Frames refresh on events only; no polling. -- ============================================================================ function pfUI.uf.OnUpdate() local now = _GetTime() pfUI.uf.now = now - - -- Update stats display (throttled to 0.2s) - if pfUI.uf.statsFrame and pfUI.uf.statsFrame:IsShown() then - if (pfUI.uf.statsUpdateTimer or 0) <= now then - pfUI.uf.statsUpdateTimer = now + 0.2 - if pfUI.uf.stats.startTime > 0 then - pfUI.uf.UpdateStatsDisplay() - end - end - end - - -- Cleanup lastUnitStats cache every 30 seconds to prevent memory leak - if (pfUI.uf.cacheCleanupTimer or 0) <= now then - pfUI.uf.cacheCleanupTimer = now + 30 - - -- Only keep cache for units that currently exist - if pfUI.api.lastUnitStats then - for unitstr in pairs(pfUI.api.lastUnitStats) do - if not _G.UnitExists(unitstr) then - pfUI.api.lastUnitStats[unitstr] = nil - end - end - end - end - + -- update combat feedback (no throttle - needs immediate feedback) if this.feedbackText then CombatFeedback_OnUpdate(arg1) end -- Throttle raid/party frames for performance if this.label == "raid" or this.label == "party" then if (this.throttleTick or 0) > now then - if pfUI.uf.stats and pfUI.uf.stats.enabled then - pfUI.uf.stats.throttledSkips = pfUI.uf.stats.throttledSkips + 1 - end return end this.throttleTick = now + 0.1 -- Default: 10 FPS @@ -1284,19 +1068,7 @@ function pfUI.uf.OnUpdate() local unit = this.label .. this.id local heal = libpredict:UnitGetIncomingHeals(unit) - -- O(1) Nampower lookup via GUID (same pattern as nameplates.lua) - local health, maxHealth - if GetUnitField then - local guid = UnitGUID(unit) - if guid then - health = GetUnitField(guid, "health") - maxHealth = GetUnitField(guid, "maxHealth") - end - end - -- Fallback to standard API - if not health or not maxHealth or maxHealth == 0 then - health, maxHealth = UnitHealth(unit), UnitHealthMax(unit) - end + local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit) if heal - health - maxHealth ~= this.predictstate then local overhealperc = tonumber(this.config.overhealperc) @@ -1353,86 +1125,6 @@ function pfUI.uf.OnUpdate() -- EVENT-BASED UPDATES (Health, Mana, Auras, etc.) -- ============================================================================ - -- Check if we have pending updates from events - local hasUpdates = this.update_full or this.update_base or - this.update_aura or this.update_portrait or - this.update_pvp or this.update_indicators - - -- Track event-triggered updates (not API calls, just frame updates) - if hasUpdates and pfUI.uf.stats and pfUI.uf.stats.enabled then - pfUI.uf.stats.eventUpdates = pfUI.uf.stats.eventUpdates + 1 - end - - -- Heartbeat Polling: If no events pending, check if we need fallback - if not hasUpdates then - local timeSinceEvent = this.lastEventUpdate and (now - this.lastEventUpdate) or 999 - - -- If >0.5s since last event and unit exists, try heartbeat - if timeSinceEvent > 0.5 and this.label and _G.UnitExists(this.label .. this.id) then - local needsFallback = false - - -- Check if Nampower can provide data - if GetUnitField then - -- Use _G.UnitExists to avoid conflicts with range checking - local unitstr = this.label .. this.id - local exists = _G.UnitExists(unitstr) - if exists then - local _, guid = _G.UnitExists(unitstr) - if guid then - local hp = GetUnitField(guid, "health") - if not hp or hp == 0 then - needsFallback = true - end - else - needsFallback = true - end - else - needsFallback = true - end - else - needsFallback = true - end - - if needsFallback then - -- GLOBAL Throttle: Limit fallback updates across ALL frames - local throttle = pfUI.uf.fallbackThrottle - - -- Reset counter each interval - if now - throttle.lastUpdate > throttle.interval then - throttle.lastUpdate = now - throttle.updatesThisInterval = 0 - end - - -- Check if we've exceeded max updates this interval - if throttle.updatesThisInterval >= throttle.maxUpdatesPerInterval then - if pfUI.uf.stats and pfUI.uf.stats.enabled then - pfUI.uf.stats.earlyReturns = pfUI.uf.stats.earlyReturns + 1 - end - return - end - - throttle.updatesThisInterval = throttle.updatesThisInterval + 1 - - -- Nampower not available or no data - trigger fallback update - this.update_base = true - if pfUI.uf.stats and pfUI.uf.stats.enabled then - pfUI.uf.stats.heartbeatUpdates = pfUI.uf.stats.heartbeatUpdates + 1 - end - else - -- Nampower working fine, no update needed - if pfUI.uf.stats and pfUI.uf.stats.enabled then - pfUI.uf.stats.earlyReturns = pfUI.uf.stats.earlyReturns + 1 - end - return - end - else - -- Too soon or unit doesn't exist - if pfUI.uf.stats and pfUI.uf.stats.enabled then - pfUI.uf.stats.earlyReturns = pfUI.uf.stats.earlyReturns + 1 - end - return - end - end -- process indicator update events if this.update_indicators then @@ -2316,7 +2008,7 @@ function pfUI.uf:RefreshUnit(unit, component) -- base frame if component == "all" or component == "base" then -- Unit HP/MP with Nampower Integration - local hp, hpmax, power, powermax, powerType = pfUI.api.GetUnitStats(unitstr, true) + local hp, hpmax, power, powermax, powerType = pfUI.api.GetUnitStats(unitstr) -- Store original values for color calculations (before invert_healthbar modifies hp) local hp_orig, hpmax_orig = hp, hpmax @@ -2891,7 +2583,7 @@ function pfUI.uf:GetStatusValue(unit, pos) end -- Get stats with Nampower Integration - local hp, hpmax, mp, mpmax, powerType = pfUI.api.GetUnitStats(unitstr, true) + local hp, hpmax, mp, mpmax, powerType = pfUI.api.GetUnitStats(unitstr) local rhp, rhpmax = hp, hpmax -- Use libhealth for mob health estimation (overrides Nampower/Standard) @@ -3047,19 +2739,7 @@ function pfUI.uf.GetColor(self, preset) r, g, b = color.r, color.g, color.b elseif preset == "health" and config["healthcolor"] == "1" then - -- O(1) Nampower lookup for health gradient color - local hp, hpmax - if GetUnitField then - local guid = UnitGUID(unitstr) - if guid then - hp = GetUnitField(guid, "health") - hpmax = GetUnitField(guid, "maxHealth") - end - end - -- Fallback to standard API - if not hp or not hpmax then - hp, hpmax = UnitHealth(unitstr), UnitHealthMax(unitstr) - end + local hp, hpmax = UnitHealth(unitstr), UnitHealthMax(unitstr) if hpmax and hpmax > 0 then r, g, b = GetColorGradient(hp / hpmax) else @@ -3081,59 +2761,3 @@ function pfUI.uf.GetColor(self, preset) return rgbhex(r,g,b) end --- ============================================================================ --- Slash Commands for Stats Frame --- ============================================================================ -pfUI.api.RegisterSlashCommand("PFUISTATS", { "/pfuistats", "/ufstats" }, function(msg) - msg = string.lower(msg or "") - - if not pfUI.uf.stats then - DEFAULT_CHAT_FRAME:AddMessage("|cffff0000ERROR:|r Stats not initialized!") - return - end - - -- Initialize startTime on first use - if pfUI.uf.stats.startTime == 0 then - pfUI.uf.stats.startTime = GetTime() - end - - if msg == "reset" then - pfUI.uf.stats.eventUpdates = 0 - pfUI.uf.stats.heartbeatUpdates = 0 - pfUI.uf.stats.earlyReturns = 0 - pfUI.uf.stats.nampowerUsed = 0 - pfUI.uf.stats.fallbackUsed = 0 - pfUI.uf.stats.throttledSkips = 0 - pfUI.uf.stats.startTime = GetTime() - DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00pfUI Stats:|r Reset!") - - elseif msg == "toggle" then - pfUI.uf.stats.enabled = not pfUI.uf.stats.enabled - local status = pfUI.uf.stats.enabled and "|cff00ff00ON|r" or "|cffff0000OFF|r" - DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00pfUI Stats:|r Tracking: " .. status) - - elseif msg == "show" then - if pfUI.uf.statsFrame then - pfUI.uf.statsFrame:Show() - DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00pfUI Stats:|r Frame shown") - end - - elseif msg == "hide" then - if pfUI.uf.statsFrame then - pfUI.uf.statsFrame:Hide() - DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00pfUI Stats:|r Frame hidden") - end - - else - -- Toggle frame (default action) - if pfUI.uf.statsFrame then - if pfUI.uf.statsFrame:IsShown() then - pfUI.uf.statsFrame:Hide() - DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00pfUI Stats:|r Frame hidden") - else - pfUI.uf.statsFrame:Show() - DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00pfUI Stats:|r Frame shown") - end - end - end -end, true) \ No newline at end of file diff --git a/compat/vanilla.lua b/compat/vanilla.lua index 0e2dc39f..26e698a0 100644 --- a/compat/vanilla.lua +++ b/compat/vanilla.lua @@ -29,15 +29,6 @@ UNITFRAME_SECURE_TEMPLATE = nil --[[ Vanilla API Extensions ]]-- -do -- GetItemInfo - local name, link, rarity, minlevel, itype, isubtype, stack - function GetItemInfo(item) - if not item then return end - name, link, rarity, minlevel, itype, isubtype, stack = _G.GetItemInfo(item) - return name, link, rarity, nil, minlevel, itype, isubtype, stack - end -end - do -- RunMacroText local obj = { ["GetText"] = function(self) return self.text end } obj = setmetatable(obj, {__index = function(tab,key) diff --git a/libs/libdebuff.lua b/libs/libdebuff.lua index cd0da210..2fb3e79f 100644 --- a/libs/libdebuff.lua +++ b/libs/libdebuff.lua @@ -1125,7 +1125,7 @@ if hasNampower then -- Rank aus spellId ermitteln local rankNum = 0 - local rankString = GetSpellRecField(spellId, "rank") + local rankString = C_Spell.GetSpellSubtext(spellId) if rankString and rankString ~= "" then rankNum = tonumber((string.gsub(rankString, "Rank ", ""))) or 0 end diff --git a/libs/libpredict.lua b/libs/libpredict.lua index 7f42c96f..84b65b7f 100644 --- a/libs/libpredict.lua +++ b/libs/libpredict.lua @@ -291,7 +291,7 @@ pfUI.libdebuff_spell_start_other_hooks["libpredict"] = function(spellId, casterG local targetName = resolveNameFromGuid(targetGuid) if not targetName then return end - local rankStr = GetSpellRecField and GetSpellRecField(spellId, "rank") or "" + local rankStr = C_Spell.GetSpellSubtext(spellId) or "" local spellKey = spellName .. (rankStr or "") local amount = foreignCache[casterName] and foreignCache[casterName][spellKey] @@ -355,11 +355,9 @@ pfUI.libdebuff_spell_go_hooks["libpredict"] = function(spellId, a1, a2, a3, a4, elseif hotType == "Renew" then duration = renewDuration or 15 end local rank = 0 - if GetSpellRecField then - local rankStr = GetSpellRecField(spellId, "rank") - if rankStr and rankStr ~= "" then - rank = tonumber((string.gsub(rankStr, "Rank ", ""))) or 0 - end + local rankSub = C_Spell.GetSpellSubtext(spellId) + if rankSub and rankSub ~= "" then + rank = tonumber((string.gsub(rankSub, "Rank ", ""))) or 0 end local playerName = UnitName("player") libpredict:Hot(playerName, targetName, hotType, duration, nil, "SPELL_GO_SELF", rank) diff --git a/modules/bags.lua b/modules/bags.lua index d8b1198b..99116b88 100644 --- a/modules/bags.lua +++ b/modules/bags.lua @@ -448,7 +448,7 @@ pfUI:RegisterModule("bags", function () end end - local _, _, q, _, _, _, itype = GetItemInfo(itemID) + local _, _, q, _, _, _, itype = C_Item.GetItemInfo(itemID) -- running advanced item color scan if C.appearance.bags.borderonlygear == "0" and texture and quality and quality < 1 then diff --git a/modules/castbar.lua b/modules/castbar.lua index ffbcaaf9..1c6acfc9 100644 --- a/modules/castbar.lua +++ b/modules/castbar.lua @@ -93,8 +93,8 @@ pfUI:RegisterModule("castbar", function () cb.bar:SetStatusBarColor(strsplit(",", C.appearance.castbar[isChannel and "channelcolor" or "castbarcolor"])) local rank = "" - if spellID and GetSpellRecField then - rank = GetSpellRecField(spellID, "rank") or "" + if spellID then + rank = C_Spell.GetSpellSubtext(spellID) or "" end local spellname = (cb.showname and name) and (name .. " ") or "" local rankstr = (cb.showrank and rank ~= "") and string.format("|cffaaffcc[%s]|r", rank) or "" diff --git a/modules/feigndeath.lua b/modules/feigndeath.lua index 221ca609..053680f3 100644 --- a/modules/feigndeath.lua +++ b/modules/feigndeath.lua @@ -1,6 +1,6 @@ pfUI:RegisterModule("feigndeath", function () - local oldUnitHealth = UnitHealth - function UnitHealth(unit) + local oldUnitHealth = _G.UnitHealth + _G.UnitHealth = function(unit) if UnitIsFeignDeath(unit) then local hp = GetUnitField(unit, "health") if hp and hp > 0 then return hp end diff --git a/modules/focus.lua b/modules/focus.lua index ee6e395a..207e7f8b 100644 --- a/modules/focus.lua +++ b/modules/focus.lua @@ -2,20 +2,22 @@ pfUI:RegisterModule("focus", function () -- do not go further on disabled UFs if C.unitframes.disable == "1" then return end - pfUI.uf.focus = pfUI.uf:CreateUnitFrame("Focus", nil, C.unitframes.focus, .2) + pfUI.uf.focus = pfUI.uf:CreateUnitFrame("Focus", nil, C.unitframes.focus) pfUI.uf.focus:UpdateFrameSize() pfUI.uf.focus:SetPoint("BOTTOMLEFT", UIParent, "BOTTOM", 220, 220) UpdateMovable(pfUI.uf.focus) pfUI.uf.focus:Hide() - pfUI.uf.focustarget = pfUI.uf:CreateUnitFrame("FocusTarget", nil, C.unitframes.focustarget, .2) + pfUI.uf.focustarget = pfUI.uf:CreateUnitFrame("FocusTarget", nil, C.unitframes.focustarget) pfUI.uf.focustarget:UpdateFrameSize() pfUI.uf.focustarget:SetPoint("BOTTOMLEFT", pfUI.uf.focus, "TOP", 0, 10) UpdateMovable(pfUI.uf.focustarget) pfUI.uf.focustarget:Hide() -- PLAYER_FOCUS_CHANGED drives immediate refresh on focus assign / clear. - -- The frame's 0.2s tick keeps health/power/aura data fresh between events. + -- Between events, ClassicAPI fires UNIT_* (health/mana/aura/...) with + -- arg1 == "focus" and arg1 == "focustarget", so both frames update + -- event-driven like target and need no polling tick. local refresher = CreateFrame("Frame") refresher:RegisterEvent("PLAYER_FOCUS_CHANGED") refresher:SetScript("OnEvent", function() diff --git a/modules/map.lua b/modules/map.lua index 2c906e7e..f8738b27 100644 --- a/modules/map.lua +++ b/modules/map.lua @@ -25,11 +25,7 @@ pfUI:RegisterModule("map", function () pfUI.map = { UpdateConfig = UpdateTooltipScale } function _G.ToggleWorldMap() - if WorldMapFrame:IsShown() then - WorldMapFrame:Hide() - else - WorldMapFrame:Show() - end + WorldMapFrame:SetShown(not WorldMapFrame:IsShown()) end C.position["WorldMapFrame"] = C.position["WorldMapFrame"] or { alpha = 1.0, scale = 0.7 } diff --git a/modules/minimap.lua b/modules/minimap.lua index ead0c510..29748fd9 100644 --- a/modules/minimap.lua +++ b/modules/minimap.lua @@ -33,11 +33,9 @@ pfUI:RegisterModule("minimap", function () pfUI.minimap.UpdateConfig = function(self) size = tonumber(C.appearance.minimap.size) or 140 - pfUI.minimap:SetWidth(size) - pfUI.minimap:SetHeight(size) + pfUI.minimap:SetSize(size, size) - Minimap:SetWidth(size) - Minimap:SetHeight(size) + Minimap:SetSize(size, size) -- vanilla+tbc: do the best to detect the minimap arrow local arrowscale = tonumber(C.appearance.minimap.arrowscale) @@ -158,8 +156,7 @@ pfUI:RegisterModule("minimap", function () pfUI.minimapCoordinates:SetPoint("BOTTOMLEFT", 3, 3) end - pfUI.minimapCoordinates:SetHeight(C.global.font_size) - pfUI.minimapCoordinates:SetWidth(Minimap:GetWidth()) + pfUI.minimapCoordinates:SetSize(Minimap:GetWidth(), C.global.font_size) pfUI.minimapCoordinates.text = pfUI.minimapCoordinates:CreateFontString("MinimapCoordinatesText", "LOW", "GameFontNormal") pfUI.minimapCoordinates.text:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE") pfUI.minimapCoordinates.text:SetTextColor(1,1,1,1) @@ -171,19 +168,14 @@ pfUI:RegisterModule("minimap", function () pfUI.minimapCoordinates.text:SetJustifyH("LEFT") end - if C.appearance.minimap.coordstext ~= "on" then - pfUI.minimapCoordinates:Hide() - else - pfUI.minimapCoordinates:Show() - end + pfUI.minimapCoordinates:SetShown(C.appearance.minimap.coordstext == "on") -- Create zone text frame in top center of minimap pfUI.minimapZone = CreateFrame("Frame", "pfMinimapZone", pfUI.minimap) pfUI.minimapZone:RegisterEvent("MINIMAP_ZONE_CHANGED") pfUI.minimapZone:RegisterEvent("PLAYER_ENTERING_WORLD") pfUI.minimapZone:SetPoint("TOP", 0, -3) - pfUI.minimapZone:SetHeight(C.global.font_size + 2) - pfUI.minimapZone:SetWidth(Minimap:GetWidth()) + pfUI.minimapZone:SetSize(Minimap:GetWidth(), C.global.font_size + 2) pfUI.minimapZone.text = pfUI.minimapZone:CreateFontString("minimapZoneText", "LOW", "GameFontNormal") pfUI.minimapZone.text:SetFont(pfUI.font_default, C.global.font_size + 2, "OUTLINE") pfUI.minimapZone.text:SetAllPoints(pfUI.minimapZone) @@ -205,17 +197,13 @@ pfUI:RegisterModule("minimap", function () elseif pvp == "contested" then pfUI.minimapZone.text:SetTextColor(1.0, 0.7, 0) else - pfUI.minimapZone.text:SetTextColor(1, 1, 1, 1) + pfUI.minimapZone.text:SetTextColor(WHITE_FONT_COLOR:GetRGBA()) end pfUI.minimapZone.text:SetText(GetMinimapZoneText()) end end) - if C.appearance.minimap.zonetext ~= "on" then - pfUI.minimapZone:Hide() - else - pfUI.minimapZone:Show() - end + pfUI.minimapZone:SetShown(C.appearance.minimap.zonetext == "on") -- Minimap hover event -- Update and toggle showing of coordinates and zone text on mouse enter/leave @@ -241,8 +229,7 @@ pfUI:RegisterModule("minimap", function () pfUI.minimap.pvpicon:RegisterEvent("UPDATE_FACTION") pfUI.minimap.pvpicon:RegisterEvent("UNIT_FACTION") pfUI.minimap.pvpicon:SetFrameStrata("HIGH") - pfUI.minimap.pvpicon:SetWidth(16) - pfUI.minimap.pvpicon:SetHeight(16) + pfUI.minimap.pvpicon:SetSize(16, 16) pfUI.minimap.pvpicon:SetAlpha(.5) pfUI.minimap.pvpicon:SetParent(pfUI.minimap) pfUI.minimap.pvpicon:SetPoint("BOTTOMRIGHT", pfUI.minimap, "BOTTOMRIGHT", -5, 5) @@ -251,11 +238,7 @@ pfUI:RegisterModule("minimap", function () pfUI.minimap.pvpicon.texture:SetAllPoints(pfUI.minimap.pvpicon) pfUI.minimap.pvpicon:SetScript("OnEvent", function() - if C.unitframes.player.showPVPMinimap == "1" and UnitIsPVP("player") then - pfUI.minimap.pvpicon:Show() - else - pfUI.minimap.pvpicon:Hide() - end + pfUI.minimap.pvpicon:SetShown(C.unitframes.player.showPVPMinimap == "1" and UnitIsPVP("player")) end) end) diff --git a/modules/nameplates.lua b/modules/nameplates.lua index 6e158ea6..d1baf17d 100644 --- a/modules/nameplates.lua +++ b/modules/nameplates.lua @@ -61,13 +61,11 @@ pfUI:RegisterModule("nameplates", function () local raidGuidCache = {} -- guid -> name (rebuilt on RAID_ROSTER_UPDATE/PARTY_MEMBERS_CHANGED) - -- Resolve a plate GUID to its cast/channel info via C_Spell. Returns a + -- Resolve a unit token to its cast/channel info via C_Spell. Returns a -- compact struct (spellName / icon / startTime / endTime / duration / - -- isChannel) or nil when the unit isn't casting / the GUID can't map to a - -- live token. - local function GetCastInfo(guid) - if not guid then return nil end - local unit = UnitTokenFromGUID(guid) + -- isChannel) or nil when the unit isn't casting. Callers already hold the + -- nameplate token, so there's no GUID->token round-trip. + local function GetCastInfo(unit) if not unit then return nil end local name, _, texture, startMs, endMs, _, _, _, spellID = C_Spell.UnitCastingInfo(unit) local isChannel @@ -87,7 +85,6 @@ pfUI:RegisterModule("nameplates", function () } end - local guidTargetTokenCache = {} -- guid -> "target" interned string local debuffCache = {} -- guid -> { [spellID] = { start, duration } } -- Reusable per-plate debuff display buffer (avoid GC churn from per-call table creation) local debuffDisplayBuf = {} -- [i] = { effect, texture, stacks, dtype, duration, timeleft } @@ -165,12 +162,6 @@ pfUI:RegisterModule("nameplates", function () -- cache default border color local er, eg, eb, ea = GetStringColor(pfUI_config.appearance.border.color) - -- Vanilla Lua 5.0 bitwise check: math.mod(math.floor(value / flag), 2) ~= 0 - local function HasFlag(flags, flag) - return math.mod(math.floor(flags / flag), 2) ~= 0 - end - - local UNIT_FLAG_IN_COMBAT = 524288 -- 0x00080000 local NULL_GUID = "0x0000000000000000" local function RebuildRaidGuidCache() @@ -189,10 +180,11 @@ pfUI:RegisterModule("nameplates", function () local combatColorCache = {} -- guid -> { color, expires } - local function GetCombatStateColor(guid) + local function GetCombatStateColor(guid, token) -- PERF: Quick exit if player not in combat if not UnitAffectingCombat("player") then return false end - if UnitCanAssist("player", guid) then return false end + if not token then return false end + if UnitCanAssist("player", token) then return false end -- PERF: 0.2s throttle per guid - color changes are not time-critical local now = frameState.now @@ -201,24 +193,17 @@ pfUI:RegisterModule("nameplates", function () return cached.color end - local flags = GetUnitField and GetUnitField(guid, "flags") - if not flags then return false end - if not HasFlag(flags, UNIT_FLAG_IN_COMBAT) then return false end + if not UnitAffectingCombat(token) then return false end - local mobTargetGuid = GetUnitField and GetUnitField(guid, "target") + -- The mob's current target via the nameplate token chain (ClassicAPI): + -- "nameplateNtarget" resolves to whatever this plate's unit is targeting, + -- so no GetUnitField("target") or SuperWoW "target" token needed. + local target = token .. "target" + local mobTargetGuid = UnitGUID(target) local hasTarget = mobTargetGuid and mobTargetGuid ~= NULL_GUID - - -- PERF: cache the SuperWoW-style "target" unit token. The concat - -- intern-hits Lua's string pool every call; caching once per guid - -- saves the hash+lookup. Cleared in NAME_PLATE_UNIT_REMOVED. - local target = guidTargetTokenCache[guid] - if not target then - target = guid .. "target" - guidTargetTokenCache[guid] = target - end local color = false - local castInfo = GetCastInfo(guid) + local castInfo = GetCastInfo(token) local isCasting = castInfo and castInfo.endTime and now < castInfo.endTime local targetingPlayer = hasTarget and UnitIsUnit(target, "player") @@ -466,10 +451,8 @@ nameplates:RegisterEvent("PARTY_MEMBERS_CHANGED") nameplates:RegisterEvent("NAME_PLATE_CREATED") nameplates:RegisterEvent("NAME_PLATE_UNIT_ADDED") nameplates:RegisterEvent("NAME_PLATE_UNIT_REMOVED") -if GetUnitField then - nameplates:RegisterEvent("UNIT_FLAGS_GUID") - nameplates:RegisterEvent("UNIT_AURA_GUID") -end +nameplates:RegisterEvent("UNIT_AURA") +nameplates:RegisterEvent("UNIT_FLAGS") nameplates:SetScript("OnEvent", function() -- Stop event handling during logout to prevent crash 132 @@ -542,10 +525,12 @@ end end elseif event == "NAME_PLATE_UNIT_ADDED" then - -- arg1 = "nameplateN" unit token; resolve to GUID for cache keys + -- arg1 = "nameplateN" unit token. Cache the GUID for cache keys and the + -- token itself for token-based UnitX reads (stable per plate lifetime). local plate = C_NamePlate.GetNamePlateForUnit(arg1) if plate and plate.nameplate then plate.nameplate.cachedGuid = UnitGUID(arg1) + plate.nameplate.unit = arg1 nameplates.OnShow(plate) end visiblePlateCount = visiblePlateCount + 1 @@ -558,53 +543,54 @@ end if guid then if debuffCache[guid] then debuffCache[guid] = nil end if threatMemory[guid] then threatMemory[guid] = nil end - if guidTargetTokenCache[guid] then guidTargetTokenCache[guid] = nil end if combatColorCache[guid] then combatColorCache[guid] = nil end local plate = C_NamePlate.GetNamePlateForUnit(arg1) if plate and plate.nameplate and plate.nameplate.cachedGuid == guid then plate.nameplate.cachedGuid = nil + plate.nameplate.unit = nil end end - elseif event == "UNIT_FLAGS_GUID" then - -- Nampower: fires instantly when any unit's flags change (e.g. stun, combat enter/leave) - -- arg1 = guid — directly flag that nameplate for immediate update, bypassing throttle - local plate = C_NamePlate.GetNamePlateForGUID(arg1) - if plate and plate.nameplate then - plate.nameplate.eventcache = true + elseif event == "UNIT_FLAGS" then + -- ClassicAPI: fires with arg1 == "nameplateN" when a unit's flags change + -- (stun, combat enter/leave). Flag that plate for an immediate update, + -- bypassing the throttle. Guard on the token prefix -- UNIT_FLAGS also + -- fires for target/party/raid, which aren't ours to handle here. + if arg1 and strfind(arg1, "^nameplate") then + local plate = C_NamePlate.GetNamePlateForUnit(arg1) + if plate and plate.nameplate then + plate.nameplate.eventcache = true + end end - elseif event == "UNIT_AURA_GUID" then - -- Nampower: fires when a unit's aura set changes (add/remove/modify). - -- arg1 = guid. Flag the matching plate so OnUpdate triggers a fresh - -- C_UnitAuras read on the next tick instead of waiting on the 0.5s - -- throttle — covers expirations, dispels, refreshes, and stack changes - -- in one event. - local plate = C_NamePlate.GetNamePlateForGUID(arg1) - if plate and plate.nameplate then - plate.nameplate.auraUpdate = true + elseif event == "UNIT_AURA" then + -- ClassicAPI: fires with arg1 == "nameplateN" when a unit's aura set + -- changes (add/remove/modify). Flag the matching plate so OnUpdate does a + -- fresh C_UnitAuras read next tick instead of waiting on the 0.5s + -- throttle -- covers expirations, dispels, refreshes, and stack changes + -- in one event. Guard on the token prefix (UNIT_AURA also fires for + -- target/party/raid). + if arg1 and strfind(arg1, "^nameplate") then + local plate = C_NamePlate.GetNamePlateForUnit(arg1) + if plate and plate.nameplate then + plate.nameplate.auraUpdate = true + end end elseif event == "PLAYER_TARGET_CHANGED" then - -- Flag target plate for update via GUID registry - local targetGuid = UnitGUID("target") - if targetGuid then - local plate = C_NamePlate.GetNamePlateForGUID(targetGuid) - if plate and plate.nameplate then - plate.nameplate.targetUpdate = true - end + -- Flag the target's plate for update + local plate = C_NamePlate.GetNamePlateForUnit("target") + if plate and plate.nameplate then + plate.nameplate.targetUpdate = true end -- Also propagate to all plates for alpha/strata updates this.eventcache = true elseif event == "PLAYER_COMBO_POINTS" or event == "UNIT_COMBO_POINTS" then - -- Only flag the target plate for combo point update - local targetGuid = UnitGUID("target") - if targetGuid then - local plate = C_NamePlate.GetNamePlateForGUID(targetGuid) - if plate and plate.nameplate then - plate.nameplate.comboUpdate = true - end + -- Only flag the target's plate for combo point update + local plate = C_NamePlate.GetNamePlateForUnit("target") + if plate and plate.nameplate then + plate.nameplate.comboUpdate = true end else this.eventcache = true @@ -986,16 +972,14 @@ end -- always make sure to keep plate visible plate:Show() - if target and cfg.targetglow then - plate.glow:Show() else plate.glow:Hide() - end + plate.glow:SetShown(target and cfg.targetglow) -- target indicator if cfg.outcombatstate then local guid = plate.cachedGuid or "" -- determine color based on combat state - local color = GetCombatStateColor(guid) + local color = GetCombatStateColor(guid, plate.unit) if not color then color = combatstate.NONE end -- set border color @@ -1070,7 +1054,7 @@ end if guild and C.nameplates.showguildname == "1" then plate.guild:SetText(guild) - if guild == GetGuildInfo("player") then + if UnitIsInMyGuild(plate.unit) then plate.guild:SetTextColor(0, 0.9, 0, 1) else plate.guild:SetTextColor(0.8, 0.8, 0.8, 1) @@ -1089,15 +1073,15 @@ end if cfg.showhp then local rhp, rhpmax, estimated - local guid = plate.cachedGuid - if guid and GetUnitField then - local npHp = GetUnitField(guid, "health") - local npMaxHp = GetUnitField(guid, "maxHealth") + local unit = plate.unit + if unit then + local npHp = UnitHealth(unit) + local npMaxHp = UnitHealthMax(unit) if npHp and npHp > 0 and npMaxHp and npMaxHp > 0 and npMaxHp ~= 100 then rhp, rhpmax = npHp, npMaxHp end end - + -- Fallback to existing methods if not rhp then if hpmax > 100 or (round(hpmax/100*hp) ~= hp) then @@ -1148,7 +1132,7 @@ end if cfg.barcombatstate then local guid = plate.cachedGuid or "" - local color = GetCombatStateColor(guid) + local color = GetCombatStateColor(guid, plate.unit) if color then r, g, b, a = color.r, color.g, color.b, color.a @@ -1268,19 +1252,7 @@ end end nameplates.OnShow = function(frame) - local frame = frame or this - local nameplate = frame.nameplate - - -- cachedGuid is set by NAME_PLATE_UNIT_ADDED before this fires - local guid = nameplate.cachedGuid - if guid and pfUI.api.libunitscan and pfUI.api.libunitscan.ScanGuid then - -- notify libunitscan so it can cache unit data without mouseover - local name = nameplate.original.name:GetText() - local npcFlags = GetUnitField(guid, "npcFlags") or 0 - pfUI.api.libunitscan.ScanGuid(guid, name, npcFlags == 0) - end - - nameplates:OnDataChanged(nameplate) + nameplates:OnDataChanged((frame or this).nameplate) end nameplates.OnUpdate = function(frame, state) @@ -1300,7 +1272,7 @@ end -- smooth animation without overloading the central loop. local isCastingNonTarget = not target and nameplate.castbar and nameplate.castbar:IsShown() if not isCastingNonTarget and not target and cfg.showcastbar and nameplate.cachedGuid then - local castInfo = GetCastInfo(nameplate.cachedGuid) + local castInfo = GetCastInfo(nameplate.unit) if castInfo and castInfo.endTime > now then isCastingNonTarget = true end @@ -1372,8 +1344,7 @@ end if C.nameplates["overlap"] == "1" then if frame:GetWidth() > 1 then - frame:SetWidth(1) - frame:SetHeight(1) + frame:SetSize(1, 1) end else if not nameplate.dwidth then @@ -1381,8 +1352,9 @@ end end if floor(frame:GetWidth()) ~= nameplate.dwidth then - frame:SetWidth(nameplate:GetWidth() * UIParent:GetScale()) - frame:SetHeight(nameplate:GetHeight() * UIParent:GetScale()) + local nameW, nameH = nameplate:GetSize() + local uiScale = UIParent:GetScale() + frame:SetSize(nameW * uiScale, nameH * uiScale) end end @@ -1439,13 +1411,7 @@ end -- trigger update when name color changed (includes combat state check) local r, g, b = original.name:GetTextColor() - local inCombatWithPlayer = false - if cfg.namefightcolor then - local guid = nameplate.cachedGuid - if guid then - inCombatWithPlayer = UnitAffectingCombat(guid) and UnitAffectingCombat("player") - end - end + local inCombatWithPlayer = cfg.namefightcolor and UnitAffectingCombat(nameplate.unit) and UnitAffectingCombat("player") if r + g + b ~= nameplate.cache.namecolor or (cfg.namefightcolor and nameplate.cache.inCombat ~= inCombatWithPlayer) then nameplate.cache.namecolor = r + g + b @@ -1493,7 +1459,7 @@ end nameplate.health.targetHeight = hc end - local w, h = nameplate.health:GetWidth(), nameplate.health:GetHeight() + local w, h = nameplate.health:GetSize() local wc, hc = nameplate.health.targetWidth, nameplate.health.targetHeight if wc and hc then @@ -1513,7 +1479,7 @@ end end end elseif nameplate.health.zoomed or nameplate.health.zoomTransition then - local w, h = nameplate.health:GetWidth(), nameplate.health:GetHeight() + local w, h = nameplate.health:GetSize() local wc = cfg.width local hc = cfg.heighthealth @@ -1522,8 +1488,7 @@ end elseif h > hc + 0.5 then nameplate.health:SetHeight(h*0.95) else - nameplate.health:SetWidth(wc) - nameplate.health:SetHeight(hc) + nameplate.health:SetSize(wc, hc) nameplate.health.zoomTransition = nil nameplate.health.zoomed = nil nameplate.health.targetWidth = nil @@ -1589,7 +1554,7 @@ end -- Shared castbar update logic (used by both dedicated frame and central loop) nameplates.UpdateCastbar = function(nameplate, now) if not nameplate or not nameplate.castbar then return end - local castInfo = GetCastInfo(nameplate.cachedGuid) + local castInfo = GetCastInfo(nameplate.unit) if not castInfo or castInfo.endTime < now then nameplate.castbar.isShown = nil nameplate.castbar.lastEndTime = nil @@ -1635,10 +1600,7 @@ end if (this.tick or 0) > now then return end this.tick = now + throttle - local targetGuid = UnitExists("target") and UnitGUID("target") - if not targetGuid then return end - - local frame = C_NamePlate.GetNamePlateForGUID(targetGuid) + local frame = C_NamePlate.GetNamePlateForUnit("target") if not frame or not frame.nameplate then return end nameplates.UpdateCastbar(frame.nameplate, now) diff --git a/modules/nampower.lua b/modules/nampower.lua index 66052cc3..87b1bafa 100644 --- a/modules/nampower.lua +++ b/modules/nampower.lua @@ -52,8 +52,7 @@ pfUI:RegisterModule("nampower", function () return end - local eventCode = arg1 - local spellId = arg2 + local eventCode, spellId = arg1, arg2 if eventCode == NORMAL_QUEUED or eventCode == NON_GCD_QUEUED or eventCode == ON_SWING_QUEUED then local texture = C_Spell.GetSpellTexture(spellId) @@ -78,16 +77,16 @@ pfUI:RegisterModule("nampower", function () -- Reactive spells by class local reactiveSpells = { WARRIOR = { - { name = "Overpower", texture = "Interface\\Icons\\Ability_MeleeDamage" }, - { name = "Revenge", texture = "Interface\\Icons\\Ability_Warrior_Revenge" }, - { name = "Execute", texture = "Interface\\Icons\\INV_Sword_48" }, + 7384, -- Overpower + 6572, -- Revenge + 5283, -- Execute }, ROGUE = { - { name = "Riposte", texture = "Interface\\Icons\\Ability_Warrior_Challange" }, + 76, -- Riposte }, HUNTER = { - { name = "Mongoose Bite", texture = "Interface\\Icons\\Ability_Hunter_SwiftStrike" }, - { name = "Counterattack", texture = "Interface\\Icons\\Ability_Warrior_Challange" }, + 1495, -- Mongoose Bite + 19306, -- Counterattack }, } @@ -96,8 +95,7 @@ pfUI:RegisterModule("nampower", function () pfUI.reactive = CreateFrame("Frame", "pfReactiveIndicator", UIParent) pfUI.reactive:SetFrameStrata("HIGH") local spellCount = table.getn(spells) - pfUI.reactive:SetWidth(size * spellCount + 4 * (spellCount - 1)) - pfUI.reactive:SetHeight(size) + pfUI.reactive:SetSize(size * spellCount + 4 * (spellCount - 1), size) pfUI.reactive:SetPoint("CENTER", UIParent, "CENTER", 0, -200) pfUI.reactive:Hide() @@ -109,7 +107,7 @@ pfUI:RegisterModule("nampower", function () icon.texture = icon:CreateTexture(nil, "ARTWORK") icon.texture:SetAllPoints(icon) - icon.texture:SetTexture(spell.texture) + icon.texture:SetTexture(C_Spell.GetSpellTexture(spell)) icon.texture:SetTexCoord(.08, .92, .08, .92) icon.glow = icon:CreateTexture(nil, "OVERLAY") @@ -120,7 +118,7 @@ pfUI:RegisterModule("nampower", function () CreateBackdrop(icon) icon:Hide() - icon.spellName = spell.name + icon.spellName = C_Spell.GetSpellName(spell) pfUI.reactive.icons[i] = icon end @@ -148,7 +146,7 @@ pfUI:RegisterModule("nampower", function () local arg = (msg and msg ~= "") and msg or "greens" local target = tonumber(arg) or arg DisenchantAll(target) - DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: DisenchantAll(" .. tostring(target) .. ")") + print("|cff33ffccpfUI|r: DisenchantAll(" .. tostring(target) .. ")") end, true) end diff --git a/modules/player.lua b/modules/player.lua index d52f5c9c..98db1614 100644 --- a/modules/player.lua +++ b/modules/player.lua @@ -47,7 +47,7 @@ pfUI:RegisterModule("player", function () return string.format("%02X%02X%02X", r * 255, g * 255, b * 255) end - -- SP school colors indexed by GetSpellPower("net") return order + -- SP school colors indexed by GetSpellBonusDamage's 1-based school order -- (1=phys, 2=holy, 3=fire, 4=nature, 5=frost, 6=shadow, 7=arcane) local spColors = { "FFFFFF", "FFFF80", "FF8000", "4DFF4D", "80FFFF", "9482C9", "FFFFFF" } @@ -60,16 +60,14 @@ pfUI:RegisterModule("player", function () -- Compute and cache the haste/SP text; called from OnUpdate, throttled to 0.25s local function UpdateInfoText() - if not GetUnitField then return end -- do nothing for older nampower - local cfg = playerFrame.config if not cfg then return end - -- display_haste: "0"=hidden, "1"=show modCastSpeed (gear haste). Talent- - -- side cast-time reductions show up in the actual cast bar via - -- C_Spell.UnitCastingInfo; double-folding them into this overlay was - -- mixing two different concepts into one number. + -- display_haste: "0"=hidden, "1"=show cast-speed haste (UnitSpellHaste, + -- from UNIT_MOD_CAST_SPEED). Talent/spell-specific cast-time reductions + -- show up in the actual cast bar via C_Spell.UnitCastingInfo; folding them + -- in here too was mixing two different concepts into one number. local showHaste = cfg.display_haste == "1" local showSP = cfg.display_spellpower == "1" @@ -79,21 +77,20 @@ pfUI:RegisterModule("player", function () return end - local haste = GetUnitField("player", "modCastSpeed") + local haste = UnitSpellHaste("player") local text = "" if showHaste and isSpellCaster and haste then local hasteHex = cfgColorToHex(cfg.display_haste_color) or "FFFFFF" - text = string.format("|cff%s%.1f%%|r", hasteHex, (1 / haste - 1) * 100) + text = string.format("|cff%s%.1f%%|r", hasteHex, haste) end if showSP and isSpellCaster then - local schools = { GetSpellPower("net") } local defSchool = spDefaultSchool[myclass] or 2 - local maxSP = schools[defSchool] or 0 + local maxSP = GetSpellBonusDamage(defSchool) or 0 local maxColor = spColors[defSchool] - for i = 2, 7 do -- skip physical (1) - local v = schools[i] or 0 + for i = 2, 7 do -- skip physical (1); default school seeds the tiebreak + local v = GetSpellBonusDamage(i) or 0 if v > maxSP then maxSP = v maxColor = spColors[i] diff --git a/modules/raid.lua b/modules/raid.lua index e71d8cb0..1be1c174 100644 --- a/modules/raid.lua +++ b/modules/raid.lua @@ -131,6 +131,13 @@ pfUI:RegisterModule("raid", function () pet:UpdateVisibility() end + if pfUI.uf.showall then + for id = 1, maxraid do + if self.pets[id] then place(self.pets[id], id, id) end + end + return + end + if C.unitframes.raidpet.collapse == "1" then -- Pack the pets that exist into the leading cells, no gaps. local k = 0 diff --git a/modules/roll.lua b/modules/roll.lua index e0253e08..7cab0d11 100644 --- a/modules/roll.lua +++ b/modules/roll.lua @@ -42,7 +42,7 @@ pfUI:RegisterModule("roll", function () end local _, _, itemLink = string.find(hyperlink, "(item:%d+:%d+:%d+:%d+)") - local itemName = GetItemInfo(itemLink) + local itemName = C_Item.GetItemInfo(itemLink) -- delete obsolete tables if pfUI.roll.cache[itemName] and pfUI.roll.cache[itemName]["TIMESTAMP"] < GetTime() - 60 then diff --git a/modules/unitxp.lua b/modules/unitxp.lua index 33a9ddf6..8f69202d 100644 --- a/modules/unitxp.lua +++ b/modules/unitxp.lua @@ -331,26 +331,6 @@ pfUI:RegisterModule("unitxp", function () return success and found end - pfUI.api.UnitInLineOfSight = function(unit1, unit2) - if not unit2 then - unit2 = unit1 - unit1 = "player" - end - local success, inSight = pcall(UnitXP, "inSight", unit1, unit2) - if success then return inSight end - return nil - end - - pfUI.api.UnitIsBehind = function(unit1, unit2) - if not unit2 then - unit2 = unit1 - unit1 = "player" - end - local success, behind = pcall(UnitXP, "behind", unit1, unit2) - if success then return behind end - return nil - end - -- Debug command to test UnitXP indicators pfUI.api.RegisterSlashCommand("PFUNITXP", { "/pfunitxp" }, function() local chat = DEFAULT_CHAT_FRAME diff --git a/modules/whisperproxy.lua b/modules/whisperproxy.lua index 308d34cc..79fce12f 100644 --- a/modules/whisperproxy.lua +++ b/modules/whisperproxy.lua @@ -3,8 +3,7 @@ pfUI:RegisterModule("whisperproxy", function () local proxy = CreateFrame("Button", "pfWhisperProxy", pfUI.chat.left.panelTop) proxy:SetPoint("TOPRIGHT", pfUI.chat.left, "TOPRIGHT", -22, -5) - proxy:SetWidth(12) - proxy:SetHeight(12) + proxy:SetSize(12, 12) proxy.tex = proxy:CreateTexture(nil, "OVERLAY") proxy.tex:SetAllPoints() proxy.tex:SetTexture(pfUI.media["img:proxy"]) diff --git a/modules/xpbar.lua b/modules/xpbar.lua index bdcbbd3e..ca1cfcf3 100644 --- a/modules/xpbar.lua +++ b/modules/xpbar.lua @@ -183,11 +183,7 @@ end local self = self or this if self.text_mouse == "1" then - if MouseIsOver(self) then - self.bar.text:Show() - else - self.bar.text:Hide() - end + self.bar.text:SetShown(MouseIsOver(self)) end if self.always then return end @@ -352,11 +348,7 @@ end b.bar.text:SetJustifyH("CENTER") b.bar.text:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE") - if b.text == "1" then - b.bar.text:Show() - else - b.bar.text:Hide() - end + b.bar.text:SetShown(b.text == "1") b.restedbar = b.restedbar or CreateFrame("StatusBar", nil, b) b.restedbar:SetStatusBarTexture(pfUI.media[C.panel.xp.texture]) diff --git a/pfUI.lua b/pfUI.lua index 2e3ea610..4e9d9863 100644 --- a/pfUI.lua +++ b/pfUI.lua @@ -23,7 +23,7 @@ do -- ClassicAPI dependency check. -- pfUI relies pervasively on the modern C_* / SuperWoW / nameplate / focus -- API surface that ClassicAPI polyfills, so presence is required. - local PFUI_CLASSIC_API_MIN = 10705 -- (X*10000 + Y*100 + Z) + local PFUI_CLASSIC_API_MIN = 10800 -- (X*10000 + Y*100 + Z) local PFUI_CLASSIC_API_LATEST = PFUI_CLASSIC_API_MIN local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI" local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest" diff --git a/skins/blizzard/auction.lua b/skins/blizzard/auction.lua index d1bb2711..12047cfe 100644 --- a/skins/blizzard/auction.lua +++ b/skins/blizzard/auction.lua @@ -2,15 +2,10 @@ pfUI:RegisterSkin("Auctionhouse", function () local rawborder, border = GetBorderSize() local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel() HookAddonOrVariable("Blizzard_AuctionUI", function() - -- Compatibility - if BrowseResetButton then -- tbc - SkinButton(BrowseResetButton) - else -- vanilla - SkinArrowButton(BidPrevPageButton, "left", 18) - SkinArrowButton(BidNextPageButton, "right", 18) - SkinArrowButton(AuctionsPrevPageButton, "left", 18) - SkinArrowButton(AuctionsNextPageButton, "right", 18) - end + SkinArrowButton(BidPrevPageButton, "left", 18) + SkinArrowButton(BidNextPageButton, "right", 18) + SkinArrowButton(AuctionsPrevPageButton, "left", 18) + SkinArrowButton(AuctionsNextPageButton, "right", 18) hooksecurefunc("AuctionFrame_OnShow", function() AuctionFrame:ClearAllPoints() diff --git a/skins/blizzard/battlefield.lua b/skins/blizzard/battlefield.lua index 6d1d0d0a..3a7818d2 100644 --- a/skins/blizzard/battlefield.lua +++ b/skins/blizzard/battlefield.lua @@ -52,8 +52,7 @@ pfUI:RegisterSkin("Battlefield", function () end) BattlefieldFrame.textbox = CreateFrame("Frame", "BattlefieldFrameTextBox", BattlefieldFrame) - BattlefieldFrame.textbox:SetWidth(320) - BattlefieldFrame.textbox:SetHeight(110) + BattlefieldFrame.textbox:SetSize(320, 110) CreateBackdrop(BattlefieldFrame.textbox) BattlefieldFrame.textbox:SetPoint("BOTTOM", BattlefieldFrame.backdrop, "BOTTOM", 0, 36) BattlefieldFrameZoneDescription:ClearAllPoints() diff --git a/skins/blizzard/battlefield_minimap.lua b/skins/blizzard/battlefield_minimap.lua index 5b541092..e56a30d0 100644 --- a/skins/blizzard/battlefield_minimap.lua +++ b/skins/blizzard/battlefield_minimap.lua @@ -6,8 +6,7 @@ pfUI:RegisterSkin("Battlefield Minimap", function () CreateBackdrop(BattlefieldMinimap, nil, nil, 0) CreateBackdropShadow(BattlefieldMinimap) - BattlefieldMinimap:SetWidth(220) - BattlefieldMinimap:SetHeight(146) + BattlefieldMinimap:SetSize(220, 146) SkinCloseButton(BattlefieldMinimapCloseButton, BattlefieldMinimap, 0, 0) diff --git a/skins/blizzard/character.lua b/skins/blizzard/character.lua index 27f1664d..271e532d 100644 --- a/skins/blizzard/character.lua +++ b/skins/blizzard/character.lua @@ -131,7 +131,7 @@ pfUI:RegisterSkin("Character", function () if ShaguScore and itemID then local itemLevel = C_Item.GetCurrentItemLevel({ equipmentSlotIndex = slotId }) - local _, _, quality, _, _, _, _, _, itemSlot, _ = GetItemInfo(itemID) + local _, _, quality, _, _, _, _, _, itemSlot, _ = C_Item.GetItemInfo(itemID) local score = ShaguScore:Calculate(itemSlot, quality, itemLevel) if score and score > 0 and quality and quality > 0 then local r,g,b = GetItemQualityColor(quality) @@ -177,8 +177,7 @@ pfUI:RegisterSkin("Character", function () for i,c in pairs(magicResTextureCords) do local magicResFrame = _G["MagicResFrame"..i] - magicResFrame:SetWidth(26) - magicResFrame:SetHeight(26) + magicResFrame:SetSize(26, 26) CreateBackdrop(magicResFrame) SetAllPointsOffset(magicResFrame.backdrop, magicResFrame, 2) local icon = GetNoNameObject(magicResFrame, "Texture", "BACKGROUND", "ResistanceIcons") @@ -236,8 +235,7 @@ pfUI:RegisterSkin("Character", function () for i,c in pairs(magicResTextureCords) do local magicResFrame = _G["PetMagicResFrame"..i] - magicResFrame:SetWidth(26) - magicResFrame:SetHeight(26) + magicResFrame:SetSize(26, 26) CreateBackdrop(magicResFrame) SetAllPointsOffset(magicResFrame.backdrop, magicResFrame, 2) local icon = GetNoNameObject(magicResFrame, "Texture", "BACKGROUND", "ResistanceIcons") @@ -257,8 +255,7 @@ pfUI:RegisterSkin("Character", function () local war = _G["ReputationBar"..i.."AtWarCheck"] StripTextures(war) - war:SetWidth(13) - war:SetHeight(13) + war:SetSize(13, 13) war:ClearAllPoints() war:SetPoint("LEFT", bar.backdrop, "RIGHT", 6, 0) war.icon = war:CreateTexture(nil, "OVERLAY") @@ -356,8 +353,7 @@ pfUI:RegisterSkin("Character", function () SkillDetailStatusBar:SetParent(SkillDetailScrollFrame) StripTextures(SkillDetailStatusBarUnlearnButton) - SkillDetailStatusBarUnlearnButton:SetWidth(20) - SkillDetailStatusBarUnlearnButton:SetHeight(20) + SkillDetailStatusBarUnlearnButton:SetSize(20, 20) SkillDetailStatusBarUnlearnButton:SetHitRectInsets(0,0,0,0) SkillDetailStatusBarUnlearnButton:ClearAllPoints() SkillDetailStatusBarUnlearnButton:SetPoint("LEFT", SkillDetailStatusBar, "RIGHT", 6, 0) diff --git a/skins/blizzard/lft.lua b/skins/blizzard/lft.lua index d80c2e17..d87662c0 100644 --- a/skins/blizzard/lft.lua +++ b/skins/blizzard/lft.lua @@ -167,12 +167,10 @@ pfUI:RegisterSkin("Turtle LFT", function () local sep = LFTGroupReadyFrame:CreateTexture(nil, "ARTWORK") sep:SetTexture("Interface\\FrameXML\\LFT\\images\\ui-lfg-separator") sep:SetPoint("TOPLEFT", LFTGroupReadyFrame, "TOPLEFT", 10, -125) - sep:SetWidth(288) - sep:SetHeight(16) + sep:SetSize(288, 16) -- Restore role icon (updated dynamically by LFT_GroupReadyShow) - LFTGroupReadyFrameRoleTexture:SetWidth(56) - LFTGroupReadyFrameRoleTexture:SetHeight(56) + LFTGroupReadyFrameRoleTexture:SetSize(56, 56) LFTGroupReadyFrameRoleTexture:ClearAllPoints() LFTGroupReadyFrameRoleTexture:SetPoint("LEFT", LFTGroupReadyFrame, "LEFT", 20, -20) LFTGroupReadyFrameRoleTexture:Show() diff --git a/skins/blizzard/questlog.lua b/skins/blizzard/questlog.lua index 35152106..adef8344 100644 --- a/skins/blizzard/questlog.lua +++ b/skins/blizzard/questlog.lua @@ -6,31 +6,15 @@ pfUI:RegisterSkin("Quest Log", function () _G.MAX_WATCHABLE_QUESTS = 20 -- TODO do -- quest log frame - -- Compatibility - local QUEST_COUNT - if QuestLogCount then -- tbc - QUEST_COUNT = QuestLogCount - - StripTextures(QUEST_COUNT) - QUEST_COUNT:ClearAllPoints() - hooksecurefunc("QuestLogUpdateQuestCount", function(numQuests) - QUEST_COUNT:ClearAllPoints() - QUEST_COUNT:SetPoint("BOTTOMRIGHT", QuestLogFrame, "TOPRIGHT", 0, -50) - end) - else -- vanilla - QUEST_COUNT = QuestLogQuestCount - - QUEST_COUNT:ClearAllPoints() - QUEST_COUNT:SetPoint("TOPRIGHT", -10, -30) - end + QuestLogQuestCount:ClearAllPoints() + QuestLogQuestCount:SetPoint("TOPRIGHT", -10, -30) hooksecurefunc("QuestLog_OnShow", function() QuestLogFrame:ClearAllPoints() QuestLogFrame:SetPoint("TOPLEFT", 10, -104) end) - QuestLogFrame:SetWidth(676) - QuestLogFrame:SetHeight(440) + QuestLogFrame:SetSize(676, 440) QuestLogFrame:DisableDrawLayer("BACKGROUND") StripTextures(QuestLogFrame, true) @@ -64,10 +48,9 @@ pfUI:RegisterSkin("Quest Log", function () QuestLogFrameLevelsCheckButtonText:SetText(T["Quest Levels"]) CreateBackdrop(QuestLogTrack) - QuestLogTrack:SetHeight(8) - QuestLogTrack:SetWidth(8) + QuestLogTrack:SetSize(8, 8) QuestLogTrack:ClearAllPoints() - QuestLogTrack:SetPoint("RIGHT", QUEST_COUNT, "LEFT", -5, 0) + QuestLogTrack:SetPoint("RIGHT", QuestLogQuestCount, "LEFT", -5, 0) StripTextures(QuestLogTrack) QuestLogTrackTracking:SetTexture(.8,.8,.8,1) @@ -228,8 +211,7 @@ pfUI:RegisterSkin("Quest Log", function () SetAllPointsOffset(item.backdrop, item, 4) SetHighlight(item) - icon:SetWidth(ysize) - icon:SetHeight(ysize) + icon:SetSize(ysize, ysize) icon:ClearAllPoints() icon:SetPoint("LEFT", 6, 0) icon:SetTexCoord(.08, .92, .08, .92) diff --git a/skins/blizzard/readycheck.lua b/skins/blizzard/readycheck.lua index 30212ce3..f7cadb33 100644 --- a/skins/blizzard/readycheck.lua +++ b/skins/blizzard/readycheck.lua @@ -1,13 +1,5 @@ pfUI:RegisterSkin("Readycheck", function () HookAddonOrVariable("Blizzard_RaidUI", function() - -- Compatibility - local update_func - if ReadyCheckFrame_OnUpdate then -- tbc - update_func = "ReadyCheckFrame_OnUpdate" - else -- vanilla - update_func = "ReadyCheck_OnUpdate" - end - StripTextures(ReadyCheckFrame, true) CreateBackdrop(ReadyCheckFrame, nil, nil, .75) CreateBackdropShadow(ReadyCheckFrame) @@ -25,8 +17,7 @@ pfUI:RegisterSkin("Readycheck", function () local frame = CreateFrame("Button", nil, ReadyCheckFrame) frame:SetPoint("TOP", ReadyCheckFrameText, "BOTTOM", 0, -6) - frame:SetWidth(220) - frame:SetHeight(10) + frame:SetSize(220, 10) frame.bar = CreateFrame("StatusBar", "ReadyCheckFrameStatusBar", ReadyCheckFrame) frame.bar:SetStatusBarTexture(pfUI.media["img:bar"]) @@ -35,7 +26,7 @@ pfUI:RegisterSkin("Readycheck", function () frame.bar.text = frame.bar:CreateFontString("Status", "DIALOG", "GameFontNormal") frame.bar.text:SetFontObject(GameFontWhite) frame.bar.text:SetFont(pfUI.font_default, 12, "OUTLINE") - frame.bar.text:SetPoint("CENTER", 0, 0) + frame.bar.text:SetPoint("CENTER") local max hooksecurefunc("ShowReadyCheck", function() @@ -43,7 +34,7 @@ pfUI:RegisterSkin("Readycheck", function () frame.bar:SetMinMaxValues(0, max) end) - hooksecurefunc(update_func, function() + hooksecurefunc("ReadyCheck_OnUpdate", function() if not ReadyCheckFrame.timer then return end local perc = ReadyCheckFrame.timer/max diff --git a/skins/blizzard/talents.lua b/skins/blizzard/talents.lua index 737dff7c..1ba18243 100644 --- a/skins/blizzard/talents.lua +++ b/skins/blizzard/talents.lua @@ -4,14 +4,7 @@ pfUI:RegisterSkin("Talents", function () HookAddonOrVariable("Blizzard_TalentUI", function() -- Compatibility - local TALENT_FRAME, TALENT_FRAME_NAME - if PlayerTalentFrame then -- tbc - TALENT_FRAME = _G.PlayerTalentFrame - else -- vanilla - TALENT_FRAME = _G.TalentFrame - end - TALENT_FRAME_NAME = TALENT_FRAME:GetName() - + local TALENT_FRAME, TALENT_FRAME_NAME = _G.TalentFrame, _G.TalentFrame:GetName() StripTextures(TALENT_FRAME) CreateBackdrop(TALENT_FRAME, nil, nil, .75)