mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 07:36:56 +00:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b945c2c97 | |||
| 452eef3864 | |||
| 6f7a57f530 | |||
| a55460e543 | |||
| 58aaeef5f0 | |||
| 487af0c8f4 | |||
| 00292ca3b4 | |||
| cba3604906 | |||
| a31d10384b | |||
| f06af48bc2 | |||
| d73c4de695 | |||
| dd8c529463 | |||
| 47a7b4c686 | |||
| cf3f1e5440 | |||
| 182127bd67 | |||
| 3d2e6e202b | |||
| 3a062ee2ac | |||
| 5ed1d98ecc | |||
| fa1dc5637e | |||
| 8506f5ffbf | |||
| 9c529512d1 | |||
| 88d0f7bf74 | |||
| a3ff20782d | |||
| 88c2462fbd | |||
| e28a7e5606 | |||
| dfa74c5756 | |||
| 1c0c9dc019 | |||
| 801935130e | |||
| 8cdced5ec0 | |||
| 756e8840af | |||
| b2db091d54 | |||
| 5fae0bd459 | |||
| 3deddf2b08 | |||
| 650bcda001 | |||
| 931fe6c22d | |||
| bd4a40b0f2 | |||
| 31ff2773b3 | |||
| 8176b906df | |||
| 721ecce59d | |||
| 73b409fb88 | |||
| 0665764610 | |||
| 3faf06141f | |||
| 0c06401ec4 | |||
| c68e48111d | |||
| 6936fd894b | |||
| b5277ea457 | |||
| 63f0dcbf7a | |||
| 0344bff471 | |||
| 1510969105 | |||
| 6e7361c543 | |||
| 2e20a03cbd | |||
| 7389c241a4 | |||
| fb5230828c | |||
| 7aee348a70 | |||
| 2a5f480839 | |||
| 23d1ab840c | |||
| 13a08b0ea3 | |||
| a2177fbf49 | |||
| 9cd83e90ad | |||
| 9bcc11e64f | |||
| acab272ec0 | |||
| 61c2f996fa | |||
| 59ce6d9e74 |
+94
-49
@@ -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,14 +92,23 @@ 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.
|
||||
local stringsplit = _G.string.split
|
||||
function pfUI.api.strsplit(delimiter, subject)
|
||||
if not subject then return nil end
|
||||
local delimiter, fields = delimiter or ":", {}
|
||||
delimiter = delimiter or ":"
|
||||
if stringsplit then
|
||||
return stringsplit(delimiter, subject)
|
||||
end
|
||||
local fields = {}
|
||||
local pattern = string.format("([^%s]+)", delimiter)
|
||||
string.gsub(subject, pattern, function(c) fields[table.getn(fields)+1] = c end)
|
||||
return unpack(fields)
|
||||
@@ -102,11 +119,7 @@ end
|
||||
-- 'tbl' [table] the table that shall be checked
|
||||
-- return: [boolean] result of the check.
|
||||
function pfUI.api.isempty(tbl)
|
||||
if not tbl then return true end
|
||||
for k, v in pairs(tbl) do
|
||||
return false
|
||||
end
|
||||
return true
|
||||
return next(tbl or {}) == nil
|
||||
end
|
||||
|
||||
-- [ checkversion ]
|
||||
@@ -135,7 +148,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
|
||||
@@ -143,6 +155,11 @@ function pfUI.api.UnitInRange(unit)
|
||||
return 1
|
||||
end
|
||||
|
||||
-- master switch: with the 40y check off, a visible unit beyond interact
|
||||
-- range counts as in range (nothing fades). Invisible units already
|
||||
-- returned nil above, matching the pre-collapse behavior.
|
||||
if C.unitframes.rangecheck == "0" then return 1 end
|
||||
|
||||
-- UnitXP precise mode: skip librange entirely, use direct distance check
|
||||
if C.unitframes.rangecheck_mode == "unitxp" and _G.UnitXP then
|
||||
local threshold = tonumber(C.unitframes.rangecheck_distance) or 40
|
||||
@@ -266,11 +283,7 @@ end
|
||||
-- 'f' [float] the number to breakdown.
|
||||
-- returns: [int],[float] whole and fractional part.
|
||||
function pfUI.api.modf(f)
|
||||
if modf then return modf(f) end
|
||||
if f > 0 then
|
||||
return math.floor(f), mod(f,1)
|
||||
end
|
||||
return math.ceil(f), mod(f,1)
|
||||
return math.modf(f)
|
||||
end
|
||||
|
||||
-- [ GetServerEpoch ]
|
||||
@@ -389,10 +402,10 @@ end
|
||||
-- returns: [string] entire itemLink for the given item
|
||||
function pfUI.api.GetItemLinkByName(name)
|
||||
for itemID = 1, 25818 do
|
||||
local itemName, hyperLink, itemQuality = GetItemInfo(itemID)
|
||||
if (itemName and itemName == name) then
|
||||
local _, _, _, hex = GetItemQualityColor(tonumber(itemQuality))
|
||||
return hex.. "|H"..hyperLink.."|h["..itemName.."]|h|r"
|
||||
local itemName = C_Item.GetItemNameByID(itemID)
|
||||
if itemName and itemName == name then
|
||||
local _, itemLink = C_Item.GetItemInfo(itemID)
|
||||
return itemLink
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -542,29 +555,60 @@ do -- create a scope so we don't have to worry about upvalue collisions
|
||||
end
|
||||
end
|
||||
|
||||
-- [ HookScript ]
|
||||
-- Securely post-hooks a script handler.
|
||||
-- 'f' [frame] the frame which needs a hook
|
||||
-- 'script' [string] the handler to hook
|
||||
-- 'func' [function] the function that should be added
|
||||
function HookScript(f, script, func)
|
||||
f:HookScript(script, func)
|
||||
end
|
||||
|
||||
function hooksecurefunc(tbl, name, func)
|
||||
if type(tbl) == "string" then tbl, name, func = _G, tbl, name end
|
||||
if not tbl or type(tbl[name]) ~= "function" then return end
|
||||
return _G.hooksecurefunc(tbl, name, func)
|
||||
end
|
||||
|
||||
-- [ HookAddonOrVariable ]
|
||||
-- Sets a function to be called automatically once an addon gets loaded
|
||||
-- 'addon' [string] addon or variable name
|
||||
-- 'func' [function] function that should run
|
||||
function pfUI.api.HookAddonOrVariable(addon, func)
|
||||
local lurker = CreateFrame("Frame", nil)
|
||||
lurker.func = func
|
||||
lurker:RegisterEvent("ADDON_LOADED")
|
||||
lurker:RegisterEvent("VARIABLES_LOADED")
|
||||
lurker:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
lurker:SetScript("OnEvent",function()
|
||||
-- only run when config is available
|
||||
if event == "ADDON_LOADED" and not this.foundConfig then
|
||||
return
|
||||
elseif event == "VARIABLES_LOADED" then
|
||||
this.foundConfig = true
|
||||
do
|
||||
local lurker
|
||||
local pending = {}
|
||||
|
||||
local function ProcessPending()
|
||||
if not lurker.foundConfig then return end
|
||||
for i = table.getn(pending), 1, -1 do
|
||||
local hook = pending[i]
|
||||
if IsAddOnLoaded(hook.addon) or _G[hook.addon] then
|
||||
hook.func()
|
||||
table.remove(pending, i)
|
||||
end
|
||||
end
|
||||
if table.getn(pending) == 0 then
|
||||
lurker:UnregisterAllEvents()
|
||||
end
|
||||
end
|
||||
|
||||
function pfUI.api.HookAddonOrVariable(addon, func)
|
||||
if not lurker then
|
||||
lurker = CreateFrame("Frame", nil)
|
||||
lurker:SetScript("OnEvent", function()
|
||||
if event == "VARIABLES_LOADED" or event == "PLAYER_ENTERING_WORLD" then
|
||||
this.foundConfig = true
|
||||
end
|
||||
ProcessPending()
|
||||
end)
|
||||
end
|
||||
|
||||
if IsAddOnLoaded(addon) or _G[addon] then
|
||||
this:func()
|
||||
this:UnregisterAllEvents()
|
||||
end
|
||||
end)
|
||||
table.insert(pending, { addon = addon, func = func })
|
||||
lurker:RegisterEvent("ADDON_LOADED")
|
||||
lurker:RegisterEvent("VARIABLES_LOADED")
|
||||
lurker:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
ProcessPending()
|
||||
end
|
||||
end
|
||||
|
||||
-- [ QueueFunction ]
|
||||
@@ -688,24 +732,15 @@ function pfUI.api.CopyTable(src)
|
||||
end
|
||||
|
||||
-- [ Wipe Table ]
|
||||
-- Empties a table and returns it
|
||||
-- Empties a table and returns it.
|
||||
-- 'src' [table] the table that should be emptied.
|
||||
-- return: [table] the emptied table.
|
||||
-- Delegates to ClassicAPI's table.wipe, which also resets the Lua 5.0 getn
|
||||
-- length (luaL_setn(t,0)) so table.insert on a wiped table resumes at [1].
|
||||
-- Append to wiped arrays with table.insert -- NOT the t[table.getn(t)+1]=v
|
||||
-- idiom, which needs an unmanaged length counter and won't work here.
|
||||
function pfUI.api.wipe(src)
|
||||
-- notes: table.insert, table.remove will have undefined behavior
|
||||
-- when used on tables emptied this way because Lua removes nil
|
||||
-- entries from tables after an indeterminate time.
|
||||
-- Instead of table.insert(t,v) use t[table.getn(t)+1]=v as table.getn collapses nil entries.
|
||||
-- There are no issues with hash tables, t[k]=v where k is not a number behaves as expected.
|
||||
local mt = getmetatable(src) or {}
|
||||
if mt.__mode == nil or mt.__mode ~= "kv" then
|
||||
mt.__mode = "kv"
|
||||
src=setmetatable(src,mt)
|
||||
end
|
||||
for k in pairs(src) do
|
||||
src[k] = nil
|
||||
end
|
||||
return src
|
||||
return table.wipe(src)
|
||||
end
|
||||
|
||||
-- [ Load Movable ]
|
||||
@@ -1546,6 +1581,16 @@ end
|
||||
-- 'arg1' [string]
|
||||
-- return object
|
||||
function pfUI.api.GetNoNameObject(frame, objtype, layer, arg1, arg2)
|
||||
-- A nil/non-frame parent otherwise dies on frame:GetRegions()/:GetChildren()
|
||||
-- below, and the traceback stops here — useless, since all callers share this
|
||||
-- line. pfUI shadows Lua's `error` (dropping the level arg and not throwing),
|
||||
-- so fold the caller frame in via debugstack to name the offending skin, then
|
||||
-- bail so we don't fall through and crash on frame:GetRegions() anyway.
|
||||
if type(frame) ~= "table" or not frame.GetRegions then
|
||||
error("GetNoNameObject: invalid parent frame\n" .. debugstack(2, 3, 0))
|
||||
return
|
||||
end
|
||||
|
||||
local arg1 = arg1 and gsub(arg1, "([%+%-%*%(%)%?%[%]%^])", "%%%1")
|
||||
local arg2 = arg2 and gsub(arg2, "([%+%-%*%(%)%?%[%]%^])", "%%%1")
|
||||
|
||||
|
||||
+31
-9
@@ -162,6 +162,8 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("appearance", "infight", "intensity", "16")
|
||||
pfUI:UpdateConfig("appearance", "bags", "unusable", "1")
|
||||
pfUI:UpdateConfig("appearance", "bags", "unusable_color", ".9,.2,.2,1")
|
||||
pfUI:UpdateConfig("appearance", "bags", "newitem", "1")
|
||||
pfUI:UpdateConfig("appearance", "bags", "newitem_color", "1,1,1,1")
|
||||
pfUI:UpdateConfig("appearance", "bags", "borderlimit", "1")
|
||||
pfUI:UpdateConfig("appearance", "bags", "borderonlygear", "0")
|
||||
pfUI:UpdateConfig("appearance", "bags", "fulltext", "1")
|
||||
@@ -172,6 +174,8 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("appearance", "bags", "bagrowlength", "10")
|
||||
pfUI:UpdateConfig("appearance", "bags", "bankrowlength", "10")
|
||||
pfUI:UpdateConfig("appearance", "bags", "autoSortOnOpen", "0")
|
||||
pfUI:UpdateConfig("appearance", "bags", "sortreverse", "0")
|
||||
pfUI:UpdateConfig("appearance", "bags", "sortprioreverse", "0")
|
||||
pfUI:UpdateConfig("appearance", "minimap", "size", "140")
|
||||
pfUI:UpdateConfig("appearance", "minimap", "arrowscale", "1")
|
||||
pfUI:UpdateConfig("appearance", "minimap", "zonetext", "off")
|
||||
@@ -196,6 +200,8 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("loot", nil, "rollannounce", "0")
|
||||
pfUI:UpdateConfig("loot", nil, "raritytimer", "1")
|
||||
|
||||
pfUI:UpdateConfig("loothistory", nil, "autoshow", "0")
|
||||
|
||||
pfUI:UpdateConfig("unitframes", nil, "disable", "0")
|
||||
pfUI:UpdateConfig("unitframes", nil, "pastel", "1")
|
||||
pfUI:UpdateConfig("unitframes", nil, "custom", "0")
|
||||
@@ -227,8 +233,8 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("unitframes", nil, "druidmanaoffy", "0")
|
||||
pfUI:UpdateConfig("unitframes", nil, "druidmanaspace", "-3")
|
||||
pfUI:UpdateConfig("unitframes", nil, "druidmanatexture", "Interface\\AddOns\\pfUI\\img\\bar")
|
||||
pfUI:UpdateConfig("unitframes", nil, "druidmanatext", "1")
|
||||
|
||||
pfUI:UpdateConfig("unitframes", nil, "rangechecki", "4")
|
||||
pfUI:UpdateConfig("unitframes", nil, "combowidth", "6")
|
||||
pfUI:UpdateConfig("unitframes", nil, "comboheight", "6")
|
||||
pfUI:UpdateConfig("unitframes", nil, "swingtimerwidth", "200")
|
||||
@@ -379,6 +385,27 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("unitframes", "grouppet", "glowcombat", "0")
|
||||
pfUI:UpdateConfig("unitframes", "grouppet", "txthpright", "healthperc")
|
||||
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "portrait", "off")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "width", "50")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "height", "14")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "pheight", "0")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "buffs", "off")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "buffsize", "16")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "debuffs", "off")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "debuffsize", "16")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "faderange", "1")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "glowcombat", "0")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "txthpright", "healthperc")
|
||||
-- off by default; mirrors the raid grid layout when enabled
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "visible", "0")
|
||||
-- collapse: pack only pets that exist (from the roster snapshot) instead
|
||||
-- of mirroring every raid slot
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "collapse", "1")
|
||||
-- pet block has its own layout, independent of the raid grid
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "raidlayout", "8x5")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "raidpadding", "3")
|
||||
pfUI:UpdateConfig("unitframes", "raidpet", "raidfill", "VERTICAL")
|
||||
|
||||
pfUI:UpdateConfig("unitframes", "raid", "portrait", "off")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "width", "50")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "height", "26")
|
||||
@@ -397,6 +424,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("unitframes", "raid", "raidlayout", "8x5")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "raidpadding", "3")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "raidfill", "VERTICAL")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "collapse", "0")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "raidgrouplabel", "0")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "grouplabelxoff", "0")
|
||||
pfUI:UpdateConfig("unitframes", "raid", "grouplabelyoff", "8")
|
||||
@@ -452,7 +480,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("unitframes", "ptarget", "txthpright", "none")
|
||||
pfUI:UpdateConfig("unitframes", "ptarget", "overhealperc", "10")
|
||||
|
||||
local ufs = { "player", "target", "focus", "focustarget", "group", "grouptarget", "grouppet", "raid", "ttarget", "pet", "ptarget", "fallback", "tttarget" }
|
||||
local ufs = { "player", "target", "focus", "focustarget", "group", "grouptarget", "grouppet", "raid", "raidpet", "ttarget", "pet", "ptarget", "fallback", "tttarget" }
|
||||
for _, unit in pairs(ufs) do
|
||||
pfUI:UpdateConfig("unitframes", unit, "selfdebuff", "0")
|
||||
pfUI:UpdateConfig("unitframes", unit, "visible", "1")
|
||||
@@ -624,6 +652,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("bars", nil, "pagemastershift", "0")
|
||||
pfUI:UpdateConfig("bars", nil, "pagemasterctrl", "0")
|
||||
pfUI:UpdateConfig("bars", nil, "druidstealth", "0")
|
||||
pfUI:UpdateConfig("bars", nil, "priestshadow", "0")
|
||||
pfUI:UpdateConfig("bars", nil, "showcastable", "1")
|
||||
pfUI:UpdateConfig("bars", nil, "glowrange", "1")
|
||||
pfUI:UpdateConfig("bars", nil, "rangecolor", "1,0.1,0.1,1")
|
||||
@@ -1105,13 +1134,6 @@ function pfUI:MigrateConfig()
|
||||
end
|
||||
end
|
||||
|
||||
-- migrating rangecheck interval (> 3.2.2)
|
||||
if checkversion(3, 2, 2) then
|
||||
if tonumber(pfUI_config.unitframes.rangechecki) <= 1 then
|
||||
pfUI_config.unitframes.rangechecki = "2"
|
||||
end
|
||||
end
|
||||
|
||||
-- migrating legacy buff/debuff naming (> 3.5.0)
|
||||
if checkversion(3, 5, 0) then
|
||||
local unitframes = { "player", "target", "focus", "group", "grouptarget", "grouppet", "raid", "ttarget", "pet", "ptarget", "fallback" }
|
||||
|
||||
+23
-57
@@ -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()
|
||||
|
||||
+157
-471
@@ -19,10 +19,10 @@ function pfUI.uf.ClearGuidTracking()
|
||||
end
|
||||
|
||||
-- slash command to toggle unitframe test mode
|
||||
_G.SLASH_PFTEST1, _G.SLASH_PFTEST2 = "/pftest", "/pfuftest"
|
||||
_G.SlashCmdList.PFTEST = function()
|
||||
pfUI.api.RegisterSlashCommand("PFTEST", { "/pftest", "/pfuftest" }, function()
|
||||
pfUI.uf.showall = not pfUI.uf.showall
|
||||
end
|
||||
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
|
||||
-- reused by other spells. Maps icon (lowercased) → expected aura name +
|
||||
@@ -127,115 +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
|
||||
|
||||
|
||||
-- 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
|
||||
-- Get guid via the extended UnitExists for Nampower
|
||||
local _, guid = _G.UnitExists(unitstr)
|
||||
|
||||
if guid then
|
||||
hp = GetUnitField(guid, "health")
|
||||
maxHp = GetUnitField(guid, "maxHealth")
|
||||
|
||||
-- Get power type from bytes0
|
||||
local bytes0 = GetUnitField(guid, "bytes0")
|
||||
if bytes0 then
|
||||
local temp = math.floor(bytes0 / 16777216)
|
||||
powerType = temp - math.floor(temp / 256) * 256
|
||||
else
|
||||
powerType = UnitPowerType(unitstr) or 0
|
||||
end
|
||||
|
||||
-- Get power values based on type
|
||||
if powerType == 1 then
|
||||
-- Rage (Nampower stores rage * 10, maxPower2 stores maxRage * 10)
|
||||
local rage = GetUnitField(guid, "power2")
|
||||
local maxRage = GetUnitField(guid, "maxPower2")
|
||||
power = rage and math.floor(rage / 10) or UnitMana(unitstr)
|
||||
maxPower = maxRage and math.floor(maxRage / 10) or UnitManaMax(unitstr)
|
||||
elseif powerType == 3 then
|
||||
-- Energy
|
||||
power = GetUnitField(guid, "power4") or UnitMana(unitstr)
|
||||
if power then power = math.floor(power) end
|
||||
maxPower = GetUnitField(guid, "maxPower4") or UnitManaMax(unitstr)
|
||||
elseif powerType == 2 then
|
||||
-- Focus (Hunter pets use power3)
|
||||
power = GetUnitField(guid, "power3") or UnitMana(unitstr)
|
||||
if power then power = math.floor(power) end
|
||||
maxPower = GetUnitField(guid, "maxPower3") or UnitManaMax(unitstr)
|
||||
|
||||
else
|
||||
-- Mana (default)
|
||||
power = GetUnitField(guid, "power1") or UnitMana(unitstr)
|
||||
maxPower = GetUnitField(guid, "maxPower1") or UnitManaMax(unitstr)
|
||||
end
|
||||
|
||||
-- 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
|
||||
end
|
||||
|
||||
-- Fallback to standard API (for players when Nampower fails)
|
||||
hp = UnitHealth(unitstr) or 0
|
||||
maxHp = UnitHealthMax(unitstr) or 1
|
||||
powerType = UnitPowerType(unitstr) or 0
|
||||
power = UnitMana(unitstr) or 0
|
||||
maxPower = UnitManaMax(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 = { }
|
||||
@@ -294,7 +195,7 @@ function pfUI.uf:UpdateVisibility()
|
||||
-- cache result of strsub to avoid repeating calls
|
||||
if not self.cache_raid then
|
||||
if strsub(self:GetName(),0,6) == "pfRaid" then
|
||||
self.cache_raid = tonumber(strsub(self:GetName(),7,8))
|
||||
self.cache_raid = tonumber(strsub(self:GetName(),7,8)) or 0
|
||||
else
|
||||
self.cache_raid = 0
|
||||
end
|
||||
@@ -305,7 +206,7 @@ function pfUI.uf:UpdateVisibility()
|
||||
local id = self.cache_raid
|
||||
|
||||
-- always show self in raidframes
|
||||
if not IsInRaid() and IsInGroup() and C.unitframes.selfinraid == "1" and id == 1 then
|
||||
if not IsInGroup() and C.unitframes.selfinraid == "1" and id == 1 then
|
||||
self.id = ""
|
||||
self.label = "player"
|
||||
|
||||
@@ -339,6 +240,12 @@ function pfUI.uf:UpdateVisibility()
|
||||
local unitstr = string.format("%s%s", self.label or "", self.id or "")
|
||||
local visibility = string.format("[target=%s,exists] show; hide", unitstr)
|
||||
|
||||
-- Group frames are redundant when the group is already shown as a raid grid:
|
||||
-- either an actual raid, or a party promoted to the raid grid via
|
||||
-- raidforgroup. hide_in_raid gates whether we hide them in that case.
|
||||
local hide_group = C["unitframes"]["group"]["hide_in_raid"] == "1"
|
||||
and (IsInRaid() or (C.unitframes.raidforgroup == "1" and IsInGroup()))
|
||||
|
||||
if pfUI.unlock and pfUI.unlock:IsShown() then
|
||||
-- display during unlock mode
|
||||
visibility = "show"
|
||||
@@ -347,13 +254,14 @@ function pfUI.uf:UpdateVisibility()
|
||||
-- frame shall not be visible
|
||||
visibility = "hide"
|
||||
self.visible = nil
|
||||
elseif C["unitframes"]["group"]["hide_in_raid"] == "1" and self.label and strsub(self.label,0,5) == "party" and IsInRaid() then
|
||||
-- hide group while in raid and option is set
|
||||
elseif hide_group and self.cache_raid == 0 and self.label and strsub(self.label,0,5) == "party" then
|
||||
-- hide group while shown as a raid grid and option is set (raid frames
|
||||
-- carry label "party" under raidforgroup, so exclude them by cache_raid)
|
||||
visibility = "hide"
|
||||
self.visible = nil
|
||||
elseif ( self.fname == "Group0" or self.fname == "PartyPet0" or self.fname == "Party0Target" )
|
||||
and (not IsInGroup() or (C["unitframes"]["group"]["hide_in_raid"] == "1" and IsInRaid())) then
|
||||
-- hide self in group if solo or hide in raid is set
|
||||
and (not IsInGroup() or hide_group) then
|
||||
-- hide self in group if solo or shown as a raid grid
|
||||
visibility = "hide"
|
||||
self.visible = nil
|
||||
end
|
||||
@@ -373,6 +281,11 @@ function pfUI.uf:UpdateVisibility()
|
||||
self:Hide()
|
||||
return
|
||||
end
|
||||
elseif self.label == "raidpet" then
|
||||
if not UnitIsVisible(unitstr) or not UnitExists("raid" .. self.id) then
|
||||
self:Hide()
|
||||
return
|
||||
end
|
||||
elseif self.label == "pettarget" then
|
||||
if not UnitIsVisible(unitstr) or not UnitExists("pet") then
|
||||
self:Hide()
|
||||
@@ -407,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()
|
||||
@@ -456,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()
|
||||
@@ -465,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)
|
||||
|
||||
@@ -518,6 +426,50 @@ function pfUI.uf:UpdateConfig()
|
||||
fontstyle = C.global.font_unit_style
|
||||
end
|
||||
|
||||
-- Druid secondary mana bar: texture/color/size/position below the power bar,
|
||||
-- using its own C.unitframes.druidmana* config. Values are read in
|
||||
-- UpdateDruidMana; here we only lay it out.
|
||||
if f.druidmana then
|
||||
local DC = C.unitframes
|
||||
local dmTexture = DC.druidmanatexture or "Interface\\AddOns\\pfUI\\img\\bar"
|
||||
f.druidmana:SetStatusBarTexture(pfUI.media[dmTexture] or dmTexture)
|
||||
f.druidmana:SetFrameLevel(f:GetFrameLevel() + 5)
|
||||
|
||||
local manacolor = f.config.defcolor == "0" and f.config.manacolor or C.unitframes.manacolor
|
||||
f.druidmana:SetStatusBarColor(GetStringColor(manacolor))
|
||||
|
||||
local dmHeight = tonumber(DC.druidmanaheight) or 10
|
||||
local dmWidth = DC.druidmanawidth or "-1"
|
||||
local dmOffX = tonumber(DC.druidmanaoffx) or 0
|
||||
local dmOffY = tonumber(DC.druidmanaoffy) or 0
|
||||
local dmSpace = tonumber(DC.druidmanaspace) or -3
|
||||
local dmSpacing = -2 * default_border - dmSpace
|
||||
|
||||
f.druidmana:SetHeight(dmHeight)
|
||||
f.druidmana:ClearAllPoints()
|
||||
local w = dmWidth ~= "-1" and tonumber(dmWidth) or nil
|
||||
if w then
|
||||
f.druidmana:SetWidth(w)
|
||||
f.druidmana:SetPoint("TOP", f.power, "BOTTOM", dmOffX, dmSpacing + dmOffY)
|
||||
else
|
||||
f.druidmana:SetPoint("TOPLEFT", f.power, "BOTTOMLEFT", dmOffX, dmSpacing + dmOffY)
|
||||
f.druidmana:SetPoint("TOPRIGHT", f.power, "BOTTOMRIGHT", dmOffX, dmSpacing + dmOffY)
|
||||
end
|
||||
|
||||
if not f.druidmana._hasbd then
|
||||
CreateBackdrop(f.druidmana, default_border)
|
||||
CreateBackdropShadow(f.druidmana)
|
||||
f.druidmana._hasbd = true
|
||||
end
|
||||
|
||||
local tr, tg, tb = ManaBarColor[Enum.PowerType.Mana].r, ManaBarColor[Enum.PowerType.Mana].g, ManaBarColor[Enum.PowerType.Mana].b
|
||||
if C.unitframes.pastel == "1" then
|
||||
tr, tg, tb = (tr + .75) * .5, (tg + .75) * .5, (tb + .75) * .5
|
||||
end
|
||||
f.druidmana.text:SetFont(fontname, fontsize, fontstyle)
|
||||
f.druidmana.text:SetTextColor(tr, tg, tb, 1)
|
||||
end
|
||||
|
||||
f.portrait.tex:SetAllPoints(f.portrait)
|
||||
f.portrait.tex:SetTexCoord(.1, .9, .1, .9)
|
||||
f.portrait.model:SetAllPoints(f.portrait)
|
||||
@@ -574,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
|
||||
@@ -647,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)
|
||||
@@ -664,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)
|
||||
@@ -778,8 +718,7 @@ function pfUI.uf:UpdateConfig()
|
||||
invert_v * (i-1-row*perrow)*(multiply*default_border + f.config.buffsize + 1),
|
||||
invert_h * (row*(multiply*default_border + f.config.buffsize + 1) + (multiply*default_border + 1)))
|
||||
|
||||
f.buffs[i]:SetWidth(f.config.buffsize)
|
||||
f.buffs[i]:SetHeight(f.config.buffsize)
|
||||
f.buffs[i]:SetSize(f.config.buffsize, f.config.buffsize)
|
||||
|
||||
-- Create CD frame if it doesn't exist
|
||||
if not f.buffs[i].cd then
|
||||
@@ -808,11 +747,7 @@ function pfUI.uf:UpdateConfig()
|
||||
|
||||
-- immediately show/hide existing cooldown text
|
||||
if f.buffs[i].cd.pfCooldownText then
|
||||
if cooldown_text == 1 then
|
||||
f.buffs[i].cd.pfCooldownText:Show()
|
||||
else
|
||||
f.buffs[i].cd.pfCooldownText:Hide()
|
||||
end
|
||||
f.buffs[i].cd.pfCooldownText:SetShown(cooldown_text == 1)
|
||||
end
|
||||
|
||||
f.buffs[i].id = i
|
||||
@@ -886,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
|
||||
@@ -1020,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
|
||||
@@ -1043,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
|
||||
@@ -1274,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)
|
||||
@@ -1343,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
|
||||
@@ -1638,6 +1340,19 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
||||
f.power = CreateFrame("Frame",nil, f)
|
||||
f.power.bar = CreateStatusBar(nil, f.power)
|
||||
|
||||
-- Druid secondary mana bar: shows base mana (read via ClassicAPI
|
||||
-- UnitPower(unit, Enum.PowerType.Mana), which works regardless of the active
|
||||
-- power) while shapeshifted into a form that uses energy/rage. Player +
|
||||
-- target only;
|
||||
-- styled/positioned in UpdateConfig, driven in UpdateDruidMana.
|
||||
if C.unitframes.druidmanabar == "1" and (f.label == "player" or f.label == "target") then
|
||||
f.druidmana = CreateFrame("StatusBar", "pfDruidMana_" .. f.label .. f.id, f)
|
||||
f.druidmana.text = f.druidmana:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
||||
f.druidmana.text:SetPoint("CENTER", f.druidmana, "CENTER", 0, 0)
|
||||
f.druidmana.text:SetJustifyH("CENTER")
|
||||
f.druidmana:Hide()
|
||||
end
|
||||
|
||||
f.glow = CreateFrame("Frame", nil, f)
|
||||
f.combat = CreateFrame("Frame", nil, f.hp.bar)
|
||||
f.combat.tex = f.combat:CreateTexture(nil, "OVERLAY")
|
||||
@@ -1847,6 +1562,32 @@ function pfUI.uf:RefreshIndicators(unit)
|
||||
end
|
||||
end
|
||||
|
||||
-- Druid secondary mana bar update. Reads base mana with ClassicAPI
|
||||
-- UnitPower/UnitPowerMax(unit, Enum.PowerType.Mana), which return the mana
|
||||
-- slot regardless of the unit's active power -- so it works while shapeshifted,
|
||||
-- with no nampower/GetUnitField dependency. Shown only while off mana
|
||||
-- (Cat=energy, Bear=rage); non-player frames only for druid units.
|
||||
function pfUI.uf:UpdateDruidMana(unit)
|
||||
local bar = unit.druidmana
|
||||
local unitstr = unit.label .. unit.id
|
||||
if not UnitExists(unitstr) then bar:Hide() return end
|
||||
if unit.label ~= "player" then
|
||||
local _, cls = UnitClass(unitstr)
|
||||
if cls ~= "DRUID" then bar:Hide() return end
|
||||
end
|
||||
if UnitPowerType(unitstr) == Enum.PowerType.Mana then bar:Hide() return end
|
||||
local mana, maxmana = UnitPower(unitstr, Enum.PowerType.Mana), UnitPowerMax(unitstr, Enum.PowerType.Mana)
|
||||
if not maxmana or maxmana == 0 then bar:Hide() return end
|
||||
bar:SetMinMaxValues(0, maxmana)
|
||||
bar:SetValue(mana)
|
||||
if C.unitframes.druidmanatext == "1" then
|
||||
bar.text:SetText(pfUI.api.Abbreviate(mana) .. "/" .. pfUI.api.Abbreviate(maxmana))
|
||||
else
|
||||
bar.text:SetText("")
|
||||
end
|
||||
bar:Show()
|
||||
end
|
||||
|
||||
function pfUI.uf:RefreshUnit(unit, component)
|
||||
-- break early on misconfigured UF's
|
||||
if not unit.label then return end
|
||||
@@ -2267,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
|
||||
@@ -2351,13 +2092,13 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
|
||||
local r, g, b, a = .5, .5, .5, 1
|
||||
local utype = UnitPowerType(unitstr)
|
||||
if utype == 0 then
|
||||
if utype == Enum.PowerType.Mana then
|
||||
r, g, b, a = GetStringColor(mana)
|
||||
elseif utype == 1 then
|
||||
elseif utype == Enum.PowerType.Rage then
|
||||
r, g, b, a = GetStringColor(rage)
|
||||
elseif utype == 2 then
|
||||
elseif utype == Enum.PowerType.Focus then
|
||||
r, g, b, a = GetStringColor(focus)
|
||||
elseif utype == 3 then
|
||||
elseif utype == Enum.PowerType.Energy then
|
||||
r, g, b, a = GetStringColor(energy)
|
||||
end
|
||||
|
||||
@@ -2393,6 +2134,8 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
end
|
||||
end
|
||||
|
||||
if unit.druidmana then pfUI.uf:UpdateDruidMana(unit) end
|
||||
|
||||
pfUI.uf:RefreshUnitState(unit)
|
||||
end
|
||||
end
|
||||
@@ -2840,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)
|
||||
@@ -2870,6 +2613,19 @@ function pfUI.uf:GetStatusValue(unit, pos)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
elseif config == "ownername" then
|
||||
local owner
|
||||
if unit.label == "raidpet" then owner = "raid" .. unit.id
|
||||
elseif unit.label == "partypet" then owner = "party" .. unit.id
|
||||
elseif unit.label == "pet" then owner = "player" end
|
||||
if not (owner and UnitExists(owner)) then return "" end
|
||||
local color = ""
|
||||
if unit.config["classcolor"] == "1" and UnitIsPlayer(owner) then
|
||||
local _, r, g, b = GetUnitColor(owner)
|
||||
if C.unitframes.pastel == "1" then r, g, b = (r+.75)*.5, (g+.75)*.5, (b+.75)*.5 end
|
||||
color = rgbhex(r, g, b)
|
||||
end
|
||||
return color .. pfUI.uf:GetNameString(owner)
|
||||
|
||||
-- health
|
||||
elseif config == "health" then
|
||||
@@ -2929,7 +2685,7 @@ function pfUI.uf:GetStatusValue(unit, pos)
|
||||
elseif config == "powermax" then
|
||||
return unit:GetColor("power") .. pfUI.api.Abbreviate(mpmax)
|
||||
elseif config == "powerperc" then
|
||||
local perc = UnitManaMax(unitstr) > 0 and ceil(mp / mpmax * 100) or 0
|
||||
local perc = UnitPowerMax(unitstr) > 0 and ceil(mp / mpmax * 100) or 0
|
||||
return unit:GetColor("power") .. perc
|
||||
elseif config == "powermiss" then
|
||||
local power = ceil(mp - mpmax)
|
||||
@@ -2940,7 +2696,7 @@ function pfUI.uf:GetStatusValue(unit, pos)
|
||||
end
|
||||
elseif config == "powerdyn" then
|
||||
-- show percentage when only mana is less than 100%
|
||||
if mp ~= mpmax and UnitPowerType(unitstr) == 0 then
|
||||
if mp ~= mpmax and UnitPowerType(unitstr) == Enum.PowerType.Mana then
|
||||
return unit:GetColor("power") .. pfUI.api.Abbreviate(mp) .. " - " .. ceil(mp / mpmax * 100) .. "%"
|
||||
else
|
||||
return unit:GetColor("power") .. pfUI.api.Abbreviate(mp)
|
||||
@@ -2983,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
|
||||
@@ -3017,61 +2761,3 @@ function pfUI.uf.GetColor(self, preset)
|
||||
return rgbhex(r,g,b)
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- Slash Commands for Stats Frame
|
||||
-- ============================================================================
|
||||
_G.SLASH_PFUISTATS1 = "/pfuistats"
|
||||
_G.SLASH_PFUISTATS2 = "/ufstats"
|
||||
_G.SlashCmdList["PFUISTATS"] = 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
|
||||
@@ -28,26 +28,6 @@ ACTIONBAR_SECURE_TEMPLATE_BUTTON = nil
|
||||
UNITFRAME_SECURE_TEMPLATE = nil
|
||||
|
||||
--[[ Vanilla API Extensions ]]--
|
||||
-- Safe post-hook helper. The global `hooksecurefunc` belongs to ClassicAPI
|
||||
-- (its C implementation); this wrapper only adds pfUI's missing-target guard:
|
||||
-- ClassicAPI errors when target[name] isn't a function, whereas a lot of our
|
||||
-- call sites hook optional/late-loaded frames and rely on a silent no-op.
|
||||
-- Normalizes the string form, skips when the target is absent, then delegates
|
||||
-- to the C version (uncapped args, callback-pcall, taint parity).
|
||||
function pfUI.hooksecurefunc(tbl, name, func)
|
||||
if type(tbl) == "string" then tbl, name, func = _G, tbl, name end
|
||||
if not tbl or type(tbl[name]) ~= "function" then return end
|
||||
return _G.hooksecurefunc(tbl, name, func)
|
||||
end
|
||||
|
||||
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 }
|
||||
|
||||
Vendored
-17
@@ -1,20 +1,3 @@
|
||||
-- this table is added in later expansions
|
||||
CLASS_SORT_ORDER = CLASS_SORT_ORDER or {
|
||||
"WARRIOR",
|
||||
"DEATHKNIGHT",
|
||||
"PALADIN",
|
||||
"MONK",
|
||||
"PRIEST",
|
||||
"SHAMAN",
|
||||
"DRUID",
|
||||
"ROGUE",
|
||||
"MAGE",
|
||||
"WARLOCK",
|
||||
"HUNTER",
|
||||
"DEMONHUNTER",
|
||||
"UNKNOWN",
|
||||
}
|
||||
|
||||
CLASS_ICON_TCOORDS = CLASS_ICON_TCOORDS or {
|
||||
["WARRIOR"] = {0, 0.25, 0, 0.25},
|
||||
["MAGE"] = {0.25, 0.49609375, 0, 0.25},
|
||||
|
||||
Vendored
+7
-4
@@ -27,7 +27,6 @@ pfUI_translation["deDE"] = {
|
||||
["Always Show Item Comparison"] = nil,
|
||||
["Always Show On Target Units"] = nil,
|
||||
["Always Show On Units With Missing HP"] = nil,
|
||||
["Always Show Self In Raid Frames"] = nil,
|
||||
["Always Use 2D Portraits"] = nil,
|
||||
["Ammo Counter"] = nil,
|
||||
["Anchor Bags Above Chat"] = nil,
|
||||
@@ -124,6 +123,7 @@ pfUI_translation["deDE"] = {
|
||||
["Click Casting"] = nil,
|
||||
["Clock"] = nil,
|
||||
["Close"] = nil,
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = nil,
|
||||
["Color Buff Stacks"] = nil,
|
||||
["Color Debuff Stacks"] = nil,
|
||||
@@ -138,7 +138,6 @@ pfUI_translation["deDE"] = {
|
||||
["Combat Timer"] = nil,
|
||||
["Combopoint Height"] = nil,
|
||||
["Combopoint Width"] = nil,
|
||||
["Compare Item Base Stats"] = nil,
|
||||
["Components"] = nil,
|
||||
["Config UI Settings"] = nil,
|
||||
["Configuration"] = nil,
|
||||
@@ -569,6 +568,7 @@ pfUI_translation["deDE"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = nil,
|
||||
["Overwrite If Unit Is Attacking You"] = nil,
|
||||
["Overwrite If Unit Is Casting"] = nil,
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = nil,
|
||||
["Paging Actionbar"] = nil,
|
||||
["Panel"] = nil,
|
||||
@@ -616,12 +616,13 @@ pfUI_translation["deDE"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = nil,
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = nil,
|
||||
["Random Roll Announcement Rarity"] = nil,
|
||||
["Random Rolling"] = nil,
|
||||
["Range Based Hunter Paging"] = nil,
|
||||
["Range Check Interval"] = nil,
|
||||
["Rank"] = nil,
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = nil,
|
||||
["Red Name Text On Infight Units"] = nil,
|
||||
["Regional Settings"] = nil,
|
||||
@@ -703,6 +704,7 @@ pfUI_translation["deDE"] = {
|
||||
["Show Description"] = nil,
|
||||
["Show Dispel Indicators"] = nil,
|
||||
["Show Druid Mana Bar"] = nil,
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = nil,
|
||||
["Show Empty Buttons"] = nil,
|
||||
["Show FPS and Latency Colors"] = nil,
|
||||
@@ -739,6 +741,7 @@ pfUI_translation["deDE"] = {
|
||||
["Show Required Questitem Count"] = nil,
|
||||
["Show Resting"] = nil,
|
||||
["Show Self In Group Frames"] = nil,
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
@@ -783,6 +786,7 @@ pfUI_translation["deDE"] = {
|
||||
["Target Castbar"] = nil,
|
||||
["Target Debuff Bar"] = nil,
|
||||
["Target Nameplate Zoom Factor"] = nil,
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = nil,
|
||||
["Target-Target-Target"] = nil,
|
||||
["Text"] = nil,
|
||||
@@ -877,7 +881,6 @@ pfUI_translation["deDE"] = {
|
||||
["XP Percentage"] = nil,
|
||||
["Yellow Border On Neutral Units"] = nil,
|
||||
["Yes"] = nil,
|
||||
["You gain (.+) Mana from Totemic Recall"] = nil,
|
||||
["You got"] = nil,
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = nil,
|
||||
["Your items have been repaired for"] = nil,
|
||||
|
||||
Vendored
+17
-4
@@ -19,6 +19,7 @@ pfUI_translation["enUS"] = {
|
||||
["Align Chat Windows"] = nil,
|
||||
["Aligned Position"] = nil,
|
||||
["All messages will be forwarded to:"] = nil,
|
||||
["All players passed"] = nil,
|
||||
["Alt-Click Action"] = nil,
|
||||
["Always Allow Drag Via Shift Key"] = nil,
|
||||
["Always Show"] = nil,
|
||||
@@ -27,7 +28,6 @@ pfUI_translation["enUS"] = {
|
||||
["Always Show Item Comparison"] = nil,
|
||||
["Always Show On Target Units"] = nil,
|
||||
["Always Show On Units With Missing HP"] = nil,
|
||||
["Always Show Self In Raid Frames"] = nil,
|
||||
["Always Use 2D Portraits"] = nil,
|
||||
["Ammo Counter"] = nil,
|
||||
["Anchor Bags Above Chat"] = nil,
|
||||
@@ -119,11 +119,13 @@ pfUI_translation["enUS"] = {
|
||||
["Chat Bubble Transparency"] = nil,
|
||||
["Chat Default Brackets"] = nil,
|
||||
["Class"] = nil,
|
||||
["Clear"] = nil,
|
||||
["Clear Rolls"] = nil,
|
||||
["Click Action"] = nil,
|
||||
["Click Casting"] = nil,
|
||||
["Clock"] = nil,
|
||||
["Close"] = nil,
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = nil,
|
||||
["Color Buff Stacks"] = nil,
|
||||
["Color Debuff Stacks"] = nil,
|
||||
@@ -138,7 +140,6 @@ pfUI_translation["enUS"] = {
|
||||
["Combat Timer"] = nil,
|
||||
["Combopoint Height"] = nil,
|
||||
["Combopoint Width"] = nil,
|
||||
["Compare Item Base Stats"] = nil,
|
||||
["Components"] = nil,
|
||||
["Config UI Settings"] = nil,
|
||||
["Configuration"] = nil,
|
||||
@@ -195,6 +196,7 @@ pfUI_translation["enUS"] = {
|
||||
["Deficit"] = nil,
|
||||
["Delete profile"] = nil,
|
||||
["Delete / Reset"] = nil,
|
||||
["Dependencies"] = nil,
|
||||
["Descending"] = nil,
|
||||
["Description Font"] = nil,
|
||||
["Description Font Size"] = nil,
|
||||
@@ -409,6 +411,7 @@ pfUI_translation["enUS"] = {
|
||||
["Highlight Equipped Items"] = nil,
|
||||
["Highlight Not Usable Spells"] = nil,
|
||||
["Highlight Out Of Mana Spells"] = nil,
|
||||
["Highlight New Items"] = nil,
|
||||
["Highlight Out Of Range Spells"] = nil,
|
||||
["Highlight Settings That Require Reload"] = nil,
|
||||
["Highlight Unusable Items"] = nil,
|
||||
@@ -477,6 +480,7 @@ pfUI_translation["enUS"] = {
|
||||
["Look & Feel"] = nil,
|
||||
["Loot"] = nil,
|
||||
["Loot & Spam"] = nil,
|
||||
["Loot History"] = nil,
|
||||
["Macro Text Color"] = nil,
|
||||
["Macro Text Size"] = nil,
|
||||
["Main Actionbar"] = nil,
|
||||
@@ -499,6 +503,7 @@ pfUI_translation["enUS"] = {
|
||||
["Menu Font Size"] = nil,
|
||||
["Messages are no longer forwarded to:"] = nil,
|
||||
["Middle Mouse Button"] = nil,
|
||||
["Missing"] = nil,
|
||||
["Minimap"] = nil,
|
||||
["Minimap Panel"] = nil,
|
||||
["Minimap Size (|cffffaaaaExperimental|r)"] = nil,
|
||||
@@ -525,6 +530,7 @@ pfUI_translation["enUS"] = {
|
||||
["Network Latency"] = nil,
|
||||
["Network Up"] = nil,
|
||||
["New entry:"] = nil,
|
||||
["New Item Color"] = nil,
|
||||
["NEW TIMER"] = nil,
|
||||
["Next"] = nil,
|
||||
["Next Memory Cleanup"] = nil,
|
||||
@@ -552,6 +558,7 @@ pfUI_translation["enUS"] = {
|
||||
["Only Show Own Debuffs (|cffffaaaaExperimental|r)"] = nil,
|
||||
["Only Show Target Castbar"] = nil,
|
||||
["On State Change"] = nil,
|
||||
["Optional Dependencies"] = nil,
|
||||
["Options"] = nil,
|
||||
["Orientation"] = nil,
|
||||
["Other Panel: Minimap"] = nil,
|
||||
@@ -569,6 +576,7 @@ pfUI_translation["enUS"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = nil,
|
||||
["Overwrite If Unit Is Attacking You"] = nil,
|
||||
["Overwrite If Unit Is Casting"] = nil,
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = nil,
|
||||
["Paging Actionbar"] = nil,
|
||||
["Panel"] = nil,
|
||||
@@ -616,12 +624,13 @@ pfUI_translation["enUS"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = nil,
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = nil,
|
||||
["Random Roll Announcement Rarity"] = nil,
|
||||
["Random Rolling"] = nil,
|
||||
["Range Based Hunter Paging"] = nil,
|
||||
["Range Check Interval"] = nil,
|
||||
["Rank"] = nil,
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = nil,
|
||||
["Red Name Text On Infight Units"] = nil,
|
||||
["Regional Settings"] = nil,
|
||||
@@ -645,6 +654,7 @@ pfUI_translation["enUS"] = {
|
||||
["Resting"] = nil,
|
||||
["Reveal Unexplored Areas"] = nil,
|
||||
["Switch to current zone"] = nil,
|
||||
["Retrieving item information..."] = nil,
|
||||
["Right"] = nil,
|
||||
["Right Actionbar"] = nil,
|
||||
["Right Anchor"] = nil,
|
||||
@@ -703,6 +713,7 @@ pfUI_translation["enUS"] = {
|
||||
["Show Description"] = nil,
|
||||
["Show Dispel Indicators"] = nil,
|
||||
["Show Druid Mana Bar"] = nil,
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = nil,
|
||||
["Show Empty Buttons"] = nil,
|
||||
["Show FPS and Latency Colors"] = nil,
|
||||
@@ -739,6 +750,7 @@ pfUI_translation["enUS"] = {
|
||||
["Show Required Questitem Count"] = nil,
|
||||
["Show Resting"] = nil,
|
||||
["Show Self In Group Frames"] = nil,
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
@@ -780,12 +792,14 @@ pfUI_translation["enUS"] = {
|
||||
["Switch Pages On Alt Key Press"] = nil,
|
||||
["Switch Pages On Ctrl Key Press"] = nil,
|
||||
["Switch Pages On Druid Stealth"] = nil,
|
||||
["Switch Pages On Priest Shadowform"] = nil,
|
||||
["Switch Pages On Shift Key Press"] = nil,
|
||||
["Systeminfo"] = nil,
|
||||
["Target"] = nil,
|
||||
["Target Castbar"] = nil,
|
||||
["Target Debuff Bar"] = nil,
|
||||
["Target Nameplate Zoom Factor"] = nil,
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = nil,
|
||||
["Target-Target-Target"] = nil,
|
||||
["Text"] = nil,
|
||||
@@ -883,7 +897,6 @@ pfUI_translation["enUS"] = {
|
||||
["XP Percentage"] = nil,
|
||||
["Yellow Border On Neutral Units"] = nil,
|
||||
["Yes"] = nil,
|
||||
["You gain (.+) Mana from Totemic Recall"] = nil,
|
||||
["You got"] = nil,
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = nil,
|
||||
["Your items have been repaired for"] = nil,
|
||||
|
||||
Vendored
+7
-4
@@ -27,7 +27,6 @@ pfUI_translation["esES"] = {
|
||||
["Always Show Item Comparison"] = "Mostrar siempre la comparativa entre objetos",
|
||||
["Always Show On Target Units"] = "Mostrar siempre en el objectivo",
|
||||
["Always Show On Units With Missing HP"] = "Mostrar siempre en unidades con falta de salud",
|
||||
["Always Show Self In Raid Frames"] = "Mostrarse siempre a sí mismo en los marcos de banda",
|
||||
["Always Use 2D Portraits"] = "Usar siempre retratos 2D",
|
||||
["Ammo Counter"] = "Contador de munición",
|
||||
["Anchor Bags Above Chat"] = nil,
|
||||
@@ -124,6 +123,7 @@ pfUI_translation["esES"] = {
|
||||
["Click Casting"] = "Lanzamiento al hacer click",
|
||||
["Clock"] = "Reloj",
|
||||
["Close"] = "Cerrar",
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = nil,
|
||||
["Color Buff Stacks"] = "Colorear pilas de beneficios",
|
||||
["Color Debuff Stacks"] = "Colorear pilas de perjuicios",
|
||||
@@ -138,7 +138,6 @@ pfUI_translation["esES"] = {
|
||||
["Combat Timer"] = "Temporizador de combate",
|
||||
["Combopoint Height"] = nil,
|
||||
["Combopoint Width"] = nil,
|
||||
["Compare Item Base Stats"] = "Comparar estadísticas bases de objetos",
|
||||
["Components"] = "Componentes",
|
||||
["Config UI Settings"] = nil,
|
||||
["Configuration"] = "Configuración",
|
||||
@@ -569,6 +568,7 @@ pfUI_translation["esES"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = nil,
|
||||
["Overwrite If Unit Is Attacking You"] = nil,
|
||||
["Overwrite If Unit Is Casting"] = nil,
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = "Paginable",
|
||||
["Paging Actionbar"] = "Paginando la barra de acción",
|
||||
["Panel"] = "Panel",
|
||||
@@ -616,12 +616,13 @@ pfUI_translation["esES"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = "Espaciado del marco de banda",
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = "Aleatorio",
|
||||
["Random Roll Announcement Rarity"] = "Anuncio para tirar los dados aleatoriamente",
|
||||
["Random Rolling"] = "Tirar los dados aleatoriamente",
|
||||
["Range Based Hunter Paging"] = "Paginado de alcance para cazadores",
|
||||
["Range Check Interval"] = "Intervalo de comprobación de alcance",
|
||||
["Rank"] = "Rango",
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = "Borde rojo en unidades enemigas",
|
||||
["Red Name Text On Infight Units"] = nil,
|
||||
["Regional Settings"] = nil,
|
||||
@@ -703,6 +704,7 @@ pfUI_translation["esES"] = {
|
||||
["Show Description"] = "Mostrar descripción",
|
||||
["Show Dispel Indicators"] = "Mostrar indicadores para disipar",
|
||||
["Show Druid Mana Bar"] = nil,
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = "Mostrar la duración dentro del beneficios",
|
||||
["Show Empty Buttons"] = "Mostrar botones vacíos",
|
||||
["Show FPS and Latency Colors"] = "Mostrar FPS y colores de latencia",
|
||||
@@ -739,6 +741,7 @@ pfUI_translation["esES"] = {
|
||||
["Show Required Questitem Count"] = "Muestra el número requerido de objetos de misión",
|
||||
["Show Resting"] = "Mostrar descanso",
|
||||
["Show Self In Group Frames"] = "Mostrar a sí mismo en marcos de grupo",
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = "Mostrar icono de hechizo",
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = "Mostrar pilas",
|
||||
@@ -783,6 +786,7 @@ pfUI_translation["esES"] = {
|
||||
["Target Castbar"] = "Barra de lanzamiento del objetivo",
|
||||
["Target Debuff Bar"] = "Barra de perjuicios del objetivo",
|
||||
["Target Nameplate Zoom Factor"] = "Factor de zoom de la placa de nombre del objetivo",
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = "Objetivo-Objetivo",
|
||||
["Target-Target-Target"] = "Objetivo-Objetivo-Objetivo",
|
||||
["Text"] = nil,
|
||||
@@ -877,7 +881,6 @@ pfUI_translation["esES"] = {
|
||||
["XP Percentage"] = "Porcentaje de exp.",
|
||||
["Yellow Border On Neutral Units"] = "Borde amarillo en unidades neutrales",
|
||||
["Yes"] = "Sí",
|
||||
["You gain (.+) Mana from Totemic Recall"] = nil,
|
||||
["You got"] = "Obtienes",
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = "Ahora su interfaz está configurada.\n\nPara la configuración avanzada, abra la configuración |cff33ffccpf|rUI por el menú de escape o escriba \"|cffffffaa/pfui|r\" en el chat.",
|
||||
["Your items have been repaired for"] = "Tus objetos se han reparado por",
|
||||
|
||||
Vendored
+7
-4
@@ -27,7 +27,6 @@ pfUI_translation["frFR"] = {
|
||||
["Always Show Item Comparison"] = "Toujours afficher la comparaison d'objet",
|
||||
["Always Show On Target Units"] = "Toujours montrer sur la cible",
|
||||
["Always Show On Units With Missing HP"] = "Toujours montrer sur les cibles avec de la vie manquante",
|
||||
["Always Show Self In Raid Frames"] = "Toujours montrer soi-même dans le cadre de raid",
|
||||
["Always Use 2D Portraits"] = "Toujours utiliser les portraits 2D",
|
||||
["Ammo Counter"] = "Compteur de munitions",
|
||||
["Anchor Bags Above Chat"] = nil,
|
||||
@@ -124,6 +123,7 @@ pfUI_translation["frFR"] = {
|
||||
["Click Casting"] = "Clique sur le lancement de sort",
|
||||
["Clock"] = "Horloge",
|
||||
["Close"] = "Fermer",
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = nil,
|
||||
["Color Buff Stacks"] = "Couleur des l'empilements des Améliorations",
|
||||
["Color Debuff Stacks"] = "Couleur de l'empilements de Affaiblissements",
|
||||
@@ -138,7 +138,6 @@ pfUI_translation["frFR"] = {
|
||||
["Combat Timer"] = "Chronomètre de combat",
|
||||
["Combopoint Height"] = nil,
|
||||
["Combopoint Width"] = nil,
|
||||
["Compare Item Base Stats"] = "Compare les stats de base d'un objet",
|
||||
["Components"] = "Composants",
|
||||
["Config UI Settings"] = nil,
|
||||
["Configuration"] = "Configuration",
|
||||
@@ -569,6 +568,7 @@ pfUI_translation["frFR"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = nil,
|
||||
["Overwrite If Unit Is Attacking You"] = nil,
|
||||
["Overwrite If Unit Is Casting"] = nil,
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = "Pageable",
|
||||
["Paging Actionbar"] = "Barre d'action de pagination",
|
||||
["Panel"] = "Panneau",
|
||||
@@ -616,12 +616,13 @@ pfUI_translation["frFR"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = "Remplissage du Raid",
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = "Aléatoire",
|
||||
["Random Roll Announcement Rarity"] = "Rareté des annonces des jets de dés aléatoires",
|
||||
["Random Rolling"] = "Lancer de dés aléatoires",
|
||||
["Range Based Hunter Paging"] = "Pagination de distance basée sur le chasseur",
|
||||
["Range Check Interval"] = "Intervalle de vérification de la distance",
|
||||
["Rank"] = nil,
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = "Bordure rouge sur les unités ennemies",
|
||||
["Red Name Text On Infight Units"] = nil,
|
||||
["Regional Settings"] = nil,
|
||||
@@ -703,6 +704,7 @@ pfUI_translation["frFR"] = {
|
||||
["Show Description"] = "Afficher les descriptions",
|
||||
["Show Dispel Indicators"] = "Afficher les indicateurs de dissipation",
|
||||
["Show Druid Mana Bar"] = nil,
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = "Afficher la durée à l'intérieur des améliorations",
|
||||
["Show Empty Buttons"] = "Afficher les boutons vides",
|
||||
["Show FPS and Latency Colors"] = nil,
|
||||
@@ -739,6 +741,7 @@ pfUI_translation["frFR"] = {
|
||||
["Show Required Questitem Count"] = nil,
|
||||
["Show Resting"] = "Afficher au repos",
|
||||
["Show Self In Group Frames"] = "S'afficher dans les cadres de groupe",
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = "Afficher l'icone des sorts",
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = "Afficher les empilements",
|
||||
@@ -783,6 +786,7 @@ pfUI_translation["frFR"] = {
|
||||
["Target Castbar"] = "Barre d'incantation de la cible",
|
||||
["Target Debuff Bar"] = "Barre des affaiblissements de la cible",
|
||||
["Target Nameplate Zoom Factor"] = "Facteur de zoom du Nameplate de la cible",
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = "Cible de la cible",
|
||||
["Target-Target-Target"] = "Cible de la cible de la cible",
|
||||
["Text"] = nil,
|
||||
@@ -877,7 +881,6 @@ pfUI_translation["frFR"] = {
|
||||
["XP Percentage"] = "Pourcentage de la barre d'expérience",
|
||||
["Yellow Border On Neutral Units"] = "Bordure jaune sur les unités neutres",
|
||||
["Yes"] = "Oui",
|
||||
["You gain (.+) Mana from Totemic Recall"] = nil,
|
||||
["You got"] = "Vous avez",
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = nil,
|
||||
["Your items have been repaired for"] = "Vos objets ont été réparés pour",
|
||||
|
||||
Vendored
+7
-4
@@ -27,7 +27,6 @@ pfUI_translation["koKR"] = {
|
||||
["Always Show Item Comparison"] = "항상 착용 장비와 비교 표시",
|
||||
["Always Show On Target Units"] = nil,
|
||||
["Always Show On Units With Missing HP"] = nil,
|
||||
["Always Show Self In Raid Frames"] = nil,
|
||||
["Always Use 2D Portraits"] = "항상 2D초상화 사용",
|
||||
["Ammo Counter"] = "탄약 갯수",
|
||||
["Anchor Bags Above Chat"] = nil,
|
||||
@@ -124,6 +123,7 @@ pfUI_translation["koKR"] = {
|
||||
["Click Casting"] = nil,
|
||||
["Clock"] = "시계",
|
||||
["Close"] = "닫기",
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = nil,
|
||||
["Color Buff Stacks"] = nil,
|
||||
["Color Debuff Stacks"] = nil,
|
||||
@@ -138,7 +138,6 @@ pfUI_translation["koKR"] = {
|
||||
["Combat Timer"] = "전투 타이머",
|
||||
["Combopoint Height"] = nil,
|
||||
["Combopoint Width"] = nil,
|
||||
["Compare Item Base Stats"] = nil,
|
||||
["Components"] = nil,
|
||||
["Config UI Settings"] = nil,
|
||||
["Configuration"] = "구성",
|
||||
@@ -569,6 +568,7 @@ pfUI_translation["koKR"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = nil,
|
||||
["Overwrite If Unit Is Attacking You"] = nil,
|
||||
["Overwrite If Unit Is Casting"] = nil,
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = nil,
|
||||
["Paging Actionbar"] = nil,
|
||||
["Panel"] = "패널",
|
||||
@@ -616,12 +616,13 @@ pfUI_translation["koKR"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = nil,
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = nil,
|
||||
["Random Roll Announcement Rarity"] = nil,
|
||||
["Random Rolling"] = nil,
|
||||
["Range Based Hunter Paging"] = nil,
|
||||
["Range Check Interval"] = nil,
|
||||
["Rank"] = nil,
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = nil,
|
||||
["Red Name Text On Infight Units"] = nil,
|
||||
["Regional Settings"] = nil,
|
||||
@@ -703,6 +704,7 @@ pfUI_translation["koKR"] = {
|
||||
["Show Description"] = nil,
|
||||
["Show Dispel Indicators"] = nil,
|
||||
["Show Druid Mana Bar"] = nil,
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = nil,
|
||||
["Show Empty Buttons"] = nil,
|
||||
["Show FPS and Latency Colors"] = nil,
|
||||
@@ -739,6 +741,7 @@ pfUI_translation["koKR"] = {
|
||||
["Show Required Questitem Count"] = nil,
|
||||
["Show Resting"] = nil,
|
||||
["Show Self In Group Frames"] = nil,
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
@@ -783,6 +786,7 @@ pfUI_translation["koKR"] = {
|
||||
["Target Castbar"] = nil,
|
||||
["Target Debuff Bar"] = nil,
|
||||
["Target Nameplate Zoom Factor"] = nil,
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = "대상-대상",
|
||||
["Target-Target-Target"] = nil,
|
||||
["Text"] = nil,
|
||||
@@ -877,7 +881,6 @@ pfUI_translation["koKR"] = {
|
||||
["XP Percentage"] = "경험치 퍼센트",
|
||||
["Yellow Border On Neutral Units"] = nil,
|
||||
["Yes"] = nil,
|
||||
["You gain (.+) Mana from Totemic Recall"] = nil,
|
||||
["You got"] = nil,
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = nil,
|
||||
["Your items have been repaired for"] = nil,
|
||||
|
||||
Vendored
+7
-4
@@ -27,7 +27,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Always Show Item Comparison"] = "Всегда показывать сравнение предметов",
|
||||
["Always Show On Target Units"] = "Всегда показывать над выбранной целью",
|
||||
["Always Show On Units With Missing HP"] = "Всегда показывать над целями с неполным здоровьем",
|
||||
["Always Show Self In Raid Frames"] = "Всегда показывать себя в рейде",
|
||||
["Always Use 2D Portraits"] = "Всегда использовать 2D-портреты",
|
||||
["Ammo Counter"] = "Счетчик боеприпасов",
|
||||
["Anchor Bags Above Chat"] = nil,
|
||||
@@ -124,6 +123,7 @@ pfUI_translation["ruRU"] = {
|
||||
["Click Casting"] = "Каст по нажатию",
|
||||
["Clock"] = "Часы",
|
||||
["Close"] = "Закрыть",
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = nil,
|
||||
["Color Buff Stacks"] = "Цвет стаков баффа",
|
||||
["Color Debuff Stacks"] = "Цвет стаков дебаффа",
|
||||
@@ -138,7 +138,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Combat Timer"] = "Таймер боя",
|
||||
["Combopoint Height"] = nil,
|
||||
["Combopoint Width"] = nil,
|
||||
["Compare Item Base Stats"] = "Сравнивать базовые характеристики предмета",
|
||||
["Components"] = "Компоненты",
|
||||
["Config UI Settings"] = "Настройка параметров пользовательского интерфейса",
|
||||
["Configuration"] = "Конфигурация",
|
||||
@@ -569,6 +568,7 @@ pfUI_translation["ruRU"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = nil,
|
||||
["Overwrite If Unit Is Attacking You"] = nil,
|
||||
["Overwrite If Unit Is Casting"] = nil,
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = "Прокрутка страниц",
|
||||
["Paging Actionbar"] = "Прокрутка панелей",
|
||||
["Panel"] = "Панель",
|
||||
@@ -616,12 +616,13 @@ pfUI_translation["ruRU"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = "Отступ рейда",
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = "Случайно",
|
||||
["Random Roll Announcement Rarity"] = "Оповещение случайного броска для качества предмета",
|
||||
["Random Rolling"] = "Случайный бросок костей для",
|
||||
["Range Based Hunter Paging"] = "[|cffA9D271Охотник|r] Переключение страниц на основе диапазона",
|
||||
["Range Check Interval"] = "Интервал проверки диапазона",
|
||||
["Rank"] = "Ранг",
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = "Красные границы вражеских юнитов",
|
||||
["Red Name Text On Infight Units"] = nil,
|
||||
["Regional Settings"] = "Региональные настройки",
|
||||
@@ -703,6 +704,7 @@ pfUI_translation["ruRU"] = {
|
||||
["Show Description"] = "Показать описание",
|
||||
["Show Dispel Indicators"] = "Показать индикаторы рассеивания",
|
||||
["Show Druid Mana Bar"] = nil,
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = "Показать продолжительность внутри баффа",
|
||||
["Show Empty Buttons"] = "Показать пустые кнопки",
|
||||
["Show FPS and Latency Colors"] = "Показать частоту кадров и задержку в цвете",
|
||||
@@ -739,6 +741,7 @@ pfUI_translation["ruRU"] = {
|
||||
["Show Required Questitem Count"] = "Показать необходимое количество предметов для задания",
|
||||
["Show Resting"] = "Показать иконку отдыха",
|
||||
["Show Self In Group Frames"] = "Показать себя в окне группы",
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = "Показать иконку заклинания",
|
||||
["Show Spell Name"] = "Показать название заклинания",
|
||||
["Show Stacks"] = "Показать стаки",
|
||||
@@ -783,6 +786,7 @@ pfUI_translation["ruRU"] = {
|
||||
["Target Castbar"] = "Панель применения цели",
|
||||
["Target Debuff Bar"] = "Панель дебаффов цели",
|
||||
["Target Nameplate Zoom Factor"] = "Коэффициент увеличения индикатора здоровья цели",
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = "Цель цели",
|
||||
["Target-Target-Target"] = "Цель цели цели",
|
||||
["Text"] = nil,
|
||||
@@ -877,7 +881,6 @@ pfUI_translation["ruRU"] = {
|
||||
["XP Percentage"] = "Процент опыта",
|
||||
["Yellow Border On Neutral Units"] = "Желтые границы на нейтральных юнитах",
|
||||
["Yes"] = "Да",
|
||||
["You gain (.+) Mana from Totemic Recall"] = nil,
|
||||
["You got"] = "Вы получили",
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = "Теперь ваш интерфейс настроен.\n\nДля расширенной настройки откройте \"Настройки |cff33ffccpf|rUI\" с помощью escape меню или введите \"|cffffffaa/pfui|r\" в чат.\n\nЖелаю хорошего путешествия!\n\n|cffaaaaaa- Shagu",
|
||||
["Your items have been repaired for"] = "Ваши предметы были отремонтированы за",
|
||||
|
||||
Vendored
+7
-4
@@ -27,7 +27,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Always Show Item Comparison"] = "始终显示装备比较(或按SHIFT键)",
|
||||
["Always Show On Target Units"] = "始终在目标单位上显示",
|
||||
["Always Show On Units With Missing HP"] = "始终在未满血单位上显示",
|
||||
["Always Show Self In Raid Frames"] = "始终在团队框架中显示自己",
|
||||
["Always Use 2D Portraits"] = "始终使用2D头像",
|
||||
["Ammo Counter"] = "弹药数量",
|
||||
["Anchor Bags Above Chat"] = "将背包锚定在聊天框上方",
|
||||
@@ -124,6 +123,7 @@ pfUI_translation["zhCN"] = {
|
||||
["Click Casting"] = "点击施法",
|
||||
["Clock"] = "时间",
|
||||
["Close"] = "关闭",
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = "颜色",
|
||||
["Color Buff Stacks"] = "Buff堆叠颜色",
|
||||
["Color Debuff Stacks"] = "Debuff堆叠颜色",
|
||||
@@ -138,7 +138,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Combat Timer"] = "战斗计时器",
|
||||
["Combopoint Height"] = "连击点高度",
|
||||
["Combopoint Width"] = "连击点宽度",
|
||||
["Compare Item Base Stats"] = "基于属性的装备对比",
|
||||
["Components"] = "组件",
|
||||
["Config UI Settings"] = "界面设置",
|
||||
["Configuration"] = "配置",
|
||||
@@ -569,6 +568,7 @@ pfUI_translation["zhCN"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = "如果单位正在攻击其它单位则变色",
|
||||
["Overwrite If Unit Is Attacking You"] = "如果单位正在攻击你则变色",
|
||||
["Overwrite If Unit Is Casting"] = "如果单位正在施法则变色",
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = "可分页",
|
||||
["Paging Actionbar"] = "分页动作条",
|
||||
["Panel"] = "面板",
|
||||
@@ -616,12 +616,13 @@ pfUI_translation["zhCN"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = "团队填充",
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = "给随机玩家",
|
||||
["Random Roll Announcement Rarity"] = "随机Roll点稀有度",
|
||||
["Random Rolling"] = "随机Roll点 物品:",
|
||||
["Range Based Hunter Paging"] = "启用基于范围的自动分页[|cff7fff7f猎人|r]",
|
||||
["Range Check Interval"] = "范围检查间隔",
|
||||
["Rank"] = "军衔",
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = "显示敌方单位红色边框",
|
||||
["Red Name Text On Infight Units"] = "进战斗的单位显示红色姓名",
|
||||
["Regional Settings"] = "区域设置",
|
||||
@@ -703,6 +704,7 @@ pfUI_translation["zhCN"] = {
|
||||
["Show Description"] = "显示描述",
|
||||
["Show Dispel Indicators"] = "显示驱散指示器",
|
||||
["Show Druid Mana Bar"] = "显示德鲁伊法力条",
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = "显示持续时间在Buff里面",
|
||||
["Show Empty Buttons"] = "显示空按钮",
|
||||
["Show FPS and Latency Colors"] = "显示帧数以及延迟颜色",
|
||||
@@ -740,6 +742,7 @@ pfUI_translation["zhCN"] = {
|
||||
["Show Required Questitem Count"] = "显示所需的任务物品计数",
|
||||
["Show Resting"] = "显示休息图标",
|
||||
["Show Self In Group Frames"] = "在队伍框架中显示自己",
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = "显示技能图标",
|
||||
["Show Spell Name"] = "显示技能名称",
|
||||
["Show Stacks"] = "显示堆叠",
|
||||
@@ -784,6 +787,7 @@ pfUI_translation["zhCN"] = {
|
||||
["Target Castbar"] = "目标施法条",
|
||||
["Target Debuff Bar"] = "目标Debuffs条",
|
||||
["Target Nameplate Zoom Factor"] = "目标姓名板缩放系数",
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = "目标的目标",
|
||||
["Target-Target-Target"] = "目标的目标的目标",
|
||||
["Text"] = "文本",
|
||||
@@ -878,7 +882,6 @@ pfUI_translation["zhCN"] = {
|
||||
["XP Percentage"] = "经验百分比",
|
||||
["Yellow Border On Neutral Units"] = "显示中立单位黄色边框",
|
||||
["Yes"] = "是",
|
||||
["You gain (.+) Mana from Totemic Recall"] = "你从图腾召回获得了(.+)点法力值",
|
||||
["You got"] = "你已得到",
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = "你的界面现在已经完成设置.高级设置请点击游戏菜单或者输入命令/pfui进行设置.祝您游戏愉快",
|
||||
["Your items have been repaired for"] = "你的物品已经修好了",
|
||||
|
||||
Vendored
+7
-4
@@ -27,7 +27,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Always Show Item Comparison"] = "始終顯示裝備比較",
|
||||
["Always Show On Target Units"] = nil,
|
||||
["Always Show On Units With Missing HP"] = nil,
|
||||
["Always Show Self In Raid Frames"] = nil,
|
||||
["Always Use 2D Portraits"] = "始終使用2D頭像",
|
||||
["Ammo Counter"] = "彈藥數量",
|
||||
["Anchor Bags Above Chat"] = nil,
|
||||
@@ -124,6 +123,7 @@ pfUI_translation["zhTW"] = {
|
||||
["Click Casting"] = nil,
|
||||
["Clock"] = "時間",
|
||||
["Close"] = "關閉",
|
||||
["Collapse Empty Slots"] = nil,
|
||||
["Color"] = nil,
|
||||
["Color Buff Stacks"] = nil,
|
||||
["Color Debuff Stacks"] = nil,
|
||||
@@ -138,7 +138,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Combat Timer"] = "戰鬥計時器",
|
||||
["Combopoint Height"] = nil,
|
||||
["Combopoint Width"] = nil,
|
||||
["Compare Item Base Stats"] = "基於屬性的裝備對比",
|
||||
["Components"] = "組件",
|
||||
["Config UI Settings"] = nil,
|
||||
["Configuration"] = "配置",
|
||||
@@ -569,6 +568,7 @@ pfUI_translation["zhTW"] = {
|
||||
["Overwrite If Unit Is Attacking Others"] = "如果单位正在攻擊其它单位則覆蓋",
|
||||
["Overwrite If Unit Is Attacking You"] = "如果单位正在攻擊你則覆蓋",
|
||||
["Overwrite If Unit Is Casting"] = "如果单位正在施法則覆蓋",
|
||||
["Owner Name"] = nil,
|
||||
["Pageable"] = nil,
|
||||
["Paging Actionbar"] = nil,
|
||||
["Panel"] = "面板",
|
||||
@@ -616,12 +616,13 @@ pfUI_translation["zhTW"] = {
|
||||
["Raid Mark X-Offset"] = nil,
|
||||
["Raid Mark Y-Offset"] = nil,
|
||||
["Raid Padding"] = nil,
|
||||
["Raid-Pet"] = nil,
|
||||
["Random"] = "給隨機玩家",
|
||||
["Random Roll Announcement Rarity"] = "隨機Roll點公示稀有度",
|
||||
["Random Rolling"] = "隨機Roll點 物品:",
|
||||
["Range Based Hunter Paging"] = nil,
|
||||
["Range Check Interval"] = "範圍檢查間隔",
|
||||
["Rank"] = nil,
|
||||
["Recast Totem"] = nil,
|
||||
["Red Border On Enemy Units"] = nil,
|
||||
["Red Name Text On Infight Units"] = nil,
|
||||
["Regional Settings"] = nil,
|
||||
@@ -703,6 +704,7 @@ pfUI_translation["zhTW"] = {
|
||||
["Show Description"] = nil,
|
||||
["Show Dispel Indicators"] = nil,
|
||||
["Show Druid Mana Bar"] = nil,
|
||||
["Show Druid Mana Bar Text"] = nil,
|
||||
["Show Duration Inside Buff"] = "顯示持續時間在Buff裏面",
|
||||
["Show Empty Buttons"] = nil,
|
||||
["Show FPS and Latency Colors"] = nil,
|
||||
@@ -739,6 +741,7 @@ pfUI_translation["zhTW"] = {
|
||||
["Show Required Questitem Count"] = nil,
|
||||
["Show Resting"] = nil,
|
||||
["Show Self In Group Frames"] = nil,
|
||||
["Show Self In Raid Frames When Solo"] = nil,
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
@@ -783,6 +786,7 @@ pfUI_translation["zhTW"] = {
|
||||
["Target Castbar"] = nil,
|
||||
["Target Debuff Bar"] = nil,
|
||||
["Target Nameplate Zoom Factor"] = nil,
|
||||
["Target Totem"] = nil,
|
||||
["Target-Target"] = "目標的目標",
|
||||
["Target-Target-Target"] = nil,
|
||||
["Text"] = nil,
|
||||
@@ -877,7 +881,6 @@ pfUI_translation["zhTW"] = {
|
||||
["XP Percentage"] = "經驗百分比",
|
||||
["Yellow Border On Neutral Units"] = nil,
|
||||
["Yes"] = nil,
|
||||
["You gain (.+) Mana from Totemic Recall"] = nil,
|
||||
["You got"] = nil,
|
||||
["Your interface is now set up.\n\nFor advanced configuration, just open the |cff33ffccpf|rUI settings via the escape menu or type \"|cffffffaa/pfui|r\" into the chat.\n\n Have a nice trip!\n\n|cffaaaaaa- Shagu"] = "您的UI已經設置完畢.使用遊戲菜單或在聊天窗口輸入\"|cffffffaa/pfui|r\"開啟高級設置.祝您遊戲愉快!\n\n|cffaaaaaa- Shagu",
|
||||
["Your items have been repaired for"] = "你的物品已經修好了",
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
<Include file="..\libs\libdebuff.lua"/>
|
||||
<Include file="..\libs\librange.lua"/>
|
||||
<Include file="..\libs\libunitscan.lua"/>
|
||||
<Include file="..\libs\libtooltip.lua"/>
|
||||
<Include file="..\libs\libhealth.lua"/>
|
||||
<Include file="..\libs\libtotem.lua"/>
|
||||
<Include file="..\libs\libthrottle.lua"/>
|
||||
<Include file="..\libs\libpredict.lua"/>
|
||||
<Include file="..\libs\libbagsort.lua"/>
|
||||
|
||||
@@ -78,4 +78,6 @@
|
||||
<Include file="..\modules\unitxp.lua"/>
|
||||
<Include file="..\modules\bgscore.lua"/>
|
||||
<Include file="..\modules\equipmentmanager.lua"/>
|
||||
<Include file="..\modules\loothistory.lua"/>
|
||||
<Include file="..\modules\newitem.lua"/>
|
||||
</Ui>
|
||||
@@ -1,5 +1,6 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Include file="..\skins\blizzard\character.lua"/>
|
||||
<Include file="..\skins\blizzard\inspect.lua"/>
|
||||
<Include file="..\skins\blizzard\spellbook.lua"/>
|
||||
<Include file="..\skins\blizzard\friends.lua"/>
|
||||
<Include file="..\skins\blizzard\talents.lua"/>
|
||||
|
||||
+123
-63
@@ -11,26 +11,27 @@ pfUI.api.libbagsort = libbagsort
|
||||
libbagsort.itemGrid = {}
|
||||
libbagsort.bagList = nil
|
||||
|
||||
local HEARTHSTONE_ITEM_ID = 6948
|
||||
local ItemClass = Enum.ItemClass
|
||||
local ItemQuality = Enum.ItemQuality
|
||||
|
||||
-- Lower prefix = sorted earlier in the bag.
|
||||
local function SortCategoryPrefix(itemId, itemType, itemSubType, quality)
|
||||
if itemId == HEARTHSTONE_ITEM_ID then return "00" end
|
||||
if quality == 0 then return "13" end -- Poor (gray) always last
|
||||
if itemType == "Weapon" or itemType == "Armor" then
|
||||
if quality and quality >= 4 then return "01" end -- Epic+ gear
|
||||
if quality == 3 then return "02" end -- Rare gear
|
||||
if quality == 2 then return "03" end -- Uncommon gear
|
||||
return "04" -- Common/poor gear
|
||||
local function SortCategoryPrefix(itemId, classID, quality)
|
||||
if itemId == HEARTHSTONE_ITEM_ID then return "00" end
|
||||
if quality == ItemQuality.Poor then return "13" end -- gray always last
|
||||
if classID == ItemClass.Weapon or classID == ItemClass.Armor then
|
||||
if quality and quality >= ItemQuality.Epic then return "01" end -- Epic+ gear
|
||||
if quality == ItemQuality.Rare then return "02" end -- Rare gear
|
||||
if quality == ItemQuality.Uncommon then return "03" end -- Uncommon gear
|
||||
return "04" -- Common/poor gear
|
||||
end
|
||||
if itemType == "Consumable" then return "05" end
|
||||
if itemType == "Reagent" then return "06" end
|
||||
if itemType == "Trade Goods" then return "07" end
|
||||
if itemType == "Quest" then return "08" end
|
||||
if classID == ItemClass.Consumable then return "05" end
|
||||
if classID == ItemClass.Reagent then return "06" end
|
||||
if classID == ItemClass.Tradegoods then return "07" end
|
||||
if classID == ItemClass.Questitem then return "08" end
|
||||
-- Non-gear items without a specific type, sorted by quality
|
||||
if quality and quality >= 4 then return "09" end
|
||||
if quality == 3 then return "10" end
|
||||
if quality == 2 then return "11" end
|
||||
if quality and quality >= ItemQuality.Epic then return "09" end
|
||||
if quality == ItemQuality.Rare then return "10" end
|
||||
if quality == ItemQuality.Uncommon then return "11" end
|
||||
return "12"
|
||||
end
|
||||
|
||||
@@ -41,18 +42,31 @@ local function SortCountSuffix(count)
|
||||
return string.sub(s, -6)
|
||||
end
|
||||
|
||||
local function SortKey(itemId, name, itype, subtype, quality, count)
|
||||
return SortCategoryPrefix(itemId, itype, subtype, quality)
|
||||
.. (itype or "") .. "|" .. (subtype or "") .. "|" .. (name or "zzz") .. "|" .. SortCountSuffix(count)
|
||||
local function SortKey(itemId, name, classID, subClassID, quality, count)
|
||||
-- Zero-pad the class/subclass so the secondary grouping sorts numerically
|
||||
-- (as a string, "10" would otherwise precede "2").
|
||||
return SortCategoryPrefix(itemId, classID, quality)
|
||||
.. string.format("%02d|%02d|", classID or 99, subClassID or 99)
|
||||
.. (name or "zzz") .. "|" .. SortCountSuffix(count)
|
||||
end
|
||||
|
||||
local function ClearSortData()
|
||||
libbagsort.itemGrid = {}
|
||||
libbagsort.bagList = nil
|
||||
libbagsort.opts = nil
|
||||
libbagsort:UnregisterEvent("BAG_UPDATE_DELAYED")
|
||||
libbagsort:SetScript("OnEvent", nil)
|
||||
end
|
||||
|
||||
local function ReverseArray(t)
|
||||
local i, j = 1, table.getn(t)
|
||||
while i < j do
|
||||
t[i], t[j] = t[j], t[i]
|
||||
i = i + 1
|
||||
j = j - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Two-pointer consolidation: sorts stacks largest-first, then merges from
|
||||
-- both ends toward the middle. n is set explicitly so table.getn / table.sort
|
||||
-- work correctly in Lua 5.0.
|
||||
@@ -112,36 +126,61 @@ local function BuildConsolidateOps(bagList)
|
||||
return ops
|
||||
end
|
||||
|
||||
-- Bag family bitmask (1 << (familyID-1)); 0 = general-purpose (holds
|
||||
-- anything). Backpack (0) and bank (-1) are always general. A specialty
|
||||
-- bag's family comes from the equipped bag item -- ClassicAPI derives it
|
||||
-- from the container subclass when the raw field is empty (Turtle leaves
|
||||
-- bags' m_bagFamily at 0), so quivers/soul/profession bags report properly.
|
||||
local function BagFamily(bag)
|
||||
if bag == 0 or bag == -1 then return 0 end
|
||||
local id = GetInventoryItemID("player", ContainerIDToInventoryID(bag))
|
||||
return id and C_Item.GetItemFamily(id) or 0
|
||||
end
|
||||
|
||||
local function BuildSortGrid()
|
||||
local bagList = libbagsort.bagList
|
||||
libbagsort.itemGrid = {}
|
||||
local normalItems = {}
|
||||
local poorItems = {}
|
||||
local bagCount = 0
|
||||
local bagSlots = {}
|
||||
|
||||
-- Destination cells, split by the family they can accept. A specialty
|
||||
-- bag's slots only take items of its own family; general slots take
|
||||
-- anything. Cells are collected in forward order (bag order, slot 1..n).
|
||||
local generalCells = {} -- { {bag=,slot=}, ... }
|
||||
local specialtyCells = {} -- family -> { {bag=,slot=}, ... }
|
||||
|
||||
for _, bag in ipairs(bagList) do
|
||||
bagCount = bagCount + 1
|
||||
local fam = BagFamily(bag)
|
||||
local numSlots = GetContainerNumSlots(bag)
|
||||
bagSlots[bagCount] = numSlots
|
||||
if numSlots > 0 then
|
||||
libbagsort.itemGrid[bag] = {}
|
||||
for slot = 1, numSlots do
|
||||
if fam == 0 then
|
||||
tinsert(generalCells, {bag=bag, slot=slot})
|
||||
else
|
||||
specialtyCells[fam] = specialtyCells[fam] or {}
|
||||
tinsert(specialtyCells[fam], {bag=bag, slot=slot})
|
||||
end
|
||||
|
||||
local itemId = C_Container.GetContainerItemID(bag, slot)
|
||||
if itemId then
|
||||
-- pfUI's compat layer shims GetItemInfo to the modern 10-field
|
||||
-- signature (inserts nil for itemLevel between quality and
|
||||
-- minlevel) — so itype/subtype sit at positions 6/7, not 5/6.
|
||||
local name, _, quality, _, _, itype, subtype = GetItemInfo(itemId)
|
||||
-- C_Item.GetItemInfo is the full 18-field tuple; classID/subClassID
|
||||
-- sit at positions 12/13. We categorize on those numeric class IDs
|
||||
-- rather than the localized itemType/itemSubType strings. (pfUI's
|
||||
-- shimmed global GetItemInfo is only 10 fields and lacks them.)
|
||||
local name, _, quality, _, _, _, _, _, _, _, _, classID, subClassID = C_Item.GetItemInfo(itemId)
|
||||
local _, count = GetContainerItemInfo(bag, slot)
|
||||
local item = {
|
||||
key = SortKey(itemId, name, itype, subtype, quality, count),
|
||||
key = SortKey(itemId, name, classID, subClassID, quality, count),
|
||||
-- vanilla items carry at most one family bit, so equality
|
||||
-- against a bag family suffices (no bit.band needed).
|
||||
family = C_Item.GetItemFamily(itemId) or 0,
|
||||
srcBag = bag,
|
||||
srcSlot = slot,
|
||||
curBag = bag,
|
||||
curSlot = slot,
|
||||
}
|
||||
if quality == 0 then
|
||||
if quality == ItemQuality.Poor then
|
||||
tinsert(poorItems, item)
|
||||
else
|
||||
tinsert(normalItems, item)
|
||||
@@ -152,46 +191,61 @@ local function BuildSortGrid()
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(normalItems, function(a, b) return a.key < b.key end)
|
||||
-- Sort poor items descending so they read in ascending order when placed
|
||||
-- back-to-front (last poor item lands on the last slot).
|
||||
table.sort(poorItems, function(a, b) return a.key > b.key end)
|
||||
local opts = libbagsort.opts or {}
|
||||
local reverse = opts.reverse
|
||||
local reversePrio = opts.reversePrio
|
||||
|
||||
-- Forward pass: assign normal items from slot 1 of bag 1 onward
|
||||
local bagIdx, destSlot = 1, 1
|
||||
while bagIdx <= bagCount and bagSlots[bagIdx] == 0 do
|
||||
bagIdx = bagIdx + 1
|
||||
if reverse then
|
||||
ReverseArray(generalCells)
|
||||
for _, cells in pairs(specialtyCells) do
|
||||
ReverseArray(cells)
|
||||
end
|
||||
end
|
||||
|
||||
if reversePrio then
|
||||
table.sort(normalItems, function(a, b) return a.key > b.key end)
|
||||
else
|
||||
table.sort(normalItems, function(a, b) return a.key < b.key end)
|
||||
end
|
||||
|
||||
if reverse then
|
||||
table.sort(poorItems, function(a, b) return a.key < b.key end)
|
||||
else
|
||||
table.sort(poorItems, function(a, b) return a.key > b.key end)
|
||||
end
|
||||
|
||||
-- Forward pass: route each normal item into the next free cell that
|
||||
-- accepts it -- a matching specialty bag first, overflowing to general.
|
||||
local genIdx = 1
|
||||
local specIdx = {} -- family -> next free index into specialtyCells[family]
|
||||
for _, item in ipairs(normalItems) do
|
||||
while bagIdx <= bagCount do
|
||||
if destSlot <= bagSlots[bagIdx] then break end
|
||||
bagIdx = bagIdx + 1
|
||||
destSlot = 1
|
||||
local cell
|
||||
local fam = item.family
|
||||
if fam ~= 0 and specialtyCells[fam] then
|
||||
local i = specIdx[fam] or 1
|
||||
if i <= table.getn(specialtyCells[fam]) then
|
||||
cell = specialtyCells[fam][i]
|
||||
specIdx[fam] = i + 1
|
||||
end
|
||||
end
|
||||
if bagIdx > bagCount then break end
|
||||
local grid = libbagsort.itemGrid[item.srcBag][item.srcSlot]
|
||||
grid.destBag = bagList[bagIdx]
|
||||
grid.destSlot = destSlot
|
||||
destSlot = destSlot + 1
|
||||
if not cell and genIdx <= table.getn(generalCells) then
|
||||
cell = generalCells[genIdx]
|
||||
genIdx = genIdx + 1
|
||||
end
|
||||
if not cell then break end
|
||||
item.destBag = cell.bag
|
||||
item.destSlot = cell.slot
|
||||
end
|
||||
|
||||
-- Reverse pass: assign poor items from the last slot of the last bag backward
|
||||
local rBagIdx = bagCount
|
||||
local rDestSlot = 0
|
||||
while rBagIdx >= 1 do
|
||||
if bagSlots[rBagIdx] > 0 then rDestSlot = bagSlots[rBagIdx]; break end
|
||||
rBagIdx = rBagIdx - 1
|
||||
end
|
||||
-- Reverse pass: poor items are general; fill remaining general cells from
|
||||
-- the back, stopping before the ones the forward pass already claimed.
|
||||
local genBack = table.getn(generalCells)
|
||||
for _, item in ipairs(poorItems) do
|
||||
while rBagIdx >= 1 and rDestSlot < 1 do
|
||||
rBagIdx = rBagIdx - 1
|
||||
rDestSlot = rBagIdx >= 1 and bagSlots[rBagIdx] or 0
|
||||
end
|
||||
if rBagIdx < 1 then break end
|
||||
local grid = libbagsort.itemGrid[item.srcBag][item.srcSlot]
|
||||
grid.destBag = bagList[rBagIdx]
|
||||
grid.destSlot = rDestSlot
|
||||
rDestSlot = rDestSlot - 1
|
||||
if genBack < genIdx then break end
|
||||
local cell = generalCells[genBack]
|
||||
genBack = genBack - 1
|
||||
item.destBag = cell.bag
|
||||
item.destSlot = cell.slot
|
||||
end
|
||||
end
|
||||
|
||||
@@ -248,9 +302,15 @@ end
|
||||
-- BAG_UPDATE_DELAYED cycle), then place items by category/name/quality.
|
||||
-- e.g. `libbagsort:Sort({0, 1, 2, 3, 4})` for the main bags;
|
||||
-- `{-1, 5, 6, 7, 8, 9, 10}` for the bank.
|
||||
function libbagsort:Sort(bagList)
|
||||
--
|
||||
-- opts (optional): { reverse = bool, reversePrio = bool }
|
||||
-- reverse - place the first-ranked item into the last slot of the last
|
||||
-- bag (junk fills from the opposite end).
|
||||
-- reversePrio - flip the category ranking (e.g. hearthstone sorts last).
|
||||
function libbagsort:Sort(bagList, opts)
|
||||
ClearSortData()
|
||||
self.bagList = bagList
|
||||
self.opts = opts
|
||||
|
||||
-- Phase 1: fire every consolidation op in a single batch.
|
||||
local ops = BuildConsolidateOps(bagList)
|
||||
|
||||
+58
-7
@@ -11,12 +11,14 @@ setfenv(1, pfUI:GetEnvironment())
|
||||
-- This eliminates ~400 lines of error-prone shift logic while maintaining full
|
||||
-- multi-caster tracking support.
|
||||
--
|
||||
-- The public per-aura readers (UnitDebuff, UnitOwnDebuff) were retired in favor
|
||||
-- of ClassicAPI's C_UnitAuras (which now provides sourceUnit/sourceGUID and
|
||||
-- non-player expirationTime). What remains in libdebuff is the cast-event
|
||||
-- bookkeeping consumed by GetBestAuraCast (libpredict HoT tracking) and the
|
||||
-- libdebuff_*_hooks broadcast surface (subscribers in actionbar / swingtimer
|
||||
-- / libtotem react to SPELL_GO and SPELL_FAILED).
|
||||
-- The internal debuff plumbing now runs on ClassicAPI's C_UnitAuras (which
|
||||
-- provides sourceUnit/sourceGUID and non-player expirationTime). The public
|
||||
-- per-aura readers (UnitDebuff, UnitOwnDebuff) survive only as thin adapters
|
||||
-- over C_UnitAuras for third-party addons (e.g. pfUI-WeakIcons) that still
|
||||
-- expect the legacy multi-return signature. The rest of libdebuff is the
|
||||
-- cast-event bookkeeping consumed by GetBestAuraCast (libpredict HoT tracking)
|
||||
-- and the libdebuff_*_hooks broadcast surface (subscribers in actionbar /
|
||||
-- swingtimer react to SPELL_GO and SPELL_FAILED).
|
||||
|
||||
-- return instantly when another libdebuff is already active
|
||||
if pfUI.api.libdebuff then return end
|
||||
@@ -762,6 +764,55 @@ function libdebuff:GetBestAuraCast(guid, spellName)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- API: UnitDebuff / UnitOwnDebuff (C_UnitAuras adapters)
|
||||
-- ============================================================================
|
||||
-- Thin readers kept for third-party addons (e.g. pfUI-WeakIcons) that still
|
||||
-- expect libdebuff's legacy multi-return signature:
|
||||
-- effect, rank, texture, stacks, dtype, duration, timeleft, caster
|
||||
-- ClassicAPI's C_UnitAuras already resolves source and expiration, so these
|
||||
-- just remap its AuraData onto that tuple -- no cast-tracking tables
|
||||
-- (ownDebuffs/allAuraCasts) or GetUnitField slot mapping involved.
|
||||
|
||||
local function AuraToLegacy(aura)
|
||||
if not aura then return nil end
|
||||
|
||||
local duration = aura.duration or 0
|
||||
local timeleft = -1
|
||||
-- Only report a timer for genuinely timed auras. ClassicAPI can leave a
|
||||
-- stale expirationTime on permanent (duration 0) auras, so gate on duration.
|
||||
if duration > 0 and aura.expirationTime and aura.expirationTime > 0 then
|
||||
timeleft = aura.expirationTime - GetTime()
|
||||
if timeleft < 0 then timeleft = 0 end
|
||||
end
|
||||
|
||||
-- Aura spellId is the specific cast rank, so its subtext is the active rank.
|
||||
local rank
|
||||
local subtext = aura.spellId and C_Spell.GetSpellSubtext(aura.spellId)
|
||||
if subtext and subtext ~= "" then
|
||||
rank = tonumber((string.gsub(subtext, "Rank ", "")))
|
||||
end
|
||||
|
||||
local dtype = aura.dispelName
|
||||
if dtype == "" then dtype = nil end
|
||||
|
||||
local caster = aura.isFromPlayerOrPlayerPet and "player" or "other"
|
||||
|
||||
return aura.name, rank, aura.icon, aura.applications or 0, dtype, duration, timeleft, caster
|
||||
end
|
||||
|
||||
-- id is a 1-based harmful-aura index, matching C_UnitAuras / Blizzard's
|
||||
-- compacted debuff slots.
|
||||
function libdebuff:UnitDebuff(unit, id)
|
||||
return AuraToLegacy(C_UnitAuras.GetAuraDataByIndex(unit, id, "HARMFUL"))
|
||||
end
|
||||
|
||||
-- Player-cast harmful auras only, via the PLAYER filter -- no manual
|
||||
-- caster-GUID bookkeeping needed.
|
||||
function libdebuff:UnitOwnDebuff(unit, id)
|
||||
return AuraToLegacy(C_UnitAuras.GetAuraDataByIndex(unit, id, "HARMFUL|PLAYER"))
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- NAMPOWER EVENT HANDLING
|
||||
-- ============================================================================
|
||||
@@ -1125,7 +1176,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
|
||||
|
||||
+9
-10
@@ -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)
|
||||
@@ -897,7 +895,7 @@ local INSTANT_HOT_COOLDOWN = 1.0 -- 1 Sekunde Cooldown (GCD ist 1.5s)
|
||||
local pendingHots = {}
|
||||
|
||||
-- Gather Data by User Actions
|
||||
pfUI.hooksecurefunc("CastSpell", function(id, bookType)
|
||||
hooksecurefunc("CastSpell", function(id, bookType)
|
||||
if not libpredict.sender.enabled then return end
|
||||
local effect, rank = libspell.GetSpellInfo(id, bookType)
|
||||
if not effect then return end
|
||||
@@ -950,7 +948,7 @@ pfUI.hooksecurefunc("CastSpell", function(id, bookType)
|
||||
end
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("CastSpellByName", function(effect, target)
|
||||
hooksecurefunc("CastSpellByName", function(effect, target)
|
||||
if not libpredict.sender.enabled then return end
|
||||
local effect, rank = libspell.GetSpellInfo(effect)
|
||||
if not effect then return end
|
||||
@@ -1014,13 +1012,14 @@ pfUI.hooksecurefunc("CastSpellByName", function(effect, target)
|
||||
end
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||
hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||
if not libpredict.sender.enabled then return end
|
||||
if not IsCurrentAction(slot) then return end
|
||||
local kind, id = GetActionInfo(slot)
|
||||
local effect, rank
|
||||
if kind == "spell" then
|
||||
effect, rank = GetSpellInfo(id)
|
||||
local spellInfo = C_Spell.GetSpellInfo(id)
|
||||
effect, rank = spellInfo.name, spellInfo.rank
|
||||
elseif kind == "macro" then
|
||||
effect, rank = GetMacroSpell(id)
|
||||
end
|
||||
|
||||
+14
-164
@@ -2,178 +2,28 @@
|
||||
setfenv(1, pfUI:GetEnvironment())
|
||||
|
||||
--[[ librange ]]--
|
||||
-- A pfUI library that detects and caches distance to units.
|
||||
-- A thin wrapper over ClassicAPI's UnitInRange: a fixed 40y healing-range
|
||||
-- check computed C-side from unit positions, valid for any unit. There is
|
||||
-- no cache or scan loop -- the check is cheap enough to run per query,
|
||||
-- which also sidesteps the staleness a cached scan hit on zone changes and
|
||||
-- roster re-indexing.
|
||||
--
|
||||
-- librange:UnitInSpellRange(unit)
|
||||
-- Returns `1` if the unit is within range, `nil` otherwise.
|
||||
--
|
||||
-- Requires SuperWoW's UnitPosition for the friendly scan path. Target
|
||||
-- range still works via IsActionInRange (vanilla-native) for any class
|
||||
-- with a known 40y healing spell on the action bar.
|
||||
|
||||
if pfUI.api.librange then return end
|
||||
|
||||
local _, class = UnitClass("player")
|
||||
local librange = CreateFrame("Frame", "pfRangecheck", UIParent)
|
||||
|
||||
-- 40y spells per class. Only consulted to find an action-bar slot for the
|
||||
-- IsActionInRange target-range path; the party/raid scan uses UnitPosition.
|
||||
local spells = {
|
||||
["PALADIN"] = {
|
||||
"Interface\\Icons\\Spell_Holy_FlashHeal",
|
||||
"Interface\\Icons\\Spell_Holy_HolyBolt",
|
||||
},
|
||||
["PRIEST"] = {
|
||||
"Interface\\Icons\\Spell_Holy_FlashHeal",
|
||||
"Interface\\Icons\\Spell_Holy_LesserHeal",
|
||||
"Interface\\Icons\\Spell_Holy_Heal",
|
||||
"Interface\\Icons\\Spell_Holy_GreaterHeal",
|
||||
"Interface\\Icons\\Spell_Holy_Renew",
|
||||
},
|
||||
["DRUID"] = {
|
||||
"Interface\\Icons\\Spell_Nature_HealingTouch",
|
||||
"Interface\\Icons\\Spell_Nature_ResistNature",
|
||||
"Interface\\Icons\\Spell_Nature_Rejuvenation",
|
||||
},
|
||||
["SHAMAN"] = {
|
||||
"Interface\\Icons\\Spell_Nature_MagicImmunity",
|
||||
"Interface\\Icons\\Spell_Nature_HealingWaveLesser",
|
||||
"Interface\\Icons\\Spell_Nature_HealingWaveGreater",
|
||||
},
|
||||
}
|
||||
|
||||
-- friendly units the scan loop iterates
|
||||
local units = {}
|
||||
table.insert(units, "pet")
|
||||
for i=1,4 do table.insert(units, "party" .. i) end
|
||||
for i=1,4 do table.insert(units, "partypet" .. i) end
|
||||
for i=1,40 do table.insert(units, "raid" .. i) end
|
||||
for i=1,40 do table.insert(units, "raidpet" .. i) end
|
||||
local numunits = table.getn(units)
|
||||
|
||||
local unitcache = {}
|
||||
local unitdata = {}
|
||||
local librange_isLoggingOut = false
|
||||
librange.id = 1
|
||||
|
||||
librange:Hide()
|
||||
librange:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
||||
librange:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
librange:RegisterEvent("PLAYER_LOGOUT")
|
||||
librange:RegisterEvent("PLAYER_LEAVING_WORLD")
|
||||
librange:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_LOGOUT" or event == "PLAYER_LEAVING_WORLD" then
|
||||
librange_isLoggingOut = true
|
||||
this:SetScript("OnUpdate", nil)
|
||||
this:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if pfUI_config.unitframes.rangecheck == "0" then
|
||||
this:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
this.interval = tonumber(C.unitframes.rangechecki)/numunits
|
||||
|
||||
if event == "ACTIONBAR_SLOT_CHANGED" or event == "PLAYER_ENTERING_WORLD" then
|
||||
librange.slot = this:GetRangeSlot()
|
||||
if UnitPosition then this:Show() end
|
||||
end
|
||||
end)
|
||||
|
||||
librange:SetScript("OnUpdate", function()
|
||||
if librange_isLoggingOut then return end
|
||||
|
||||
if (this.tick or 1) > GetTime() then return end
|
||||
this.tick = GetTime() + this.interval
|
||||
|
||||
while not this:NeedRangeScan(units[this.id]) and this.id <= numunits do
|
||||
this.id = this.id + 1
|
||||
end
|
||||
|
||||
if this.id <= numunits then
|
||||
local unit = units[this.id]
|
||||
if not UnitIsUnit("target", unit) then
|
||||
local x1, y1, z1 = UnitPosition("player")
|
||||
local x2, y2, z2 = UnitPosition(unit)
|
||||
if x1 and x2 then
|
||||
local distance = ((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2)^.5
|
||||
unitdata[unit] = distance < 45 and 1 or 0
|
||||
end
|
||||
end
|
||||
this.id = this.id + 1
|
||||
else
|
||||
this.id = 1
|
||||
end
|
||||
end)
|
||||
|
||||
function librange:NeedRangeScan(unit)
|
||||
if not UnitExists(unit) then return nil end
|
||||
if not UnitIsVisible(unit) then return nil end
|
||||
if CheckInteractDistance(unit, 4) then return nil end
|
||||
return true
|
||||
end
|
||||
|
||||
function librange:GetRealUnit(unit)
|
||||
if unitdata[unit] then return unit end
|
||||
|
||||
if unitcache[unit] and UnitIsUnit(unitcache[unit], unit) then
|
||||
return unitcache[unit]
|
||||
end
|
||||
|
||||
for id, realunit in pairs(units) do
|
||||
if UnitIsUnit(realunit, unit) then
|
||||
unitcache[unit] = realunit
|
||||
return realunit
|
||||
end
|
||||
end
|
||||
|
||||
return unit
|
||||
end
|
||||
|
||||
function librange:GetRangeSlot()
|
||||
if not spells[class] then return nil end
|
||||
for i=1,120 do
|
||||
-- Resolve the slot to a spellID for both spell and macro actions; the old
|
||||
-- `not GetActionText` macro-filter missed macros that cast a 40y heal but
|
||||
-- displayed a non-spell icon. C_Spell.GetSpellTexture(spellID) gives the
|
||||
-- spell's *intrinsic* icon, which is what we match against.
|
||||
local kind, id = GetActionInfo(i)
|
||||
local spellID
|
||||
if kind == "spell" then
|
||||
spellID = id
|
||||
elseif kind == "macro" then
|
||||
local _, _, sid = GetMacroSpell(id)
|
||||
spellID = sid
|
||||
end
|
||||
if spellID then
|
||||
local texture = C_Spell.GetSpellTexture(spellID)
|
||||
if texture then
|
||||
for _, check in pairs(spells[class]) do
|
||||
if check == texture then return i end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
local librange = {}
|
||||
|
||||
function librange:UnitInSpellRange(unit)
|
||||
if UnitIsUnit("target", unit) then
|
||||
if not librange.slot then return nil end
|
||||
return IsActionInRange(librange.slot) == 1 and 1 or nil
|
||||
end
|
||||
|
||||
local unit = librange:GetRealUnit(unit)
|
||||
|
||||
if unitdata[unit] and unitdata[unit] == 1 then
|
||||
return 1
|
||||
elseif not unitdata[unit] then
|
||||
return 1
|
||||
else
|
||||
return nil
|
||||
end
|
||||
-- _G-qualified: bare `UnitInRange` resolves to pfUI.api.UnitInRange inside
|
||||
-- the pfUI environment (which calls us), so this must reach ClassicAPI's
|
||||
-- global directly or it recurses.
|
||||
local inRange, checked = _G.UnitInRange(unit)
|
||||
-- position miss (e.g. a unit outside the client's sync range): we can't
|
||||
-- tell, so default to in-range -- matches the old cache's nil behavior.
|
||||
if not checked then return 1 end
|
||||
return inRange and 1 or nil
|
||||
end
|
||||
|
||||
-- add librange to pfUI API
|
||||
|
||||
+3
-1
@@ -118,7 +118,9 @@ end
|
||||
local resetcache = CreateFrame("Frame")
|
||||
resetcache:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
resetcache:SetScript("OnEvent", function()
|
||||
spellmaxrank, spellindex, spellinfo = {}, {}, {}
|
||||
table.wipe(spellmaxrank)
|
||||
table.wipe(spellindex)
|
||||
table.wipe(spellinfo)
|
||||
end)
|
||||
|
||||
-- add libspell to pfUI API
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
-- load pfUI environment
|
||||
setfenv(1, pfUI:GetEnvironment())
|
||||
|
||||
--[[ libtooltip ]]--
|
||||
-- A pfUI library that provides additional GameTooltip information.
|
||||
--
|
||||
-- libtooltip:GetItemID()
|
||||
-- returns the itemID of the current GameTooltip
|
||||
-- `nil` when no item is displayed
|
||||
--
|
||||
-- libtooltip:GetItemLink()
|
||||
-- returns the itemLink of the current GameTooltip
|
||||
-- `nil` when no item is displayed
|
||||
--
|
||||
-- libtooltip:GetItemCount()
|
||||
-- returns the item count (bags) of the current GameTooltip
|
||||
-- `nil` when no item is displayed
|
||||
|
||||
-- return instantly when another libtooltip is already active
|
||||
if pfUI.api.libtooltip then return end
|
||||
|
||||
local libtooltip = CreateFrame("Frame" , "pfLibTooltip", GameTooltip)
|
||||
|
||||
libtooltip:SetScript("OnShow", function()
|
||||
if this:GetParent():HasItem() then
|
||||
libtooltip.itemName, libtooltip.itemLink, libtooltip.itemID = this:GetParent():GetItem()
|
||||
end
|
||||
end)
|
||||
|
||||
libtooltip:SetScript("OnHide", function()
|
||||
this.itemID = nil
|
||||
this.itemLink = nil
|
||||
this.itemCount = nil
|
||||
this.itemName = nil
|
||||
end)
|
||||
|
||||
-- core functions
|
||||
libtooltip.GetItemID = function(self)
|
||||
if not libtooltip.itemLink then return end
|
||||
if not libtooltip.itemID then
|
||||
libtooltip.itemID = C_Item.GetItemInfoInstant(libtooltip.itemLink)
|
||||
end
|
||||
|
||||
return libtooltip.itemID
|
||||
end
|
||||
|
||||
libtooltip.GetItemLink = function(self)
|
||||
return libtooltip.itemLink
|
||||
end
|
||||
|
||||
libtooltip.GetItemCount = function(self)
|
||||
return libtooltip.itemCount
|
||||
end
|
||||
|
||||
pfUI.api.libtooltip = libtooltip
|
||||
|
||||
pfUI.hooksecurefunc(GameTooltip, "SetBagItem", function(self, container, slot)
|
||||
_, libtooltip.itemCount = GetContainerItemInfo(container, slot)
|
||||
end)
|
||||
@@ -1,274 +0,0 @@
|
||||
-- load pfUI environment
|
||||
setfenv(1, pfUI:GetEnvironment())
|
||||
|
||||
--[[ libtotem ]]--
|
||||
-- A pfUI library that tries to emulate the TotemAPI that was introduced in Patch 2.4.
|
||||
-- It detects and saves all current totems of the player and returns information based
|
||||
-- on the totem slot ID. The function GetTotemInfo is supposed to work as it would
|
||||
-- on later expansions.
|
||||
--
|
||||
-- GetTotemInfo(id)
|
||||
-- Returns totem informations on the givent totem slot
|
||||
-- active, name, start, duration, icon
|
||||
|
||||
-- return instantly when another libtotem is already active
|
||||
if pfUI.api.libtotem then return end
|
||||
|
||||
MAX_TOTEMS = MAX_TOTEMS or 4
|
||||
FIRE_TOTEM_SLOT = FIRE_TOTEM_SLOT or 1
|
||||
EARTH_TOTEM_SLOT = EARTH_TOTEM_SLOT or 2
|
||||
WATER_TOTEM_SLOT = WATER_TOTEM_SLOT or 3
|
||||
AIR_TOTEM_SLOT = AIR_TOTEM_SLOT or 4
|
||||
|
||||
local _, class = UnitClass("player")
|
||||
|
||||
local libtotem
|
||||
local active = { [1] = {}, [2] = {}, [3] = {}, [4] = {} }
|
||||
|
||||
-- SpellID -> { slot, duration } mapping
|
||||
-- rank-specific durations are handled via spellId directly
|
||||
local spellids = {
|
||||
-- FIRE (slot 1)
|
||||
[1535] = { slot = FIRE_TOTEM_SLOT, duration = 5 }, -- Fire Nova Totem R1
|
||||
[8498] = { slot = FIRE_TOTEM_SLOT, duration = 5 }, -- Fire Nova Totem R2
|
||||
[8499] = { slot = FIRE_TOTEM_SLOT, duration = 5 }, -- Fire Nova Totem R3
|
||||
[11314] = { slot = FIRE_TOTEM_SLOT, duration = 5 }, -- Fire Nova Totem R4
|
||||
[11315] = { slot = FIRE_TOTEM_SLOT, duration = 5 }, -- Fire Nova Totem R5
|
||||
[8227] = { slot = FIRE_TOTEM_SLOT, duration = 120 }, -- Flametongue Totem R1
|
||||
[8249] = { slot = FIRE_TOTEM_SLOT, duration = 120 }, -- Flametongue Totem R2
|
||||
[10526] = { slot = FIRE_TOTEM_SLOT, duration = 120 }, -- Flametongue Totem R3
|
||||
[16387] = { slot = FIRE_TOTEM_SLOT, duration = 120 }, -- Flametongue Totem R4
|
||||
[8184] = { slot = FIRE_TOTEM_SLOT, duration = 120 }, -- Frost Resistance Totem R1
|
||||
[10478] = { slot = FIRE_TOTEM_SLOT, duration = 120 }, -- Frost Resistance Totem R2
|
||||
[10479] = { slot = FIRE_TOTEM_SLOT, duration = 120 }, -- Frost Resistance Totem R3
|
||||
[8190] = { slot = FIRE_TOTEM_SLOT, duration = 20 }, -- Magma Totem R1
|
||||
[10585] = { slot = FIRE_TOTEM_SLOT, duration = 20 }, -- Magma Totem R2
|
||||
[10586] = { slot = FIRE_TOTEM_SLOT, duration = 20 }, -- Magma Totem R3
|
||||
[10587] = { slot = FIRE_TOTEM_SLOT, duration = 20 }, -- Magma Totem R4
|
||||
[3599] = { slot = FIRE_TOTEM_SLOT, duration = 30 }, -- Searing Totem R1
|
||||
[6363] = { slot = FIRE_TOTEM_SLOT, duration = 35 }, -- Searing Totem R2
|
||||
[6364] = { slot = FIRE_TOTEM_SLOT, duration = 40 }, -- Searing Totem R3
|
||||
[6365] = { slot = FIRE_TOTEM_SLOT, duration = 45 }, -- Searing Totem R4
|
||||
[10437] = { slot = FIRE_TOTEM_SLOT, duration = 50 }, -- Searing Totem R5
|
||||
[10438] = { slot = FIRE_TOTEM_SLOT, duration = 55 }, -- Searing Totem R6
|
||||
|
||||
-- EARTH (slot 2)
|
||||
[2484] = { slot = EARTH_TOTEM_SLOT, duration = 45 }, -- Earthbind Totem
|
||||
[5730] = { slot = EARTH_TOTEM_SLOT, duration = 15 }, -- Stoneclaw Totem R1
|
||||
[6390] = { slot = EARTH_TOTEM_SLOT, duration = 15 }, -- Stoneclaw Totem R2
|
||||
[6391] = { slot = EARTH_TOTEM_SLOT, duration = 15 }, -- Stoneclaw Totem R3
|
||||
[6392] = { slot = EARTH_TOTEM_SLOT, duration = 15 }, -- Stoneclaw Totem R4
|
||||
[10427] = { slot = EARTH_TOTEM_SLOT, duration = 15 }, -- Stoneclaw Totem R5
|
||||
[10428] = { slot = EARTH_TOTEM_SLOT, duration = 15 }, -- Stoneclaw Totem R6
|
||||
[8071] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Stoneskin Totem R1
|
||||
[8154] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Stoneskin Totem R2
|
||||
[8155] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Stoneskin Totem R3
|
||||
[10406] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Stoneskin Totem R4
|
||||
[10407] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Stoneskin Totem R5
|
||||
[10408] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Stoneskin Totem R6
|
||||
[8075] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Strength of Earth Totem R1
|
||||
[8160] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Strength of Earth Totem R2
|
||||
[8161] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Strength of Earth Totem R3
|
||||
[10442] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Strength of Earth Totem R4
|
||||
[25361] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Strength of Earth Totem R5
|
||||
[8143] = { slot = EARTH_TOTEM_SLOT, duration = 120 }, -- Tremor Totem
|
||||
|
||||
-- WATER (slot 3)
|
||||
[8170] = { slot = WATER_TOTEM_SLOT, duration = 120 }, -- Disease Cleansing Totem
|
||||
[8185] = { slot = WATER_TOTEM_SLOT, duration = 120 }, -- Fire Resistance Totem R1
|
||||
[10537] = { slot = WATER_TOTEM_SLOT, duration = 120 }, -- Fire Resistance Totem R2
|
||||
[10538] = { slot = WATER_TOTEM_SLOT, duration = 120 }, -- Fire Resistance Totem R3
|
||||
[5394] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Healing Stream Totem R1
|
||||
[6375] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Healing Stream Totem R2
|
||||
[6377] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Healing Stream Totem R3
|
||||
[10462] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Healing Stream Totem R4
|
||||
[10463] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Healing Stream Totem R5
|
||||
[5675] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Mana Spring Totem R1
|
||||
[10495] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Mana Spring Totem R2
|
||||
[10496] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Mana Spring Totem R3
|
||||
[10497] = { slot = WATER_TOTEM_SLOT, duration = 60 }, -- Mana Spring Totem R4
|
||||
[16190] = { slot = WATER_TOTEM_SLOT, duration = 12 }, -- Mana Tide Totem
|
||||
[8166] = { slot = WATER_TOTEM_SLOT, duration = 120 }, -- Poison Cleansing Totem
|
||||
|
||||
-- AIR (slot 4)
|
||||
[8835] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Grace of Air Totem R1
|
||||
[10627] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Grace of Air Totem R2
|
||||
[8177] = { slot = AIR_TOTEM_SLOT, duration = 45 }, -- Grounding Totem
|
||||
[10595] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Nature Resistance Totem R1
|
||||
[10600] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Nature Resistance Totem R2
|
||||
[10601] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Nature Resistance Totem R3
|
||||
[25359] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Tranquil Air Totem
|
||||
[8512] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Windfury Totem R1
|
||||
[10613] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Windfury Totem R2
|
||||
[10614] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Windfury Totem R3
|
||||
[15107] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Windwall Totem R1
|
||||
[15421] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Windwall Totem R2
|
||||
[15422] = { slot = AIR_TOTEM_SLOT, duration = 120 }, -- Windwall Totem R3
|
||||
}
|
||||
|
||||
-- icon-based fallback table (used by CastSpell/UseAction hooks that don't have spellId)
|
||||
local totems = {
|
||||
[FIRE_TOTEM_SLOT] = {
|
||||
["Spell_Fire_SealOfFire"] = {[-1] = 5},
|
||||
["Spell_Nature_GuardianWard"] = {[-1] = 120},
|
||||
["Spell_FrostResistanceTotem_01"] = {[-1] = 120},
|
||||
["Spell_Fire_SelfDestruct"] = {[-1] = 20},
|
||||
["Spell_Fire_SearingTotem"] = {[-1] = 55,[1] = 30,[2] = 35,[3] = 40,[4] = 45,[5] = 50,[6] = 55},
|
||||
},
|
||||
[EARTH_TOTEM_SLOT] = {
|
||||
["Spell_Nature_StrengthOfEarthTotem02"] = {[-1] = 45},
|
||||
["Spell_Nature_StoneClawTotem"] = {[-1] = 15},
|
||||
["Spell_Nature_StoneSkinTotem"] = {[-1] = 120},
|
||||
["Spell_Nature_EarthBindTotem"] = {[-1] = 120},
|
||||
["Spell_Nature_TremorTotem"] = {[-1] = 120},
|
||||
},
|
||||
[WATER_TOTEM_SLOT] = {
|
||||
["Spell_Nature_DiseaseCleansingTotem"] = {[-1] = 120},
|
||||
["Spell_FireResistanceTotem_01"] = {[-1] = 120},
|
||||
["INV_Spear_04"] = {[-1] = 60},
|
||||
["Spell_Nature_ManaRegenTotem"] = {[-1] = 60},
|
||||
["Spell_Frost_SummonWaterElemental"] = {[-1] = 12},
|
||||
["Spell_Nature_PoisonCleansingTotem"] = {[-1] = 120},
|
||||
},
|
||||
[AIR_TOTEM_SLOT] = {
|
||||
["Spell_Nature_InvisibilityTotem"] = {[-1] = 120},
|
||||
["Spell_Nature_GroundingTotem"] = {[-1] = 45},
|
||||
["Spell_Nature_NatureResistanceTotem"] = {[-1] = 120},
|
||||
["Spell_Nature_Brilliance"] = {[-1] = 120},
|
||||
["Spell_Nature_Windfury"] = {[-1] = 120},
|
||||
["Spell_Nature_EarthBind"] = {[-1] = 120},
|
||||
},
|
||||
}
|
||||
|
||||
GetTotemInfo = function(id)
|
||||
if not active[id] or not active[id].name then return end
|
||||
if active[id].start + active[id].duration - GetTime() < 0 then
|
||||
libtotem:Clean(id)
|
||||
return nil
|
||||
end
|
||||
return 1, active[id].name, active[id].start, active[id].duration, active[id].icon
|
||||
end
|
||||
|
||||
if class ~= "SHAMAN" then return end
|
||||
|
||||
libtotem = CreateFrame("Frame")
|
||||
libtotem:RegisterEvent("PLAYER_DEAD")
|
||||
libtotem:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_DEAD" then
|
||||
for i = 1, 4 do libtotem:Clean(i) end
|
||||
end
|
||||
end)
|
||||
|
||||
libtotem.totems = totems
|
||||
|
||||
libtotem.Clean = function(self, slot)
|
||||
active[slot].name = nil
|
||||
active[slot].start = nil
|
||||
active[slot].duration = nil
|
||||
active[slot].icon = nil
|
||||
end
|
||||
|
||||
-- Direct SpellID commit (Nampower SPELL_GO_SELF, most accurate)
|
||||
libtotem.CommitBySpellId = function(spellId, icon)
|
||||
local data = spellids[spellId]
|
||||
if not data then return false end
|
||||
local slot = data.slot
|
||||
active[slot].name = active[slot].pending_name or active[slot].name
|
||||
active[slot].duration = data.duration
|
||||
active[slot].icon = icon or active[slot].pending_icon
|
||||
active[slot].start = GetTime()
|
||||
active[slot].pending_name = nil
|
||||
active[slot].pending_icon = nil
|
||||
return true
|
||||
end
|
||||
|
||||
-- Fallback: icon-based lookup (for CastSpell/UseAction without spellId)
|
||||
libtotem.CheckAddQueue = function(self, name, rank, icon, spellId)
|
||||
-- if we have a spellId, just store the name/icon as pending for SPELL_GO
|
||||
if spellId and spellids[spellId] then
|
||||
local slot = spellids[spellId].slot
|
||||
active[slot].pending_name = name
|
||||
active[slot].pending_icon = icon
|
||||
return true
|
||||
end
|
||||
|
||||
-- icon-based fallback
|
||||
for slot = 1, 4 do
|
||||
for texture, data in pairs(totems[slot]) do
|
||||
if string.find(icon, texture, 1) then
|
||||
if rank then
|
||||
_, _, rank = string.find(rank, "%s(%d+)")
|
||||
end
|
||||
local duration
|
||||
if rank and tonumber(rank) and data[tonumber(rank)] then
|
||||
duration = data[tonumber(rank)]
|
||||
else
|
||||
duration = data[-1]
|
||||
end
|
||||
active[slot].pending_name = name
|
||||
active[slot].pending_icon = icon
|
||||
active[slot].pending_duration = duration
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- assign library to global space
|
||||
pfUI.api.libtotem = libtotem
|
||||
|
||||
-- SPELL_GO_SELF from libdebuff: commit directly by SpellID, no queue needed
|
||||
pfUI.libdebuff_spell_go_hooks = pfUI.libdebuff_spell_go_hooks or {}
|
||||
pfUI.libdebuff_spell_go_hooks["libtotem"] = function(spellId)
|
||||
if not spellId then return end
|
||||
local data = spellids[spellId]
|
||||
if not data then return end
|
||||
local slot = data.slot
|
||||
-- use pending name/icon if available (set by CastSpellByName hook), else GetSpellInfo
|
||||
local name = active[slot].pending_name
|
||||
local icon = active[slot].pending_icon
|
||||
if not name and GetSpellInfo then
|
||||
name = GetSpellInfo(spellId)
|
||||
end
|
||||
active[slot].name = name
|
||||
active[slot].duration = data.duration
|
||||
active[slot].icon = icon
|
||||
active[slot].start = GetTime()
|
||||
active[slot].pending_name = nil
|
||||
active[slot].pending_icon = nil
|
||||
active[slot].pending_duration = nil
|
||||
end
|
||||
|
||||
-- Hook CastSpellByName to store pending name/icon per slot
|
||||
pfUI.hooksecurefunc("CastSpellByName", function(effect, target)
|
||||
local name, rank, icon, _, _, _, spellId = libspell.GetSpellInfo(effect)
|
||||
if not name then return end
|
||||
libtotem:CheckAddQueue(name, rank, icon, spellId)
|
||||
end)
|
||||
|
||||
-- Hook CastSpell to store pending name/icon per slot
|
||||
pfUI.hooksecurefunc("CastSpell", function(id, bookType)
|
||||
if not id or not bookType then return end
|
||||
if bookType ~= BOOKTYPE_SPELL and bookType ~= BOOKTYPE_PET then return end
|
||||
local name, rank, icon, _, _, _, spellId = libspell.GetSpellInfo(id, bookType)
|
||||
if not name then return end
|
||||
libtotem:CheckAddQueue(name, rank, icon, spellId)
|
||||
end)
|
||||
|
||||
-- Hook UseAction. GetActionInfo + GetMacroSpell give us the spellID
|
||||
-- directly for both spell-action and macro-action slots, so the
|
||||
-- tooltip-scan fallback (and the "no spellId available" caveat) goes away.
|
||||
pfUI.hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||
if not IsCurrentAction(slot) then return end
|
||||
local kind, id = GetActionInfo(slot)
|
||||
local name, rank, spellID
|
||||
if kind == "spell" then
|
||||
spellID = id
|
||||
name, rank = GetSpellInfo(id)
|
||||
elseif kind == "macro" then
|
||||
name, rank, spellID = GetMacroSpell(id)
|
||||
end
|
||||
if not name then return end
|
||||
libtotem:CheckAddQueue(name, rank, GetActionTexture(slot), spellID)
|
||||
end)
|
||||
+29
-15
@@ -853,16 +853,20 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
end
|
||||
end
|
||||
|
||||
local cat, stealth
|
||||
local inCatForm = nil
|
||||
local prowlActive = nil
|
||||
|
||||
-- Cat Form ID per vanilla 1.12 SpellShapeshiftForm.dbc.
|
||||
-- Form IDs per vanilla 1.12 SpellShapeshiftForm.dbc.
|
||||
local CAT_FORM = 1
|
||||
local SHADOWFORM = 28
|
||||
local function HasCatForm()
|
||||
return GetShapeshiftFormID() == CAT_FORM and true or nil
|
||||
end
|
||||
|
||||
local function InShadowform()
|
||||
return GetShapeshiftFormID() == SHADOWFORM and true or nil
|
||||
end
|
||||
|
||||
local function FullScan()
|
||||
if class ~= "DRUID" then return nil end
|
||||
inCatForm = HasCatForm()
|
||||
@@ -872,7 +876,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
-- pagemaster / meta page switch
|
||||
do
|
||||
local prowl, shift, ctrl, alt, default = 8, 6, 5, 3, 1
|
||||
local formpage, shift, ctrl, alt, default = 8, 6, 5, 3, 1
|
||||
|
||||
-- set temporary pagemaster bindings keybinds
|
||||
if C.bars.pagemaster == "1" then
|
||||
@@ -890,8 +894,10 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
end)
|
||||
end
|
||||
|
||||
-- setup page switch frame
|
||||
local prowling = nil
|
||||
-- setup page switch frame. `formpaging` is the shared "auto-page is
|
||||
-- active" flag; druid prowl and priest shadowform each drive it, and
|
||||
-- no character is ever both, so one flag covers both features.
|
||||
local formpaging = nil
|
||||
local pageswitch = CreateFrame("Frame", "pfActionBarPageSwitch", UIParent)
|
||||
pageswitch:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
pageswitch:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
|
||||
@@ -905,10 +911,17 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
return
|
||||
end
|
||||
|
||||
if class == "PRIEST" then
|
||||
if event == "UPDATE_SHAPESHIFT_FORM" or event == "PLAYER_ENTERING_WORLD" then
|
||||
formpaging = InShadowform()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if class ~= "DRUID" then return end
|
||||
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
prowling = FullScan()
|
||||
formpaging = FullScan()
|
||||
return
|
||||
end
|
||||
|
||||
@@ -917,7 +930,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
inCatForm = HasCatForm()
|
||||
if not inCatForm then
|
||||
prowlActive = nil
|
||||
prowling = nil
|
||||
formpaging = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
@@ -927,10 +940,10 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
if inCatForm then
|
||||
if IsStealthed() then
|
||||
prowlActive = true
|
||||
prowling = true
|
||||
formpaging = true
|
||||
else
|
||||
prowlActive = nil
|
||||
prowling = nil
|
||||
formpaging = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -946,7 +959,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
if PROWL_IDS[spellId] then
|
||||
inCatForm = true
|
||||
prowlActive = true
|
||||
prowling = true
|
||||
formpaging = true
|
||||
end
|
||||
end
|
||||
pageswitch:SetScript("OnUpdate", function()
|
||||
@@ -964,11 +977,12 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
SwitchBar(default)
|
||||
end
|
||||
|
||||
-- switch actionbar page if druid stealth is detected
|
||||
if C.bars.druidstealth == "1" then
|
||||
if prowling and _G.CURRENT_ACTIONBAR_PAGE == 1 then
|
||||
SwitchBar(prowl)
|
||||
elseif not prowling and _G.CURRENT_ACTIONBAR_PAGE == 8 then
|
||||
-- switch actionbar page while druid stealth / priest shadowform is active
|
||||
if (class == "DRUID" and C.bars.druidstealth == "1")
|
||||
or (class == "PRIEST" and C.bars.priestshadow == "1") then
|
||||
if formpaging and _G.CURRENT_ACTIONBAR_PAGE == 1 then
|
||||
SwitchBar(formpage)
|
||||
elseif not formpaging and _G.CURRENT_ACTIONBAR_PAGE == 8 then
|
||||
SwitchBar(default)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -440,6 +440,5 @@ pfUI:RegisterModule("addonbuttons", function ()
|
||||
|
||||
pfUI.addonbuttons:UpdateConfig()
|
||||
|
||||
_G.SLASH_PFABP1, _G.SLASH_PFABP2 = "/abp", "/pfabp"
|
||||
_G.SlashCmdList.PFABP = ManualAddOrRemove
|
||||
pfUI.api.RegisterSlashCommand("PFABP", { "/abp", "/pfabp" }, ManualAddOrRemove, true)
|
||||
end)
|
||||
|
||||
@@ -217,6 +217,21 @@ pfUI:RegisterModule("addons", function ()
|
||||
pfUI.addons.list:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
pfUI.addons.list:SetHeight(GetNumAddOns() * 25 + 26)
|
||||
|
||||
local function AddDependencyLines(header, deps)
|
||||
if not deps or table.getn(deps) == 0 then return end
|
||||
GameTooltip:AddLine(" ")
|
||||
GameTooltip:AddLine(header .. ":", .2, 1, .8)
|
||||
for _, dep in ipairs(deps) do
|
||||
if IsAddOnLoaded(dep) then
|
||||
GameTooltip:AddLine(" " .. dep, .5, 1, .5)
|
||||
elseif C_AddOns.DoesAddOnExist(dep) then
|
||||
GameTooltip:AddLine(" " .. dep, 1, .82, 0)
|
||||
else
|
||||
GameTooltip:AddLine(" " .. dep .. " (" .. T["Missing"] .. ")", 1, .4, .4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function AddonOnEnter()
|
||||
this:SetBackdropBorderColor(1,1,1,.08)
|
||||
|
||||
@@ -231,6 +246,8 @@ pfUI:RegisterModule("addons", function ()
|
||||
end
|
||||
|
||||
GameTooltip:AddLine(this.anote, .75,.75,.75,1)
|
||||
AddDependencyLines(T["Dependencies"], this.adeps)
|
||||
AddDependencyLines(T["Optional Dependencies"], this.aoptdeps)
|
||||
GameTooltip:SetWidth(180)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
@@ -272,6 +289,8 @@ pfUI:RegisterModule("addons", function ()
|
||||
frame.anote = anote
|
||||
frame.aauthor = aauthor
|
||||
frame.aversion = aversion
|
||||
frame.adeps = { GetAddOnDependencies(i) } -- required (.toc Dependencies)
|
||||
frame.aoptdeps = { C_AddOns.GetAddOnOptionalDependencies(i) } -- optional (.toc OptionalDeps)
|
||||
|
||||
frame:SetWidth(340)
|
||||
frame:SetHeight(25)
|
||||
|
||||
+16
-4
@@ -8,6 +8,13 @@ pfUI:RegisterModule("bags", function ()
|
||||
|
||||
local scanner = libtipscan:GetScanner("input_search")
|
||||
|
||||
local function BagSortOpts()
|
||||
return {
|
||||
reverse = C.appearance.bags.sortreverse == "1",
|
||||
reversePrio = C.appearance.bags.sortprioreverse == "1",
|
||||
}
|
||||
end
|
||||
|
||||
-- function to detect openable items in inventory
|
||||
local openable = { bag = nil, slot = nil, icon = nil }
|
||||
local function GetNextOpenable()
|
||||
@@ -337,12 +344,13 @@ pfUI:RegisterModule("bags", function ()
|
||||
local chat = pfUI.chat and ( object == "bank" and pfUI.chat.left or pfUI.chat.right) or nil
|
||||
|
||||
frame:SetScript("OnShow", function()
|
||||
frame.opened = true
|
||||
if C.appearance.bags.hidechat == "1" and chat and chat:IsVisible() then
|
||||
frame.chatWasOpen = true
|
||||
chat:Hide()
|
||||
end
|
||||
if C.appearance.bags.autoSortOnOpen == "1" then
|
||||
libbagsort:Sort({0, 1, 2, 3, 4})
|
||||
libbagsort:Sort({0, 1, 2, 3, 4}, BagSortOpts())
|
||||
end
|
||||
pfUI.bag:CreateBags(object)
|
||||
PlaySound("INTERFACESOUND_BACKPACKOPEN")
|
||||
@@ -355,6 +363,10 @@ pfUI:RegisterModule("bags", function ()
|
||||
end
|
||||
pfUI.bag:CreateBags(object)
|
||||
PlaySound("INTERFACESOUND_BACKPACKCLOSE")
|
||||
if frame.opened then
|
||||
frame.opened = nil
|
||||
pfUI.events:TriggerEvent("bag:closed", object)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -443,7 +455,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
|
||||
@@ -988,7 +1000,7 @@ pfUI:RegisterModule("bags", function ()
|
||||
end)
|
||||
|
||||
frame.sort:SetScript("OnClick", function()
|
||||
libbagsort:Sort({0, 1, 2, 3, 4})
|
||||
libbagsort:Sort({0, 1, 2, 3, 4}, BagSortOpts())
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -1226,7 +1238,7 @@ pfUI:RegisterModule("bags", function ()
|
||||
end)
|
||||
|
||||
frame.sort:SetScript("OnClick", function()
|
||||
libbagsort:Sort({-1, 5, 6, 7, 8, 9, 10})
|
||||
libbagsort:Sort({-1, 5, 6, 7, 8, 9, 10}, BagSortOpts())
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
+2
-9
@@ -17,12 +17,6 @@ pfUI:RegisterModule("bubbles", function ()
|
||||
RunNextFrame(function() pfUI.bubbles:ScanBubbles() end)
|
||||
end)
|
||||
|
||||
function pfUI.bubbles:IsBubble(f)
|
||||
if f:GetName() then return end
|
||||
if not f:GetRegions() then return end
|
||||
return f:GetRegions().GetTexture and f:GetRegions():GetTexture() == "Interface\\Tooltips\\ChatBubble-Background"
|
||||
end
|
||||
|
||||
function pfUI.bubbles:ProcessBubble(f)
|
||||
f.text:Hide()
|
||||
f.text:SetFont(pfUI.font_default, tonumber(C.global.font_size) * UIParent:GetScale(), "OUTLINE")
|
||||
@@ -34,9 +28,8 @@ pfUI:RegisterModule("bubbles", function ()
|
||||
end
|
||||
|
||||
function pfUI.bubbles:ScanBubbles()
|
||||
local childs = { WorldFrame:GetChildren() }
|
||||
for _, f in pairs(childs) do
|
||||
if not f.frame and pfUI.bubbles:IsBubble(f) then
|
||||
for _, f in ipairs(C_ChatBubbles.GetAllChatBubbles()) do
|
||||
if not f.frame then
|
||||
local textures = {f:GetRegions()}
|
||||
for _, object in pairs(textures) do
|
||||
if object:GetObjectType() == "Texture" then
|
||||
|
||||
+8
-3
@@ -69,6 +69,11 @@ pfUI:RegisterModule("castbar", function ()
|
||||
-- spark to the left edge of the bar.
|
||||
local function StartTradeskillCraft(cb)
|
||||
cb.currentCraftStart = GetTime() * 1000
|
||||
local remaining = cb.tradeskillTotal - (cb.tradeskillCompleted or 0)
|
||||
cb.endTime = cb.currentCraftStart + cb.tradeskillSingleMs * remaining
|
||||
local duration = (cb.endTime - cb.startTime) / 1000
|
||||
cb.bar:SetMinMaxValues(0, duration)
|
||||
cb.lastMax = duration
|
||||
UpdateTradeskillLabel(cb)
|
||||
end
|
||||
|
||||
@@ -88,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 ""
|
||||
@@ -490,7 +495,7 @@ pfUI:RegisterModule("castbar", function ()
|
||||
-- (the config knob is read at event time so toggling takes effect on the
|
||||
-- next craft without a /reload). DoTradeSkill is synchronous; the server
|
||||
-- roundtrip to SPELLCAST_START gives us plenty of time after this hook.
|
||||
pfUI.hooksecurefunc("DoTradeSkill", function(index, num)
|
||||
hooksecurefunc("DoTradeSkill", function(index, num)
|
||||
if pfUI.castbar.player then
|
||||
pfUI.castbar.player.pendingTradeskillCount = tonumber(num) or 1
|
||||
end
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ pfUI:RegisterModule("chat", function ()
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("UnitPopup_OnClick", function(self)
|
||||
hooksecurefunc("UnitPopup_OnClick", function(self)
|
||||
if this.value == "IGNORE_PLAYER" then
|
||||
AddIgnore(_G[UIDROPDOWNMENU_INIT_MENU].name)
|
||||
end
|
||||
@@ -449,7 +449,7 @@ pfUI:RegisterModule("chat", function ()
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("FCF_SaveDock", pfUI.chat.RefreshChat)
|
||||
hooksecurefunc("FCF_SaveDock", pfUI.chat.RefreshChat)
|
||||
|
||||
if C.chat.global.tabmouse == "1" then
|
||||
pfUI.chat.mouseovertab = CreateFrame("Frame")
|
||||
|
||||
@@ -136,5 +136,5 @@ pfUI:RegisterModule("cooldown", function ()
|
||||
|
||||
-- vanilla does not have a cooldown frame type, so we hook the
|
||||
-- regular SetTimer function that each one is calling.
|
||||
pfUI.hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
|
||||
hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
|
||||
end)
|
||||
@@ -32,10 +32,10 @@ pfUI:RegisterModule("energytick", function()
|
||||
energytick:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS")
|
||||
|
||||
energytick:SetScript("OnEvent", function()
|
||||
if UnitPowerType("player") == 0 and C.unitframes.player.manatick == "1" then
|
||||
if UnitPowerType("player") == Enum.PowerType.Mana and C.unitframes.player.manatick == "1" then
|
||||
this.mode = "MANA"
|
||||
this:Show()
|
||||
elseif UnitPowerType("player") == 3 and C.unitframes.player.energy == "1" then
|
||||
elseif UnitPowerType("player") == Enum.PowerType.Energy and C.unitframes.player.energy == "1" then
|
||||
this.mode = "ENERGY"
|
||||
this:Show()
|
||||
else
|
||||
@@ -51,11 +51,11 @@ pfUI:RegisterModule("energytick", function()
|
||||
end
|
||||
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
this.lastMana = UnitMana("player")
|
||||
this.lastMana = UnitPower("player")
|
||||
end
|
||||
|
||||
if (event == "UNIT_MANA" or event == "UNIT_ENERGY") and arg1 == "player" then
|
||||
this.currentMana = UnitMana("player")
|
||||
this.currentMana = UnitPower("player")
|
||||
local diff = 0
|
||||
if this.lastMana then
|
||||
diff = this.currentMana - this.lastMana
|
||||
@@ -64,7 +64,7 @@ pfUI:RegisterModule("energytick", function()
|
||||
if this.mode == "MANA" and diff < 0 then
|
||||
this.target = 5
|
||||
elseif this.mode == "MANA" and diff > 0 then
|
||||
if UnitMana("player") >= UnitManaMax("player") then
|
||||
if UnitPower("player") >= UnitPowerMax("player") then
|
||||
this.start = nil
|
||||
this.spark:SetAlpha(0)
|
||||
this:Hide()
|
||||
@@ -105,7 +105,7 @@ pfUI:RegisterModule("energytick", function()
|
||||
|
||||
if this.current > this.max then
|
||||
-- Don't restart tick timer if mana is full
|
||||
if this.mode == "MANA" and UnitMana("player") >= UnitManaMax("player") then
|
||||
if this.mode == "MANA" and UnitPower("player") >= UnitPowerMax("player") then
|
||||
this.start = nil
|
||||
this.spark:SetAlpha(0)
|
||||
return
|
||||
|
||||
@@ -88,7 +88,7 @@ pfUI:RegisterModule("eqcompare", function ()
|
||||
|
||||
local prevMerchant = ShoppingTooltip1.SetMerchantCompareItem
|
||||
local function SetMerchantCompareItem(self, index, compareItem)
|
||||
if C.tooltip.compare.basestats == "1" and compareItem == 1 then
|
||||
if compareItem == 1 then
|
||||
ShowCompareItem(nil, GetMerchantItemLink(index), 1)
|
||||
return false
|
||||
end
|
||||
@@ -97,7 +97,7 @@ pfUI:RegisterModule("eqcompare", function ()
|
||||
|
||||
local prevAuction = ShoppingTooltip1.SetAuctionCompareItem
|
||||
local function SetAuctionCompareItem(self, type, index, compareItem)
|
||||
if C.tooltip.compare.basestats == "1" and compareItem == 1 then
|
||||
if compareItem == 1 then
|
||||
ShowCompareItem(nil, GetAuctionItemLink(type, index), 1)
|
||||
return false
|
||||
end
|
||||
@@ -132,15 +132,13 @@ pfUI:RegisterModule("eqcompare", function ()
|
||||
|
||||
local function makeHook(getter)
|
||||
return function(tooltip, arg1, arg2, arg3)
|
||||
if C.tooltip.compare.basestats == "1" then
|
||||
ShowCompareItem(tooltip, getter(arg1, arg2, arg3))
|
||||
end
|
||||
ShowCompareItem(tooltip, getter(arg1, arg2, arg3))
|
||||
end
|
||||
end
|
||||
|
||||
local function HookTooltip(tooltip)
|
||||
for setter, getter in pairs(TooltipHooks) do
|
||||
pfUI.hooksecurefunc(tooltip, setter, makeHook(getter))
|
||||
hooksecurefunc(tooltip, setter, makeHook(getter))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ pfUI:RegisterModule("farmmode", function ()
|
||||
Minimap_ZoomOut()
|
||||
end
|
||||
|
||||
_G.SLASH_PFFARMMAP1, _G.SLASH_PFFARMMAP2 = "/farm", "/farmmode"
|
||||
_G.SlashCmdList.PFFARMMAP = ToggleFarmMode
|
||||
pfUI.api.RegisterSlashCommand("PFFARMMAP", { "/farm", "/farmmode" }, ToggleFarmMode, true)
|
||||
|
||||
pfUI.farmmap = CreateFrame("Minimap", "pfFarmMap", UIParent)
|
||||
pfUI.farmmap:Hide()
|
||||
|
||||
@@ -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
|
||||
|
||||
+11
-12
@@ -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()
|
||||
@@ -30,8 +32,7 @@ end)
|
||||
-- /focusname is pfUI-specific because the engine has no name→GUID
|
||||
-- lookup for off-screen units — we resolve via a short target-swap.
|
||||
|
||||
SLASH_PFFOCUSNAME1, SLASH_PFFOCUSNAME2 = '/focusname', '/pffocusname'
|
||||
function SlashCmdList.PFFOCUSNAME(msg)
|
||||
pfUI.api.RegisterSlashCommand("PFFOCUSNAME", { '/focusname', '/pffocusname' }, function(msg)
|
||||
if msg == "" then return end
|
||||
|
||||
local prevGUID = UnitGUID("target")
|
||||
@@ -61,10 +62,9 @@ function SlashCmdList.PFFOCUSNAME(msg)
|
||||
else
|
||||
ClearTarget()
|
||||
end
|
||||
end
|
||||
end, true)
|
||||
|
||||
SLASH_PFCASTFOCUS1, SLASH_PFCASTFOCUS2 = '/castfocus', '/pfcastfocus'
|
||||
function SlashCmdList.PFCASTFOCUS(msg)
|
||||
pfUI.api.RegisterSlashCommand("PFCASTFOCUS", { '/castfocus', '/pfcastfocus' }, function(msg)
|
||||
local focusGUID = UnitGUID("focus")
|
||||
if not focusGUID or focusGUID == "0x0000000000000000" then
|
||||
UIErrorsFrame:AddMessage(SPELL_FAILED_BAD_TARGETS, 1, 0, 0)
|
||||
@@ -105,10 +105,9 @@ function SlashCmdList.PFCASTFOCUS(msg)
|
||||
else
|
||||
TargetLastTarget()
|
||||
end
|
||||
end
|
||||
end, true)
|
||||
|
||||
SLASH_PFSWAPFOCUS1, SLASH_PFSWAPFOCUS2 = '/swapfocus', '/pfswapfocus'
|
||||
function SlashCmdList.PFSWAPFOCUS(msg)
|
||||
pfUI.api.RegisterSlashCommand("PFSWAPFOCUS", { '/swapfocus', '/pfswapfocus' }, function(msg)
|
||||
local targetGUID = UnitGUID("target")
|
||||
local oldFocusGUID = UnitGUID("focus")
|
||||
|
||||
@@ -118,4 +117,4 @@ function SlashCmdList.PFSWAPFOCUS(msg)
|
||||
TargetUnit(oldFocusGUID)
|
||||
end
|
||||
end
|
||||
end
|
||||
end, true)
|
||||
|
||||
+2
-2
@@ -150,7 +150,7 @@ pfUI:RegisterSkin("Friends", function ()
|
||||
end
|
||||
|
||||
-- set positions
|
||||
pfUI.hooksecurefunc("WhoList_Update", function()
|
||||
hooksecurefunc("WhoList_Update", function()
|
||||
for i = 1, WHOS_TO_DISPLAY do
|
||||
local level = _G["WhoFrameButton"..i.."Level"]
|
||||
level:ClearAllPoints()
|
||||
@@ -231,7 +231,7 @@ pfUI:RegisterSkin("Friends", function ()
|
||||
end
|
||||
|
||||
-- set positions
|
||||
pfUI.hooksecurefunc("GuildStatus_Update", function()
|
||||
hooksecurefunc("GuildStatus_Update", function()
|
||||
for i = 1, GUILDMEMBERS_TO_DISPLAY do
|
||||
local level = _G["GuildFrameButton"..i.."Level"]
|
||||
level:ClearAllPoints()
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ pfUI:RegisterModule("gm", function ()
|
||||
-- pet dropdown
|
||||
-- table.insert(UnitPopupMenus["PET"], "GM_HEADER")
|
||||
|
||||
pfUI.hooksecurefunc("UnitPopup_OnClick", function()
|
||||
hooksecurefunc("UnitPopup_OnClick", function()
|
||||
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
||||
local button = this.value
|
||||
local unit = dropdownFrame.unit
|
||||
|
||||
+20
-20
@@ -961,7 +961,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
"16:" .. T["Very Slow"],
|
||||
},
|
||||
["uf_rangecheck_mode"] = {
|
||||
"vanilla:" .. T["Vanilla (Spellbook)"],
|
||||
"vanilla:" .. T["ClassicAPI (UnitInRange)"],
|
||||
"unitxp:" .. T["UnitXP (Precise)"],
|
||||
},
|
||||
["uf_raidlayout"] = {
|
||||
@@ -1068,6 +1068,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
"unitrev:" .. T["Unit String (Reverse)"],
|
||||
"name:" .. T["Name"],
|
||||
"nameshort:" .. T["Name (Short)"],
|
||||
"ownername:" .. T["Owner Name"],
|
||||
"level:" .. T["Level"],
|
||||
"class:" .. T["Class"],
|
||||
"namehealth:" .. T["Name | Health Missing"],
|
||||
@@ -2119,10 +2120,9 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Enable 40y-Range Check"], C.unitframes, "rangecheck", "checkbox", nil, nil, nil, nil)
|
||||
CreateConfig(nil, T["Range Check Mode"], C.unitframes, "rangecheck_mode", "dropdown", pfUI.gui.dropdowns.uf_rangecheck_mode, nil, nil, nil)
|
||||
CreateConfig(nil, T["UnitXP Range Threshold (yards)"], C.unitframes, "rangecheck_distance", nil, nil, nil, nil, nil)
|
||||
CreateConfig(nil, T["Range Check Interval"], C.unitframes, "rangechecki", "dropdown", pfUI.gui.dropdowns.uf_rangecheckinterval, nil, nil, nil)
|
||||
CreateConfig(nil, T["Use Raid Frames To Display Group Members"], C.unitframes, "raidforgroup", "checkbox")
|
||||
CreateConfig(nil, T["Always Show Self In Raid Frames"], C.unitframes, "selfinraid", "checkbox")
|
||||
CreateConfig(nil, T["Show Self In Raid Frames When Solo"], C.unitframes, "selfinraid", "checkbox")
|
||||
CreateConfig(nil, T["Show Self In Group Frames"], C.unitframes, "selfingroup", "checkbox")
|
||||
CreateConfig(nil, T["Use Raid Frames To Display Group Members"], C.unitframes, "raidforgroup", "checkbox")
|
||||
CreateConfig(nil, T["Hide Group Frames While In Raid"], C.unitframes.group, "hide_in_raid", "checkbox")
|
||||
CreateConfig(nil, T["Max Amount Of Raid Frames"], C.unitframes, "maxraid", "dropdown", pfUI.gui.dropdowns.maxraid)
|
||||
|
||||
@@ -2143,6 +2143,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
|
||||
CreateConfig(nil, T["Druid Settings"], nil, nil, "header")
|
||||
CreateConfig(nil, T["Show Druid Mana Bar"], C.unitframes, "druidmanabar", "checkbox", nil, nil, nil, nil)
|
||||
CreateConfig(nil, T["Show Druid Mana Bar Text"], C.unitframes, "druidmanatext", "checkbox", nil, nil, nil, nil)
|
||||
CreateConfig(nil, T["Druid Mana Bar Height"], C.unitframes, "druidmanaheight", nil, nil, nil, nil, nil)
|
||||
CreateConfig(nil, T["Druid Mana Bar Width (-1 = auto)"], C.unitframes, "druidmanawidth", nil, nil, nil, nil, nil)
|
||||
CreateConfig(nil, T["Druid Mana Bar X-Offset"], C.unitframes, "druidmanaoffx", nil, nil, nil, nil, nil)
|
||||
@@ -2185,6 +2186,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
[10] = { "grouptarget", T["Group-Target"]},
|
||||
[11] = { "grouppet", T["Group-Pet"] },
|
||||
[12] = { "raid", T["Raid"] },
|
||||
[13] = { "raidpet", T["Raid-Pet"] },
|
||||
}
|
||||
|
||||
CreateGUIEntry(T["Unit Frames"], T["Click Casting"], function()
|
||||
@@ -2234,6 +2236,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
U.ptarget = U["pettarget"]
|
||||
U.grouptarget = U["group"]
|
||||
U.grouppet = U["group"]
|
||||
U.raidpet = U["raid"]
|
||||
|
||||
-- build config entries
|
||||
CreateConfig(U[c], T["Display Frame"] .. ": " .. t, C.unitframes[c], "visible", "checkbox")
|
||||
@@ -2278,6 +2281,13 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U["raid"], T["Raid Padding"], C.unitframes[c], "raidpadding")
|
||||
CreateConfig(U["raid"], T["Raid Layout"], C.unitframes[c], "raidlayout", "dropdown", pfUI.gui.dropdowns.uf_raidlayout)
|
||||
CreateConfig(U["raid"], T["Raid Fill Direction"], C.unitframes[c], "raidfill", "dropdown", pfUI.gui.dropdowns.orientation)
|
||||
CreateConfig(U["raid"], T["Collapse Empty Slots"], C.unitframes[c], "collapse", "checkbox")
|
||||
elseif c == "raidpet" then
|
||||
CreateConfig(U[c], T["Layout"], nil, nil, "header")
|
||||
CreateConfig(U["raid"], T["Raid Padding"], C.unitframes[c], "raidpadding")
|
||||
CreateConfig(U["raid"], T["Raid Layout"], C.unitframes[c], "raidlayout", "dropdown", pfUI.gui.dropdowns.uf_raidlayout)
|
||||
CreateConfig(U["raid"], T["Raid Fill Direction"], C.unitframes[c], "raidfill", "dropdown", pfUI.gui.dropdowns.orientation)
|
||||
CreateConfig(U["raid"], T["Collapse Empty Slots"], C.unitframes[c], "collapse", "checkbox")
|
||||
end
|
||||
|
||||
CreateConfig(U[c], T["Healthbar"], nil, nil, "header")
|
||||
@@ -2413,6 +2423,8 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Enable Item Quality Color For Equipment Only"], C.appearance.bags, "borderonlygear", "checkbox")
|
||||
CreateConfig(nil, T["Highlight Unusable Items"], C.appearance.bags, "unusable", "checkbox")
|
||||
CreateConfig(nil, T["Unusable Item Color"], C.appearance.bags, "unusable_color", "color")
|
||||
CreateConfig(nil, T["Highlight New Items"], C.appearance.bags, "newitem", "checkbox")
|
||||
CreateConfig(nil, T["New Item Color"], C.appearance.bags, "newitem_color", "color")
|
||||
CreateConfig(nil, T["Enable Movable Bags"], C.appearance.bags, "movable", "checkbox")
|
||||
CreateConfig(nil, T["Anchor Bags Above Chat"], C.appearance.bags, "abovechat", "checkbox")
|
||||
CreateConfig(nil, T["Hide Chat When Bags Are Opened"], C.appearance.bags, "hidechat", "checkbox")
|
||||
@@ -2423,6 +2435,8 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Auto Sell Grey Items"], C.global, "autosell", "checkbox")
|
||||
CreateConfig(nil, T["Auto Repair Items"], C.global, "autorepair", "checkbox")
|
||||
CreateConfig(nil, T["Auto Sort When Opening Bags"], C.appearance.bags, "autoSortOnOpen", "checkbox")
|
||||
CreateConfig(nil, T["Reverse Sort Direction (Last Bag First)"], C.appearance.bags, "sortreverse", "checkbox")
|
||||
CreateConfig(nil, T["Reverse Sort Priority (Hearthstone Last)"], C.appearance.bags, "sortprioreverse", "checkbox")
|
||||
end)
|
||||
|
||||
CreateGUIEntry(T["Loot"], nil, function()
|
||||
@@ -2573,6 +2587,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U["bars"], T["Switch Pages On Shift Key Press"], C.bars, "pagemastershift", "checkbox")
|
||||
CreateConfig(U["bars"], T["Switch Pages On Ctrl Key Press"], C.bars, "pagemasterctrl", "checkbox")
|
||||
CreateConfig(U["bars"], T["Switch Pages On Druid Stealth"], C.bars, "druidstealth", "checkbox")
|
||||
CreateConfig(U["bars"], T["Switch Pages On Priest Shadowform"], C.bars, "priestshadow", "checkbox")
|
||||
CreateConfig(nil, T["Range Based Hunter Paging"], C.bars, "hunterbar", "checkbox", nil, nil, nil, nil)
|
||||
end)
|
||||
|
||||
@@ -2759,22 +2774,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Show Movement Speed"], C.tooltip, "movespeed", "checkbox")
|
||||
CreateConfig(nil, T["Custom Transparency"], C.tooltip, "alpha")
|
||||
CreateConfig(nil, T["Status Bar Texture"], C.tooltip.statusbar, "texture", "dropdown", pfUI.gui.dropdowns.uf_bartexture)
|
||||
CreateConfig(nil, T["Compare Item Base Stats"], C.tooltip.compare, "basestats", "checkbox")
|
||||
local showAlways = CreateConfig(nil, T["Always Show Item Comparison"], C.tooltip.compare, "showalways", "checkbox")
|
||||
local function gate()
|
||||
local on = C.tooltip.compare.basestats == "1"
|
||||
if on then
|
||||
showAlways.input:Enable()
|
||||
showAlways.caption:SetTextColor(1, 1, 1)
|
||||
else
|
||||
showAlways.input:Disable()
|
||||
showAlways.caption:SetTextColor(0.5, 0.5, 0.5)
|
||||
end
|
||||
end
|
||||
gate()
|
||||
pfUI.events:RegisterCallback("config:changed", function(_, cat, key)
|
||||
if cat == C.tooltip.compare and key == "basestats" then gate() end
|
||||
end, "eqcompare-showalways-gate")
|
||||
CreateConfig(nil, T["Always Show Item Comparison"], C.tooltip.compare, "showalways", "checkbox")
|
||||
CreateConfig(nil, T["Always Show Extended Vendor Values"], C.tooltip.vendor, "showalways", "checkbox")
|
||||
CreateConfig(U["questitem"], T["Show Related Quest On Questitems"], C.tooltip.questitem, "showquest", "checkbox")
|
||||
CreateConfig(U["questitem"], T["Show Required Questitem Count"], C.tooltip.questitem, "showcount", "checkbox")
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
-- Announces Innervate casts via raid/party/battleground chat
|
||||
-- Registers AURA_CAST events directly - zero polling, pure event-driven
|
||||
|
||||
pfUI:RegisterNewModule("innervatecall", "Innervate Callout", "DRUID")
|
||||
pfUI:RegisterModule("innervatecall", function ()
|
||||
-- Requires Nampower for AURA_CAST events
|
||||
if not GetNampowerVersion then return end
|
||||
|
||||
@@ -41,7 +41,7 @@ pfUI:RegisterModule("itemcount", function ()
|
||||
end
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("SetItemRef", function()
|
||||
hooksecurefunc("SetItemRef", function()
|
||||
if ItemRefTooltip:HasItem() then
|
||||
local _, _, id = ItemRefTooltip:GetItem()
|
||||
if id then AddCounts(ItemRefTooltip, id) end
|
||||
|
||||
+4
-4
@@ -236,7 +236,7 @@ pfUI:RegisterModule("loot", function ()
|
||||
if (candidate) then
|
||||
index_to_name[i] = candidate
|
||||
name_to_index[candidate] = i
|
||||
randoms[table.getn(randoms)+1]=i
|
||||
table.insert(randoms, i)
|
||||
if candidate == pfUI.loot.me then
|
||||
pfUI.loot.my_index = i
|
||||
end
|
||||
@@ -392,7 +392,7 @@ pfUI:RegisterModule("loot", function ()
|
||||
end
|
||||
pfUI.loot:RemoveMasterlootMenus() -- remove then add to ensure no duplicate menus
|
||||
pfUI.loot:AddMasterLootMenus()
|
||||
pfUI.hooksecurefunc("UnitPopup_OnClick",function()
|
||||
hooksecurefunc("UnitPopup_OnClick",function()
|
||||
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
||||
if not dropdownFrame then return end
|
||||
local button = this.value
|
||||
@@ -405,7 +405,7 @@ pfUI:RegisterModule("loot", function ()
|
||||
end
|
||||
end
|
||||
end)
|
||||
pfUI.hooksecurefunc("UnitPopup_HideButtons",function()
|
||||
hooksecurefunc("UnitPopup_HideButtons",function()
|
||||
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
||||
local unit = dropdownFrame.unit
|
||||
local name = dropdownFrame.name
|
||||
@@ -693,7 +693,7 @@ pfUI:RegisterModule("loot", function ()
|
||||
else -- not an eligible candidate for that item
|
||||
pfUI.loot.rollers[who] = {roll=tonumber(roll),value="disabled"}
|
||||
end
|
||||
pfUI.loot.rollers_sorted[table.getn(pfUI.loot.rollers_sorted)+1]={who=who,roll=tonumber(roll),value=pfUI.loot.rollers[who].value}
|
||||
table.insert(pfUI.loot.rollers_sorted, {who=who,roll=tonumber(roll),value=pfUI.loot.rollers[who].value})
|
||||
end
|
||||
end
|
||||
table.sort(pfUI.loot.rollers_sorted,function(a,b)
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
pfUI:RegisterModule("loothistory", function ()
|
||||
local rawborder, border = GetBorderSize()
|
||||
|
||||
-- Layout
|
||||
local ITEM_H, PLAYER_H = 24, 18
|
||||
local ITEM_W, PLAYER_W = 350, 330
|
||||
|
||||
-- rollType constants returned by C_LootHistory.GetPlayerInfo (0/1/2; vanilla
|
||||
-- has no disenchant roll).
|
||||
local ROLL_PASS, ROLL_NEED, ROLL_GREED = 0, 1, 2
|
||||
local ROLL_TEX = {
|
||||
[ROLL_NEED] = "Interface\\Buttons\\UI-GroupLoot-Dice-Up",
|
||||
[ROLL_GREED] = "Interface\\Buttons\\UI-GroupLoot-Coin-Up",
|
||||
[ROLL_PASS] = "Interface\\Buttons\\UI-GroupLoot-Pass-Up",
|
||||
}
|
||||
local WINMARK = "Interface\\Buttons\\UI-CheckBox-Check"
|
||||
local QUESTIONMARK = "Interface\\Icons\\INV_Misc_QuestionMark"
|
||||
|
||||
local function ClassColor(class)
|
||||
local c = class and RAID_CLASS_COLORS[class]
|
||||
if c then return c.r, c.g, c.b end
|
||||
return 1, 1, 1
|
||||
end
|
||||
|
||||
-- Paint an item row's icon/name/quality from a loaded Item mixin.
|
||||
local function RenderItemVisual(f, item)
|
||||
local r, g, b = 1, 1, 1
|
||||
local qc = item:GetItemQualityColor()
|
||||
if qc then r, g, b = qc.r, qc.g, qc.b end
|
||||
f.icon:SetTexture(item:GetItemIcon())
|
||||
f.iconbg:SetBackdropBorderColor(r, g, b, 1)
|
||||
f.name:SetText(item:GetItemName() or UNKNOWN)
|
||||
f.name:SetTextColor(r, g, b)
|
||||
end
|
||||
|
||||
local function ShowRetrieving(f)
|
||||
f.icon:SetTexture(QUESTIONMARK)
|
||||
f.iconbg:SetBackdropBorderColor(1, .3, .3, 1)
|
||||
f.name:SetText(T["Retrieving item information..."])
|
||||
f.name:SetTextColor(1, .3, .3)
|
||||
end
|
||||
|
||||
-- expansion state keyed on the stable rollID (survives ring-index shifts)
|
||||
local expanded = {}
|
||||
|
||||
-- ==========================================================================
|
||||
-- Window
|
||||
-- ==========================================================================
|
||||
pfUI.loothistory = CreateFrame("Frame", "pfLootHistory", UIParent)
|
||||
pfUI.loothistory:SetFrameStrata("DIALOG")
|
||||
pfUI.loothistory:SetSize(380, 490)
|
||||
pfUI.loothistory:SetPoint("CENTER", 0, 0)
|
||||
pfUI.loothistory:SetMovable(true)
|
||||
pfUI.loothistory:EnableMouse(true)
|
||||
pfUI.loothistory:RegisterForDrag("LeftButton")
|
||||
pfUI.loothistory:SetScript("OnDragStart", function() this:StartMoving() end)
|
||||
pfUI.loothistory:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
|
||||
pfUI.loothistory:Hide()
|
||||
|
||||
CreateBackdrop(pfUI.loothistory, nil, true, .75)
|
||||
CreateBackdropShadow(pfUI.loothistory)
|
||||
tinsert(UISpecialFrames, "pfLootHistory")
|
||||
|
||||
pfUI.loothistory.caption = pfUI.loothistory:CreateFontString("Status", "LOW", "GameFontNormal")
|
||||
pfUI.loothistory.caption:SetFont(pfUI.font_default, C.global.font_size + 4, "OUTLINE")
|
||||
pfUI.loothistory.caption:SetTextColor(.2, 1, .8, 1)
|
||||
pfUI.loothistory.caption:SetPoint("TOP", 0, -10)
|
||||
pfUI.loothistory.caption:SetText(T["Loot History"])
|
||||
|
||||
-- close button
|
||||
pfUI.loothistory.close = CreateFrame("Button", nil, pfUI.loothistory)
|
||||
pfUI.loothistory.close:SetPoint("TOPRIGHT", -border*2, -border*2)
|
||||
CreateBackdrop(pfUI.loothistory.close)
|
||||
pfUI.loothistory.close:SetSize(15, 15)
|
||||
pfUI.loothistory.close.texture = pfUI.loothistory.close:CreateTexture("pfLootHistoryClose")
|
||||
pfUI.loothistory.close.texture:SetTexture(pfUI.media["img:close"])
|
||||
pfUI.loothistory.close.texture:SetPoint("TOPLEFT", pfUI.loothistory.close, "TOPLEFT", 4, -4)
|
||||
pfUI.loothistory.close.texture:SetPoint("BOTTOMRIGHT", pfUI.loothistory.close, "BOTTOMRIGHT", -4, 4)
|
||||
pfUI.loothistory.close.texture:SetVertexColor(1, .25, .25, 1)
|
||||
pfUI.loothistory.close:SetScript("OnEnter", function()
|
||||
CreateBackdrop(pfUI.loothistory.close)
|
||||
pfUI.loothistory.close.backdrop:SetBackdropBorderColor(1, .25, .25, 1)
|
||||
end)
|
||||
pfUI.loothistory.close:SetScript("OnLeave", function() CreateBackdrop(pfUI.loothistory.close) end)
|
||||
pfUI.loothistory.close:SetScript("OnClick", function() pfUI.loothistory:Hide() end)
|
||||
|
||||
-- clear button
|
||||
pfUI.loothistory.clear = CreateFrame("Button", nil, pfUI.loothistory, "UIPanelButtonTemplate")
|
||||
SkinButton(pfUI.loothistory.clear)
|
||||
pfUI.loothistory.clear:SetSize(60, 16)
|
||||
pfUI.loothistory.clear:SetPoint("TOPLEFT", 10, -8)
|
||||
pfUI.loothistory.clear:SetText(T["Clear"])
|
||||
pfUI.loothistory.clear:SetScript("OnClick", function() C_LootHistory.Clear() end)
|
||||
|
||||
-- scroll frame
|
||||
pfUI.loothistory.scroll = CreateScrollFrame("pfLootHistoryScroll", pfUI.loothistory)
|
||||
pfUI.loothistory.scroll:SetSize(360, 440)
|
||||
pfUI.loothistory.scroll:SetPoint("BOTTOM", 0, 10)
|
||||
|
||||
pfUI.loothistory.scroll.backdrop = CreateFrame("Frame", nil, pfUI.loothistory.scroll)
|
||||
pfUI.loothistory.scroll.backdrop:SetFrameLevel(1)
|
||||
pfUI.loothistory.scroll.backdrop:SetPoint("TOPLEFT", pfUI.loothistory.scroll, "TOPLEFT", -5, 5)
|
||||
pfUI.loothistory.scroll.backdrop:SetPoint("BOTTOMRIGHT", pfUI.loothistory.scroll, "BOTTOMRIGHT", 5, -5)
|
||||
CreateBackdrop(pfUI.loothistory.scroll.backdrop, nil, true)
|
||||
|
||||
local list = CreateScrollChild("pfLootHistoryList", pfUI.loothistory.scroll)
|
||||
pfUI.loothistory.list = list
|
||||
|
||||
-- ==========================================================================
|
||||
-- Frame pools
|
||||
-- ==========================================================================
|
||||
local itemFrames = {}
|
||||
local usedPlayers, freePlayers = {}, {}
|
||||
|
||||
local FullUpdate -- forward declaration (toggle handlers call it)
|
||||
|
||||
local function CreateItemFrame()
|
||||
local f = CreateFrame("Button", nil, list)
|
||||
f:SetSize(ITEM_W, ITEM_H)
|
||||
f:SetBackdrop(pfUI.backdrop_hover)
|
||||
f:SetBackdropBorderColor(1, 1, 1, .04)
|
||||
f:EnableMouse(1)
|
||||
|
||||
-- expand / collapse toggle
|
||||
f.toggle = CreateFrame("Button", nil, f)
|
||||
f.toggle:SetSize(14, 14)
|
||||
f.toggle:SetPoint("LEFT", 4, 0)
|
||||
f.toggle:SetScript("OnClick", function()
|
||||
local id = f.rollID
|
||||
if id then expanded[id] = not expanded[id]; FullUpdate() end
|
||||
end)
|
||||
|
||||
-- icon + quality-colored border
|
||||
f.iconbg = CreateFrame("Frame", nil, f)
|
||||
f.iconbg:SetSize(ITEM_H - 8, ITEM_H - 8)
|
||||
f.iconbg:SetPoint("LEFT", f.toggle, "RIGHT", 4, 0)
|
||||
CreateBackdrop(f.iconbg, nil, true)
|
||||
f.icon = f.iconbg:CreateTexture(nil, "ARTWORK")
|
||||
f.icon:SetPoint("TOPLEFT", f.iconbg, "TOPLEFT", 2, -2)
|
||||
f.icon:SetPoint("BOTTOMRIGHT", f.iconbg, "BOTTOMRIGHT", -2, 2)
|
||||
f.icon:SetTexCoord(.08, .92, .08, .92)
|
||||
|
||||
-- winner block (right side, shown for decided rolls)
|
||||
f.winicon = f:CreateTexture(nil, "OVERLAY")
|
||||
f.winicon:SetSize(14, 14)
|
||||
f.winicon:SetPoint("RIGHT", f, "RIGHT", -6, 0)
|
||||
|
||||
f.winroll = f:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
f.winroll:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
f.winroll:SetPoint("RIGHT", f.winicon, "LEFT", -2, 0)
|
||||
f.winroll:SetTextColor(1, 1, 1, 1)
|
||||
|
||||
f.winname = f:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
f.winname:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
f.winname:SetPoint("RIGHT", f.winroll, "LEFT", -4, 0)
|
||||
f.winname:SetJustifyH("RIGHT")
|
||||
|
||||
-- item name (leaves room on the right for the winner block)
|
||||
f.name = f:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
f.name:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
f.name:SetPoint("LEFT", f.iconbg, "RIGHT", 5, 0)
|
||||
f.name:SetPoint("RIGHT", f, "RIGHT", -100, 0)
|
||||
f.name:SetJustifyH("LEFT")
|
||||
|
||||
f:SetScript("OnEnter", function()
|
||||
this:SetBackdropBorderColor(1, 1, 1, .08)
|
||||
if this.itemLink then
|
||||
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetHyperlink(this.itemLink)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end)
|
||||
f:SetScript("OnLeave", function()
|
||||
this:SetBackdropBorderColor(1, 1, 1, .04)
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
f:SetScript("OnClick", function()
|
||||
local id = this.rollID
|
||||
if id then expanded[id] = not expanded[id]; FullUpdate() end
|
||||
end)
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
local function CreatePlayerFrame()
|
||||
local f = CreateFrame("Frame", nil, list)
|
||||
f:SetSize(PLAYER_W, PLAYER_H)
|
||||
|
||||
-- name is indented to leave room for the winner checkmark on its left
|
||||
f.name = f:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
f.name:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
f.name:SetPoint("LEFT", 20, 0)
|
||||
f.name:SetJustifyH("LEFT")
|
||||
|
||||
f.rollicon = f:CreateTexture(nil, "OVERLAY")
|
||||
f.rollicon:SetSize(16, 16)
|
||||
f.rollicon:SetPoint("RIGHT", -4, 0)
|
||||
|
||||
f.rolltext = f:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
f.rolltext:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
f.rolltext:SetPoint("RIGHT", f.rollicon, "LEFT", -3, 0)
|
||||
f.rolltext:SetTextColor(1, 1, 1, 1)
|
||||
|
||||
-- winner checkmark, just left of the player name (matches reference)
|
||||
f.winmark = f:CreateTexture(nil, "OVERLAY")
|
||||
f.winmark:SetSize(16, 16)
|
||||
f.winmark:SetTexture(WINMARK)
|
||||
f.winmark:SetPoint("RIGHT", f.name, "LEFT", -1, 0)
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
local function RecycleAllPlayers()
|
||||
for i = 1, table.getn(usedPlayers) do
|
||||
local pf = usedPlayers[i]
|
||||
pf:Hide()
|
||||
table.insert(freePlayers, pf)
|
||||
end
|
||||
usedPlayers = {}
|
||||
end
|
||||
|
||||
local function GetPlayerFrame()
|
||||
local pf = table.remove(freePlayers) or CreatePlayerFrame()
|
||||
table.insert(usedPlayers, pf)
|
||||
return pf
|
||||
end
|
||||
|
||||
local function SetToggleTexture(toggle, isExpanded)
|
||||
if isExpanded then
|
||||
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up")
|
||||
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-Down")
|
||||
else
|
||||
toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up")
|
||||
toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-Down")
|
||||
end
|
||||
end
|
||||
|
||||
-- ==========================================================================
|
||||
-- Rendering
|
||||
-- ==========================================================================
|
||||
local function UpdateItemFrame(f, i)
|
||||
local rollID, itemLink, numPlayers, isDone, winnerIdx = C_LootHistory.GetItem(i)
|
||||
f.rollID = rollID
|
||||
f.itemIdx = i
|
||||
f.itemLink = itemLink
|
||||
f.numPlayers = numPlayers or 0
|
||||
f.isDone = isDone
|
||||
|
||||
local isExpanded = rollID and expanded[rollID]
|
||||
SetToggleTexture(f.toggle, isExpanded)
|
||||
|
||||
-- Item icon/name/quality via the ClassicAPI Item mixin. When the item
|
||||
-- isn't cached yet, show a placeholder and re-paint this row from the
|
||||
-- ContinueOnItemLoad callback (guarded on rollID: rows are pooled, so the
|
||||
-- callback must no-op if the row has since been reused for another roll).
|
||||
local item = itemLink and Item:CreateFromItemLink(itemLink)
|
||||
if item and not item:IsItemEmpty() then
|
||||
if item:IsItemDataCached() then
|
||||
RenderItemVisual(f, item)
|
||||
else
|
||||
ShowRetrieving(f)
|
||||
local pending = rollID
|
||||
item:ContinueOnItemLoad(function()
|
||||
if f.rollID == pending then RenderItemVisual(f, item) end
|
||||
end)
|
||||
end
|
||||
else
|
||||
ShowRetrieving(f)
|
||||
end
|
||||
|
||||
-- winner summary only on a decided, collapsed row
|
||||
if isDone and not isExpanded then
|
||||
if winnerIdx then
|
||||
local wname, wclass, wrollType, wroll = C_LootHistory.GetPlayerInfo(i, winnerIdx)
|
||||
f.winicon:SetTexture(ROLL_TEX[wrollType] or ROLL_TEX[ROLL_NEED])
|
||||
f.winicon:Show()
|
||||
if wroll and wroll > 0 then f.winroll:SetText(wroll) else f.winroll:SetText("") end
|
||||
f.winroll:Show()
|
||||
f.winname:SetText(wname or UNKNOWN)
|
||||
f.winname:SetTextColor(ClassColor(wclass))
|
||||
f.winname:Show()
|
||||
else
|
||||
-- nobody won: everyone passed
|
||||
f.winicon:SetTexture(ROLL_TEX[ROLL_PASS])
|
||||
f.winicon:Show()
|
||||
f.winroll:SetText("")
|
||||
f.winroll:Show()
|
||||
f.winname:SetText(T["All players passed"])
|
||||
f.winname:SetTextColor(1, .4, .4)
|
||||
f.winname:Show()
|
||||
end
|
||||
else
|
||||
f.winicon:Hide()
|
||||
f.winroll:Hide()
|
||||
f.winname:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function RenderPlayerFrame(pf, name, class, rollType, roll, isWinner)
|
||||
pf.name:SetText(name or UNKNOWN)
|
||||
pf.name:SetTextColor(ClassColor(class))
|
||||
|
||||
pf.rollicon:SetTexture(ROLL_TEX[rollType] or ROLL_TEX[ROLL_PASS])
|
||||
if roll and roll > 0 then pf.rolltext:SetText(roll) else pf.rolltext:SetText("") end
|
||||
|
||||
if isWinner then pf.winmark:Show() else pf.winmark:Hide() end
|
||||
end
|
||||
|
||||
-- A player row is worth showing while the roll is undecided (see everyone),
|
||||
-- or afterwards only if they actually rolled or it's you (hide the passers'
|
||||
-- noise on a decided roll) — mirrors Blizzard's ShouldDisplayPlayer.
|
||||
local function ShouldDisplayPlayer(isDone, roll, isMe)
|
||||
return isMe or (roll and roll > 0) or not isDone
|
||||
end
|
||||
|
||||
function FullUpdate()
|
||||
if not pfUI.loothistory:IsShown() then return end
|
||||
RecycleAllPlayers()
|
||||
|
||||
local num = C_LootHistory.GetNumItems()
|
||||
local y = -2
|
||||
|
||||
for i = 1, num do
|
||||
local f = itemFrames[i] or CreateItemFrame()
|
||||
itemFrames[i] = f
|
||||
UpdateItemFrame(f, i)
|
||||
f:ClearAllPoints()
|
||||
f:SetPoint("TOPLEFT", list, "TOPLEFT", 4, y)
|
||||
f:Show()
|
||||
y = y - ITEM_H - 2
|
||||
|
||||
if f.rollID and expanded[f.rollID] then
|
||||
for p = 1, f.numPlayers do
|
||||
local name, class, rollType, roll, isWinner, isMe = C_LootHistory.GetPlayerInfo(i, p)
|
||||
if ShouldDisplayPlayer(f.isDone, roll, isMe) then
|
||||
local pf = GetPlayerFrame()
|
||||
RenderPlayerFrame(pf, name, class, rollType, roll, isWinner)
|
||||
pf:ClearAllPoints()
|
||||
pf:SetPoint("TOPLEFT", list, "TOPLEFT", 22, y)
|
||||
pf:Show()
|
||||
y = y - PLAYER_H
|
||||
end
|
||||
end
|
||||
y = y - 2
|
||||
end
|
||||
end
|
||||
|
||||
for i = num + 1, table.getn(itemFrames) do
|
||||
itemFrames[i]:Hide()
|
||||
end
|
||||
|
||||
-- Resize the scroll child and re-attach it: SetHeight alone on a
|
||||
-- SetAllPoints'd child doesn't make the ScrollFrame recompute its scroll
|
||||
-- range, so a dynamically-grown list wouldn't scroll until a /reload.
|
||||
list:SetHeight(math.max(1, -y + 2))
|
||||
pfUI.loothistory.scroll:SetScrollChild(list)
|
||||
pfUI.loothistory.scroll:UpdateScrollState()
|
||||
end
|
||||
|
||||
pfUI.loothistory:SetScript("OnShow", function() FullUpdate() end)
|
||||
|
||||
-- ==========================================================================
|
||||
-- Events
|
||||
-- ==========================================================================
|
||||
local events = CreateFrame("Frame")
|
||||
events:RegisterEvent("LOOT_HISTORY_FULL_UPDATE")
|
||||
events:RegisterEvent("LOOT_HISTORY_ROLL_CHANGED")
|
||||
events:RegisterEvent("LOOT_HISTORY_ROLL_COMPLETE")
|
||||
events:SetScript("OnEvent", function()
|
||||
-- auto-show on a new roll opening / completing, if enabled
|
||||
if C.loothistory.autoshow == "1"
|
||||
and (event == "LOOT_HISTORY_FULL_UPDATE" or event == "LOOT_HISTORY_ROLL_COMPLETE")
|
||||
and not pfUI.loothistory:IsShown() then
|
||||
pfUI.loothistory:Show() -- OnShow runs FullUpdate
|
||||
return
|
||||
end
|
||||
FullUpdate() -- no-op while hidden
|
||||
end)
|
||||
|
||||
-- ==========================================================================
|
||||
-- Slash command
|
||||
-- ==========================================================================
|
||||
local function Toggle()
|
||||
pfUI.loothistory:SetShown(not pfUI.loothistory:IsShown())
|
||||
end
|
||||
|
||||
pfUI.api.RegisterSlashCommand("PFLOOTHISTORY", { "/loothistory", "/pfloothistory" }, Toggle, true)
|
||||
end)
|
||||
+6
-10
@@ -2,15 +2,14 @@ pfUI:RegisterModule("macrotweak", function ()
|
||||
local conflictAddons = { "Supermacro", "SuperCleveRoidMacros", "UltimaMacros" }
|
||||
local disabled = false
|
||||
|
||||
local function CheckConflicts()
|
||||
for _, name in pairs(conflictAddons) do
|
||||
if IsAddOnLoaded(name) then
|
||||
for _, addon in pairs(conflictAddons) do
|
||||
local name = addon
|
||||
EventUtil.ContinueOnAddOnLoaded(name, function()
|
||||
if not disabled then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: " .. name .. " found, macrotweak disabled.")
|
||||
disabled = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
disabled = true
|
||||
end)
|
||||
end
|
||||
|
||||
-- do not write macro calls into chat input history
|
||||
@@ -64,7 +63,4 @@ pfUI:RegisterModule("macrotweak", function ()
|
||||
UseInventoryItem(slot)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Check conflicts after one tick so all addons have finished loading
|
||||
RunNextFrame(CheckConflicts)
|
||||
end)
|
||||
+1
-5
@@ -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 }
|
||||
|
||||
@@ -125,13 +125,13 @@ pfUI:RegisterModule("mapcolors", function ()
|
||||
|
||||
-- WorldMap
|
||||
Initialize('WorldMap')
|
||||
pfUI.hooksecurefunc('WorldMapButton_OnUpdate', function()
|
||||
hooksecurefunc('WorldMapButton_OnUpdate', function()
|
||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||
UpdateUnitFrames('WorldMap')
|
||||
end)
|
||||
|
||||
if C.appearance.worldmap.colornames == "1" then
|
||||
pfUI.hooksecurefunc('WorldMapUnit_OnEnter', function()
|
||||
hooksecurefunc('WorldMapUnit_OnEnter', function()
|
||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||
UpdateUnitColors('WorldMap', WorldMapTooltip)
|
||||
end)
|
||||
@@ -141,13 +141,13 @@ pfUI:RegisterModule("mapcolors", function ()
|
||||
HookAddonOrVariable("Blizzard_BattlefieldMinimap", function()
|
||||
Initialize('BattlefieldMinimap')
|
||||
|
||||
pfUI.hooksecurefunc('BattlefieldMinimap_OnUpdate', function()
|
||||
hooksecurefunc('BattlefieldMinimap_OnUpdate', function()
|
||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||
UpdateUnitFrames('BattlefieldMinimap')
|
||||
end)
|
||||
|
||||
if C.appearance.worldmap.colornames == "1" then
|
||||
pfUI.hooksecurefunc('BattlefieldMinimapUnit_OnEnter', function()
|
||||
hooksecurefunc('BattlefieldMinimapUnit_OnEnter', function()
|
||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||
UpdateUnitColors('BattlefieldMinimap', GameTooltip)
|
||||
end)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
pfUI:RegisterNewModule("marktracking", "Mark Tracker")
|
||||
pfUI:RegisterModule("marktracking", function ()
|
||||
-- Requires mark1-mark8 unit tokens (Turtle WoW / Nampower)
|
||||
if not UnitExists("mark1") and not UnitExists("mark8") then
|
||||
|
||||
+10
-27
@@ -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)
|
||||
@@ -58,7 +56,7 @@ pfUI:RegisterModule("minimap", function ()
|
||||
|
||||
pfUI.minimap:UpdateConfig()
|
||||
|
||||
pfUI.hooksecurefunc("ToggleMinimap", function()
|
||||
hooksecurefunc("ToggleMinimap", function()
|
||||
if pfUI.farmmap and pfUI.farmmap:IsShown() then
|
||||
Minimap:Hide()
|
||||
return
|
||||
@@ -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)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
pfUI:RegisterModule("mouseover", function ()
|
||||
_G.SLASH_PFCAST1, _G.SLASH_PFCAST2 = "/pfcast", "/pfmouse"
|
||||
function SlashCmdList.PFCAST(msg)
|
||||
pfUI.api.RegisterSlashCommand("PFCAST", { "/pfcast", "/pfmouse" }, function(msg)
|
||||
local func = pfUI.api.TryMemoizedFuncLoadstringForSpellCasts(msg)
|
||||
local unit = "mouseover"
|
||||
|
||||
@@ -30,5 +29,5 @@ pfUI:RegisterModule("mouseover", function ()
|
||||
if restore_target then TargetUnit(unit) end
|
||||
func()
|
||||
if restore_target then TargetLastTarget() end
|
||||
end
|
||||
end, true)
|
||||
end)
|
||||
+71
-111
@@ -15,8 +15,6 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
local UnitCanAssist = UnitCanAssist
|
||||
local UnitHealth = UnitHealth
|
||||
local UnitHealthMax = UnitHealthMax
|
||||
local UnitMana = UnitMana
|
||||
local UnitManaMax = UnitManaMax
|
||||
local pairs = pairs
|
||||
local tonumber = tonumber
|
||||
local strlower = strlower
|
||||
@@ -63,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
|
||||
@@ -89,7 +85,6 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
}
|
||||
end
|
||||
|
||||
local guidTargetTokenCache = {} -- guid -> "<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 }
|
||||
@@ -167,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()
|
||||
@@ -191,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
|
||||
@@ -203,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 "<guid>target" token needed.
|
||||
local target = token .. "target"
|
||||
local mobTargetGuid = UnitGUID(target)
|
||||
local hasTarget = mobTargetGuid and mobTargetGuid ~= NULL_GUID
|
||||
|
||||
-- PERF: cache the SuperWoW-style "<guid>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")
|
||||
|
||||
@@ -468,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
|
||||
@@ -544,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
|
||||
@@ -560,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
|
||||
@@ -988,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
|
||||
@@ -1072,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)
|
||||
@@ -1091,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
|
||||
@@ -1150,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
|
||||
@@ -1270,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)
|
||||
@@ -1302,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
|
||||
@@ -1374,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
|
||||
@@ -1383,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
|
||||
|
||||
@@ -1441,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
|
||||
@@ -1495,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
|
||||
@@ -1515,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
|
||||
|
||||
@@ -1524,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
|
||||
@@ -1591,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
|
||||
@@ -1637,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)
|
||||
|
||||
+19
-220
@@ -15,8 +15,7 @@ pfUI:RegisterModule("nampower", function ()
|
||||
|
||||
pfUI.spellqueue = CreateFrame("Frame", "pfSpellQueue", UIParent)
|
||||
pfUI.spellqueue:SetFrameStrata("HIGH")
|
||||
pfUI.spellqueue:SetWidth(size)
|
||||
pfUI.spellqueue:SetHeight(size)
|
||||
pfUI.spellqueue:SetSize(size, size)
|
||||
pfUI.spellqueue:Hide()
|
||||
|
||||
-- Position near player castbar if available
|
||||
@@ -53,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)
|
||||
@@ -74,21 +72,21 @@ pfUI:RegisterModule("nampower", function ()
|
||||
-- Shows when reactive abilities like Overpower, Revenge, Execute are usable
|
||||
if C.unitframes.reactive_indicator == "1" then
|
||||
local size = tonumber(C.unitframes.reactive_size) or 28
|
||||
local _, class = UnitClass("player")
|
||||
local class = UnitClassBase("player")
|
||||
|
||||
-- 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
|
||||
},
|
||||
}
|
||||
|
||||
@@ -97,21 +95,19 @@ 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()
|
||||
|
||||
pfUI.reactive.icons = {}
|
||||
for i, spell in ipairs(spells) do
|
||||
local icon = CreateFrame("Frame", nil, pfUI.reactive)
|
||||
icon:SetWidth(size)
|
||||
icon:SetHeight(size)
|
||||
icon:SetSize(size, size)
|
||||
icon:SetPoint("LEFT", pfUI.reactive, "LEFT", (i-1) * (size + 4), 0)
|
||||
|
||||
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")
|
||||
@@ -122,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
|
||||
|
||||
@@ -132,27 +128,17 @@ pfUI:RegisterModule("nampower", function ()
|
||||
local anyVisible = false
|
||||
for _, icon in ipairs(this.icons) do
|
||||
local usable = C_Spell.IsSpellUsable(icon.spellName)
|
||||
if usable then
|
||||
icon:Show()
|
||||
anyVisible = true
|
||||
else
|
||||
icon:Hide()
|
||||
end
|
||||
end
|
||||
if anyVisible then
|
||||
this:Show()
|
||||
else
|
||||
this:Hide()
|
||||
icon:SetShown(usable)
|
||||
anyVisible = anyVisible or usable
|
||||
end
|
||||
this:SetShown(anyVisible)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- /disenchantall slash command (DisenchantAll is Nampower-provided)
|
||||
if DisenchantAll then
|
||||
_G.SLASH_PFDISENCHANTALL1 = "/disenchantall"
|
||||
_G.SLASH_PFDISENCHANTALL2 = "/dea"
|
||||
SlashCmdList["PFDISENCHANTALL"] = function(msg)
|
||||
pfUI.api.RegisterSlashCommand("PFDISENCHANTALL", { "/disenchantall", "/dea" }, function(msg)
|
||||
-- DisenchantAll(itemIdOrName | quality, [includeSoulbound]).
|
||||
-- Quality is a string keyword ("greens", "blues", "purples", or pipe-
|
||||
-- combined). Numbers are interpreted as item IDs, not quality levels.
|
||||
@@ -160,195 +146,8 @@ 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) .. ")")
|
||||
end
|
||||
print("|cff33ffccpfUI|r: DisenchantAll(" .. tostring(target) .. ")")
|
||||
end, true)
|
||||
end
|
||||
|
||||
-- Druid Secondary Mana Bar
|
||||
-- Shows base mana when druid is in shapeshift form (Bear/Cat uses Rage/Energy)
|
||||
-- Uses Nampower's GetUnitField to get base mana values
|
||||
-- Fully self-contained: uses its own config settings from C.unitframes.druidmana*
|
||||
if GetUnitField and pfUI.uf and pfUI_config.unitframes.druidmanabar == "1" then
|
||||
local rawborder, default_border = GetBorderSize("unitframes")
|
||||
local DC = C.unitframes -- druid mana config lives here as druidmana* keys
|
||||
|
||||
-- Shared helper: create a druid mana bar on a unit frame
|
||||
local function CreateDruidManaBar(parent, unit)
|
||||
if not parent then return nil end
|
||||
|
||||
local parentConfig = parent.config
|
||||
|
||||
-- Read own config values
|
||||
local dmHeight = tonumber(DC.druidmanaheight) or 10
|
||||
local dmWidth = DC.druidmanawidth or "-1"
|
||||
local dmOffX = tonumber(DC.druidmanaoffx) or 0
|
||||
local dmOffY = tonumber(DC.druidmanaoffy) or 0
|
||||
local dmSpace = tonumber(DC.druidmanaspace) or -3
|
||||
local dmTexture = DC.druidmanatexture or "Interface\\AddOns\\pfUI\\img\\bar"
|
||||
|
||||
local bar = CreateFrame("StatusBar", "pfDruidMana_" .. unit, parent)
|
||||
bar:SetFrameStrata(parent:GetFrameStrata())
|
||||
bar:SetFrameLevel(parent:GetFrameLevel() + 5)
|
||||
bar:SetStatusBarTexture(pfUI.media[dmTexture] or dmTexture)
|
||||
|
||||
-- Bar color: use same manacolor logic as the normal power bar
|
||||
local manacolor = parentConfig.defcolor == "0" and parentConfig.manacolor or C.unitframes.manacolor
|
||||
local r, g, b, a = pfUI.api.strsplit(",", manacolor)
|
||||
bar:SetStatusBarColor(tonumber(r) or .25, tonumber(g) or .25, tonumber(b) or 1, tonumber(a) or 1)
|
||||
|
||||
-- Size: own width/height, fallback to parent power bar width if -1
|
||||
local width = dmWidth ~= "-1" and tonumber(dmWidth) or nil
|
||||
if width then
|
||||
bar:SetWidth(width)
|
||||
end
|
||||
bar:SetHeight(dmHeight)
|
||||
|
||||
-- Position below the power bar with own spacing + offsets
|
||||
local spacing = -2 * default_border - dmSpace
|
||||
if width then
|
||||
-- Fixed width: use single point with offset
|
||||
bar:SetPoint("TOP", parent.power, "BOTTOM", dmOffX, spacing + dmOffY)
|
||||
else
|
||||
-- Auto width: anchor to both sides of power bar
|
||||
bar:SetPoint("TOPLEFT", parent.power, "BOTTOMLEFT", dmOffX, spacing + dmOffY)
|
||||
bar:SetPoint("TOPRIGHT", parent.power, "BOTTOMRIGHT", dmOffX, spacing + dmOffY)
|
||||
end
|
||||
bar:Hide()
|
||||
|
||||
CreateBackdrop(bar)
|
||||
CreateBackdropShadow(bar)
|
||||
|
||||
-- Font settings (same logic as power bar)
|
||||
local fontname = pfUI.font_unit
|
||||
local fontsize = tonumber(pfUI_config.global.font_unit_size)
|
||||
local fontstyle = pfUI_config.global.font_unit_style
|
||||
|
||||
if parentConfig.customfont == "1" then
|
||||
fontname = pfUI.media[parentConfig.customfont_name]
|
||||
fontsize = tonumber(parentConfig.customfont_size)
|
||||
fontstyle = parentConfig.customfont_style
|
||||
end
|
||||
|
||||
-- Text color (always mana-colored)
|
||||
local tr, tg, tb = ManaBarColor[0].r, ManaBarColor[0].g, ManaBarColor[0].b
|
||||
if C.unitframes.pastel == "1" then
|
||||
tr, tg, tb = (tr + .75) * .5, (tg + .75) * .5, (tb + .75) * .5
|
||||
end
|
||||
|
||||
-- Single center text showing current/max
|
||||
bar.text = bar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
||||
bar.text:SetFontObject(GameFontWhite)
|
||||
bar.text:SetFont(fontname, fontsize, fontstyle)
|
||||
bar.text:SetPoint("CENTER", bar, "CENTER", 0, 0)
|
||||
bar.text:SetJustifyH("CENTER")
|
||||
bar.text:SetTextColor(tr, tg, tb, 1)
|
||||
|
||||
return bar
|
||||
end
|
||||
|
||||
-- Shared helper: update druid mana bar values and text
|
||||
local function UpdateDruidManaBar(bar, unit)
|
||||
if not UnitExists(unit) then
|
||||
bar:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
-- For non-player units, only show if the target is a Druid
|
||||
if unit ~= "player" then
|
||||
local _, unitClass = UnitClass(unit)
|
||||
if unitClass ~= "DRUID" then
|
||||
bar:Hide()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local powerType = UnitPowerType(unit)
|
||||
|
||||
-- Only show when NOT using mana (i.e., in Bear/Cat form)
|
||||
if powerType == 0 then
|
||||
bar:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
-- Get base mana using Nampower's GetUnitField
|
||||
local baseMana, baseMaxMana
|
||||
local guid = UnitGUID(unit)
|
||||
|
||||
if guid then
|
||||
baseMana = GetUnitField(guid, "power1")
|
||||
baseMaxMana = GetUnitField(guid, "maxPower1")
|
||||
end
|
||||
|
||||
-- Round down power values (Nampower can return decimals)
|
||||
if baseMana then baseMana = math.floor(baseMana) end
|
||||
if baseMaxMana then baseMaxMana = math.floor(baseMaxMana) end
|
||||
|
||||
if type(baseMana) ~= "number" or type(baseMaxMana) ~= "number" or baseMaxMana == 0 then
|
||||
bar:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
-- Update bar
|
||||
bar:SetMinMaxValues(0, baseMaxMana)
|
||||
bar:SetValue(baseMana)
|
||||
|
||||
-- Always show current/max
|
||||
bar.text:SetText(string.format("%s/%s", Abbreviate(baseMana), Abbreviate(baseMaxMana)))
|
||||
|
||||
bar:Show()
|
||||
end
|
||||
|
||||
-- ===== Player Druid Mana Bar =====
|
||||
local _, playerClass = UnitClass("player")
|
||||
if pfUI.uf.player and playerClass == "DRUID" then
|
||||
local playerMana = CreateDruidManaBar(pfUI.uf.player, "player")
|
||||
|
||||
if playerMana then
|
||||
playerMana:RegisterEvent("UNIT_MANA")
|
||||
playerMana:RegisterEvent("UNIT_MAXMANA")
|
||||
playerMana:RegisterEvent("UNIT_DISPLAYPOWER")
|
||||
playerMana:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
|
||||
playerMana:RegisterEvent("PLAYER_LOGOUT")
|
||||
playerMana:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
return
|
||||
end
|
||||
if arg1 == nil or arg1 == "player" then
|
||||
UpdateDruidManaBar(playerMana, "player")
|
||||
end
|
||||
end)
|
||||
|
||||
-- Initial update
|
||||
UpdateDruidManaBar(playerMana, "player")
|
||||
end
|
||||
end
|
||||
|
||||
-- ===== Target Druid Mana Bar =====
|
||||
if pfUI.uf.target then
|
||||
local targetMana = CreateDruidManaBar(pfUI.uf.target, "target")
|
||||
|
||||
if targetMana then
|
||||
targetMana:RegisterEvent("UNIT_MANA")
|
||||
targetMana:RegisterEvent("UNIT_MAXMANA")
|
||||
targetMana:RegisterEvent("UNIT_DISPLAYPOWER")
|
||||
targetMana:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
targetMana:RegisterEvent("PLAYER_LOGOUT")
|
||||
targetMana:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
return
|
||||
end
|
||||
if event == "PLAYER_TARGET_CHANGED" or arg1 == nil or arg1 == "target" then
|
||||
UpdateDruidManaBar(targetMana, "target")
|
||||
end
|
||||
end)
|
||||
|
||||
-- Initial update
|
||||
UpdateDruidManaBar(targetMana, "target")
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,68 @@
|
||||
pfUI:RegisterModule("newitem", function ()
|
||||
if not pfUI.bag then return end
|
||||
if C.appearance.bags.newitem ~= "1" then return end
|
||||
|
||||
pfUI.newitem = {}
|
||||
|
||||
local color = CreateColor(strsplit(",", C.appearance.bags.newitem_color))
|
||||
|
||||
function pfUI.newitem:UpdateSlot(bag, slot)
|
||||
if bag < 0 or bag > 4 then return end
|
||||
if not pfUI.bags[bag] then return end
|
||||
if not pfUI.bags[bag].slots[slot] then return end
|
||||
|
||||
local frame = pfUI.bags[bag].slots[slot].frame
|
||||
|
||||
if frame.hasItem and C_NewItems.IsNewItem(bag, slot) then
|
||||
if not frame.newitem then
|
||||
local glow = frame:CreateTexture(nil, "OVERLAY")
|
||||
glow:SetTexture("Interface\\Buttons\\UI-ActionButton-Border")
|
||||
glow:SetBlendMode("ADD")
|
||||
glow:SetVertexColor(color:GetRGBA())
|
||||
glow:SetPoint("CENTER", frame, "CENTER")
|
||||
glow:Hide()
|
||||
glow.RefreshSize = function(g)
|
||||
local w = g:GetParent():GetWidth()
|
||||
if w > 0 then g:SetSize(w * 1.8, w * 1.8) end
|
||||
end
|
||||
frame.newitem = glow
|
||||
|
||||
frame:HookScript("OnEnter", function()
|
||||
C_NewItems.RemoveNewItem(bag, slot)
|
||||
end)
|
||||
end
|
||||
frame.newitem:RefreshSize()
|
||||
frame.newitem:Show()
|
||||
elseif frame.newitem and frame.newitem:IsShown() then
|
||||
frame.newitem:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
-- The new-item set can change without any slot's contents changing (an item
|
||||
-- acknowledged, pruned when it leaves the bags, or ClearAll) -- re-evaluate
|
||||
-- every decorated slot when that happens.
|
||||
function pfUI.newitem:RefreshAll()
|
||||
for bag in pairs(pfUI.bags) do
|
||||
local slots = pfUI.bags[bag] and pfUI.bags[bag].slots
|
||||
if slots then
|
||||
for slot in pairs(slots) do
|
||||
pfUI.newitem:UpdateSlot(bag, slot)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- per-slot: pfUI re-runs UpdateSlot whenever a slot's contents change.
|
||||
hooksecurefunc(pfUI.bag, "UpdateSlot", function(self, bag, slot)
|
||||
pfUI.newitem:UpdateSlot(bag, slot)
|
||||
end)
|
||||
|
||||
EventRegistry:RegisterFrameEventAndCallback("BAG_NEW_ITEMS_UPDATED", function()
|
||||
pfUI.newitem:RefreshAll()
|
||||
end)
|
||||
|
||||
pfUI.events:RegisterCallback("bag:closed", function(_, object)
|
||||
if object then return end
|
||||
C_NewItems.ClearAll()
|
||||
end, "newitem")
|
||||
end)
|
||||
+11
-14
@@ -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]
|
||||
@@ -141,7 +138,7 @@ pfUI:RegisterModule("player", function ()
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("UnitPopup_OnClick", function()
|
||||
hooksecurefunc("UnitPopup_OnClick", function()
|
||||
local button = this.value
|
||||
if button == "RESET_INSTANCES_FIX" then
|
||||
StaticPopup_Show("CONFIRM_RESET_INSTANCES")
|
||||
|
||||
+58
-37
@@ -1,8 +1,43 @@
|
||||
pfUI:RegisterModule("questitem", function ()
|
||||
-- [itemID] = { index = questLogIndex, count = requiredCount }. Rebuilt
|
||||
-- on QUEST_LOG_UPDATE from ClassicAPI's per-quest cached requirements.
|
||||
local requiredItems = {}
|
||||
|
||||
local function AddQuest(questID)
|
||||
local details = C_QuestLog.GetQuestDetails(questID)
|
||||
if not details then return false end
|
||||
if details.requirements then
|
||||
for _, req in ipairs(details.requirements) do
|
||||
if req.kind == "item" and req.id and req.id > 0 then
|
||||
requiredItems[req.id] = {
|
||||
questID = questID,
|
||||
title = details.title,
|
||||
level = details.level,
|
||||
count = req.count,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function RemoveQuest(questID)
|
||||
for itemID, entry in pairs(requiredItems) do
|
||||
if entry.questID == questID then requiredItems[itemID] = nil end
|
||||
end
|
||||
end
|
||||
|
||||
local function Seed()
|
||||
for k in pairs(requiredItems) do requiredItems[k] = nil end
|
||||
local complete = true
|
||||
local i = 1
|
||||
while true do
|
||||
local questID = C_QuestLog.GetQuestIDForLogIndex(i)
|
||||
if questID == nil then break end
|
||||
if questID > 0 and not AddQuest(questID) then complete = false end
|
||||
i = i + 1
|
||||
end
|
||||
return complete
|
||||
end
|
||||
|
||||
local function AddTooltip(frame, itemID)
|
||||
if not itemID then return end
|
||||
if C.tooltip.questitem.showquest ~= "1" then return end
|
||||
@@ -19,7 +54,7 @@ pfUI:RegisterModule("questitem", function ()
|
||||
if not entry and not replace then return end
|
||||
|
||||
local quest, level = UNKNOWN, 255
|
||||
if entry then quest, level = GetQuestLogTitle(entry.index) end
|
||||
if entry then quest, level = entry.title, entry.level end
|
||||
if not quest then return end
|
||||
|
||||
local color = GetDifficultyColor(level)
|
||||
@@ -42,48 +77,37 @@ pfUI:RegisterModule("questitem", function ()
|
||||
pfUI.questitem = CreateFrame("Frame", "pfQuestItemScanner", UIParent)
|
||||
pfUI.questitem:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
pfUI.questitem:RegisterEvent("QUEST_LOG_UPDATE")
|
||||
pfUI.questitem:RegisterEvent("QUEST_ACCEPTED")
|
||||
pfUI.questitem:RegisterEvent("QUEST_REMOVED")
|
||||
pfUI.questitem:SetScript("OnEvent", function()
|
||||
-- debounce rebuilds — QUEST_LOG_UPDATE fires in bursts
|
||||
this.run = GetTime() + .5
|
||||
if C.tooltip.questitem.showquest ~= "1" then return end
|
||||
if event == "QUEST_ACCEPTED" then -- arg1 = logIndex, arg2 = questID
|
||||
if not AddQuest(arg2) then -- cache cold (rare) -> reseed
|
||||
this.seeding = true
|
||||
this.run = GetTime() + .5
|
||||
end
|
||||
elseif event == "QUEST_REMOVED" then -- arg1 = questID
|
||||
RemoveQuest(arg1)
|
||||
elseif event == "PLAYER_ENTERING_WORLD" then
|
||||
this.seeding = true -- seed pre-existing quests
|
||||
this.run = GetTime() + .5
|
||||
elseif event == "QUEST_LOG_UPDATE" and this.seeding then
|
||||
this.run = GetTime() + .5 -- keep retrying while cache warms
|
||||
end
|
||||
end)
|
||||
|
||||
pfUI.questitem:SetScript("OnUpdate", function()
|
||||
if C.tooltip.questitem.showquest ~= "1" then return end
|
||||
if not this.run or GetTime() < this.run then return end
|
||||
|
||||
for k in pairs(requiredItems) do requiredItems[k] = nil end
|
||||
|
||||
-- GetQuestIDForLogIndex returns nil past the end, 0 for headers, else
|
||||
-- the questID. GetQuestDetails reads the engine's static-info cache —
|
||||
-- nil if not yet populated; we'll catch it on the next refresh.
|
||||
local i = 1
|
||||
while true do
|
||||
local questID = C_QuestLog.GetQuestIDForLogIndex(i)
|
||||
if questID == nil then break end
|
||||
if questID > 0 then
|
||||
local details = C_QuestLog.GetQuestDetails(questID)
|
||||
if details and details.requirements then
|
||||
for _, req in ipairs(details.requirements) do
|
||||
if req.kind == "item" and req.id and req.id > 0 then
|
||||
requiredItems[req.id] = { index = i, count = req.count }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
this.run = nil
|
||||
if Seed() then this.seeding = nil end
|
||||
end)
|
||||
|
||||
-- reload quest entries on config change
|
||||
pfUI.questitem.UpdateConfig = function()
|
||||
if C.tooltip.questitem.showquest ~= "1" then return end
|
||||
pfUI.questitem.seeding = true
|
||||
pfUI.questitem.run = GetTime() + .5
|
||||
end
|
||||
|
||||
-- regular tooltip: catch every Show via a child frame's OnShow, then ask
|
||||
-- the tooltip directly for the item it's displaying. Replaces a libtooltip
|
||||
-- indirection that did the same query with extra caching layers.
|
||||
pfUI.questitem.tooltip = CreateFrame("Frame", "pfQuestItems", GameTooltip)
|
||||
pfUI.questitem.tooltip:SetScript("OnShow", function()
|
||||
if GameTooltip:HasItem() then
|
||||
@@ -92,10 +116,7 @@ pfUI:RegisterModule("questitem", function ()
|
||||
end
|
||||
end)
|
||||
|
||||
-- itemref tooltip (chat link clicks): hooksecurefunc runs after SetItemRef
|
||||
-- populates ItemRefTooltip, so we just read the item back out of the tooltip
|
||||
-- instead of re-parsing the "item:NNN" out of the link string.
|
||||
pfUI.hooksecurefunc("SetItemRef", function()
|
||||
hooksecurefunc("SetItemRef", function()
|
||||
if IsModifierKeyDown() then return end
|
||||
if ItemRefTooltip:HasItem() then
|
||||
local _, _, id = ItemRefTooltip:GetItem()
|
||||
|
||||
+117
-9
@@ -13,11 +13,32 @@ pfUI:RegisterModule("raid", function ()
|
||||
local rawborder, default_border = GetBorderSize("chat")
|
||||
local cluster = CreateFrame("Frame", "pfRaidCluster", UIParent)
|
||||
cluster:SetFrameLevel(20)
|
||||
cluster:SetWidth(120)
|
||||
cluster:SetHeight(10)
|
||||
cluster:SetSize(120, 10)
|
||||
cluster:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", default_border*2, C.chat.left.height + default_border*5)
|
||||
UpdateMovable(cluster)
|
||||
|
||||
-- Separate, independently-movable block that mirrors the raid grid layout
|
||||
-- for pet frames (raidpet1..40). Defaults to the right of the raid grid.
|
||||
local petcluster = CreateFrame("Frame", "pfRaidPetCluster", UIParent)
|
||||
petcluster:SetFrameLevel(20)
|
||||
petcluster:SetSize(120, 10)
|
||||
petcluster:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", default_border*2 + 300, C.chat.left.height + default_border*5)
|
||||
UpdateMovable(petcluster)
|
||||
|
||||
-- flat pool of pet frames, laid out by LayoutPets (mirror or collapsed)
|
||||
pfUI.uf.raid.pets = {}
|
||||
|
||||
-- 1-based grid slot -> (row, col) for the current fill direction, matching
|
||||
-- the raid grid's own fill loops.
|
||||
local function SlotToCoord(slot, fill, x, y)
|
||||
slot = slot - 1
|
||||
if fill == "VERTICAL" then
|
||||
return floor(slot / y) + 1, mod(slot, y) + 1
|
||||
else
|
||||
return mod(slot, x) + 1, floor(slot / x) + 1
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.uf.raid.tanksfirst = {
|
||||
["PF_TANK_TOGGLE"] = { T["Toggle as Tank"], "toggleTank" }
|
||||
}
|
||||
@@ -28,6 +49,8 @@ pfUI:RegisterModule("raid", function ()
|
||||
function pfUI.uf.raid:UpdateConfig()
|
||||
local rawborder, default_border = GetBorderSize("unitframes")
|
||||
maxraid = tonumber(C.unitframes.maxraid)
|
||||
local showpets = C.unitframes.raidpet.visible == "1"
|
||||
self.showpets = showpets
|
||||
|
||||
for i=1,maxraid do
|
||||
pfUI.uf.raid[i] = pfUI.uf.raid[i] or pfUI.uf:CreateUnitFrame("Raid", i, C.unitframes.raid)
|
||||
@@ -36,6 +59,18 @@ pfUI:RegisterModule("raid", function ()
|
||||
|
||||
pfUI.uf.raid[i]:UpdateConfig()
|
||||
pfUI.uf.raid[i]:UpdateFrameSize()
|
||||
|
||||
if showpets then
|
||||
self.pets[i] = self.pets[i] or pfUI.uf:CreateUnitFrame("RaidPet", i, C.unitframes.raidpet, 0.5)
|
||||
self.pets[i]:SetParent(petcluster)
|
||||
self.pets[i]:SetFrameLevel(5)
|
||||
self.pets[i]:UpdateConfig()
|
||||
self.pets[i]:UpdateFrameSize()
|
||||
elseif self.pets[i] then
|
||||
self.pets[i]:UpdateConfig()
|
||||
self.pets[i]:Hide()
|
||||
RemoveMovable(self.pets[i])
|
||||
end
|
||||
end
|
||||
|
||||
local i = 1
|
||||
@@ -47,6 +82,17 @@ pfUI:RegisterModule("raid", function ()
|
||||
local _, _, x, y = string.find(layout,"(.+)x(.+)")
|
||||
x, y = tonumber(x), tonumber(y)
|
||||
|
||||
if showpets then
|
||||
local petcfg = C.unitframes.raidpet
|
||||
local _, _, px, py = string.find(petcfg.raidlayout, "(.+)x(.+)")
|
||||
self.petgrid = {
|
||||
fill = petcfg.raidfill, x = tonumber(px), y = tonumber(py),
|
||||
pad = tonumber(petcfg.raidpadding) * GetPerfectPixel(),
|
||||
w = self.pets[1]:GetWidth()+2*default_border,
|
||||
h = self.pets[1]:GetHeight()+2*default_border,
|
||||
}
|
||||
end
|
||||
|
||||
if fill == "VERTICAL" then
|
||||
for r=1, x do for g=1, y do
|
||||
if pfUI.uf.raid[i] then
|
||||
@@ -66,6 +112,50 @@ pfUI:RegisterModule("raid", function ()
|
||||
i = i + 1
|
||||
end end
|
||||
end
|
||||
|
||||
self:LayoutPets()
|
||||
|
||||
self:Show()
|
||||
end
|
||||
|
||||
function pfUI.uf.raid:LayoutPets()
|
||||
if not self.showpets or not self.petgrid then return end
|
||||
local grid = self.petgrid
|
||||
|
||||
local function place(pet, cell, id)
|
||||
pet.id = id
|
||||
local r, g = SlotToCoord(cell, grid.fill, grid.x, grid.y)
|
||||
pet:ClearAllPoints()
|
||||
pet:SetPoint("BOTTOMLEFT", petcluster, "BOTTOMLEFT", (r-1)*(grid.pad+grid.w), (g-1)*(grid.pad+grid.h))
|
||||
UpdateMovable(pet, true)
|
||||
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
|
||||
for id = 1, maxraid do
|
||||
if UnitExists("raidpet"..id) and self.pets[k+1] then
|
||||
k = k + 1
|
||||
place(self.pets[k], k, id)
|
||||
end
|
||||
end
|
||||
for j = k+1, maxraid do
|
||||
if self.pets[j] then self.pets[j].id = 0 self.pets[j]:Hide() end
|
||||
end
|
||||
else
|
||||
-- Mirror: cell N always shows raidpet<N> at a fixed position.
|
||||
for id = 1, maxraid do
|
||||
if self.pets[id] then place(self.pets[id], id, id) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.uf.raid:UpdateConfig()
|
||||
@@ -76,13 +166,22 @@ pfUI:RegisterModule("raid", function ()
|
||||
frame:UpdateVisibility()
|
||||
end
|
||||
|
||||
-- add units to the beginning of their groups
|
||||
-- add units to their groups; collapse packs everyone into the leading slots
|
||||
function pfUI.uf.raid:AddUnitToGroup(index, group)
|
||||
for subindex = 1, 5 do
|
||||
local ids = subindex + 5*(group-1)
|
||||
if pfUI.uf.raid[ids] and pfUI.uf.raid[ids].id == 0 and pfUI.uf.raid[ids].config.visible == "1" then
|
||||
SetRaidIndex(pfUI.uf.raid[ids], index)
|
||||
return
|
||||
if C.unitframes.raid.collapse == "1" then
|
||||
for ids = 1, maxraid do
|
||||
if pfUI.uf.raid[ids] and pfUI.uf.raid[ids].id == 0 and pfUI.uf.raid[ids].config.visible == "1" then
|
||||
SetRaidIndex(pfUI.uf.raid[ids], index)
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
for subindex = 1, 5 do
|
||||
local ids = subindex + 5*(group-1)
|
||||
if pfUI.uf.raid[ids] and pfUI.uf.raid[ids].id == 0 and pfUI.uf.raid[ids].config.visible == "1" then
|
||||
SetRaidIndex(pfUI.uf.raid[ids], index)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -92,7 +191,14 @@ pfUI:RegisterModule("raid", function ()
|
||||
pfUI.uf.raid:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
pfUI.uf.raid:RegisterEvent("PARTY_LEADER_CHANGED")
|
||||
pfUI.uf.raid:RegisterEvent("VARIABLES_LOADED")
|
||||
pfUI.uf.raid:RegisterEvent("UNIT_PET")
|
||||
pfUI.uf.raid:SetScript("OnEvent", function()
|
||||
if event == "UNIT_PET" then
|
||||
if this.showpets and C.unitframes.raidpet.collapse == "1" then
|
||||
this:LayoutPets()
|
||||
end
|
||||
return
|
||||
end
|
||||
this:Show()
|
||||
-- Debounce: delay update by 0.5s to batch rapid roster changes (mass swaps)
|
||||
this.pendingUpdate = GetTime() + 0.5
|
||||
@@ -127,6 +233,8 @@ pfUI:RegisterModule("raid", function ()
|
||||
end
|
||||
end
|
||||
|
||||
this:LayoutPets()
|
||||
|
||||
-- Smart GUID-based updates: only refresh frames where unit changed
|
||||
if pfUI.uf.guidTracker then
|
||||
local tracker = pfUI.uf.guidTracker
|
||||
@@ -164,7 +272,7 @@ pfUI:RegisterModule("raid", function ()
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("UnitPopup_OnClick", function()
|
||||
hooksecurefunc("UnitPopup_OnClick", function()
|
||||
local dropdownFrame = UIDROPDOWNMENU_INIT_MENU and _G[UIDROPDOWNMENU_INIT_MENU]
|
||||
if not dropdownFrame then return end
|
||||
local button = this.value
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+138
-15
@@ -1,13 +1,11 @@
|
||||
pfUI:RegisterModule("sellvalue", function ()
|
||||
local function AddVendorPrices(frame, id, count)
|
||||
if not id then return end
|
||||
-- Sell price comes from the engine (item DBC); buy price from pfSellData
|
||||
-- (curated vendor data, since vendor purchase prices aren't a static field).
|
||||
local sell = C_Item.GetItemSellPriceByID(id) or 0
|
||||
local buy = pfSellData[id]
|
||||
if sell == 0 and not buy then return end
|
||||
|
||||
if C.tooltip.vendor.showalways == "1" or IsShiftKeyDown() then
|
||||
if C.tooltip.vendor.showalways == "1" or IsShiftKeyDown() then
|
||||
frame:AddLine(" ")
|
||||
|
||||
if sell > 0 then
|
||||
@@ -25,26 +23,151 @@ pfUI:RegisterModule("sellvalue", function ()
|
||||
frame:AddDoubleLine(T["Buy"] .. ":", CreateGoldString(buy), 1, 1, 1)
|
||||
end
|
||||
end
|
||||
elseif not MerchantFrame:IsShown() and sell > 0 then
|
||||
SetTooltipMoney(frame, sell * count)
|
||||
end
|
||||
frame:Show()
|
||||
end
|
||||
|
||||
pfUI.sellvalue = CreateFrame("Frame", "pfGameTooltip", GameTooltip)
|
||||
pfUI.sellvalue:SetScript("OnShow", function()
|
||||
if GameTooltip:HasItem() then
|
||||
local _, _, id = GameTooltip:GetItem()
|
||||
if id then
|
||||
local count = tonumber(libtooltip:GetItemCount()) or 1
|
||||
AddVendorPrices(GameTooltip, id, math.max(count, 1))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("SetItemRef", function()
|
||||
hooksecurefunc("SetItemRef", function()
|
||||
if IsModifierKeyDown() then return end
|
||||
if ItemRefTooltip:HasItem() then
|
||||
local _, _, id = ItemRefTooltip:GetItem()
|
||||
if id then AddVendorPrices(ItemRefTooltip, id, 1) end
|
||||
end
|
||||
end)
|
||||
|
||||
local TooltipHooks = {
|
||||
SetLootRollItem = {
|
||||
id = GetLootRollItemID,
|
||||
count = function(slot)
|
||||
local _, _, count = GetLootRollItemInfo(slot)
|
||||
return count
|
||||
end
|
||||
},
|
||||
SetLootItem = {
|
||||
id = GetLootSlotItemID,
|
||||
count = function(slot)
|
||||
local _, _, count = GetLootSlotInfo(slot)
|
||||
return count
|
||||
end
|
||||
},
|
||||
SetQuestLogItem = {
|
||||
id = GetQuestLogItemID,
|
||||
count = function(type, index)
|
||||
local itemCount, _;
|
||||
if type == "choice" then
|
||||
_, _, itemCount = GetQuestLogChoiceInfo(index);
|
||||
else
|
||||
_, _, itemCount = GetQuestLogRewardInfo(index)
|
||||
end
|
||||
return itemCount
|
||||
end,
|
||||
},
|
||||
SetQuestItem = {
|
||||
id = GetQuestItemID,
|
||||
count = function(type, index)
|
||||
local _, _, count = GetQuestItemInfo(type, index);
|
||||
return count
|
||||
end,
|
||||
},
|
||||
SetHyperlink = { id = C_Item.GetItemInfoInstant },
|
||||
SetBagItem = {
|
||||
id = C_Container.GetContainerItemID,
|
||||
count = function(container, slot)
|
||||
local _, count = GetContainerItemInfo(container, slot)
|
||||
return count
|
||||
end,
|
||||
},
|
||||
SetInboxItem = {
|
||||
id = GetInboxItemID,
|
||||
count = function(index)
|
||||
local _, _, _, count = GetInboxItem(index)
|
||||
return count
|
||||
end,
|
||||
},
|
||||
SetSendMailItem = {
|
||||
id = function()
|
||||
local _, id = GetSendMailItemLink()
|
||||
return id
|
||||
end,
|
||||
count = function()
|
||||
local _, _, count = GetSendMailItem()
|
||||
return count
|
||||
end,
|
||||
},
|
||||
SetInventoryItem = { id = GetInventoryItemID },
|
||||
SetTradeSkillItem = {
|
||||
id = function(skillIndex, reagentIndex)
|
||||
if reagentIndex then
|
||||
return GetTradeSkillReagentItemID(skillIndex, reagentIndex)
|
||||
else
|
||||
return GetTradeSkillItemID(skillIndex)
|
||||
end
|
||||
end,
|
||||
count = function(skillIndex, reagentIndex)
|
||||
if reagentIndex then
|
||||
local _, _, itemCount = GetTradeSkillReagentInfo(skillIndex, reagentIndex)
|
||||
return itemCount
|
||||
else
|
||||
return GetTradeSkillNumMade(skillIndex)
|
||||
end
|
||||
end,
|
||||
},
|
||||
SetAuctionItem = {
|
||||
id = GetAuctionItemLink,
|
||||
count = function(viewType, index)
|
||||
local _, _, count = GetAuctionItemInfo(viewType, index)
|
||||
return count
|
||||
end,
|
||||
},
|
||||
SetAuctionSellItem = { id = GetAuctionSellItemLink },
|
||||
SetTradePlayerItem = {
|
||||
id = GetTradePlayerItemLink,
|
||||
count = function(id)
|
||||
local _, _, count = GetTradePlayerItemInfo(id)
|
||||
return count
|
||||
end,
|
||||
},
|
||||
SetTradeTargetItem = {
|
||||
id = GetTradeTargetItemLink,
|
||||
count = function(id)
|
||||
local _, _, count = GetTradeTargetItemInfo(id)
|
||||
return count
|
||||
end,
|
||||
},
|
||||
SetMerchantItem = {
|
||||
id = GetMerchantItemID,
|
||||
count = function(index)
|
||||
local _, _, _, itemCount = GetMerchantItemInfo(index)
|
||||
return itemCount
|
||||
end
|
||||
},
|
||||
SetCraftItem = {
|
||||
id = function(recipeIndex, reagentIndex)
|
||||
return GetCraftReagentItemID(recipeIndex, reagentIndex)
|
||||
end
|
||||
},
|
||||
SetBuybackItem = {
|
||||
id = C_MerchantFrame.GetBuybackItemID,
|
||||
count = function(slotIndex)
|
||||
local _, _, _, itemCount = GetBuybackItemInfo(slotIndex)
|
||||
return itemCount
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
local function makeHook(entry)
|
||||
return function(tooltip, arg1, arg2, arg3)
|
||||
AddVendorPrices(tooltip, entry.id(arg1, arg2, arg3), entry.count and entry.count(arg1, arg2, arg3) or 1)
|
||||
end
|
||||
end
|
||||
|
||||
local function HookTooltip(tooltip)
|
||||
for setter, entry in pairs(TooltipHooks) do
|
||||
hooksecurefunc(tooltip, setter, makeHook(entry))
|
||||
end
|
||||
end
|
||||
|
||||
HookTooltip(GameTooltip)
|
||||
end)
|
||||
|
||||
+2
-3
@@ -389,9 +389,8 @@ pfUI:RegisterModule("share", function ()
|
||||
end)
|
||||
end
|
||||
|
||||
_G.SLASH_PFEXPORT1, _G.SLASH_PFEXPORT2, _G.SLASH_PFEXPORT3 = "/export", "/import", "/share"
|
||||
function SlashCmdList.PFEXPORT(msg, editbox)
|
||||
pfUI.api.RegisterSlashCommand("PFEXPORT", { "/export", "/import", "/share" }, function(msg, editbox)
|
||||
f:Show()
|
||||
end
|
||||
end, true)
|
||||
end
|
||||
end)
|
||||
|
||||
+2
-2
@@ -51,12 +51,12 @@ pfUI:RegisterModule("skin", function ()
|
||||
DurabilityFrame.SetPoint = function() return end
|
||||
|
||||
if C.appearance.cd.blizzard == "1" then
|
||||
pfUI.hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
||||
hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
||||
local cooldown = _G[this:GetName().."Cooldown"]
|
||||
if cooldown then cooldown.pfCooldownType = "BLIZZARD" end
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("SpellButton_UpdateButton", function()
|
||||
hooksecurefunc("SpellButton_UpdateButton", function()
|
||||
local cooldown = _G[this:GetName().."Cooldown"]
|
||||
if cooldown then cooldown.pfCooldownType = "BLIZZARD" end
|
||||
end)
|
||||
|
||||
@@ -10,7 +10,7 @@ pfUI:RegisterModule("socialmod", function ()
|
||||
end
|
||||
end)
|
||||
do -- add colors to guild list
|
||||
pfUI.hooksecurefunc("GuildStatus_Update", function()
|
||||
hooksecurefunc("GuildStatus_Update", function()
|
||||
local playerzone = GetRealZoneText()
|
||||
local off = FauxScrollFrame_GetOffset(GuildListScrollFrame)
|
||||
for i=1, GUILDMEMBERS_TO_DISPLAY, 1 do
|
||||
@@ -70,7 +70,7 @@ pfUI:RegisterModule("socialmod", function ()
|
||||
end
|
||||
|
||||
do -- add colors to friend list
|
||||
pfUI.hooksecurefunc("FriendsList_Update", function()
|
||||
hooksecurefunc("FriendsList_Update", function()
|
||||
if GetNumFriends() == 0 then return end
|
||||
|
||||
local playerzone = GetRealZoneText()
|
||||
@@ -123,7 +123,7 @@ pfUI:RegisterModule("socialmod", function ()
|
||||
end
|
||||
|
||||
do -- add colors to who list
|
||||
pfUI.hooksecurefunc("WhoList_Update", function()
|
||||
hooksecurefunc("WhoList_Update", function()
|
||||
local num, max = GetNumWhoResults()
|
||||
local off = FauxScrollFrame_GetOffset(WhoListScrollFrame)
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
-- https://github.com/balakethelock/SuperWoW
|
||||
|
||||
-- DLL Status Check Command (always available)
|
||||
SLASH_PFDLLSTATUS1 = "/pfdll"
|
||||
SlashCmdList["PFDLLSTATUS"] = function()
|
||||
pfUI.api.RegisterSlashCommand("PFDLLSTATUS", { "/pfdll" }, function()
|
||||
local chat = DEFAULT_CHAT_FRAME
|
||||
chat:AddMessage("|cff33ffccpfUI|r: DLL Status Check")
|
||||
|
||||
@@ -43,7 +42,7 @@ SlashCmdList["PFDLLSTATUS"] = function()
|
||||
else
|
||||
chat:AddMessage(" |cffff0000Target frame|r: NOT found")
|
||||
end
|
||||
end
|
||||
end, true)
|
||||
|
||||
pfUI:RegisterModule("superwow", function ()
|
||||
if SetAutoloot and SpellInfo and not SUPERWOW_VERSION then
|
||||
@@ -173,12 +172,10 @@ pfUI:RegisterModule("superwow", function ()
|
||||
end
|
||||
|
||||
-- Add slash command for clickthrough toggle
|
||||
_G.SLASH_PFCLICKTHROUGH1 = "/clickthrough"
|
||||
_G.SLASH_PFCLICKTHROUGH2 = "/ct"
|
||||
SlashCmdList["PFCLICKTHROUGH"] = function()
|
||||
pfUI.api.RegisterSlashCommand("PFCLICKTHROUGH", { "/clickthrough", "/ct" }, function()
|
||||
local enabled = pfUI.api.ToggleClickthrough()
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Clickthrough mode " .. (enabled and "|cff00ff00enabled|r" or "|cffff0000disabled|r"))
|
||||
end
|
||||
end, true)
|
||||
end
|
||||
|
||||
end)
|
||||
+35
-5
@@ -1,4 +1,3 @@
|
||||
pfUI:RegisterNewModule("swingtimer", "Swing Timer")
|
||||
pfUI:RegisterModule("swingtimer", function ()
|
||||
local rawborder, border = GetBorderSize()
|
||||
|
||||
@@ -28,9 +27,10 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
pendingCastSpellId = nil,
|
||||
mhFrozenAt = nil,
|
||||
hsQueued = false, cleaveQueued = false, maulQueued = false,
|
||||
hsSeenCurrent = false, cleaveSeenCurrent = false, maulSeenCurrent = false,
|
||||
isWarrior = false,
|
||||
isDruid = false,
|
||||
cachedHSSlots = {}, cachedCleaveSlots = {},
|
||||
cachedHSSlots = {}, cachedCleaveSlots = {}, cachedMaulSlots = {},
|
||||
useSpellQueueEvent = false,
|
||||
swingThrottle = 0,
|
||||
onSwingCache = {},
|
||||
@@ -416,17 +416,20 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
S.hsQueued = (kind == "hs")
|
||||
S.cleaveQueued = (kind == "cleave")
|
||||
S.maulQueued = (kind == "maul")
|
||||
S.hsSeenCurrent, S.cleaveSeenCurrent, S.maulSeenCurrent = false, false, false
|
||||
end
|
||||
|
||||
local function RebuildQueueSlotCache()
|
||||
if not S.isWarrior or not sw_hsqueue or S.useSpellQueueEvent then return end
|
||||
if not sw_hsqueue then return end
|
||||
S.cachedHSSlots = {}
|
||||
S.cachedCleaveSlots = {}
|
||||
S.cachedMaulSlots = {}
|
||||
if not (S.isWarrior or S.isDruid) then return end
|
||||
for slot = 1, 120 do
|
||||
local kind, id = GetActionInfo(slot)
|
||||
local name
|
||||
if kind == "spell" then
|
||||
name = GetSpellInfo(id)
|
||||
name = C_Spell.GetSpellName(id)
|
||||
elseif kind == "macro" then
|
||||
name = GetMacroSpell(id)
|
||||
end
|
||||
@@ -434,6 +437,8 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
table.insert(S.cachedHSSlots, slot)
|
||||
elseif name == CLEAVE_NAME then
|
||||
table.insert(S.cachedCleaveSlots, slot)
|
||||
elseif name == MAUL_NAME then
|
||||
table.insert(S.cachedMaulSlots, slot)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -445,9 +450,30 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
return false
|
||||
end
|
||||
|
||||
-- Reconcile a stale event-driven queue flag against the client's current
|
||||
-- action. Not every de-queue emits a SPELL_QUEUE pop — pressing Esc or
|
||||
-- re-pressing to cancel an on-swing spell doesn't — so the flag alone stays
|
||||
-- set. IsCurrentAction, which the client clears on cancel, is the reconciling
|
||||
-- signal, but only after it has confirmed the ability as current at least once
|
||||
-- (`seen`): a nampower-initiated cast may never flip IsCurrentAction, and must
|
||||
-- keep its color until its own pop/resolve rather than be cleared early.
|
||||
-- Returns the updated (queued, seen).
|
||||
local function ReconcileQueued(queued, slots, seen)
|
||||
if not queued then return false, false end
|
||||
if CheckQueuedAction(slots) then return true, true end
|
||||
if seen then return false, false end -- was current, now gone -> cancelled
|
||||
return true, false -- never confirmed current -> keep
|
||||
end
|
||||
|
||||
local function IsHSOrCleaveQueued()
|
||||
if not sw_hsqueue or not S.isWarrior then return false, false end
|
||||
if S.useSpellQueueEvent then return S.hsQueued, S.cleaveQueued end
|
||||
if S.useSpellQueueEvent then
|
||||
S.hsQueued, S.hsSeenCurrent =
|
||||
ReconcileQueued(S.hsQueued, S.cachedHSSlots, S.hsSeenCurrent)
|
||||
S.cleaveQueued, S.cleaveSeenCurrent =
|
||||
ReconcileQueued(S.cleaveQueued, S.cachedCleaveSlots, S.cleaveSeenCurrent)
|
||||
return S.hsQueued, S.cleaveQueued
|
||||
end
|
||||
return CheckQueuedAction(S.cachedHSSlots), CheckQueuedAction(S.cachedCleaveSlots)
|
||||
end
|
||||
|
||||
@@ -526,6 +552,10 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
-- HS/Cleave color
|
||||
local curR, curG, curB = mhDefaultR, mhDefaultG, mhDefaultB
|
||||
if sw_hsqueue then
|
||||
if S.isDruid and S.useSpellQueueEvent then
|
||||
S.maulQueued, S.maulSeenCurrent =
|
||||
ReconcileQueued(S.maulQueued, S.cachedMaulSlots, S.maulSeenCurrent)
|
||||
end
|
||||
if S.maulQueued and S.isDruid then
|
||||
curR, curG, curB = 1.0, 0.55, 0.0 -- orange for druid maul queue
|
||||
elseif S.isWarrior then
|
||||
|
||||
@@ -530,7 +530,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
||||
end
|
||||
|
||||
-- replace wim class colors with pfUI ones
|
||||
pfUI.hooksecurefunc("WIM_InitClassProps", function()
|
||||
hooksecurefunc("WIM_InitClassProps", function()
|
||||
for class in pairs(PFUI_CLASS_COLORS) do
|
||||
local wimclass = _G[format("WIM_LOCALIZED_%s",class)]
|
||||
local colorstr = "|c" .. PFUI_CLASS_COLORS[class].colorStr
|
||||
@@ -547,7 +547,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
||||
btnClose:SetWidth(13)
|
||||
btnClose:SetHeight(13)
|
||||
end
|
||||
pfUI.hooksecurefunc("WIM_Icon_DropDown_Update", function()
|
||||
hooksecurefunc("WIM_Icon_DropDown_Update", function()
|
||||
for i=1,_G.WIM_MaxMenuCount do
|
||||
local btn = _G["WIM_ConversationMenuTellButton"..i]
|
||||
if i==1 and btn:IsEnabled() == 0 then return end
|
||||
@@ -729,7 +729,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
||||
SkinScrollbar(WIM_HelpScrollFrameScrollBar)
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("WIM_WindowOnShow", function()
|
||||
hooksecurefunc("WIM_WindowOnShow", function()
|
||||
if this.backdrop then return end -- already skinned
|
||||
|
||||
local windowname = this:GetName()
|
||||
@@ -904,7 +904,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
||||
end
|
||||
|
||||
-- trigger the event whenever SuperMacro got an update
|
||||
pfUI.hooksecurefunc("SM_UpdateActionSpell", function()
|
||||
hooksecurefunc("SM_UpdateActionSpell", function()
|
||||
for slot=1,120 do pfUI.bars.update[slot] = true end
|
||||
end)
|
||||
end)
|
||||
@@ -922,7 +922,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
||||
pfUI.bars.skip_macro = true
|
||||
|
||||
-- send clevermacro events to pfUI actionbars
|
||||
pfUI.hooksecurefunc("ActionButton_OnEvent", function(event)
|
||||
hooksecurefunc("ActionButton_OnEvent", function(event)
|
||||
events(this, event)
|
||||
end)
|
||||
end)
|
||||
|
||||
+6
-6
@@ -3,8 +3,7 @@ pfUI:RegisterModule("tooltip", function ()
|
||||
|
||||
pfUI.tooltip = CreateFrame('Frame', "pfTooltip", GameTooltip)
|
||||
pfUI.tooltip.anchorframe = CreateFrame('Frame', "pfTooltipAnchor", UIParent)
|
||||
pfUI.tooltip.anchorframe:SetWidth(128)
|
||||
pfUI.tooltip.anchorframe:SetHeight(72)
|
||||
pfUI.tooltip.anchorframe:SetSize(128, 72)
|
||||
pfUI.tooltip.anchorframe:SetPoint("TOP", UIParent, "TOP", 0, -50)
|
||||
pfUI.tooltip.anchorframe:Hide()
|
||||
UpdateMovable(pfUI.tooltip.anchorframe)
|
||||
@@ -30,8 +29,8 @@ pfUI:RegisterModule("tooltip", function ()
|
||||
-- create mouse follow frame
|
||||
if not tooltip.cursor then
|
||||
tooltip.cursor = CreateFrame("Frame", nil, UIParent)
|
||||
tooltip.cursor:SetWidth(tonumber(C.tooltip.cursoroffset) * 2)
|
||||
tooltip.cursor:SetHeight(tonumber(C.tooltip.cursoroffset) * 2)
|
||||
local size = tonumber(C.tooltip.cursoroffset) * 2
|
||||
tooltip.cursor:SetSize(size, size)
|
||||
tooltip.cursor:SetScript("OnUpdate", function()
|
||||
-- throttle - cursor following doesn't need to be every frame
|
||||
if (this.tick or 0) > GetTime() then return end
|
||||
@@ -172,8 +171,9 @@ pfUI:RegisterModule("tooltip", function ()
|
||||
local unit = pfUI.tooltip:GetUnit()
|
||||
if unit == "none" then
|
||||
-- process item tooltips
|
||||
if C.tooltip.itemid == "1" and libtooltip:GetItemID() then
|
||||
GameTooltip:AddLine(T["ItemID"] .. ": " .. libtooltip:GetItemID(), .25,.5,1)
|
||||
if C.tooltip.itemid == "1" and GameTooltip:HasItem() then
|
||||
local _, _, itemID = GameTooltip:GetItem()
|
||||
GameTooltip:AddLine(T["ItemID"] .. ": " .. itemID, .25,.5,1)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
|
||||
+32
-45
@@ -1,64 +1,53 @@
|
||||
pfUI:RegisterModule("totems", function ()
|
||||
local _, class = UnitClass("player")
|
||||
|
||||
local slots = {
|
||||
[FIRE_TOTEM_SLOT] = { r = .5, g = .2, b = .1 },
|
||||
[EARTH_TOTEM_SLOT] = { r = .2, g = .4, b = .1 },
|
||||
[WATER_TOTEM_SLOT] = { r = .1, g = .4, b = .6 },
|
||||
[AIR_TOTEM_SLOT] = { r = .4, g = .1, b = .7 },
|
||||
local slotColors = {
|
||||
[FIRE_TOTEM_SLOT] = CreateColor(.5, .2, .1),
|
||||
[EARTH_TOTEM_SLOT] = CreateColor(.2, .4, .1),
|
||||
[WATER_TOTEM_SLOT] = CreateColor(.1, .4, .6),
|
||||
[AIR_TOTEM_SLOT] = CreateColor(.4, .1, .7),
|
||||
}
|
||||
|
||||
local totems = CreateFrame("Frame", "pfTotems", UIParent)
|
||||
totems:RegisterEvent("PLAYER_TOTEM_UPDATE")
|
||||
totems:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
totems:SetScript("OnEvent", function(self)
|
||||
totems:RefreshList()
|
||||
totems:SetScript("OnEvent", function()
|
||||
this:RefreshList()
|
||||
end)
|
||||
|
||||
if class == "SHAMAN" then
|
||||
-- there's no totem event in vanilla using ticks instead
|
||||
local eventemu = CreateFrame("Frame")
|
||||
eventemu:SetScript("OnUpdate", function()
|
||||
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||
totems:RefreshList()
|
||||
end)
|
||||
end
|
||||
|
||||
totems.OnEnter = function(self)
|
||||
if not this.id then return end
|
||||
local active, name, start, duration, icon = GetTotemInfo(this.id)
|
||||
if not name or not active then return end -- Prüfen ob name gültig ist
|
||||
local color = slots[this.id]
|
||||
local id = this:GetID()
|
||||
local spellID = select(7, GetTotemInfo(id))
|
||||
if not spellID or spellID == 0 then return end
|
||||
GameTooltip:SetOwner(this, "ANCHOR_LEFT")
|
||||
GameTooltip:SetText(name, color.r+.2, color.g+.2, color.b+.2)
|
||||
GameTooltip:SetSpellByID(spellID)
|
||||
GameTooltip:AddDoubleLine(T["Left Click"], T["Recast Totem"], nil, nil, nil, WHITE_FONT_COLOR:GetRGB())
|
||||
GameTooltip:AddDoubleLine(T["Right Click"], T["Target Totem"], nil, nil, nil, WHITE_FONT_COLOR:GetRGB())
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
totems.OnLeave = function(self)
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
totems.OnLeave = GameTooltip_Hide
|
||||
|
||||
totems.OnClick = function(self)
|
||||
if this.id and arg1 and arg1 == "LeftButton" then
|
||||
-- Try to recast totem on left click
|
||||
local active, name, start, duration, icon = GetTotemInfo(this.id)
|
||||
if name then CastSpellByName(name) end
|
||||
local id = this:GetID()
|
||||
if arg1 == "LeftButton" then
|
||||
local spellID = select(7, GetTotemInfo(id))
|
||||
if spellID and spellID > 0 then CastSpell(FindSpellBookSlotByID(spellID)) end
|
||||
elseif arg1 == "RightButton" then
|
||||
TargetTotem(id)
|
||||
end
|
||||
end
|
||||
|
||||
totems.RefreshList = function(self)
|
||||
local count = 0
|
||||
for i = 1, MAX_TOTEMS do
|
||||
local active, name, start, duration, icon = GetTotemInfo(i)
|
||||
local _, _, start, duration, icon = GetTotemInfo(i)
|
||||
|
||||
if active and icon and icon ~= "" then
|
||||
if start and start > 0 and icon and icon ~= "" then
|
||||
count = count + 1
|
||||
local color = slots[i]
|
||||
|
||||
self.bar[count]:Show()
|
||||
self.bar[count]:SetBackdropBorderColor(color.r, color.g, color.b)
|
||||
self.bar[count]:SetBackdropBorderColor(slotColors[i]:GetRGB())
|
||||
self.bar[count].icon:SetTexture(icon)
|
||||
self.bar[count].id = i
|
||||
self.bar[count]:SetID(i)
|
||||
|
||||
CooldownFrame_SetTimer(self.bar[count].cd, start, duration, 1)
|
||||
end
|
||||
@@ -77,14 +66,14 @@ end
|
||||
self:Show()
|
||||
end
|
||||
|
||||
local count = count and count > 0 and count or MAX_TOTEMS
|
||||
count = count and count > 0 and count or MAX_TOTEMS
|
||||
|
||||
local thickness = self.iconsize + self.spacing*2
|
||||
local length = thickness * count
|
||||
if pfUI_config.totems.direction == "HORIZONTAL" then
|
||||
self:SetHeight(self.iconsize + self.spacing*2)
|
||||
self:SetWidth(self.spacing*2 + self.iconsize + (count-1)*(self.iconsize + self.spacing*2))
|
||||
self:SetSize(length, thickness)
|
||||
else
|
||||
self:SetWidth(self.iconsize + self.spacing*2)
|
||||
self:SetHeight(self.spacing*2 + self.iconsize + (count-1)*(self.iconsize + self.spacing*2))
|
||||
self:SetSize(thickness, length)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -114,8 +103,7 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
self.bar[i]:SetHeight(self.iconsize)
|
||||
self.bar[i]:SetWidth(self.iconsize)
|
||||
self.bar[i]:SetSize(self.iconsize, self.iconsize)
|
||||
CreateBackdrop(self.bar[i], nil, true)
|
||||
|
||||
self.bar[i].icon = self.bar[i].icon or self.bar[i]:CreateTexture(nil, "ARTWORK")
|
||||
@@ -123,8 +111,7 @@ end
|
||||
SetAllPointsOffset(self.bar[i].icon, self.bar[i], 2,-2)
|
||||
|
||||
self.bar[i].cdbg = self.bar[i].cdbg or CreateFrame("Frame", nil, self.bar[i])
|
||||
self.bar[i].cdbg:SetHeight(self.iconsize - 3)
|
||||
self.bar[i].cdbg:SetWidth(self.iconsize - 3)
|
||||
self.bar[i].cdbg:SetSize(self.iconsize - 3, self.iconsize - 3)
|
||||
self.bar[i].cdbg:SetPoint("CENTER", self.bar[i], "CENTER", 0, 0)
|
||||
self.bar[i].cd = self.bar[i].cd or CreateFrame(COOLDOWN_FRAME_TYPE, "pfTotemsBar"..i.."Cooldown", self.bar[i].cdbg, "CooldownFrameTemplate")
|
||||
self.bar[i].cd.pfCooldownStyleAnimation = 1
|
||||
|
||||
+42
-42
@@ -65,14 +65,14 @@ pfUI:RegisterModule("turtle-wow", function ()
|
||||
|
||||
HookAddonOrVariable("GroupFrame", function()
|
||||
-- After Turtle's own init, hide frames if pfUI handles them
|
||||
pfUI.hooksecurefunc("GroupFrame_Toggle", function()
|
||||
hooksecurefunc("GroupFrame_Toggle", function()
|
||||
if pfUIHandlesGroupOrRaid() then
|
||||
DisableTurtleGroupFrames()
|
||||
end
|
||||
end)
|
||||
|
||||
-- After every group/raid update, re-hide if pfUI handles them
|
||||
pfUI.hooksecurefunc("GroupFrame_Update", function()
|
||||
hooksecurefunc("GroupFrame_Update", function()
|
||||
if pfUIHandlesGroupOrRaid() then
|
||||
DisableTurtleGroupFrames()
|
||||
end
|
||||
@@ -80,24 +80,6 @@ pfUI:RegisterModule("turtle-wow", function ()
|
||||
end)
|
||||
end
|
||||
|
||||
-- custom debuff durations
|
||||
L["debuffs"]["Hand of Reckoning"] = {[0]=3.0}
|
||||
L["debuffs"]['Insect Swarm'] = {[0]=18.0}
|
||||
L["debuffs"]['Moonfire'] = {[1]=9.0,[2]=18.0,[3]=18.0,[4]=18.0,[5]=18.0,[6]=18.0,[7]=18.0,[8]=18.0,[9]=18.0,[10]=18.0,[0]=18.0}
|
||||
L["debuffs"]['Deep Wound'] = {[0]=6.0}
|
||||
|
||||
-- turtle wow totemic recall clear totem indicators
|
||||
local _, class = UnitClass("player")
|
||||
if libtotem and class == "SHAMAN" then
|
||||
local trecall = CreateFrame("Frame", "pfTotemsRecall", UIParent)
|
||||
trecall:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
|
||||
trecall:SetScript("OnEvent", function()
|
||||
if arg1 and string.find(arg1, T["You gain (.+) Mana from Totemic Recall"]) then
|
||||
for i = 1, 4 do libtotem:Clean(i) end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local delay = CreateFrame("Frame")
|
||||
delay:SetScript("OnUpdate", function()
|
||||
this:Hide()
|
||||
@@ -295,40 +277,58 @@ pfUI:RegisterModule("turtle-wow", function ()
|
||||
local initialized = false
|
||||
|
||||
HookAddonOrVariable("Blizzard_InspectUI", function()
|
||||
pfUI.hooksecurefunc("InspectFrame_Show", function()
|
||||
hooksecurefunc("InspectFrame_Show", function()
|
||||
-- break if theres nothing left to do
|
||||
if initialized then return end
|
||||
|
||||
-- adjust ui positions
|
||||
local _, border = GetBorderSize()
|
||||
|
||||
-- adjust the inspect frame's Talents tab
|
||||
SkinTab(InspectFrameTab3)
|
||||
InspectFrameTab3:ClearAllPoints()
|
||||
InspectFrameTab3:SetPoint("LEFT", InspectFrameTab2, "RIGHT", GetBorderSize()*2 + 1, 0)
|
||||
TWTalentFrameTab1:SetPoint("TOPLEFT", TWTalentFrameScrollFrame, "TOPLEFT", 2, TWTalentFrameTab1:GetHeight() + 4)
|
||||
|
||||
InspectFrameTab3:SetPoint("LEFT", InspectFrameTab2, "RIGHT", border*2 + 1, 0)
|
||||
-- reload text position
|
||||
InspectFrameTab3:Hide()
|
||||
InspectFrameTab3:Show()
|
||||
|
||||
-- skin inspect window elements
|
||||
StripTextures(InspectTalentsFrame)
|
||||
StripTextures(TWTalentFrameScrollFrame)
|
||||
SkinScrollbar(TWTalentFrameScrollFrameScrollBar)
|
||||
for i = 1, 3 do
|
||||
SkinTab(_G["TWTalentFrameTab"..i])
|
||||
end
|
||||
-- the talent tree frame is created lazily; skin it once it exists
|
||||
if TWTalentFrame then
|
||||
StripTextures(InspectTalentsFrame)
|
||||
StripTextures(TWTalentFrame)
|
||||
StripTextures(TWTalentFrameScrollFrame)
|
||||
SkinScrollbar(TWTalentFrameScrollFrameScrollBar)
|
||||
|
||||
-- skin each talent button
|
||||
for i = 1, (MAX_NUM_TALENTS or 100) do
|
||||
local talent = _G["TWTalentFrameTalent" .. i]
|
||||
if talent then
|
||||
StripTextures(talent)
|
||||
SkinButton(talent, nil, nil, nil, _G["TWTalentFrameTalent" .. i .. "IconTexture"])
|
||||
_G["TWTalentFrameTalent" .. i .. "Rank"]:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
-- skin + position the talent-tree tabs
|
||||
for i = 1, 3 do
|
||||
local tab = _G["TWTalentFrameTab"..i]
|
||||
if tab then
|
||||
SkinTab(tab)
|
||||
tab:ClearAllPoints()
|
||||
local lastTab = _G["TWTalentFrameTab"..(i-1)]
|
||||
if lastTab then
|
||||
tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
|
||||
else
|
||||
tab:SetPoint("TOPLEFT", TWTalentFrameScrollFrame, "TOPLEFT", 2, tab:GetHeight() + 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- only run once
|
||||
initialized = true
|
||||
-- skin each talent button
|
||||
for i = 1, (MAX_NUM_TALENTS or 100) do
|
||||
local talent = _G["TWTalentFrameTalent"..i]
|
||||
if talent then
|
||||
StripTextures(talent)
|
||||
SkinButton(talent, nil, nil, nil, _G["TWTalentFrameTalent"..i.."IconTexture"])
|
||||
local rank = _G["TWTalentFrameTalent"..i.."Rank"]
|
||||
if rank then
|
||||
rank:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- only run once the talent frame has actually been skinned
|
||||
initialized = true
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
+2
-23
@@ -331,29 +331,8 @@ 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
|
||||
_G.SLASH_PFUNITXP1 = "/pfunitxp"
|
||||
SlashCmdList["PFUNITXP"] = function()
|
||||
pfUI.api.RegisterSlashCommand("PFUNITXP", { "/pfunitxp" }, function()
|
||||
local chat = DEFAULT_CHAT_FRAME
|
||||
chat:AddMessage("|cff33ffccpfUI|r: UnitXP Indicator Debug")
|
||||
|
||||
@@ -387,5 +366,5 @@ pfUI:RegisterModule("unitxp", function ()
|
||||
else
|
||||
chat:AddMessage(" Target frame: |cffff0000NOT found|r")
|
||||
end
|
||||
end
|
||||
end, true)
|
||||
end)
|
||||
+6
-2
@@ -6,6 +6,7 @@ pfUI:RegisterModule("unlock", function ()
|
||||
-- Name Shift Ctrl
|
||||
{ "pfCombo", 5 },
|
||||
{ "pfRaid", 40, 5 },
|
||||
{ "pfRaidPet", 40, 5 },
|
||||
{ "pfGroup", 4 },
|
||||
{ "pfLootRollFrame", 4 },
|
||||
}
|
||||
@@ -35,6 +36,8 @@ pfUI:RegisterModule("unlock", function ()
|
||||
-- groupframes
|
||||
["Raid%d"] = { T["Group Frames"], T["Raid"] },
|
||||
["Raid%d%d"] = { T["Group Frames"], T["Raid"] },
|
||||
["RaidPet%d"] = { T["Group Frames"], T["Raid-Pet"] },
|
||||
["RaidPet%d%d"] = { T["Group Frames"], T["Raid-Pet"] },
|
||||
["Group%d"] = { T["Group Frames"], T["Group"] },
|
||||
["Party%dTarget"] = { T["Group Frames"], T["Group-Target"] },
|
||||
["PartyPet%d"] = { T["Group Frames"], T["Group-Pet"] },
|
||||
@@ -98,7 +101,8 @@ pfUI:RegisterModule("unlock", function ()
|
||||
-- search and add clustered frames
|
||||
for id, cluster in pairs(clusters) do
|
||||
local len = strlen(cluster[1])
|
||||
if strsub(frame:GetName(),0,len) == cluster[1] then
|
||||
local fid = tonumber(strsub(frame:GetName(),len+1,len+2))
|
||||
if fid and strsub(frame:GetName(),0,len) == cluster[1] then
|
||||
if IsShiftKeyDown() and cluster[2] then
|
||||
for i = 1, cluster[2] do
|
||||
if _G[cluster[1] .. i] ~= frame then
|
||||
@@ -106,7 +110,7 @@ pfUI:RegisterModule("unlock", function ()
|
||||
end
|
||||
end
|
||||
elseif IsControlKeyDown() and cluster[3] then
|
||||
local id = tonumber(strsub(frame:GetName(),len+1,len+2))
|
||||
local id = fid
|
||||
|
||||
local b = 1
|
||||
for i = cluster[3]+1, cluster[2], cluster[3] do
|
||||
|
||||
+10
-25
@@ -4,8 +4,6 @@ pfUI:RegisterModule("unusable", function ()
|
||||
|
||||
pfUI.unusable = {}
|
||||
|
||||
local scanner = libtipscan:GetScanner("unusable")
|
||||
local durability = string.gsub(DURABILITY_TEMPLATE, "%%[^%s]+", "(.+)")
|
||||
local r, g, b, a = strsplit(",", C.appearance.bags.unusable_color)
|
||||
|
||||
function pfUI.unusable:UpdateSlot(bag, slot)
|
||||
@@ -13,40 +11,27 @@ pfUI:RegisterModule("unusable", function ()
|
||||
if not pfUI.bags[bag] then return end
|
||||
if not pfUI.bags[bag].slots[slot] then return end
|
||||
|
||||
-- add button shortcuts
|
||||
local frame = pfUI.bags[bag].slots[slot].frame
|
||||
local name = frame:GetName()
|
||||
|
||||
-- return on empty buttons
|
||||
local frame = pfUI.bags[bag].slots[slot].frame
|
||||
if not frame.hasItem then return end
|
||||
|
||||
-- set the proper tooltip method
|
||||
if bag == BANK_CONTAINER then
|
||||
scanner:SetInventoryItem("player", 39+slot)
|
||||
else
|
||||
scanner:SetBagItem(bag, slot)
|
||||
-- C_PlayerInfo.CanUseItem is the "is this red in the tooltip" gate:
|
||||
-- proficiency, required level, class/race, skill/spell/rep. It checks
|
||||
-- *requirements* only, so a broken (0-durability) item still reads as
|
||||
-- usable -- no durability-line exclusion needed like the old scanner.
|
||||
local itemID = C_Container.GetContainerItemID(bag, slot)
|
||||
if itemID and not C_PlayerInfo.CanUseItem(itemID) then
|
||||
_G.SetItemButtonTextureVertexColor(frame, r, g, b, a)
|
||||
end
|
||||
|
||||
-- check for red color in tooltip
|
||||
local red = scanner:Color(RED_FONT_COLOR)
|
||||
if not red then return end
|
||||
|
||||
-- check for broken items
|
||||
local left = scanner:Line(red)
|
||||
local _, _, broken = string.find(left, durability, 1)
|
||||
if broken then return end
|
||||
|
||||
-- update button vertex color
|
||||
_G.SetItemButtonTextureVertexColor(frame, r, g, b, a)
|
||||
end
|
||||
|
||||
-- update on regular pfUI button updates
|
||||
pfUI.hooksecurefunc(pfUI.bag, "UpdateSlot", function(self, bag, slot)
|
||||
hooksecurefunc(pfUI.bag, "UpdateSlot", function(self, bag, slot)
|
||||
pfUI.unusable:UpdateSlot(bag, slot)
|
||||
end)
|
||||
|
||||
-- update on bank frame itemlock updates
|
||||
pfUI.hooksecurefunc("BankFrameItemButton_UpdateLock", function()
|
||||
hooksecurefunc("BankFrameItemButton_UpdateLock", function()
|
||||
pfUI.unusable:UpdateSlot(-1, this:GetID())
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -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"])
|
||||
|
||||
+2
-10
@@ -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])
|
||||
|
||||
@@ -5,11 +5,7 @@ end
|
||||
|
||||
SLASH_PFUI1 = '/pfui'
|
||||
function SlashCmdList.PFUI(msg, editbox)
|
||||
if pfUI.gui:IsShown() then
|
||||
pfUI.gui:Hide()
|
||||
else
|
||||
pfUI.gui:Show()
|
||||
end
|
||||
pfUI.gui:SetShown(not pfUI.gui:IsShown())
|
||||
end
|
||||
|
||||
SLASH_GM1, SLASH_GM2 = '/gm', '/support'
|
||||
@@ -27,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 = 10600 -- (X*10000 + Y*100 + Z)
|
||||
local PFUI_CLASSIC_API_MIN = 10802 -- (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"
|
||||
@@ -40,9 +36,16 @@ do
|
||||
if not CLASSIC_API_VERSION or CLASSIC_API_VERSION < PFUI_CLASSIC_API_MIN then
|
||||
local minVersion = FormatVersion(PFUI_CLASSIC_API_MIN)
|
||||
pfUI.disabled = true
|
||||
EventUtil.ContinueOnPlayerLogin(function()
|
||||
local detail
|
||||
if not CLASSIC_API_VERSION then
|
||||
detail = "The ClassicAPI DLL isn't loaded. The |cff33ffcc!!!ClassicAPI|r addon ships bundled with it -- delete your |cff33ffcc!!!ClassicAPI|r folder and install the latest release from:"
|
||||
else
|
||||
detail = "ClassicAPI " .. minVersion .. " or newer is required. Delete your |cff33ffcc!!!ClassicAPI|r folder and reinstall the latest release from:"
|
||||
end
|
||||
|
||||
local function ShowRequiredPopup()
|
||||
StaticPopupDialogs["PFUI_CLASSICAPI_REQUIRED"] = {
|
||||
text = "This fork of |cff33ffccpf|cffffffffUI|r requires ClassicAPI\n " .. minVersion .. " or newer.\n\nAll |cff33ffccpf|cffffffffUI|r modules have been disabled.\nInstall ClassicAPI from:",
|
||||
text = "|cff33ffccpf|cffffffffUI|r has been disabled.\n\n" .. detail,
|
||||
button1 = OKAY,
|
||||
hasEditBox = 1,
|
||||
editBoxWidth = 280,
|
||||
@@ -51,7 +54,7 @@ do
|
||||
hideOnEscape = 1,
|
||||
preferredIndex = 3,
|
||||
OnShow = function()
|
||||
local editBox = _G[this:GetName().."EditBox"]
|
||||
local editBox = getglobal(this:GetName().."EditBox")
|
||||
if editBox then
|
||||
editBox:SetText(PFUI_CLASSIC_API_LATEST_URL)
|
||||
editBox:HighlightText()
|
||||
@@ -61,9 +64,15 @@ do
|
||||
}
|
||||
StaticPopup_Show("PFUI_CLASSICAPI_REQUIRED")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
"This fork of |cff33ffccpf|cffffffffUI|r requires ClassicAPI " .. minVersion .. "+. Get it at " .. PFUI_CLASSIC_API_LATEST_URL,
|
||||
"|cff33ffccpf|cffffffffUI|r disabled: " .. detail .. " " .. PFUI_CLASSIC_API_LATEST_URL,
|
||||
1, 0.3, 0.3
|
||||
)
|
||||
end
|
||||
local loginFrame = CreateFrame("Frame")
|
||||
loginFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
loginFrame:SetScript("OnEvent", function()
|
||||
loginFrame:UnregisterEvent("PLAYER_ENTERING_WORLD")
|
||||
ShowRequiredPopup()
|
||||
end)
|
||||
elseif CLASSIC_API_VERSION < PFUI_CLASSIC_API_LATEST then
|
||||
EventUtil.ContinueOnPlayerLogin(function()
|
||||
@@ -101,9 +110,11 @@ pfUI.movables = {}
|
||||
pfUI.version = {}
|
||||
pfUI.env = {}
|
||||
|
||||
pfUI.events = Mixin({}, CallbackRegistryMixin)
|
||||
pfUI.events:OnLoad()
|
||||
pfUI.events:SetUndefinedEventsAllowed(true)
|
||||
if not pfUI.disabled then
|
||||
pfUI.events = Mixin({}, CallbackRegistryMixin)
|
||||
pfUI.events:OnLoad()
|
||||
pfUI.events:SetUndefinedEventsAllowed(true)
|
||||
end
|
||||
|
||||
-- check if macro addons are loaded (disables macrotweak/macroscan)
|
||||
function pfUI:MacroAddonsLoaded()
|
||||
|
||||
@@ -2,17 +2,12 @@ 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)
|
||||
|
||||
pfUI.hooksecurefunc("AuctionFrame_OnShow", function()
|
||||
hooksecurefunc("AuctionFrame_OnShow", function()
|
||||
AuctionFrame:ClearAllPoints()
|
||||
AuctionFrame:SetPoint("TOPLEFT", 10, -104)
|
||||
end)
|
||||
@@ -76,7 +71,7 @@ pfUI:RegisterSkin("Auctionhouse", function ()
|
||||
item:SetPoint("LEFT", 2, 0)
|
||||
end
|
||||
end
|
||||
pfUI.hooksecurefunc("AuctionFrameBrowse_Update", function()
|
||||
hooksecurefunc("AuctionFrameBrowse_Update", function()
|
||||
for i = 1, NUM_BROWSE_TO_DISPLAY do
|
||||
HandleIcon(_G["BrowseButton"..i.."Item"], _G["BrowseButton"..i.."ItemIconTexture"])
|
||||
end
|
||||
@@ -145,7 +140,7 @@ pfUI:RegisterSkin("Auctionhouse", function ()
|
||||
item:ClearAllPoints()
|
||||
item:SetPoint("LEFT", 2, 0)
|
||||
end
|
||||
pfUI.hooksecurefunc("AuctionFrameBid_Update", function()
|
||||
hooksecurefunc("AuctionFrameBid_Update", function()
|
||||
for i = 1, NUM_BIDS_TO_DISPLAY do
|
||||
HandleIcon(_G["BidButton"..i.."Item"], _G["BidButton"..i.."ItemIconTexture"])
|
||||
end
|
||||
@@ -191,14 +186,14 @@ pfUI:RegisterSkin("Auctionhouse", function ()
|
||||
item:ClearAllPoints()
|
||||
item:SetPoint("LEFT", 2, 0)
|
||||
end
|
||||
pfUI.hooksecurefunc("AuctionFrameAuctions_Update", function()
|
||||
hooksecurefunc("AuctionFrameAuctions_Update", function()
|
||||
for i = 1, NUM_AUCTIONS_TO_DISPLAY do
|
||||
HandleIcon(_G["AuctionsButton"..i.."Item"], _G["AuctionsButton"..i.."ItemIconTexture"])
|
||||
end
|
||||
end)
|
||||
|
||||
SkinButton(AuctionsItemButton)
|
||||
pfUI.hooksecurefunc("AuctionSellItemButton_OnEvent", function()
|
||||
hooksecurefunc("AuctionSellItemButton_OnEvent", function()
|
||||
if event ~= "NEW_AUCTION_UPDATE" then return end
|
||||
HandleIcon(AuctionsItemButton, AuctionsItemButton:GetNormalTexture())
|
||||
end)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -19,7 +18,7 @@ pfUI:RegisterSkin("Battlefield Minimap", function ()
|
||||
BattlefieldMinimapTab:Hide()
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("BattlefieldMinimap_ShowOpacity", function()
|
||||
hooksecurefunc("BattlefieldMinimap_ShowOpacity", function()
|
||||
OpacityFrame:ClearAllPoints()
|
||||
OpacityFrame:SetPoint("TOPRIGHT", "BattlefieldMinimap", "TOPLEFT", -2*border, 0)
|
||||
end)
|
||||
|
||||
@@ -4,7 +4,25 @@ pfUI:RegisterSkin("Character", function ()
|
||||
|
||||
-- Honor Tab
|
||||
StripTextures(HonorFrame)
|
||||
StripTextures(ArenaFrame)
|
||||
if ArenaFrame then
|
||||
StripTextures(ArenaFrame)
|
||||
for _, frame in pairs({'Arena', 'Honor'}) do
|
||||
for i = 1, 2 do
|
||||
local tab = _G[frame.."FrameTab"..i]
|
||||
local lastTab = _G[frame.."FrameTab"..(i-1)]
|
||||
if lastTab and lastTab:IsShown() then
|
||||
tab:ClearAllPoints()
|
||||
tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
|
||||
end
|
||||
SkinTab(tab)
|
||||
end
|
||||
end
|
||||
for i = 1, 3 do
|
||||
local team = _G["ArenaFrameTeam"..i]
|
||||
StripTextures(team)
|
||||
CreateBackdrop(team)
|
||||
end
|
||||
end
|
||||
|
||||
HonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
|
||||
CreateBackdrop(HonorFrameProgressBar)
|
||||
@@ -113,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)
|
||||
@@ -136,18 +154,18 @@ pfUI:RegisterSkin("Character", function ()
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("CharacterFrame_OnShow", function()
|
||||
hooksecurefunc("CharacterFrame_OnShow", function()
|
||||
RefreshCharacterSlots()
|
||||
RefreshPetPosition()
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
||||
hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
||||
if this:GetParent() == PaperDollFrame then
|
||||
RefreshCharacterSlot(this)
|
||||
end
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("PetTab_Update", RefreshPetPosition)
|
||||
hooksecurefunc("PetTab_Update", RefreshPetPosition)
|
||||
|
||||
StripTextures(PaperDollFrame)
|
||||
StripTextures(CharacterAttributesFrame)
|
||||
@@ -159,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")
|
||||
@@ -218,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")
|
||||
@@ -239,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")
|
||||
@@ -270,7 +285,7 @@ pfUI:RegisterSkin("Character", function ()
|
||||
-- the FactionStanding text from `bar.standingText` on mouseout, so we
|
||||
-- stash our augmented text there too — otherwise hovering a bar strips
|
||||
-- the "(N)" suffix off.
|
||||
pfUI.hooksecurefunc("ReputationFrame_Update", function()
|
||||
hooksecurefunc("ReputationFrame_Update", function()
|
||||
if C.character.reputation.repRequired ~= "1" then return end
|
||||
local offset = FauxScrollFrame_GetOffset(ReputationListScrollFrame)
|
||||
for i = 1, NUM_FACTIONS_DISPLAYED do
|
||||
@@ -338,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)
|
||||
|
||||
@@ -150,7 +150,7 @@ pfUI:RegisterSkin("Friends", function ()
|
||||
end
|
||||
|
||||
-- set positions
|
||||
pfUI.hooksecurefunc("WhoList_Update", function()
|
||||
hooksecurefunc("WhoList_Update", function()
|
||||
for i = 1, WHOS_TO_DISPLAY do
|
||||
local level = _G["WhoFrameButton"..i.."Level"]
|
||||
level:ClearAllPoints()
|
||||
@@ -231,7 +231,7 @@ pfUI:RegisterSkin("Friends", function ()
|
||||
end
|
||||
|
||||
-- set positions
|
||||
pfUI.hooksecurefunc("GuildStatus_Update", function()
|
||||
hooksecurefunc("GuildStatus_Update", function()
|
||||
for i = 1, GUILDMEMBERS_TO_DISPLAY do
|
||||
local level = _G["GuildFrameButton"..i.."Level"]
|
||||
level:ClearAllPoints()
|
||||
|
||||
@@ -24,11 +24,11 @@ pfUI:RegisterSkin("Gossip and Quest", function ()
|
||||
QuestRewardItemHighlightBG:SetTexture(1,1,1,.2)
|
||||
QuestRewardItemHighlightBG:SetAllPoints()
|
||||
|
||||
pfUI.hooksecurefunc("QuestFrameItems_Update", function()
|
||||
hooksecurefunc("QuestFrameItems_Update", function()
|
||||
QuestRewardItemHighlight:Hide()
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc("QuestRewardItem_OnClick", function()
|
||||
hooksecurefunc("QuestRewardItem_OnClick", function()
|
||||
if this.type == "choice" then
|
||||
QuestRewardItemHighlight:SetAllPoints(this.backdrop)
|
||||
QuestRewardItemHighlight:Show()
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
local slots = {
|
||||
"HeadSlot",
|
||||
"NeckSlot",
|
||||
"ShoulderSlot",
|
||||
"BackSlot",
|
||||
"ChestSlot",
|
||||
"ShirtSlot",
|
||||
"TabardSlot",
|
||||
"WristSlot",
|
||||
"HandsSlot",
|
||||
"WaistSlot",
|
||||
"LegsSlot",
|
||||
"FeetSlot",
|
||||
"Finger0Slot",
|
||||
"Finger1Slot",
|
||||
"Trinket0Slot",
|
||||
"Trinket1Slot",
|
||||
"MainHandSlot",
|
||||
"SecondaryHandSlot",
|
||||
"RangedSlot",
|
||||
}
|
||||
|
||||
pfUI:RegisterSkin("Inspect", function ()
|
||||
local rawborder, border = GetBorderSize()
|
||||
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
|
||||
|
||||
HookAddonOrVariable("Blizzard_InspectUI", function()
|
||||
local cache = {}
|
||||
|
||||
CreateBackdrop(InspectFrame, nil, nil, .75)
|
||||
CreateBackdropShadow(InspectFrame)
|
||||
|
||||
InspectFrame.backdrop:SetPoint("TOPLEFT", 10, -10)
|
||||
InspectFrame.backdrop:SetPoint("BOTTOMRIGHT", -30, 72)
|
||||
InspectFrame:SetHitRectInsets(10,30,10,72)
|
||||
EnableMovable("InspectFrame", "Blizzard_InspectUI", INSPECTFRAME_SUBFRAMES)
|
||||
|
||||
SkinCloseButton(InspectFrameCloseButton, InspectFrame.backdrop, -6, -6)
|
||||
|
||||
InspectFrame:DisableDrawLayer("ARTWORK")
|
||||
|
||||
InspectNameText:ClearAllPoints()
|
||||
InspectNameText:SetPoint("TOP", InspectFrame.backdrop, "TOP", 0, -10)
|
||||
|
||||
-- Turtle WoW has up to 4 inspect tabs: Character, Honor, Arena, Talents
|
||||
for i = 1, 4 do
|
||||
local tab = _G["InspectFrameTab"..i]
|
||||
if tab then
|
||||
local lastTab = _G["InspectFrameTab"..(i-1)]
|
||||
tab:ClearAllPoints()
|
||||
if lastTab then
|
||||
tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
|
||||
else
|
||||
tab:SetPoint("TOPLEFT", InspectFrame.backdrop, "BOTTOMLEFT", bpad, -(border + (border == 1 and 1 or 2)))
|
||||
end
|
||||
SkinTab(tab)
|
||||
end
|
||||
end
|
||||
|
||||
do -- Character Tab
|
||||
StripTextures(InspectPaperDollFrame)
|
||||
|
||||
EnableClickRotate(InspectModelFrame)
|
||||
local rotL = InspectModelRotateLeftButton or InspectModelFrameRotateLeftButton
|
||||
if rotL then rotL:Hide() end
|
||||
local rotR = InspectModelRotateRightButton or InspectModelFrameRotateRightButton
|
||||
if rotR then rotR:Hide() end
|
||||
|
||||
for _, slot in pairs(slots) do
|
||||
local frame = _G["Inspect"..slot]
|
||||
StripTextures(frame)
|
||||
CreateBackdrop(frame)
|
||||
SetAllPointsOffset(frame.backdrop, frame, 0)
|
||||
|
||||
HandleIcon(frame.backdrop, _G["Inspect"..slot.."IconTexture"])
|
||||
|
||||
local funce = frame:GetScript("OnEnter")
|
||||
frame:SetScript("OnEnter", function()
|
||||
local bid = this:GetID()
|
||||
if not GetInventoryItemLink(InspectFrame.unit, this:GetID()) and this.hasItem then
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOPRIGHT")
|
||||
GameTooltip:SetHyperlink("item:"..cache[bid]["id"])
|
||||
GameTooltip:Show()
|
||||
else
|
||||
funce()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function ColorSlot(slot, id, itemID, vslot)
|
||||
local item = Item:CreateFromItemID(itemID)
|
||||
if item:IsItemEmpty() then return end
|
||||
|
||||
item:ContinueOnItemLoad(function()
|
||||
if not InspectFrame.unit then return end
|
||||
if GetInventoryItemID(InspectFrame.unit, id) ~= itemID then return end
|
||||
|
||||
local quality = item:GetItemQuality()
|
||||
if not quality then return end
|
||||
|
||||
local r, g, b = GetItemQualityColor(quality)
|
||||
slot.backdrop:SetBackdropBorderColor(r, g, b)
|
||||
|
||||
if ShaguScore then
|
||||
if not slot.scoreText then
|
||||
slot.scoreText = slot:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
slot.scoreText:SetFont(pfUI.font_default, 12, "OUTLINE")
|
||||
slot.scoreText:SetPoint("TOPRIGHT", 0, 0)
|
||||
end
|
||||
local itemLevel = ShaguScore.Database[itemID] or 0
|
||||
local score = ShaguScore:Calculate(vslot, quality, itemLevel)
|
||||
if score and score > 0 then
|
||||
slot.scoreText:SetText(score)
|
||||
slot.scoreText:SetTextColor(r, g, b)
|
||||
else
|
||||
slot.scoreText:SetText("")
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function UpdateSlots()
|
||||
if not InspectFrame.unit then return end
|
||||
|
||||
local guild, title = GetGuildInfo(InspectFrame.unit)
|
||||
if guild then
|
||||
InspectGuildText:SetPoint("TOP", InspectLevelText, "BOTTOM", 0, -1)
|
||||
InspectGuildText:SetText(format(TEXT(GUILD_TITLE_TEMPLATE), title, guild))
|
||||
InspectGuildText:Show()
|
||||
else
|
||||
InspectGuildText:SetText("")
|
||||
InspectGuildText:Hide()
|
||||
end
|
||||
|
||||
for _, vslot in pairs(slots) do
|
||||
local id = GetInventorySlotInfo(vslot)
|
||||
local itemID = GetInventoryItemID(InspectFrame.unit, id)
|
||||
local slot = _G["Inspect" .. vslot]
|
||||
|
||||
if itemID then
|
||||
ColorSlot(slot, id, itemID, vslot)
|
||||
elseif not slot.hasItem then
|
||||
-- genuinely empty slot: reset to a plain backdrop
|
||||
CreateBackdrop(slot)
|
||||
SetAllPointsOffset(slot.backdrop, slot, 0)
|
||||
if slot.scoreText then
|
||||
slot.scoreText:SetText("")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hooksecurefunc("InspectPaperDollItemSlotButton_Update", function(button)
|
||||
local bid = button:GetID()
|
||||
local itemID = GetInventoryItemID(InspectFrame.unit, bid)
|
||||
if itemID then
|
||||
cache[bid] = cache[bid] or {}
|
||||
cache[bid]["id"] = itemID
|
||||
cache[bid]["tex"] = GetInventoryItemTexture(InspectFrame.unit, button:GetID())
|
||||
cache[bid]["count"] = GetInventoryItemCount(InspectFrame.unit, button:GetID())
|
||||
cache[bid]["name"] = UnitName(InspectFrame.unit)
|
||||
elseif cache[bid] and UnitName(InspectFrame.unit) == cache[bid].name then
|
||||
-- restore cache information
|
||||
SetItemButtonTexture(button, cache[bid]["tex"])
|
||||
SetItemButtonCount(button, cache[bid]["count"])
|
||||
button.hasItem = 1
|
||||
end
|
||||
|
||||
UpdateSlots()
|
||||
end)
|
||||
end
|
||||
|
||||
do -- Honor Tab
|
||||
StripTextures(InspectHonorFrame)
|
||||
if InspectArenaFrame then
|
||||
StripTextures(InspectArenaFrame)
|
||||
for i = 1, 3 do
|
||||
local team = _G["InspectArenaFrameTeam"..i]
|
||||
StripTextures(team)
|
||||
CreateBackdrop(team)
|
||||
end
|
||||
end
|
||||
|
||||
CreateBackdrop(InspectHonorFrameProgressBar)
|
||||
InspectHonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
|
||||
InspectHonorFrameProgressBar:SetHeight(24)
|
||||
end
|
||||
|
||||
-- NOTE: Turtle WoW's Talent tab (InspectTalentsFrame / TWTalentFrame) is
|
||||
-- skinned in modules/turtle-wow.lua, which activates once this skin is
|
||||
-- registered (it gates on pfUI.skin["Inspect"]).
|
||||
end)
|
||||
end)
|
||||
@@ -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()
|
||||
|
||||
@@ -45,8 +45,7 @@ pfUI:RegisterSkin("Macro", function ()
|
||||
MacroNewButton:ClearAllPoints()
|
||||
MacroNewButton:SetPoint("RIGHT", MacroExitButton, "LEFT", -2*bpad, 0)
|
||||
|
||||
MacroEditButton:SetHeight(22)
|
||||
MacroEditButton:SetWidth(150)
|
||||
MacroEditButton:SetSize(150, 22)
|
||||
MacroEditButton:ClearAllPoints()
|
||||
MacroEditButton:SetPoint("BOTTOMLEFT", MacroFrameSelectedMacroButton, "BOTTOMRIGHT", 6, -2)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ pfUI:RegisterSkin("Mailbox", function ()
|
||||
StripTextures(SendMailPackageButton)
|
||||
SkinButton(SendMailPackageButton, nil, nil, nil, nil, true)
|
||||
|
||||
pfUI.hooksecurefunc("SendMailFrame_Update", function()
|
||||
hooksecurefunc("SendMailFrame_Update", function()
|
||||
HandleIcon(SendMailPackageButton, SendMailPackageButton:GetNormalTexture())
|
||||
|
||||
local _, itemID = GetSendMailItemLink()
|
||||
@@ -62,7 +62,7 @@ pfUI:RegisterSkin("Mailbox", function ()
|
||||
do -- OpenMailFrame
|
||||
SkinButton(OpenMailPackageButton, nil, nil, nil, OpenMailPackageButtonIconTexture)
|
||||
|
||||
pfUI.hooksecurefunc("InboxFrame_OnClick", function(index)
|
||||
hooksecurefunc("InboxFrame_OnClick", function(index)
|
||||
local _, itemID = GetInboxItemLink(index)
|
||||
if itemID then
|
||||
local quality = C_Item.GetItemQualityByID(itemID)
|
||||
|
||||
@@ -6,7 +6,7 @@ pfUI:RegisterSkin("Merchant", function ()
|
||||
if MerchantGuildBankRepairButton then -- tbc
|
||||
SkinButton(MerchantGuildBankRepairButton, nil, nil, nil, MerchantGuildBankRepairButtonIcon)
|
||||
MerchantGuildBankRepairButtonIcon:SetTexCoord(.59, .82, .06, .54)
|
||||
pfUI.hooksecurefunc("MerchantFrame_UpdateRepairButtons", function()
|
||||
hooksecurefunc("MerchantFrame_UpdateRepairButtons", function()
|
||||
MerchantGuildBankRepairButton:ClearAllPoints()
|
||||
MerchantGuildBankRepairButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -14, 0)
|
||||
MerchantRepairAllButton:ClearAllPoints()
|
||||
@@ -56,7 +56,7 @@ pfUI:RegisterSkin("Merchant", function ()
|
||||
moneyFrame:SetPoint("BOTTOMLEFT", itemButton, "BOTTOMRIGHT", 5, 1)
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("MerchantFrame_UpdateMerchantInfo", function()
|
||||
hooksecurefunc("MerchantFrame_UpdateMerchantInfo", function()
|
||||
if MerchantFrame.selectedTab == 1 then
|
||||
for i = 3, 11, 2 do
|
||||
_G["MerchantItem"..i]:ClearAllPoints()
|
||||
|
||||
@@ -184,7 +184,7 @@ pfUI:RegisterSkin("Options - New", function ()
|
||||
end
|
||||
|
||||
-- hook after category selection: UpdateOptions is local so we hook its caller
|
||||
pfUI.hooksecurefunc("OptionsListButton_OnClick", SkinControls)
|
||||
hooksecurefunc("OptionsListButton_OnClick", SkinControls)
|
||||
-- also cover initial load
|
||||
OptionsFrame:HookScript("OnShow", SkinControls)
|
||||
end)
|
||||
@@ -5,37 +5,18 @@ pfUI:RegisterSkin("Options - Sound", function ()
|
||||
|
||||
-- Compatibility
|
||||
local SoundOptionsFrameHeaderText, NUM_CHECKBOXES, NUM_SLIDERS
|
||||
if SOUND_OPTIONS then -- tbc
|
||||
SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "BACKGROUND", SOUND_OPTIONS)
|
||||
NUM_CHECKBOXES = 11
|
||||
NUM_SLIDERS = 6
|
||||
|
||||
StripTextures(AudioOptionsFrame)
|
||||
CreateBackdrop(SoundOptionsFramePlayback, nil, true, .75)
|
||||
CreateBackdrop(SoundOptionsFrameHardware, nil, true, .75)
|
||||
CreateBackdrop(SoundOptionsFrameVolume, nil, true, .75)
|
||||
SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "ARTWORK", SOUNDOPTIONS_MENU)
|
||||
NUM_CHECKBOXES = 8
|
||||
NUM_SLIDERS = 4
|
||||
|
||||
SkinDropDown(SoundOptionsOutputDropDown)
|
||||
|
||||
SoundOptionsFrameDefaults:ClearAllPoints()
|
||||
SoundOptionsFrameDefaults:SetPoint("TOPLEFT", SoundOptionsFramePlayback, "BOTTOMLEFT", 0, -10)
|
||||
SoundOptionsFrameCancel:ClearAllPoints()
|
||||
SoundOptionsFrameCancel:SetPoint("TOPRIGHT", SoundOptionsFrameVolume, "BOTTOMRIGHT", 0, -10)
|
||||
SoundOptionsFrameOkay:ClearAllPoints()
|
||||
SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
|
||||
else -- vanilla
|
||||
SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "ARTWORK", SOUNDOPTIONS_MENU)
|
||||
NUM_CHECKBOXES = 8
|
||||
NUM_SLIDERS = 4
|
||||
|
||||
SoundOptionsFrameOkay:ClearAllPoints()
|
||||
SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
|
||||
SoundOptionsFrameSlider1:ClearAllPoints()
|
||||
SoundOptionsFrameSlider1:SetPoint("TOPRIGHT", SoundOptionsFrame, "TOPRIGHT", -18, -43)
|
||||
for i=2, NUM_SLIDERS do
|
||||
_G["SoundOptionsFrameSlider"..i]:ClearAllPoints()
|
||||
_G["SoundOptionsFrameSlider"..i]:SetPoint("TOP", _G["SoundOptionsFrameSlider"..i-1], "BOTTOM", 0, -30)
|
||||
end
|
||||
SoundOptionsFrameOkay:ClearAllPoints()
|
||||
SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
|
||||
SoundOptionsFrameSlider1:ClearAllPoints()
|
||||
SoundOptionsFrameSlider1:SetPoint("TOPRIGHT", SoundOptionsFrame, "TOPRIGHT", -18, -43)
|
||||
for i=2, NUM_SLIDERS do
|
||||
_G["SoundOptionsFrameSlider"..i]:ClearAllPoints()
|
||||
_G["SoundOptionsFrameSlider"..i]:SetPoint("TOP", _G["SoundOptionsFrameSlider"..i-1], "BOTTOM", 0, -30)
|
||||
end
|
||||
|
||||
StripTextures(SoundOptionsFrame)
|
||||
|
||||
@@ -19,7 +19,7 @@ pfUI:RegisterSkin("Options - Video", function ()
|
||||
slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("OptionsFrame_Load", function()
|
||||
hooksecurefunc("OptionsFrame_Load", function()
|
||||
OptionsFramePixelShaders:SetWidth(230)
|
||||
OptionsFrameMiscellaneous:ClearAllPoints()
|
||||
OptionsFrameMiscellaneous:SetPoint("LEFT", OptionsFramePixelShaders, "RIGHT", 6, 0)
|
||||
|
||||
@@ -192,7 +192,7 @@ pfUI:RegisterSkin("Profession", function ()
|
||||
reagentlabel:SetTextColor(1,1,1,1)
|
||||
|
||||
local scanner = libtipscan:GetScanner(name)
|
||||
pfUI.hooksecurefunc(SetSelection, function(id)
|
||||
hooksecurefunc(SetSelection, function(id)
|
||||
if id and id ~= 0 then
|
||||
detailscroll:Show()
|
||||
HandleIcon(icon, icon:GetNormalTexture())
|
||||
|
||||
@@ -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
|
||||
QuestLogQuestCount:ClearAllPoints()
|
||||
QuestLogQuestCount:SetPoint("TOPRIGHT", -10, -30)
|
||||
|
||||
StripTextures(QUEST_COUNT)
|
||||
QUEST_COUNT:ClearAllPoints()
|
||||
pfUI.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
|
||||
|
||||
pfUI.hooksecurefunc("QuestLog_OnShow", function()
|
||||
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)
|
||||
@@ -163,7 +146,7 @@ pfUI:RegisterSkin("Quest Log", function ()
|
||||
QuestLogListScrollFrame:SetPoint("TOPLEFT", 10, -54)
|
||||
QuestLogListScrollFrame:SetHeight(350)
|
||||
|
||||
pfUI.hooksecurefunc("QuestLog_Update", function()
|
||||
hooksecurefunc("QuestLog_Update", function()
|
||||
local numEntries = GetNumQuestLogEntries()
|
||||
local questIndex, text, level, questTag, isHeader
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,15 +26,15 @@ 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
|
||||
pfUI.hooksecurefunc("ShowReadyCheck", function()
|
||||
hooksecurefunc("ShowReadyCheck", function()
|
||||
max = ReadyCheckFrame.timer
|
||||
frame.bar:SetMinMaxValues(0, max)
|
||||
end)
|
||||
|
||||
pfUI.hooksecurefunc(update_func, function()
|
||||
hooksecurefunc("ReadyCheck_OnUpdate", function()
|
||||
if not ReadyCheckFrame.timer then return end
|
||||
|
||||
local perc = ReadyCheckFrame.timer/max
|
||||
|
||||
@@ -32,7 +32,7 @@ pfUI:RegisterSkin("GM Survey", function ()
|
||||
CreateBackdrop(GMSurveyCommentFrame, nil, true, .75)
|
||||
SkinScrollbar(GMSurveyCommentScrollFrameScrollBar)
|
||||
GMSurveyFrameComment:SetMaxLetters(2000)
|
||||
pfUI.hooksecurefunc("GMSurveyFrame_Update", function()
|
||||
hooksecurefunc("GMSurveyFrame_Update", function()
|
||||
GMSurveyFrameComment:SetWidth(505)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -41,7 +41,7 @@ pfUI:RegisterSkin("Trade", function ()
|
||||
RecipientButtonBG:SetAllPoints()
|
||||
end
|
||||
|
||||
pfUI.hooksecurefunc("TradeFrame_UpdateTargetItem", function(id)
|
||||
hooksecurefunc("TradeFrame_UpdateTargetItem", function(id)
|
||||
HandleIcon(_G["TradeRecipientItem"..id.."ItemButton"], _G["TradeRecipientItem"..id..'IconTexture'])
|
||||
end)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ pfUI:RegisterSkin("Trainer", function ()
|
||||
|
||||
StripTextures(ClassTrainerSkillIcon)
|
||||
SkinButton(ClassTrainerSkillIcon, nil, nil, nil, nil, true)
|
||||
pfUI.hooksecurefunc("ClassTrainer_SetSelection", function()
|
||||
hooksecurefunc("ClassTrainer_SetSelection", function()
|
||||
HandleIcon(ClassTrainerSkillIcon, ClassTrainerSkillIcon:GetNormalTexture())
|
||||
end)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user