mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-27 06:10:49 +00:00
Compare commits
18
Commits
v9.0.20
...
65fcba6698
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65fcba6698 | ||
|
|
bee1aa9bdd | ||
|
|
60f2c22a6c | ||
|
|
2b5288a688 | ||
|
|
daba4e202e | ||
|
|
98c7751416 | ||
|
|
8796fab6d8 | ||
|
|
7ca0e40d8b | ||
|
|
2f93b246a1 | ||
|
|
c647698f8f | ||
|
|
48026008b6 | ||
|
|
c1d96bae58 | ||
|
|
1d44c5ec6f | ||
|
|
8f88dfd852 | ||
|
|
a57214aeb0 | ||
|
|
9bde843e33 | ||
|
|
ad13e6ace3 | ||
|
|
82c74c2db5 |
+104
@@ -0,0 +1,104 @@
|
|||||||
|
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 = 11301 -- (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"
|
||||||
|
local function FormatVersion(packed)
|
||||||
|
local x = math.floor(packed / 10000)
|
||||||
|
local y = math.floor(math.mod(packed, 10000) / 100)
|
||||||
|
local z = math.mod(packed, 100)
|
||||||
|
return string.format("v%d.%d.%d", x, y, z)
|
||||||
|
end
|
||||||
|
if not CLASSIC_API_VERSION or CLASSIC_API_VERSION < PFUI_CLASSIC_API_MIN then
|
||||||
|
local minVersion = FormatVersion(PFUI_CLASSIC_API_MIN)
|
||||||
|
pfUI_disabled = true
|
||||||
|
pfUI_locale = {}
|
||||||
|
pfUI_profiles = {}
|
||||||
|
pfUI_translation = {}
|
||||||
|
|
||||||
|
-- ClassicAPI is required. Rather than let the ~140 files that follow flood
|
||||||
|
-- errors as they load, stand up an inert stub so everything no-ops:
|
||||||
|
-- * modules/skins register their body into a no-op, so it never runs;
|
||||||
|
-- * the setfenv'd api/lib files run inside `env`, where CreateFrame and
|
||||||
|
-- any missing global (C_*, SuperWoW, ...) resolve to a null object --
|
||||||
|
-- so no real frames or live OnUpdate/OnEvent handlers get created and
|
||||||
|
-- missing API calls just return null instead of erroring.
|
||||||
|
local null -- forward declaration so the metamethods can return it
|
||||||
|
local nullmt = {
|
||||||
|
__index = function() return null end,
|
||||||
|
__newindex = function() end,
|
||||||
|
__call = function() return null end,
|
||||||
|
__concat = function() return "" end,
|
||||||
|
__tostring = function() return "" end,
|
||||||
|
}
|
||||||
|
for _, op in ipairs({ "__add","__sub","__mul","__div","__mod","__pow","__unm" }) do
|
||||||
|
nullmt[op] = function() return null end
|
||||||
|
end
|
||||||
|
for _, op in ipairs({ "__lt","__le","__eq" }) do nullmt[op] = function() return false end end
|
||||||
|
null = setmetatable({}, nullmt)
|
||||||
|
|
||||||
|
local realG = getfenv(0)
|
||||||
|
pfUI = setmetatable({}, { __index = function() return null end })
|
||||||
|
pfUI.env = setmetatable({}, {
|
||||||
|
__index = function(_, k)
|
||||||
|
if k == "CreateFrame" then return function() return null end end
|
||||||
|
local v = realG[k]
|
||||||
|
if v ~= nil then return v end
|
||||||
|
return null
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
function pfUI:RegisterModule(_, _, _) end
|
||||||
|
function pfUI:RegisterSkin(_, _, _) end
|
||||||
|
function pfUI:GetEnvironment() return pfUI.env end
|
||||||
|
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 = "|cff33ffccpf|cffffffffUI|r has been disabled.\n\n" .. detail,
|
||||||
|
button1 = OKAY,
|
||||||
|
hasEditBox = 1,
|
||||||
|
editBoxWidth = 280,
|
||||||
|
timeout = 0,
|
||||||
|
whileDead = 1,
|
||||||
|
hideOnEscape = 1,
|
||||||
|
preferredIndex = 3,
|
||||||
|
OnShow = function()
|
||||||
|
local editBox = getglobal(this:GetName().."EditBox")
|
||||||
|
if editBox then
|
||||||
|
editBox:SetText(PFUI_CLASSIC_API_LATEST_URL)
|
||||||
|
editBox:HighlightText()
|
||||||
|
editBox:SetFocus()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
StaticPopup_Show("PFUI_CLASSICAPI_REQUIRED")
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(
|
||||||
|
"|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()
|
||||||
|
C_Timer.After(8, function()
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(
|
||||||
|
"|cff33ffccpf|rUI: ClassicAPI " .. FormatVersion(PFUI_CLASSIC_API_LATEST) .. " is available — " .. PFUI_CLASSIC_API_LATEST_URL,
|
||||||
|
1, 0.85, 0.3
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
+66
-53
@@ -1638,39 +1638,40 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
for i=1, unit.config.bufflimit do
|
for i=1, unit.config.bufflimit do
|
||||||
if not unit.buffs[i] then break end
|
if not unit.buffs[i] then break end
|
||||||
|
|
||||||
local aura = C_UnitAuras.GetBuffDataByIndex(unitstr, i)
|
-- positional UnitBuff allocates nothing (vs a table per icon per refresh)
|
||||||
|
local name, icon, count, _, duration, expirationTime, _, _, _, spellId = C_UnitAuras.UnitBuff(unitstr, i)
|
||||||
|
|
||||||
if aura then
|
if name then
|
||||||
unit.buffs[i].texture:SetTexture(aura.icon)
|
unit.buffs[i].texture:SetTexture(icon)
|
||||||
unit.buffs[i]:Show()
|
unit.buffs[i]:Show()
|
||||||
|
|
||||||
if aura.applications > 1 then
|
if count > 1 then
|
||||||
unit.buffs[i].stacks:SetText(aura.applications)
|
unit.buffs[i].stacks:SetText(count)
|
||||||
else
|
else
|
||||||
unit.buffs[i].stacks:SetText("")
|
unit.buffs[i].stacks:SetText("")
|
||||||
end
|
end
|
||||||
|
|
||||||
if aura.expirationTime > 0 then
|
if expirationTime > 0 then
|
||||||
-- pfUI's cooldown text falls into a 2^32 wraparound branch when start > GetTime(),
|
-- pfUI's cooldown text falls into a 2^32 wraparound branch when start > GetTime(),
|
||||||
-- which happens for talent-extended buffs where the real duration exceeds aura.duration
|
-- which happens for talent-extended buffs where the real duration exceeds the
|
||||||
-- (the Spell.dbc base). Anchor start to now in that case to keep the remaining math sane.
|
-- Spell.dbc base. Anchor start to now in that case to keep the remaining math sane.
|
||||||
local now = GetTime()
|
local now = GetTime()
|
||||||
local start = aura.expirationTime - aura.duration
|
local start = expirationTime - duration
|
||||||
local duration = aura.duration
|
local dur = duration
|
||||||
if start > now or duration <= 0 then
|
if start > now or dur <= 0 then
|
||||||
start, duration = now, aura.expirationTime - now
|
start, dur = now, expirationTime - now
|
||||||
end
|
end
|
||||||
if duration > 0 then
|
if dur > 0 then
|
||||||
CooldownFrame_SetTimer(unit.buffs[i].cd, start, duration, 1)
|
CooldownFrame_SetTimer(unit.buffs[i].cd, start, dur, 1)
|
||||||
else
|
else
|
||||||
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
elseif aura.duration > 0 then
|
elseif duration > 0 then
|
||||||
local guid = UnitGUID(unitstr)
|
local guid = UnitGUID(unitstr)
|
||||||
local guidStarts = guid and pfUI.uf.aura_starts[guid]
|
local guidStarts = guid and pfUI.uf.aura_starts[guid]
|
||||||
local start = guidStarts and guidStarts[aura.spellId]
|
local start = guidStarts and guidStarts[spellId]
|
||||||
if start then
|
if start then
|
||||||
CooldownFrame_SetTimer(unit.buffs[i].cd, start, aura.duration, 1)
|
CooldownFrame_SetTimer(unit.buffs[i].cd, start, duration, 1)
|
||||||
else
|
else
|
||||||
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
@@ -1741,10 +1742,11 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
-- selfdebuff narrows to player-cast harmful auras via the PLAYER filter.
|
-- selfdebuff narrows to player-cast harmful auras via the PLAYER filter.
|
||||||
-- Player-frame debuffs aren't gated on it (it'd hide most party-applied
|
-- Player-frame debuffs aren't gated on it (it'd hide most party-applied
|
||||||
-- effects on you).
|
-- effects on you).
|
||||||
local filter = (unit.label ~= "player" and selfdebuff == "1") and "HARMFUL|PLAYER" or "HARMFUL"
|
-- positional UnitDebuff allocates nothing; PLAYER predicate honored for selfdebuff
|
||||||
local aura = C_UnitAuras.GetAuraDataByIndex(unitstr, i, filter)
|
local filter = (unit.label ~= "player" and selfdebuff == "1") and "PLAYER" or nil
|
||||||
if aura then
|
local name, icon, count, dispelType, duration, expirationTime = C_UnitAuras.UnitDebuff(unitstr, i, filter)
|
||||||
texture, stacks, dtype = aura.icon, aura.applications, aura.dispelName
|
if name then
|
||||||
|
texture, stacks, dtype = icon, count, dispelType
|
||||||
else
|
else
|
||||||
texture, stacks, dtype = nil, 0, nil
|
texture, stacks, dtype = nil, 0, nil
|
||||||
end
|
end
|
||||||
@@ -1757,18 +1759,18 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
if texture then
|
if texture then
|
||||||
unit.debuffs[i]:Show()
|
unit.debuffs[i]:Show()
|
||||||
|
|
||||||
if aura and aura.expirationTime > 0 then
|
if expirationTime > 0 then
|
||||||
-- Cap start to now so talent-extended debuffs (expirationTime past
|
-- Cap start to now so talent-extended debuffs (expirationTime past
|
||||||
-- the dbc base duration) don't push start into the future and trip
|
-- the dbc base duration) don't push start into the future and trip
|
||||||
-- CooldownFrame_SetTimer's 2^32-wraparound branch.
|
-- CooldownFrame_SetTimer's 2^32-wraparound branch.
|
||||||
local now = GetTime()
|
local now = GetTime()
|
||||||
local start = aura.expirationTime - aura.duration
|
local start = expirationTime - duration
|
||||||
local duration = aura.duration
|
local dur = duration
|
||||||
if start > now or duration <= 0 then
|
if start > now or dur <= 0 then
|
||||||
start, duration = now, aura.expirationTime - now
|
start, dur = now, expirationTime - now
|
||||||
end
|
end
|
||||||
if duration > 0 then
|
if dur > 0 then
|
||||||
CooldownFrame_SetTimer(unit.debuffs[i].cd, start, duration, 1)
|
CooldownFrame_SetTimer(unit.debuffs[i].cd, start, dur, 1)
|
||||||
else
|
else
|
||||||
CooldownFrame_SetTimer(unit.debuffs[i].cd, 0, 0, 0)
|
CooldownFrame_SetTimer(unit.debuffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
@@ -1826,6 +1828,17 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Scan the 16 harmful slots once into a reusable set, instead of
|
||||||
|
-- re-scanning all 16 for every dispellable type below. Reused across
|
||||||
|
-- frames (populated and consumed within this single RefreshUnit call).
|
||||||
|
local present = pfUI.uf.dispelPresent or {}
|
||||||
|
pfUI.uf.dispelPresent = present
|
||||||
|
for k in pairs(present) do present[k] = nil end
|
||||||
|
for i=1,16 do
|
||||||
|
local name, _, _, dispelType = C_UnitAuras.UnitDebuff(unitstr, i)
|
||||||
|
if name and dispelType and dispelType ~= "" then present[dispelType] = true end
|
||||||
|
end
|
||||||
|
|
||||||
for _, debuff in pairs(unit.dispellable) do
|
for _, debuff in pairs(unit.dispellable) do
|
||||||
indicator[debuff] = indicator[debuff] or CreateFrame("Frame", nil, indicator)
|
indicator[debuff] = indicator[debuff] or CreateFrame("Frame", nil, indicator)
|
||||||
indicator[debuff]:SetParent(indicator)
|
indicator[debuff]:SetParent(indicator)
|
||||||
@@ -1865,15 +1878,7 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
indicator[debuff].disp = indicator.disp
|
indicator[debuff].disp = indicator.disp
|
||||||
end
|
end
|
||||||
|
|
||||||
indicator[debuff].visible = nil
|
indicator[debuff].visible = present[debuff]
|
||||||
|
|
||||||
for i=1,16 do
|
|
||||||
local a = C_UnitAuras.GetDebuffDataByIndex(unitstr, i)
|
|
||||||
local dtype = a and a.dispelName
|
|
||||||
if dtype == debuff then
|
|
||||||
indicator[debuff].visible = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if indicator[debuff].visible then
|
if indicator[debuff].visible then
|
||||||
indicator[debuff]:Show()
|
indicator[debuff]:Show()
|
||||||
@@ -1920,50 +1925,58 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
|
|
||||||
local pos = 1
|
local pos = 1
|
||||||
if table.getn(unit.indicators) > 0 then
|
if table.getn(unit.indicators) > 0 then
|
||||||
for _, aura in ipairs(C_UnitAuras.GetUnitAuras(unitstr, "HELPFUL")) do
|
local i = 1
|
||||||
local texLower = string.lower(aura.icon)
|
while true do
|
||||||
local timeleft = aura.expirationTime > 0 and (aura.expirationTime - GetTime()) or nil
|
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitBuff(unitstr, i)
|
||||||
|
if not name then break end
|
||||||
|
local texLower = string.lower(icon)
|
||||||
|
local timeleft = expirationTime > 0 and (expirationTime - GetTime()) or nil
|
||||||
|
|
||||||
for _, filter in pairs(unit.indicators) do
|
for _, filter in pairs(unit.indicators) do
|
||||||
if filter == texLower then
|
if filter == texLower then
|
||||||
local hot = HOT_INDICATORS[texLower]
|
local hot = HOT_INDICATORS[texLower]
|
||||||
if hot and string.lower(aura.name) ~= hot.name then
|
if hot and string.lower(name) ~= hot.name then
|
||||||
break -- texture matches but name disambiguates (e.g. shared icon)
|
break -- texture matches but name disambiguates (e.g. shared icon)
|
||||||
end
|
end
|
||||||
if hot then
|
if hot then
|
||||||
local start, duration, prediction = libpredict:GetHotDuration(unitstr, hot.predict)
|
local start, duration, prediction = libpredict:GetHotDuration(unitstr, hot.predict)
|
||||||
pfUI.uf:AddIcon(unit, pos, aura.icon, timeleft or prediction, aura.applications, tonumber(start), tonumber(duration))
|
pfUI.uf:AddIcon(unit, pos, icon, timeleft or prediction, count, tonumber(start), tonumber(duration))
|
||||||
else
|
else
|
||||||
pfUI.uf:AddIcon(unit, pos, aura.icon, timeleft, aura.applications)
|
pfUI.uf:AddIcon(unit, pos, icon, timeleft, count)
|
||||||
end
|
end
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if table.getn(unit.indicator_custom) > 0 then
|
if table.getn(unit.indicator_custom) > 0 then
|
||||||
for _, aura in ipairs(C_UnitAuras.GetUnitAuras(unitstr, "HELPFUL")) do
|
local ai = 1
|
||||||
local timeleft = aura.expirationTime > 0 and (aura.expirationTime - GetTime()) or nil
|
while true do
|
||||||
local lowerName = string.lower(aura.name)
|
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitBuff(unitstr, ai)
|
||||||
|
if not name then break end
|
||||||
|
local timeleft = expirationTime > 0 and (expirationTime - GetTime()) or nil
|
||||||
|
local lowerName = string.lower(name)
|
||||||
for _, filter in pairs(unit.indicator_custom) do
|
for _, filter in pairs(unit.indicator_custom) do
|
||||||
if filter == lowerName then
|
if filter == lowerName then
|
||||||
pfUI.uf:AddIcon(unit, pos, aura.icon, timeleft, aura.applications)
|
pfUI.uf:AddIcon(unit, pos, icon, timeleft, count)
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
ai = ai + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local debuffFilter = unit.config.selfdebuff == "1" and "HARMFUL|PLAYER" or "HARMFUL"
|
local debuffFilter = unit.config.selfdebuff == "1" and "PLAYER" or nil
|
||||||
for i=1,16 do -- scan for custom debuffs
|
for i=1,16 do -- scan for custom debuffs
|
||||||
local aura = C_UnitAuras.GetAuraDataByIndex(unitstr, i, debuffFilter)
|
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitDebuff(unitstr, i, debuffFilter)
|
||||||
if aura then
|
if name then
|
||||||
local timeleft = aura.expirationTime > 0 and (aura.expirationTime - GetTime()) or nil
|
local timeleft = expirationTime > 0 and (expirationTime - GetTime()) or nil
|
||||||
for _, filter in pairs(unit.indicator_custom) do
|
for _, filter in pairs(unit.indicator_custom) do
|
||||||
if filter == string.lower(aura.name) then
|
if filter == string.lower(name) then
|
||||||
pfUI.uf:AddIcon(unit, pos, aura.icon, timeleft, aura.applications)
|
pfUI.uf:AddIcon(unit, pos, icon, timeleft, count)
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|||||||
Vendored
+6
@@ -63,6 +63,12 @@ for i=1,40 do
|
|||||||
pfValidUnits["nameplate" .. i .. "target"] = true
|
pfValidUnits["nameplate" .. i .. "target"] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if TURTLE_WOW_VERSION then -- We already know this table is going to be replaced by turtle-wow.lua, so there's no point in declaring it.
|
||||||
|
pfSellData = {} -- create empty just incase user has turtle-wow module disabled.
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- This table makes me sick.
|
||||||
-- itemid = buyPrice (copper). Sell price comes from C_Item.GetItemSellPriceByID;
|
-- itemid = buyPrice (copper). Sell price comes from C_Item.GetItemSellPriceByID;
|
||||||
-- this table only carries the curated vendor-buy price (which isn't a static
|
-- this table only carries the curated vendor-buy price (which isn't a static
|
||||||
-- engine field — it's collected from real vendor encounters).
|
-- engine field — it's collected from real vendor encounters).
|
||||||
|
|||||||
@@ -168,6 +168,9 @@ pfUI.libdebuff_spell_start_self_hooks["libpredict"] = function(spellId, casterGu
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
spell_queue[1] = spellName
|
||||||
|
spell_queue[2] = spellName .. (C_Spell.GetSpellSubtext(spellId) or "")
|
||||||
|
|
||||||
if spell_queue[1] == spellName and cache[spell_queue[2]] then
|
if spell_queue[1] == spellName and cache[spell_queue[2]] then
|
||||||
local amount = cache[spell_queue[2]][1]
|
local amount = cache[spell_queue[2]][1]
|
||||||
local casttime = castTime
|
local casttime = castTime
|
||||||
|
|||||||
+7
-7
@@ -23,7 +23,7 @@ pfUI:RegisterModule("buff", function ()
|
|||||||
CreateBackdropShadow(buff)
|
CreateBackdropShadow(buff)
|
||||||
end
|
end
|
||||||
|
|
||||||
local aura = C_UnitAuras.GetAuraDataByIndex("player", buff.id, buff.btype)
|
local name, icon, count, dispelType, _, expirationTime, _, _, _, spellId = C_UnitAuras.UnitAura("player", buff.id, buff.btype)
|
||||||
|
|
||||||
--detect weapon buffs
|
--detect weapon buffs
|
||||||
if buff.btype == "HELPFUL" and ((C.buffs.separateweapons == "0" and buff.gid <= pfUI.buff.wepbuffs.count) or (pfUI.buff.wepbuffs.count > 0 and buff.weapon ~= nil)) then
|
if buff.btype == "HELPFUL" and ((C.buffs.separateweapons == "0" and buff.gid <= pfUI.buff.wepbuffs.count) or (pfUI.buff.wepbuffs.count > 0 and buff.weapon ~= nil)) then
|
||||||
@@ -55,16 +55,16 @@ pfUI:RegisterModule("buff", function ()
|
|||||||
buff.texture:SetTexture(GetInventoryItemTexture("player", 17))
|
buff.texture:SetTexture(GetInventoryItemTexture("player", 17))
|
||||||
buff.backdrop:SetBackdropBorderColor(GetItemQualityColor(GetInventoryItemQuality("player", 17) or 1))
|
buff.backdrop:SetBackdropBorderColor(GetItemQualityColor(GetInventoryItemQuality("player", 17) or 1))
|
||||||
end
|
end
|
||||||
elseif aura and (( buff.btype == "HARMFUL" and C.buffs.debuffs == "1" ) or ( buff.btype == "HELPFUL" and C.buffs.buffs == "1" )) then
|
elseif name and (( buff.btype == "HARMFUL" and C.buffs.debuffs == "1" ) or ( buff.btype == "HELPFUL" and C.buffs.buffs == "1" )) then
|
||||||
-- Set Buff Texture and Border
|
-- Set Buff Texture and Border
|
||||||
buff.mode = buff.btype
|
buff.mode = buff.btype
|
||||||
buff.expirationTime = aura.expirationTime
|
buff.expirationTime = expirationTime
|
||||||
buff.stackCount = aura.applications
|
buff.stackCount = count
|
||||||
buff.spellId = aura.spellId
|
buff.spellId = spellId
|
||||||
buff.texture:SetTexture(aura.icon)
|
buff.texture:SetTexture(icon)
|
||||||
|
|
||||||
if buff.btype == "HARMFUL" then
|
if buff.btype == "HARMFUL" then
|
||||||
local dispelColor = C_UnitAuras.GetAuraDispelTypeColor(aura.dispelName)
|
local dispelColor = C_UnitAuras.GetAuraDispelTypeColor(dispelType)
|
||||||
buff.backdrop:SetBackdropBorderColor(dispelColor:GetRGBA())
|
buff.backdrop:SetBackdropBorderColor(dispelColor:GetRGBA())
|
||||||
else
|
else
|
||||||
buff.backdrop:SetBackdropBorderColor(br,bg,bb,ba)
|
buff.backdrop:SetBackdropBorderColor(br,bg,bb,ba)
|
||||||
|
|||||||
+10
-11
@@ -75,10 +75,10 @@ pfUI:RegisterModule("buffwatch", function ()
|
|||||||
|
|
||||||
local function GetBuffData(unit, id, type, selfdebuff)
|
local function GetBuffData(unit, id, type, selfdebuff)
|
||||||
local filter = (selfdebuff and type == "HARMFUL") and "HARMFUL|PLAYER" or type
|
local filter = (selfdebuff and type == "HARMFUL") and "HARMFUL|PLAYER" or type
|
||||||
local aura = C_UnitAuras.GetAuraDataByIndex(unit, id, filter)
|
local name, icon, count, dispelType, _, expirationTime = C_UnitAuras.UnitAura(unit, id, filter)
|
||||||
if not aura then return end
|
if not name then return end
|
||||||
local remaining = aura.expirationTime > 0 and (aura.expirationTime - GetTime()) or 0
|
local remaining = expirationTime > 0 and (expirationTime - GetTime()) or 0
|
||||||
return remaining, aura.icon, aura.name, aura.applications
|
return remaining, icon, name, count, dispelType
|
||||||
end
|
end
|
||||||
|
|
||||||
local function StatusBarOnClick()
|
local function StatusBarOnClick()
|
||||||
@@ -236,7 +236,7 @@ pfUI:RegisterModule("buffwatch", function ()
|
|||||||
local selfdebuff = frame.config.selfdebuff == "1"
|
local selfdebuff = frame.config.selfdebuff == "1"
|
||||||
|
|
||||||
for i=1,32 do
|
for i=1,32 do
|
||||||
local timeleft, texture, name, stacks = GetBuffData(frame.unit, i, frame.type, selfdebuff)
|
local timeleft, texture, name, stacks, dtype = GetBuffData(frame.unit, i, frame.type, selfdebuff)
|
||||||
timeleft = timeleft or 0
|
timeleft = timeleft or 0
|
||||||
|
|
||||||
if texture and name and name ~= "" and BuffIsVisible(frame.config, name) then
|
if texture and name and name ~= "" and BuffIsVisible(frame.config, name) then
|
||||||
@@ -245,12 +245,14 @@ pfUI:RegisterModule("buffwatch", function ()
|
|||||||
frame.buffs[i][3] = name
|
frame.buffs[i][3] = name
|
||||||
frame.buffs[i][4] = texture
|
frame.buffs[i][4] = texture
|
||||||
frame.buffs[i][5] = stacks
|
frame.buffs[i][5] = stacks
|
||||||
|
frame.buffs[i][6] = dtype
|
||||||
else
|
else
|
||||||
frame.buffs[i][1] = 0
|
frame.buffs[i][1] = 0
|
||||||
frame.buffs[i][2] = nil
|
frame.buffs[i][2] = nil
|
||||||
frame.buffs[i][3] = nil
|
frame.buffs[i][3] = nil
|
||||||
frame.buffs[i][4] = nil
|
frame.buffs[i][4] = nil
|
||||||
frame.buffs[i][5] = 0
|
frame.buffs[i][5] = 0
|
||||||
|
frame.buffs[i][6] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -294,12 +296,9 @@ pfUI:RegisterModule("buffwatch", function ()
|
|||||||
-- calculate dynamic auto color
|
-- calculate dynamic auto color
|
||||||
local r, g, b
|
local r, g, b
|
||||||
if frame.type == "HARMFUL" then
|
if frame.type == "HARMFUL" then
|
||||||
r, g, b = 1, .2, .2
|
-- official Blizzard dispel-type colors (matches unitframes/buff);
|
||||||
local a = C_UnitAuras.GetDebuffDataByIndex(frame.unit, data[2])
|
-- nil/unknown type falls back to the DEBUFF_TYPE_NONE colour
|
||||||
local dtype = a and a.dispelName
|
r, g, b = C_UnitAuras.GetAuraDispelTypeColor(data[6] or ""):GetRGBA()
|
||||||
if dtype and DebuffTypeColor[dtype] then
|
|
||||||
r,g,b = DebuffTypeColor[dtype].r,DebuffTypeColor[dtype].g,DebuffTypeColor[dtype].b
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
r,g,b = str2rgb(data[3])
|
r,g,b = str2rgb(data[3])
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
if not cb.tradeskillTotal or not cb.activeName or not cb.showname then return end
|
if not cb.tradeskillTotal or not cb.activeName or not cb.showname then return end
|
||||||
local remaining = cb.tradeskillTotal - (cb.tradeskillCompleted or 0)
|
local remaining = cb.tradeskillTotal - (cb.tradeskillCompleted or 0)
|
||||||
if remaining > 1 then
|
if remaining > 1 then
|
||||||
cb.bar.left:SetText(string.format("%s (%d)", cb.activeName, remaining))
|
cb.bar.left:SetFormattedText("%s (%d)", cb.activeName, remaining)
|
||||||
else
|
else
|
||||||
cb.bar.left:SetText(cb.activeName)
|
cb.bar.left:SetText(cb.activeName)
|
||||||
end
|
end
|
||||||
|
|||||||
+6
-11
@@ -127,7 +127,7 @@ pfUI:RegisterModule("firstrun", function ()
|
|||||||
-- welcome dialog
|
-- welcome dialog
|
||||||
pfUI.firstrun:AddStep("init", function()
|
pfUI.firstrun:AddStep("init", function()
|
||||||
local f = CreateFirstRunPage()
|
local f = CreateFirstRunPage()
|
||||||
f.text:SetText(string.format(T["Welcome to |cff33ffccpf|cffffffffUI|r!\n\nI'm the first run wizard that will guide you through some basic configuration. If you're lazy, feel free to hit the \"Defaults\" button. If you wish to run this dialog again, go to the settings and hit the \"Reset Firstrun\" button.\n\nVisit |cff33ffcc%s|r to check for the latest version."], GetAddOnMetadata(pfUI.name, "X-Website")))
|
f.text:SetFormattedText(T["Welcome to |cff33ffccpf|cffffffffUI|r!\n\nI'm the first run wizard that will guide you through some basic configuration. If you're lazy, feel free to hit the \"Defaults\" button. If you wish to run this dialog again, go to the settings and hit the \"Reset Firstrun\" button.\n\nVisit |cff33ffcc%s|r to check for the latest version."], GetAddOnMetadata(pfUI.name, "X-Website"))
|
||||||
return f
|
return f
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -137,8 +137,7 @@ pfUI:RegisterModule("firstrun", function ()
|
|||||||
f.text:SetText(T["A new installation of |cff33ffccpf|rUI ships with 4 prebuilt design profiles. Click below if you wish to load one of these profiles."])
|
f.text:SetText(T["A new installation of |cff33ffccpf|rUI ships with 4 prebuilt design profiles. Click below if you wish to load one of these profiles."])
|
||||||
|
|
||||||
f.Modern = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
f.Modern = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||||
f.Modern:SetWidth(120)
|
f.Modern:SetSize(120, 20)
|
||||||
f.Modern:SetHeight(20)
|
|
||||||
f.Modern:SetPoint("BOTTOM", -65, 100)
|
f.Modern:SetPoint("BOTTOM", -65, 100)
|
||||||
f.Modern:SetTextColor(1,1,1)
|
f.Modern:SetTextColor(1,1,1)
|
||||||
f.Modern:SetText("Modern")
|
f.Modern:SetText("Modern")
|
||||||
@@ -151,8 +150,7 @@ pfUI:RegisterModule("firstrun", function ()
|
|||||||
SkinButton(f.Modern)
|
SkinButton(f.Modern)
|
||||||
|
|
||||||
f.Nostalgia = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
f.Nostalgia = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||||
f.Nostalgia:SetWidth(120)
|
f.Nostalgia:SetSize(120, 20)
|
||||||
f.Nostalgia:SetHeight(20)
|
|
||||||
f.Nostalgia:SetPoint("BOTTOM", 65, 100)
|
f.Nostalgia:SetPoint("BOTTOM", 65, 100)
|
||||||
f.Nostalgia:SetTextColor(1,1,1)
|
f.Nostalgia:SetTextColor(1,1,1)
|
||||||
f.Nostalgia:SetText("Nostalgia")
|
f.Nostalgia:SetText("Nostalgia")
|
||||||
@@ -165,8 +163,7 @@ pfUI:RegisterModule("firstrun", function ()
|
|||||||
SkinButton(f.Nostalgia)
|
SkinButton(f.Nostalgia)
|
||||||
|
|
||||||
f.Legacy = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
f.Legacy = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||||
f.Legacy:SetWidth(120)
|
f.Legacy:SetSize(120, 20)
|
||||||
f.Legacy:SetHeight(20)
|
|
||||||
f.Legacy:SetPoint("BOTTOM", 65, 75)
|
f.Legacy:SetPoint("BOTTOM", 65, 75)
|
||||||
f.Legacy:SetTextColor(1,1,1)
|
f.Legacy:SetTextColor(1,1,1)
|
||||||
f.Legacy:SetText("Legacy")
|
f.Legacy:SetText("Legacy")
|
||||||
@@ -179,8 +176,7 @@ pfUI:RegisterModule("firstrun", function ()
|
|||||||
SkinButton(f.Legacy)
|
SkinButton(f.Legacy)
|
||||||
|
|
||||||
f.Slim = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
f.Slim = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||||
f.Slim:SetWidth(120)
|
f.Slim:SetSize(120, 20)
|
||||||
f.Slim:SetHeight(20)
|
|
||||||
f.Slim:SetPoint("BOTTOM", -65, 75)
|
f.Slim:SetPoint("BOTTOM", -65, 75)
|
||||||
f.Slim:SetTextColor(1,1,1)
|
f.Slim:SetTextColor(1,1,1)
|
||||||
f.Slim:SetText("Slim")
|
f.Slim:SetText("Slim")
|
||||||
@@ -197,8 +193,7 @@ pfUI:RegisterModule("firstrun", function ()
|
|||||||
f.Slider.text:SetPoint("TOP", f.Slider, "BOTTOM", 0, 2)
|
f.Slider.text:SetPoint("TOP", f.Slider, "BOTTOM", 0, 2)
|
||||||
f.Slider.text:SetText(T["Scale"])
|
f.Slider.text:SetText(T["Scale"])
|
||||||
|
|
||||||
f.Slider:SetWidth(240)
|
f.Slider:SetSize(240, 20)
|
||||||
f.Slider:SetHeight(20)
|
|
||||||
f.Slider:SetPoint("BOTTOM", 0, 50)
|
f.Slider:SetPoint("BOTTOM", 0, 50)
|
||||||
f.Slider:SetOrientation('HORIZONTAL')
|
f.Slider:SetOrientation('HORIZONTAL')
|
||||||
f.Slider:SetMinMaxValues(0.5, 2.0)
|
f.Slider:SetMinMaxValues(0.5, 2.0)
|
||||||
|
|||||||
+1
-1
@@ -181,7 +181,7 @@ pfUI:RegisterModule("map", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if mx and my and MouseIsOver(WorldMapButton) then
|
if mx and my and MouseIsOver(WorldMapButton) then
|
||||||
WorldMapButton.coords.text:SetText(string.format('%.1f / %.1f', mx, my))
|
WorldMapButton.coords.text:SetFormattedText('%.1f / %.1f', mx, my)
|
||||||
else
|
else
|
||||||
WorldMapButton.coords.text:SetText("")
|
WorldMapButton.coords.text:SetText("")
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-1
@@ -138,7 +138,7 @@ pfUI:RegisterModule("minimap", function ()
|
|||||||
local coord = pfUI.minimapCoordinates
|
local coord = pfUI.minimapCoordinates
|
||||||
coord.posX, coord.posY = GetPlayerMapPosition("player")
|
coord.posX, coord.posY = GetPlayerMapPosition("player")
|
||||||
if coord.posX ~= 0 and coord.posY ~= 0 then
|
if coord.posX ~= 0 and coord.posY ~= 0 then
|
||||||
coord.text:SetText(string.format("%.1f, %.1f", round(coord.posX * 100, 1), round(coord.posY * 100, 1)))
|
coord.text:SetFormattedText("%.1f, %.1f", round(coord.posX * 100, 1), round(coord.posY * 100, 1))
|
||||||
else
|
else
|
||||||
coord.text:SetText("|cffffaaaaN/A")
|
coord.text:SetText("|cffffaaaaN/A")
|
||||||
end
|
end
|
||||||
|
|||||||
+48
-50
@@ -296,18 +296,23 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
return plate.creatureType
|
return plate.creatureType
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Totem icon, read straight from the game:
|
-- Totem icon: UnitCreatedBySpell returns the totem-drop spell, whose icon IS
|
||||||
-- * Passive totems self-cast their provided buff, so they carry exactly one
|
-- the totem's icon. It's a broadcast descriptor field the client has for every
|
||||||
-- aura whose icon IS the totem's icon (Totem::Summon TOTEM_PASSIVE).
|
-- summoned unit in range, so it resolves immediately for passive and active
|
||||||
-- * Active totems (Searing/Magma/Fire Nova) cast at enemies and hold no
|
-- totems alike -- no self-aura read or attack-cast capture needed.
|
||||||
-- self-aura, so their icon arrives via UNIT_SPELLCAST_SUCCEEDED (cached
|
--
|
||||||
-- into plate.totemIcon by the event handler); nil here until then.
|
-- Re-read the spell every call rather than caching the icon outright: a shaman
|
||||||
|
-- can swap the totem in place (same unit, new drop spell) with no plate re-add
|
||||||
|
-- to invalidate a cache, so key the cached texture on the spell id and refresh
|
||||||
|
-- it only when the spell changes.
|
||||||
local function TotemPlate(plate)
|
local function TotemPlate(plate)
|
||||||
if C.nameplates.totemicons ~= "1" then return nil end
|
if C.nameplates.totemicons ~= "1" then return nil end
|
||||||
if CreatureType(plate) ~= 11 then return nil end
|
if CreatureType(plate) ~= 11 then return nil end
|
||||||
if plate.totemIcon then return plate.totemIcon end
|
local spellId = UnitCreatedBySpell(plate.cachedGuid)
|
||||||
local aura = C_UnitAuras.GetBuffDataByIndex(plate.cachedGuid, 1)
|
if spellId ~= plate.totemSpell then
|
||||||
if aura then plate.totemIcon = aura.icon end
|
plate.totemSpell = spellId
|
||||||
|
plate.totemIcon = spellId and C_Spell.GetSpellTexture(spellId) or nil
|
||||||
|
end
|
||||||
return plate.totemIcon
|
return plate.totemIcon
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -499,7 +504,6 @@ nameplates:RegisterEvent("UNIT_SPELLCAST_START")
|
|||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_STOP")
|
nameplates:RegisterEvent("UNIT_SPELLCAST_STOP")
|
||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
|
|
||||||
nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||||
|
|
||||||
nameplates:SetScript("OnEvent", function()
|
nameplates:SetScript("OnEvent", function()
|
||||||
@@ -588,6 +592,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
plate.nameplate.unit = arg1
|
plate.nameplate.unit = arg1
|
||||||
plate.nameplate.creatureType = nil -- recompute for the new unit
|
plate.nameplate.creatureType = nil -- recompute for the new unit
|
||||||
plate.nameplate.totemIcon = nil
|
plate.nameplate.totemIcon = nil
|
||||||
|
plate.nameplate.totemSpell = nil
|
||||||
if guid then
|
if guid then
|
||||||
plateByGuid[guid] = plate.nameplate
|
plateByGuid[guid] = plate.nameplate
|
||||||
-- Seed: the unit may already be mid-cast (its UNIT_SPELLCAST_START
|
-- Seed: the unit may already be mid-cast (its UNIT_SPELLCAST_START
|
||||||
@@ -665,22 +670,6 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
|
|
||||||
-- Active totems (Searing/Magma/Fire Nova) carry no self-aura, so their
|
|
||||||
-- attack cast is the only icon source. Capture it once per totem, gated on
|
|
||||||
-- creature type so a normal caster's spell never styles it as a totem.
|
|
||||||
if arg1 and strfind(arg1, "^nameplate") then
|
|
||||||
local guid = UnitGUID(arg1)
|
|
||||||
local plate = guid and plateByGuid[guid]
|
|
||||||
if plate and not plate.totemIcon and arg3 and CreatureType(plate) == 11 then
|
|
||||||
local tex = C_Spell.GetSpellTexture(arg3)
|
|
||||||
if tex then
|
|
||||||
plate.totemIcon = tex
|
|
||||||
plate.castUpdate = true -- re-render now so the icon shows
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif event == "UNIT_AURA" then
|
elseif event == "UNIT_AURA" then
|
||||||
-- ClassicAPI: fires with arg1 == "nameplateN" when a unit's aura set
|
-- ClassicAPI: fires with arg1 == "nameplateN" when a unit's aura set
|
||||||
-- changes (add/remove/modify). Flag the matching plate so OnUpdate does a
|
-- changes (add/remove/modify). Flag the matching plate so OnUpdate does a
|
||||||
@@ -1045,7 +1034,13 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
if plate.cache.player == nil and unitstr then
|
if plate.cache.player == nil and unitstr then
|
||||||
plate.cache.player = UnitIsPlayer(unitstr) and true or false
|
plate.cache.player = UnitIsPlayer(unitstr) and true or false
|
||||||
end
|
end
|
||||||
local class, ulevel, elite, player, guild = GetUnitInfo(name, true, plate.cache.player)
|
if plate.cache.minion == nil and unitstr then
|
||||||
|
plate.cache.minion = UnitIsMinion(unitstr) and true or false
|
||||||
|
end
|
||||||
|
local class, ulevel, elite, player, guild
|
||||||
|
if not plate.cache.minion then
|
||||||
|
class, ulevel, elite, player, guild = GetUnitInfo(name, true, plate.cache.player)
|
||||||
|
end
|
||||||
if plate.cache.player ~= nil then player = plate.cache.player or nil end
|
if plate.cache.player ~= nil then player = plate.cache.player or nil end
|
||||||
|
|
||||||
-- Use database level ONLY if current level is ?? (fixes ?? after reload, but doesn't override visible levels)
|
-- Use database level ONLY if current level is ?? (fixes ?? after reload, but doesn't override visible levels)
|
||||||
@@ -1065,7 +1060,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
if player and unittype == "ENEMY_NPC" then unittype = "ENEMY_PLAYER" end
|
if player and unittype == "ENEMY_NPC" then unittype = "ENEMY_PLAYER" end
|
||||||
if player and unittype == "FRIENDLY_NPC" then unittype = "FRIENDLY_PLAYER" end
|
if player and unittype == "FRIENDLY_NPC" then unittype = "FRIENDLY_PLAYER" end
|
||||||
elite = plate.original.levelicon:IsShown() and not player and "boss" or elite
|
elite = plate.original.levelicon:IsShown() and not player and "boss" or elite
|
||||||
if not class then plate.wait_for_scan = true end
|
if not class and not plate.cache.minion then plate.wait_for_scan = true end
|
||||||
|
|
||||||
-- skip data updates on invisible frames
|
-- skip data updates on invisible frames
|
||||||
if not visible then return end
|
if not visible then return end
|
||||||
@@ -1110,7 +1105,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
local TotemIcon = TotemPlate(plate)
|
local TotemIcon = TotemPlate(plate)
|
||||||
|
|
||||||
if TotemIcon then
|
if TotemIcon then
|
||||||
-- icon resolved from the totem's aura / attack cast (already a full path)
|
-- icon resolved from the totem-drop spell (already a full path)
|
||||||
plate.totem.icon:SetTexture(TotemIcon)
|
plate.totem.icon:SetTexture(TotemIcon)
|
||||||
|
|
||||||
plate.glow:Hide()
|
plate.glow:Hide()
|
||||||
@@ -1151,7 +1146,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
if plate.cache.level ~= level or plate.cache.elite ~= elite then
|
if plate.cache.level ~= level or plate.cache.elite ~= elite then
|
||||||
plate.cache.level = level
|
plate.cache.level = level
|
||||||
plate.cache.elite = elite
|
plate.cache.elite = elite
|
||||||
plate.level:SetText(string.format("%s%s", level, (elitestrings[elite] or "")))
|
plate.level:SetFormattedText("%s%s", level, (elitestrings[elite] or ""))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set level color from GetDifficultyColor when using DB level.
|
-- Set level color from GetDifficultyColor when using DB level.
|
||||||
@@ -1212,21 +1207,21 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
local hasdata = ( rhp and rhpmax ) or estimated or hpmax > 100 or (round(hpmax/100*hp) ~= hp)
|
local hasdata = ( rhp and rhpmax ) or estimated or hpmax > 100 or (round(hpmax/100*hp) ~= hp)
|
||||||
|
|
||||||
if setting == "curperc" and hasdata and rhp then
|
if setting == "curperc" and hasdata and rhp then
|
||||||
plate.health.text:SetText(string.format("%s | %s%%", Abbreviate(rhp), ceil(hp/hpmax*100)))
|
plate.health.text:SetFormattedText("%s | %s%%", Abbreviate(rhp), ceil(hp/hpmax*100))
|
||||||
elseif setting == "cur" and hasdata and rhp then
|
elseif setting == "cur" and hasdata and rhp then
|
||||||
plate.health.text:SetText(string.format("%s", Abbreviate(rhp)))
|
plate.health.text:SetFormattedText("%s", Abbreviate(rhp))
|
||||||
elseif setting == "curmax" and hasdata and rhp then
|
elseif setting == "curmax" and hasdata and rhp then
|
||||||
plate.health.text:SetText(string.format("%s - %s", Abbreviate(rhp), Abbreviate(rhpmax)))
|
plate.health.text:SetFormattedText("%s - %s", Abbreviate(rhp), Abbreviate(rhpmax))
|
||||||
elseif setting == "curmaxs" and hasdata and rhp then
|
elseif setting == "curmaxs" and hasdata and rhp then
|
||||||
plate.health.text:SetText(string.format("%s / %s", Abbreviate(rhp), Abbreviate(rhpmax)))
|
plate.health.text:SetFormattedText("%s / %s", Abbreviate(rhp), Abbreviate(rhpmax))
|
||||||
elseif setting == "curmaxperc" and hasdata and rhp then
|
elseif setting == "curmaxperc" and hasdata and rhp then
|
||||||
plate.health.text:SetText(string.format("%s - %s | %s%%", Abbreviate(rhp), Abbreviate(rhpmax), ceil(hp/hpmax*100)))
|
plate.health.text:SetFormattedText("%s - %s | %s%%", Abbreviate(rhp), Abbreviate(rhpmax), ceil(hp/hpmax*100))
|
||||||
elseif setting == "curmaxpercs" and hasdata and rhp then
|
elseif setting == "curmaxpercs" and hasdata and rhp then
|
||||||
plate.health.text:SetText(string.format("%s / %s | %s%%", Abbreviate(rhp), Abbreviate(rhpmax), ceil(hp/hpmax*100)))
|
plate.health.text:SetFormattedText("%s / %s | %s%%", Abbreviate(rhp), Abbreviate(rhpmax), ceil(hp/hpmax*100))
|
||||||
elseif setting == "deficit" and rhp then
|
elseif setting == "deficit" and rhp then
|
||||||
plate.health.text:SetText(string.format("-%s" .. (hasdata and "" or "%%"), Abbreviate(rhpmax - rhp)))
|
plate.health.text:SetFormattedText("-%s" .. (hasdata and "" or "%%"), Abbreviate(rhpmax - rhp))
|
||||||
else -- "percent" as fallback
|
else -- "percent" as fallback
|
||||||
plate.health.text:SetText(string.format("%s%%", ceil(hp/hpmax*100)))
|
plate.health.text:SetFormattedText("%s%%", ceil(hp/hpmax*100))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
plate.health.text:SetText()
|
plate.health.text:SetText()
|
||||||
@@ -1313,19 +1308,22 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
for i = 1, 16 do debuffDisplayBuf[i].effect = nil end
|
for i = 1, 16 do debuffDisplayBuf[i].effect = nil end
|
||||||
if unitstr then
|
if unitstr then
|
||||||
local filter = cfg.owndebuffs and "HARMFUL|PLAYER" or "HARMFUL"
|
local filter = cfg.owndebuffs and "HARMFUL|PLAYER" or "HARMFUL"
|
||||||
local auras = C_UnitAuras.GetUnitAuras(unitstr, filter)
|
|
||||||
local now = GetTime()
|
local now = GetTime()
|
||||||
for _, aura in ipairs(auras) do
|
-- positional UnitAura writes straight into the reusable buffer, so the
|
||||||
if debuffCount >= 16 then break end
|
-- per-plate scan allocates nothing (no per-aura table, no result array)
|
||||||
|
local i = 1
|
||||||
|
while debuffCount < 16 do
|
||||||
|
local aname, icon, count, dispelType, duration, expirationTime = C_UnitAuras.UnitAura(unitstr, i, filter)
|
||||||
|
if not aname then break end
|
||||||
debuffCount = debuffCount + 1
|
debuffCount = debuffCount + 1
|
||||||
local timeleft = (aura.expirationTime and aura.expirationTime > 0) and (aura.expirationTime - now) or nil
|
|
||||||
local b = debuffDisplayBuf[debuffCount]
|
local b = debuffDisplayBuf[debuffCount]
|
||||||
b.effect = aura.name
|
b.effect = aname
|
||||||
b.texture = aura.icon
|
b.texture = icon
|
||||||
b.stacks = aura.applications
|
b.stacks = count
|
||||||
b.dtype = aura.dispelName
|
b.dtype = dispelType
|
||||||
b.duration = aura.duration
|
b.duration = duration
|
||||||
b.timeleft = timeleft
|
b.timeleft = (expirationTime and expirationTime > 0) and (expirationTime - now) or nil
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for i = 1, 16 do
|
for i = 1, 16 do
|
||||||
@@ -1548,7 +1546,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
-- otherwise an NPC sharing a name with a known player flips wait_for_scan
|
-- otherwise an NPC sharing a name with a known player flips wait_for_scan
|
||||||
-- off here, then OnDataChanged re-sets it, every frame until the mob scan
|
-- off here, then OnDataChanged re-sets it, every frame until the mob scan
|
||||||
-- lands.
|
-- lands.
|
||||||
if nameplate.wait_for_scan and GetUnitInfo(name, true, nameplate.cache.player) then
|
if nameplate.wait_for_scan and not nameplate.cache.minion and GetUnitInfo(name, true, nameplate.cache.player) then
|
||||||
nameplate.wait_for_scan = nil
|
nameplate.wait_for_scan = nil
|
||||||
update = true
|
update = true
|
||||||
end
|
end
|
||||||
@@ -1697,7 +1695,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
rounded = floor(remaining * 100)
|
rounded = floor(remaining * 100)
|
||||||
if castbar.lastTextTick ~= rounded then
|
if castbar.lastTextTick ~= rounded then
|
||||||
castbar.lastTextTick = rounded
|
castbar.lastTextTick = rounded
|
||||||
castbar.text:SetText(string.format("%.2f", remaining))
|
castbar.text:SetFormattedText("%.2f", remaining)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+7
-3
@@ -418,8 +418,13 @@ pfUI:RegisterModule("panel", function()
|
|||||||
local repPercent = floor(cur / max * 100)
|
local repPercent = floor(cur / max * 100)
|
||||||
if repPercent < 100 then
|
if repPercent < 100 then
|
||||||
local _, _, _, hex = GetColorGradient(repPercent/100)
|
local _, _, _, hex = GetColorGradient(repPercent/100)
|
||||||
|
local link = GetInventoryItemLink("player", id)
|
||||||
|
local texture = GetInventoryItemTexture("player", id)
|
||||||
|
if texture then
|
||||||
|
link = CreateSimpleTextureMarkup(texture, 24) .. " " .. link
|
||||||
|
end
|
||||||
itemLines[table.getn(itemLines)+1] = {
|
itemLines[table.getn(itemLines)+1] = {
|
||||||
GetInventoryItemLink("player", id),
|
link,
|
||||||
string.format("%s%s%%|r", hex, repPercent)
|
string.format("%s%s%%|r", hex, repPercent)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@@ -428,8 +433,7 @@ pfUI:RegisterModule("panel", function()
|
|||||||
if totalRep > 0 then
|
if totalRep > 0 then
|
||||||
GameTooltip:ClearLines()
|
GameTooltip:ClearLines()
|
||||||
GameTooltip_SetDefaultAnchor(GameTooltip, this)
|
GameTooltip_SetDefaultAnchor(GameTooltip, this)
|
||||||
GameTooltip:SetText("|cff555555"..(string.gsub(REPAIR_COST,":","")).."|r")
|
GameTooltip:AddLine(REPAIR_COST.." " .. CreateGoldString(totalRep), 0.3333, 0.3333, 0.3333)
|
||||||
SetTooltipMoney(GameTooltip, totalRep)
|
|
||||||
for _,line in ipairs(itemLines) do
|
for _,line in ipairs(itemLines) do
|
||||||
GameTooltip:AddDoubleLine(line[1],line[2])
|
GameTooltip:AddDoubleLine(line[1],line[2])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ pfUI:RegisterModule("screenshot", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function pfUI.screenshot:CHAT_MSG_SYSTEM()
|
function pfUI.screenshot:CHAT_MSG_SYSTEM()
|
||||||
local _,_, standing, rep = string.find(arg1, FACTION_STANDING_CHANGEDregex)
|
local standing, rep = string.match(arg1, FACTION_STANDING_CHANGEDregex)
|
||||||
if standing and rep then
|
if standing and rep then
|
||||||
local dt = date("%a, %b %d, %Y %X")
|
local dt = date("%a, %b %d, %Y %X")
|
||||||
local loc = string.format("%s - %s",GetRealZoneText(),GetSubZoneText())
|
local loc = string.format("%s - %s",GetRealZoneText(),GetSubZoneText())
|
||||||
@@ -150,13 +150,13 @@ pfUI:RegisterModule("screenshot", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function pfUI.screenshot:CHAT_MSG_LOOT()
|
function pfUI.screenshot:CHAT_MSG_LOOT()
|
||||||
local _,_, item, amount = string.find(arg1, LOOT_ITEM_SELF_MULTIPLEregex)
|
local item, amount = string.match(arg1, LOOT_ITEM_SELF_MULTIPLEregex)
|
||||||
if amount then -- ignore stacks
|
if amount then -- ignore stacks
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
_,_, item = string.find(arg1, LOOT_ITEM_SELFregex)
|
item = string.match(arg1, LOOT_ITEM_SELFregex)
|
||||||
if item then
|
if item then
|
||||||
local _, _, itemColor, itemString, itemName = string.find(item, "^(|c%x+)|H(.+)|h(%[.+%])")
|
local itemColor, itemString, itemName = string.match(item, "^(|c%x+)|H(.+)|h(%[.+%])")
|
||||||
local quality = color2quality[itemColor]
|
local quality = color2quality[itemColor]
|
||||||
if quality and quality >= tonumber(C.screenshot.loot) then
|
if quality and quality >= tonumber(C.screenshot.loot) then
|
||||||
local dt = date("%a, %b %d, %Y %X")
|
local dt = date("%a, %b %d, %Y %X")
|
||||||
|
|||||||
@@ -97,20 +97,20 @@ pfUI:RegisterModule("socialmod", function ()
|
|||||||
|
|
||||||
if friendName then
|
if friendName then
|
||||||
friendName:SetText(cname)
|
friendName:SetText(cname)
|
||||||
friendLoc:SetText(format(TEXT(FRIENDS_LIST_TEMPLATE), zone, status))
|
friendLoc:SetFormattedText(TEXT(FRIENDS_LIST_TEMPLATE), zone, status)
|
||||||
else
|
else
|
||||||
friendLoc:SetText(format(TEXT(FRIENDS_LIST_TEMPLATE), cname, zone, status))
|
friendLoc:SetFormattedText(TEXT(FRIENDS_LIST_TEMPLATE), cname, zone, status)
|
||||||
end
|
end
|
||||||
|
|
||||||
friendInfo:SetText(format(TEXT(FRIENDS_LEVEL_TEMPLATE), info.level, info.className))
|
friendInfo:SetFormattedText(TEXT(FRIENDS_LEVEL_TEMPLATE), info.level, info.className)
|
||||||
caption:SetVertexColor(1,1,1,.9)
|
caption:SetVertexColor(1,1,1,.9)
|
||||||
friendInfo:SetVertexColor(1,1,1,.9)
|
friendInfo:SetVertexColor(1,1,1,.9)
|
||||||
else
|
else
|
||||||
if playerdb[name] and playerdb[name].cname and playerdb[name].level and playerdb[name].lastseen then
|
if playerdb[name] and playerdb[name].cname and playerdb[name].level and playerdb[name].lastseen then
|
||||||
caption:SetText(format(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), playerdb[name].cname))
|
caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), playerdb[name].cname)
|
||||||
friendInfo:SetText(format(TEXT(FRIENDS_LEVEL_TEMPLATE), playerdb[name].level, playerdb[name].lastseen))
|
friendInfo:SetFormattedText(TEXT(FRIENDS_LEVEL_TEMPLATE), playerdb[name].level, playerdb[name].lastseen)
|
||||||
else
|
else
|
||||||
caption:SetText(format(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), name.."|r"))
|
caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), name.."|r")
|
||||||
friendInfo:SetText(TEXT(UNKNOWN))
|
friendInfo:SetText(TEXT(UNKNOWN))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -131,9 +131,9 @@ pfUI:RegisterModule("socialmod", function ()
|
|||||||
local playerguild = GetGuildInfo("player")
|
local playerguild = GetGuildInfo("player")
|
||||||
|
|
||||||
if num + 1 >= MAX_WHOS_FROM_SERVER then
|
if num + 1 >= MAX_WHOS_FROM_SERVER then
|
||||||
WhoFrameTotals:SetText("|cffffffff" .. format(GetText("WHO_FRAME_TOTAL_TEMPLATE", nil, num), max).." |cffaaaaaa"..format(WHO_FRAME_SHOWN_TEMPLATE, MAX_WHOS_FROM_SERVER))
|
WhoFrameTotals:SetFormattedText("|cffffffff" .. GetText("WHO_FRAME_TOTAL_TEMPLATE", nil, num) .. " |cffaaaaaa" .. WHO_FRAME_SHOWN_TEMPLATE, max, MAX_WHOS_FROM_SERVER)
|
||||||
else
|
else
|
||||||
WhoFrameTotals:SetText("|cffffffff" .. format(GetText("WHO_FRAME_TOTAL_TEMPLATE", nil, num), num).." |cffaaaaaa"..format(WHO_FRAME_SHOWN_TEMPLATE, num))
|
WhoFrameTotals:SetFormattedText("|cffffffff" .. GetText("WHO_FRAME_TOTAL_TEMPLATE", nil, num) .. " |cffaaaaaa" .. WHO_FRAME_SHOWN_TEMPLATE, num, num)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i=1, WHOS_TO_DISPLAY do
|
for i=1, WHOS_TO_DISPLAY do
|
||||||
|
|||||||
@@ -592,10 +592,10 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
end
|
end
|
||||||
pfUI.swingtimer.mainhand:SetStatusBarColor(curR, curG, curB, mhA)
|
pfUI.swingtimer.mainhand:SetStatusBarColor(curR, curG, curB, mhA)
|
||||||
if sw_showtext then
|
if sw_showtext then
|
||||||
pfUI.swingtimer.mainhand.text:SetText(string.format("%.1f", math.floor(S.mhTimer * 10) / 10))
|
pfUI.swingtimer.mainhand.text:SetFormattedText("%.1f", math.floor(S.mhTimer * 10) / 10)
|
||||||
end
|
end
|
||||||
if sw_showspeed and S.mhSpeed > 0 then
|
if sw_showspeed and S.mhSpeed > 0 then
|
||||||
pfUI.swingtimer.mainhand.speed:SetText(string.format("%.2f", S.mhSpeed))
|
pfUI.swingtimer.mainhand.speed:SetFormattedText("%.2f", S.mhSpeed)
|
||||||
end
|
end
|
||||||
anyActive = true
|
anyActive = true
|
||||||
end
|
end
|
||||||
@@ -626,10 +626,10 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if sw_showtext then
|
if sw_showtext then
|
||||||
pfUI.swingtimer.offhand.text:SetText(string.format("%.1f", math.floor(S.ohTimer * 10) / 10))
|
pfUI.swingtimer.offhand.text:SetFormattedText("%.1f", math.floor(S.ohTimer * 10) / 10)
|
||||||
end
|
end
|
||||||
if sw_showspeed and S.ohSpeed > 0 then
|
if sw_showspeed and S.ohSpeed > 0 then
|
||||||
pfUI.swingtimer.offhand.speed:SetText(string.format("%.2f", S.ohSpeed))
|
pfUI.swingtimer.offhand.speed:SetFormattedText("%.2f", S.ohSpeed)
|
||||||
end
|
end
|
||||||
anyActive = true
|
anyActive = true
|
||||||
elseif not sw_showoh then
|
elseif not sw_showoh then
|
||||||
@@ -668,9 +668,9 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
end
|
end
|
||||||
if sw_showtext then
|
if sw_showtext then
|
||||||
if remaining <= 0.5 then
|
if remaining <= 0.5 then
|
||||||
pfUI.swingtimer.ranged.text:SetText(string.format("%.1f", math.floor(remaining * 10) / 10))
|
pfUI.swingtimer.ranged.text:SetFormattedText("%.1f", math.floor(remaining * 10) / 10)
|
||||||
else
|
else
|
||||||
pfUI.swingtimer.ranged.text:SetText(string.format("%.1f", math.floor((remaining - 0.5) * 10) / 10))
|
pfUI.swingtimer.ranged.text:SetFormattedText("%.1f", math.floor((remaining - 0.5) * 10) / 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -683,11 +683,11 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
pfUI.swingtimer.ranged.right:Hide()
|
pfUI.swingtimer.ranged.right:Hide()
|
||||||
pfUI.swingtimer.ranged.warn:Hide()
|
pfUI.swingtimer.ranged.warn:Hide()
|
||||||
if sw_showtext then
|
if sw_showtext then
|
||||||
pfUI.swingtimer.ranged.text:SetText(string.format("%.1f", math.floor(remaining * 10) / 10))
|
pfUI.swingtimer.ranged.text:SetFormattedText("%.1f", math.floor(remaining * 10) / 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if sw_showspeed and S.raSpeed > 0 then
|
if sw_showspeed and S.raSpeed > 0 then
|
||||||
pfUI.swingtimer.ranged.speed:SetText(string.format("%.2f", S.raSpeed))
|
pfUI.swingtimer.ranged.speed:SetFormattedText("%.2f", S.raSpeed)
|
||||||
end
|
end
|
||||||
local raProgress = 1 - (S.raTimer / S.raTimerMax)
|
local raProgress = 1 - (S.raTimer / S.raTimerMax)
|
||||||
local raMarkerX = raProgress * sw_width
|
local raMarkerX = raProgress * sw_width
|
||||||
|
|||||||
+2
-2
@@ -166,9 +166,9 @@ pfUI:RegisterModule("tooltip", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if C.tooltip.alwaysperc == "0" and ( estimated or hpmax > 100 or round(hpmax/100*hp) ~= hp ) then
|
if C.tooltip.alwaysperc == "0" and ( estimated or hpmax > 100 or round(hpmax/100*hp) ~= hp ) then
|
||||||
pfUI.tooltipStatusBar.HP:SetText(string.format("%s / %s", Abbreviate(rhp), Abbreviate(rhpmax)))
|
pfUI.tooltipStatusBar.HP:SetFormattedText("%s / %s", Abbreviate(rhp), Abbreviate(rhpmax))
|
||||||
elseif hpmax > 0 then
|
elseif hpmax > 0 then
|
||||||
pfUI.tooltipStatusBar.HP:SetText(string.format("%s%%", ceil(hp/hpmax*100)))
|
pfUI.tooltipStatusBar.HP:SetFormattedText("%s%%", ceil(hp/hpmax*100))
|
||||||
else
|
else
|
||||||
pfUI.tooltipStatusBar.HP:SetText("")
|
pfUI.tooltipStatusBar.HP:SetText("")
|
||||||
end
|
end
|
||||||
|
|||||||
+23
-90
@@ -3,56 +3,15 @@ pfUI:RegisterModule("tracking", function ()
|
|||||||
MINIMAP_TRACKING_FRAME:UnregisterAllEvents()
|
MINIMAP_TRACKING_FRAME:UnregisterAllEvents()
|
||||||
MINIMAP_TRACKING_FRAME:Hide()
|
MINIMAP_TRACKING_FRAME:Hide()
|
||||||
|
|
||||||
local function HasEntries(tbl)
|
|
||||||
for _ in pairs(tbl) do
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local rawborder, border = GetBorderSize()
|
local rawborder, border = GetBorderSize()
|
||||||
local size = tonumber(C.appearance.minimap.tracking_size)
|
local size = tonumber(C.appearance.minimap.tracking_size)
|
||||||
local pulse = C.appearance.minimap.tracking_pulse == "1"
|
local pulse = C.appearance.minimap.tracking_pulse == "1"
|
||||||
|
|
||||||
-- Tracking spells identified by SpellID + expected icon path.
|
-- Tracking spells come from ClassicAPI's native GetNumTrackingTypes /
|
||||||
-- SpellID is the primary identifier (stable, locale-independent).
|
-- GetTrackingInfo (see the DLL's docs/API.md "Tracking"). The DLL
|
||||||
-- Icon path is used as secondary confirmation when scanning the spellbook.
|
-- enumerates them straight from the spellbook by tracking-aura effect,
|
||||||
local knownTrackingSpells = {
|
-- so there is no spell table to maintain here and server-custom trackers
|
||||||
any = {
|
-- (e.g. Turtle's Find Trees) are picked up automatically.
|
||||||
{ id = 2481, icon = "Racial_Dwarf_FindTreasure" }, -- Find Treasure
|
|
||||||
{ id = 2580, icon = "Spell_Nature_Earthquake" }, -- Find Minerals
|
|
||||||
{ id = 2383, icon = "INV_Misc_Flower_02" }, -- Find Herbs (Rank 1)
|
|
||||||
{ id = 8387, icon = "INV_Misc_Flower_02" }, -- Find Herbs (Rank 2)
|
|
||||||
{ id = 52917, icon = "INV_TradeSkillItem_03" }, -- Find Trees (TurtleWow)
|
|
||||||
},
|
|
||||||
HUNTER = {
|
|
||||||
{ id = 1494, icon = "Ability_Tracking" }, -- Track Beasts
|
|
||||||
{ id = 19883, icon = "Spell_Holy_PrayerOfHealing" }, -- Track Humanoids
|
|
||||||
{ id = 19884, icon = "Spell_Shadow_DarkSummoning" }, -- Track Undead
|
|
||||||
{ id = 19885, icon = "Ability_Stealth" }, -- Track Hidden
|
|
||||||
{ id = 19880, icon = "Spell_Frost_SummonWaterElemental" }, -- Track Elementals
|
|
||||||
{ id = 19878, icon = "Spell_Shadow_SummonFelHunter" }, -- Track Demons
|
|
||||||
{ id = 19882, icon = "Ability_Racial_Avatar" }, -- Track Giants
|
|
||||||
{ id = 19879, icon = "INV_Misc_Head_Dragon_01" }, -- Track Dragonkin
|
|
||||||
},
|
|
||||||
PALADIN = {
|
|
||||||
{ id = 5502, icon = "Spell_Holy_SenseUndead" }, -- Sense Undead
|
|
||||||
},
|
|
||||||
WARLOCK = {
|
|
||||||
{ id = 5500, icon = "Spell_Shadow_Metamorphosis" }, -- Sense Demons
|
|
||||||
},
|
|
||||||
DRUID = {
|
|
||||||
{ id = 5225, icon = "Ability_Tracking" }, -- Track Humanoids (Cat Form only)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Build a flat lookup: spellId -> entry, for fast spellbook matching
|
|
||||||
local spellIdLookup = {}
|
|
||||||
for _, entries in pairs(knownTrackingSpells) do
|
|
||||||
for _, entry in ipairs(entries) do
|
|
||||||
spellIdLookup[entry.id] = entry
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local state = {
|
local state = {
|
||||||
texture = nil,
|
texture = nil,
|
||||||
@@ -128,50 +87,24 @@ pfUI:RegisterModule("tracking", function ()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
function pfUI.tracking:RefreshSpells()
|
function pfUI.tracking:RefreshSpells()
|
||||||
local playerClass = UnitClassBase("player")
|
state.spells = {}
|
||||||
local isCatForm = pfUI.tracking:PlayerIsDruidInCatForm(playerClass)
|
if not GetNumTrackingTypes then return end
|
||||||
|
|
||||||
-- Build set of valid SpellIDs for this class
|
-- Druid Track Humanoids (5225) only casts in Cat Form. Hide it out of
|
||||||
local validIds = {}
|
-- form so the menu never offers a tracker that would fail to cast.
|
||||||
for _, entry in ipairs(knownTrackingSpells.any) do
|
local isCatForm = pfUI.tracking:PlayerIsDruidInCatForm(UnitClassBase("player"))
|
||||||
validIds[entry.id] = true
|
|
||||||
end
|
|
||||||
if knownTrackingSpells[playerClass] then
|
|
||||||
for _, entry in ipairs(knownTrackingSpells[playerClass]) do
|
|
||||||
validIds[entry.id] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Druids only get Track Humanoids in Cat Form
|
for i = 1, GetNumTrackingTypes() do
|
||||||
if playerClass == "DRUID" and not isCatForm then
|
local name, texture, _, _, spellId = GetTrackingInfo(i)
|
||||||
validIds[5225] = nil
|
local castable = not (spellId == 5225 and not isCatForm)
|
||||||
end
|
if name and texture and castable
|
||||||
|
and not pfUI.tracking.invalidSpells[name] then
|
||||||
-- Scan spellbook: match by icon path, confirm SpellID is valid for this class
|
state.spells[i] = {
|
||||||
for tabIndex = 1, GetNumSpellTabs() do
|
index = i, -- tracking index, passed to SetTracking()
|
||||||
local _, _, offset, numSpells = GetSpellTabInfo(tabIndex)
|
name = name,
|
||||||
for spellIndex = offset + 1, offset + numSpells do
|
texture = texture,
|
||||||
local spellTexture = GetSpellTexture(spellIndex, BOOKTYPE_SPELL)
|
spellId = spellId,
|
||||||
local spellName = GetSpellName(spellIndex, BOOKTYPE_SPELL)
|
}
|
||||||
|
|
||||||
if pfUI.tracking.invalidSpells[spellName] then
|
|
||||||
spellTexture = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if spellTexture then
|
|
||||||
local lowerTexture = string.lower(spellTexture)
|
|
||||||
for spellId, entry in pairs(spellIdLookup) do
|
|
||||||
if validIds[spellId] and not state.spells[spellId]
|
|
||||||
and strfind(lowerTexture, string.lower(entry.icon)) then
|
|
||||||
state.spells[spellId] = {
|
|
||||||
index = spellIndex,
|
|
||||||
name = spellName,
|
|
||||||
texture = spellTexture,
|
|
||||||
spellId = spellId,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -187,7 +120,7 @@ pfUI:RegisterModule("tracking", function ()
|
|||||||
elseif not texture then
|
elseif not texture then
|
||||||
state.texture = nil
|
state.texture = nil
|
||||||
|
|
||||||
if pulse and HasEntries(state.spells) then
|
if pulse and next(state.spells) ~= nil then
|
||||||
pfUI.tracking.pulse = true
|
pfUI.tracking.pulse = true
|
||||||
pfUI.tracking.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
|
pfUI.tracking.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
|
||||||
pfUI.tracking.icon:SetVertexColor(1,1,1,1)
|
pfUI.tracking.icon:SetVertexColor(1,1,1,1)
|
||||||
@@ -217,7 +150,7 @@ pfUI:RegisterModule("tracking", function ()
|
|||||||
checked = spell.texture == state.texture,
|
checked = spell.texture == state.texture,
|
||||||
arg1 = spell,
|
arg1 = spell,
|
||||||
func = function (arg1)
|
func = function (arg1)
|
||||||
CastSpell(arg1.index, BOOKTYPE_SPELL)
|
SetTracking(arg1.index)
|
||||||
CloseDropDownMenus()
|
CloseDropDownMenus()
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|||||||
+2
-2
@@ -134,7 +134,7 @@ pfUI:RegisterModule("unitxp", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
this.text:SetTextColor(r, g, b, 1)
|
this.text:SetTextColor(r, g, b, 1)
|
||||||
this.text:SetText(string.format("%.1f%s", distance, suffix))
|
this.text:SetFormattedText("%.1f%s", distance, suffix)
|
||||||
this.text:Show()
|
this.text:Show()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ pfUI:RegisterModule("unitxp", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
f.text:SetTextColor(r, g, b, 1)
|
f.text:SetTextColor(r, g, b, 1)
|
||||||
f.text:SetText(string.format("%.1f%s", distance, suffix))
|
f.text:SetFormattedText("%.1f%s", distance, suffix)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
pfUI.uf.target.distanceIndicator = pfRangeDisplay
|
pfUI.uf.target.distanceIndicator = pfRangeDisplay
|
||||||
|
|||||||
+3
-3
@@ -236,7 +236,7 @@ end
|
|||||||
local xpperc = round(xp / xpmax * 100)
|
local xpperc = round(xp / xpmax * 100)
|
||||||
local experc = ex and round(ex / xpmax * 100) or 0
|
local experc = ex and round(ex / xpmax * 100) or 0
|
||||||
if ex then text = "%s: %s%% (%s%% %s)" end
|
if ex then text = "%s: %s%% (%s%% %s)" end
|
||||||
self.bar.text:SetText(string.format(text, T["Experience"], xpperc, experc, T["Rested"]))
|
self.bar.text:SetFormattedText(text, T["Experience"], xpperc, experc, T["Rested"])
|
||||||
|
|
||||||
self.tick = GetTime() + self.timeout
|
self.tick = GetTime() + self.timeout
|
||||||
if event == "UPDATE_EXHAUSTION" and GameTooltip:IsOwned(self) then
|
if event == "UPDATE_EXHAUSTION" and GameTooltip:IsOwned(self) then
|
||||||
@@ -254,7 +254,7 @@ end
|
|||||||
|
|
||||||
local text = "%s: %s%%"
|
local text = "%s: %s%%"
|
||||||
local xpperc = nextXP and nextXP ~= 0 and round(currXP / nextXP * 100) or 0
|
local xpperc = nextXP and nextXP ~= 0 and round(currXP / nextXP * 100) or 0
|
||||||
self.bar.text:SetText(string.format(text, T["Pet Experience"], xpperc))
|
self.bar.text:SetFormattedText(text, T["Pet Experience"], xpperc)
|
||||||
|
|
||||||
self.tick = GetTime() + self.timeout
|
self.tick = GetTime() + self.timeout
|
||||||
return
|
return
|
||||||
@@ -282,7 +282,7 @@ end
|
|||||||
local text = "%s: %s%% (%s)"
|
local text = "%s: %s%% (%s)"
|
||||||
local perc = round(barValue / barMax * 100)
|
local perc = round(barValue / barMax * 100)
|
||||||
local standing = GetText("FACTION_STANDING_LABEL"..standingID, gender)
|
local standing = GetText("FACTION_STANDING_LABEL"..standingID, gender)
|
||||||
self.bar.text:SetText(string.format(text, name, perc, standing))
|
self.bar.text:SetFormattedText(text, name, perc, standing)
|
||||||
|
|
||||||
self.tick = GetTime() + self.timeout
|
self.tick = GetTime() + self.timeout
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ function SlashCmdList.RELOAD(msg, editbox)
|
|||||||
ReloadUI()
|
ReloadUI()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if pfUI_disabled then return end
|
||||||
|
|
||||||
|
local addonName = ...
|
||||||
|
|
||||||
SLASH_PFUI1 = '/pfui'
|
SLASH_PFUI1 = '/pfui'
|
||||||
function SlashCmdList.PFUI(msg, editbox)
|
function SlashCmdList.PFUI(msg, editbox)
|
||||||
pfUI.gui:SetShown(not pfUI.gui:IsShown())
|
pfUI.gui:SetShown(not pfUI.gui:IsShown())
|
||||||
@@ -13,7 +17,7 @@ function SlashCmdList.GM(msg, editbox)
|
|||||||
ToggleHelpFrame(1)
|
ToggleHelpFrame(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
pfUI = CreateFrame("Frame", nil, UIParent)
|
local pfUI = CreateFrame("Frame", addonName, UIParent)
|
||||||
pfUI:RegisterEvent("ADDON_LOADED")
|
pfUI:RegisterEvent("ADDON_LOADED")
|
||||||
|
|
||||||
-- setup bootvar
|
-- setup bootvar
|
||||||
@@ -23,7 +27,7 @@ do
|
|||||||
-- ClassicAPI dependency check.
|
-- ClassicAPI dependency check.
|
||||||
-- pfUI relies pervasively on the modern C_* / SuperWoW / nameplate / focus
|
-- pfUI relies pervasively on the modern C_* / SuperWoW / nameplate / focus
|
||||||
-- API surface that ClassicAPI polyfills, so presence is required.
|
-- API surface that ClassicAPI polyfills, so presence is required.
|
||||||
local PFUI_CLASSIC_API_MIN = 10906 -- (X*10000 + Y*100 + Z)
|
local PFUI_CLASSIC_API_MIN = 11301 -- (X*10000 + Y*100 + Z)
|
||||||
local PFUI_CLASSIC_API_LATEST = PFUI_CLASSIC_API_MIN
|
local PFUI_CLASSIC_API_LATEST = PFUI_CLASSIC_API_MIN
|
||||||
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
|
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
|
||||||
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
|
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
|
||||||
@@ -86,14 +90,13 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initialize saved variables
|
pfUI_playerDB = pfUI_playerDB or {}
|
||||||
pfUI_playerDB = {}
|
pfUI_config = pfUI_config or {}
|
||||||
pfUI_config = {}
|
pfUI_init = pfUI_init or {}
|
||||||
pfUI_init = {}
|
pfUI_profiles = pfUI_profiles or {}
|
||||||
pfUI_profiles = {}
|
pfUI_addon_profiles = pfUI_addon_profiles or {}
|
||||||
pfUI_addon_profiles = {}
|
pfUI_cache = pfUI_cache or {}
|
||||||
pfUI_cache = {}
|
pfUI_throttle = pfUI_throttle or {}
|
||||||
pfUI_throttle = {}
|
|
||||||
|
|
||||||
-- localization
|
-- localization
|
||||||
pfUI_locale = {}
|
pfUI_locale = {}
|
||||||
@@ -118,35 +121,24 @@ pfUI.env = {}
|
|||||||
-- the flag; one that lacks it should drop the flag and get the safe fallback.
|
-- the flag; one that lacks it should drop the flag and get the safe fallback.
|
||||||
pfUI.handlesHookScript = true
|
pfUI.handlesHookScript = true
|
||||||
|
|
||||||
if not pfUI.disabled then
|
pfUI.events = Mixin({}, CallbackRegistryMixin)
|
||||||
pfUI.events = Mixin({}, CallbackRegistryMixin)
|
pfUI.events:OnLoad()
|
||||||
pfUI.events:OnLoad()
|
pfUI.events:SetUndefinedEventsAllowed(true)
|
||||||
pfUI.events:SetUndefinedEventsAllowed(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- check if macro addons are loaded (disables macrotweak/macroscan)
|
-- check if macro addons are loaded (disables macrotweak/macroscan)
|
||||||
function pfUI:MacroAddonsLoaded()
|
function pfUI:MacroAddonsLoaded()
|
||||||
return IsAddOnLoaded("Supermacro") or IsAddOnLoaded("SuperCleveRoidMacros") or IsAddOnLoaded("UltimaMacros")
|
return IsAddOnLoaded("Supermacro") or IsAddOnLoaded("SuperCleveRoidMacros") or IsAddOnLoaded("UltimaMacros")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- detect current addon path
|
pfUI.name = addonName
|
||||||
local tocs = { "", "-master", "-tbc", "-wotlk" }
|
pfUI.path = "Interface\\AddOns\\" .. addonName
|
||||||
for _, name in pairs(tocs) do
|
|
||||||
local current = string.format("pfUI%s", name)
|
|
||||||
local title = C_AddOns.GetAddOnName(current)
|
|
||||||
if title then
|
|
||||||
pfUI.name = current
|
|
||||||
pfUI.path = "Interface\\AddOns\\" .. current
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- handle/convert media dir paths
|
-- handle/convert media dir paths
|
||||||
pfUI.media = setmetatable({}, { __index = function(tab,key)
|
pfUI.media = setmetatable({}, { __index = function(tab,key)
|
||||||
local value = tostring(key)
|
local value = tostring(key)
|
||||||
if strfind(value, "img:") then
|
if value:find("img:") then
|
||||||
value = string.gsub(value, "img:", pfUI.path .. "\\img\\")
|
value = string.gsub(value, "img:", pfUI.path .. "\\img\\")
|
||||||
elseif strfind(value, "font:") then
|
elseif value:find("font:") then
|
||||||
value = string.gsub(value, "font:", pfUI.path .. "\\fonts\\")
|
value = string.gsub(value, "font:", pfUI.path .. "\\fonts\\")
|
||||||
else
|
else
|
||||||
value = string.gsub(value, "Interface\\AddOns\\pfUI\\", pfUI.path .. "\\")
|
value = string.gsub(value, "Interface\\AddOns\\pfUI\\", pfUI.path .. "\\")
|
||||||
@@ -155,9 +147,7 @@ pfUI.media = setmetatable({}, { __index = function(tab,key)
|
|||||||
return value
|
return value
|
||||||
end})
|
end})
|
||||||
|
|
||||||
-- cache client version
|
pfUI.client = INTERFACE_VERSION
|
||||||
local _, _, _, client = GetBuildInfo()
|
|
||||||
pfUI.client = client or 11200
|
|
||||||
|
|
||||||
-- setup pfUI namespace
|
-- setup pfUI namespace
|
||||||
setmetatable(pfUI.env, {__index = getfenv(0)})
|
setmetatable(pfUI.env, {__index = getfenv(0)})
|
||||||
@@ -391,14 +381,13 @@ function pfUI:CheckNewModules()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function BackwardsCompatRegister(func, arg3)
|
local function BackwardsCompatRegister(func, arg3)
|
||||||
if arg3 and type(func) == "string" and type(arg3) == "function" and string.find(func, "vanilla") then
|
if arg3 and type(func) == "string" and type(arg3) == "function" and func:find("vanilla") then
|
||||||
return arg3
|
return arg3
|
||||||
end
|
end
|
||||||
return func
|
return func
|
||||||
end
|
end
|
||||||
|
|
||||||
function pfUI:RegisterModule(name, func, arg3)
|
function pfUI:RegisterModule(name, func, arg3)
|
||||||
if pfUI.disabled then return end
|
|
||||||
if pfUI.module[name] then return end
|
if pfUI.module[name] then return end
|
||||||
func = BackwardsCompatRegister(func, arg3)
|
func = BackwardsCompatRegister(func, arg3)
|
||||||
pfUI.module[name] = func
|
pfUI.module[name] = func
|
||||||
@@ -409,7 +398,6 @@ function pfUI:RegisterModule(name, func, arg3)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function pfUI:RegisterSkin(name, func, arg3)
|
function pfUI:RegisterSkin(name, func, arg3)
|
||||||
if pfUI.disabled then return end
|
|
||||||
if pfUI.skin[name] then return end
|
if pfUI.skin[name] then return end
|
||||||
func = BackwardsCompatRegister(func, arg3)
|
func = BackwardsCompatRegister(func, arg3)
|
||||||
pfUI.skin[name] = func
|
pfUI.skin[name] = func
|
||||||
@@ -430,7 +418,6 @@ function pfUI:LoadSkin(s)
|
|||||||
end
|
end
|
||||||
|
|
||||||
pfUI:SetScript("OnEvent", function()
|
pfUI:SetScript("OnEvent", function()
|
||||||
if pfUI.disabled then return end
|
|
||||||
|
|
||||||
-- make sure to initialize and set our fonts
|
-- make sure to initialize and set our fonts
|
||||||
-- each time an addon got loaded but only
|
-- each time an addon got loaded but only
|
||||||
@@ -444,7 +431,7 @@ pfUI:SetScript("OnEvent", function()
|
|||||||
-- "@project-version@" until release tooling substitutes it — mark those
|
-- "@project-version@" until release tooling substitutes it — mark those
|
||||||
-- explicitly as "dev" instead of pretending they're a real numbered build.
|
-- explicitly as "dev" instead of pretending they're a real numbered build.
|
||||||
local raw = tostring(GetAddOnMetadata(pfUI.name, "Version"))
|
local raw = tostring(GetAddOnMetadata(pfUI.name, "Version"))
|
||||||
if strfind(raw, "@") then
|
if raw:find("@") then
|
||||||
pfUI.version.major, pfUI.version.minor, pfUI.version.fix = 0, 0, 0
|
pfUI.version.major, pfUI.version.minor, pfUI.version.fix = 0, 0, 0
|
||||||
pfUI.version.string = "dev"
|
pfUI.version.string = "dev"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
|
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
|
||||||
## X-Website: https://github.com/brues-code/pfUI
|
## X-Website: https://github.com/brues-code/pfUI
|
||||||
|
|
||||||
|
API_Check.lua
|
||||||
|
|
||||||
pfUI.lua
|
pfUI.lua
|
||||||
|
|
||||||
init\env.xml
|
init\env.xml
|
||||||
|
|||||||
@@ -295,9 +295,8 @@ pfUI:RegisterSkin("Character", function ()
|
|||||||
if faction and faction.reaction and faction.reaction < 8 then
|
if faction and faction.reaction and faction.reaction < 8 then
|
||||||
local repLeft = faction.nextReactionThreshold - faction.currentStanding
|
local repLeft = faction.nextReactionThreshold - faction.currentStanding
|
||||||
if repLeft > 1 then
|
if repLeft > 1 then
|
||||||
local text = standing:GetText() .. string.format(" (%d)", repLeft)
|
standing:SetFormattedText("%s (%d)", standing:GetText(), repLeft)
|
||||||
standing:SetText(text)
|
standing:GetParent().standingText = standing:GetText()
|
||||||
standing:GetParent().standingText = text
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ pfUI:RegisterSkin("Inspect", function ()
|
|||||||
local guild, title = GetGuildInfo(InspectFrame.unit)
|
local guild, title = GetGuildInfo(InspectFrame.unit)
|
||||||
if guild then
|
if guild then
|
||||||
InspectGuildText:SetPoint("TOP", InspectLevelText, "BOTTOM", 0, -1)
|
InspectGuildText:SetPoint("TOP", InspectLevelText, "BOTTOM", 0, -1)
|
||||||
InspectGuildText:SetText(format(TEXT(GUILD_TITLE_TEMPLATE), title, guild))
|
InspectGuildText:SetFormattedText(TEXT(GUILD_TITLE_TEMPLATE), title, guild)
|
||||||
InspectGuildText:Show()
|
InspectGuildText:Show()
|
||||||
else
|
else
|
||||||
InspectGuildText:SetText("")
|
InspectGuildText:SetText("")
|
||||||
|
|||||||
Reference in New Issue
Block a user