mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-26 22:00:49 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df21f1f26c | ||
|
|
bd7bf3f39f | ||
|
|
987c337709 | ||
|
|
cdaf9336a3 | ||
|
|
e4f0849816 | ||
|
|
c03b74c3d1 | ||
|
|
e583ac1e83 |
+35
-37
@@ -69,6 +69,35 @@ local function LayoutAuras(unit, unitstr)
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns the cooldown start and duration of an aura, 0, 0 when it has none.
|
||||
-- Start is capped to now: talent-extended auras run past their Spell.dbc base
|
||||
-- duration, and a start in the future trips the cooldown text's 2^32
|
||||
-- wraparound branch.
|
||||
local function AuraTimer(duration, expirationTime)
|
||||
if expirationTime <= 0 then return 0, 0 end
|
||||
|
||||
local now = GetTime()
|
||||
local start, dur = expirationTime - duration, duration
|
||||
if start > now or dur <= 0 then
|
||||
start, dur = now, expirationTime - now
|
||||
end
|
||||
|
||||
if dur <= 0 then return 0, 0 end
|
||||
return start, dur
|
||||
end
|
||||
|
||||
-- Starts the timers RefreshUnit stored on the shown icons of an aura block.
|
||||
local function StartAuraTimers(icons)
|
||||
if not icons then return end
|
||||
|
||||
local i = 1
|
||||
while icons[i] and icons[i]:IsShown() do
|
||||
local dur = icons[i].auraDuration
|
||||
CooldownFrame_SetTimer(icons[i].cd, icons[i].auraStart, dur, dur > 0 and 1 or 0)
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- GUID-based Roster Tracking for Smart Updates
|
||||
-- Only updates frames where the unit actually changed, not ALL 40 frames
|
||||
@@ -1711,24 +1740,7 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
unit.buffs[i].stacks:SetText("")
|
||||
end
|
||||
|
||||
if expirationTime > 0 then
|
||||
-- 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 the
|
||||
-- Spell.dbc base. Anchor start to now in that case to keep the remaining math sane.
|
||||
local now = GetTime()
|
||||
local start = expirationTime - duration
|
||||
local dur = duration
|
||||
if start > now or dur <= 0 then
|
||||
start, dur = now, expirationTime - now
|
||||
end
|
||||
if dur > 0 then
|
||||
CooldownFrame_SetTimer(unit.buffs[i].cd, start, dur, 1)
|
||||
else
|
||||
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
||||
end
|
||||
else
|
||||
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
||||
end
|
||||
unit.buffs[i].auraStart, unit.buffs[i].auraDuration = AuraTimer(duration, expirationTime)
|
||||
else
|
||||
unit.buffs[i]:Hide()
|
||||
end
|
||||
@@ -1771,24 +1783,7 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
if texture then
|
||||
unit.debuffs[i]:Show()
|
||||
|
||||
if expirationTime > 0 then
|
||||
-- Cap start to now so talent-extended debuffs (expirationTime past
|
||||
-- the dbc base duration) don't push start into the future and trip
|
||||
-- CooldownFrame_SetTimer's 2^32-wraparound branch.
|
||||
local now = GetTime()
|
||||
local start = expirationTime - duration
|
||||
local dur = duration
|
||||
if start > now or dur <= 0 then
|
||||
start, dur = now, expirationTime - now
|
||||
end
|
||||
if dur > 0 then
|
||||
CooldownFrame_SetTimer(unit.debuffs[i].cd, start, dur, 1)
|
||||
else
|
||||
CooldownFrame_SetTimer(unit.debuffs[i].cd, 0, 0, 0)
|
||||
end
|
||||
else
|
||||
CooldownFrame_SetTimer(unit.debuffs[i].cd, 0, 0, 0)
|
||||
end
|
||||
unit.debuffs[i].auraStart, unit.debuffs[i].auraDuration = AuraTimer(duration, expirationTime)
|
||||
|
||||
if stacks > 1 then
|
||||
unit.debuffs[i].stacks:SetText(stacks)
|
||||
@@ -1806,8 +1801,11 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
end
|
||||
end
|
||||
|
||||
-- timers start after the layout so each cooldown text is sized to its icon
|
||||
if component == "all" or component == "aura" then
|
||||
LayoutAuras(unit, unitstr)
|
||||
StartAuraTimers(unit.buffs)
|
||||
StartAuraTimers(unit.debuffs)
|
||||
end
|
||||
|
||||
-- indicators
|
||||
@@ -2238,7 +2236,7 @@ function pfUI.uf:AddIcon(frame, pos, icon, timeleft, stacks, start, duration)
|
||||
if not frame.icon[pos] then
|
||||
frame.icon[pos] = CreateFrame("Frame", nil, frame.icon)
|
||||
frame.icon[pos]:SetParent(frame)
|
||||
frame.icon[pos].tex = frame.icon[pos]:CreateTexture("OVERLAY")
|
||||
frame.icon[pos].tex = frame.icon[pos]:CreateTexture(nil, "OVERLAY")
|
||||
frame.icon[pos].tex:SetAllPoints(frame.icon[pos])
|
||||
frame.icon[pos].tex:SetTexCoord(.08, .92, .08, .92)
|
||||
frame.icon[pos].stacks = frame.icon[pos]:CreateFontString(nil, "OVERLAY")
|
||||
|
||||
@@ -57,7 +57,7 @@ pfUI:RegisterModule("autovendor", function ()
|
||||
-- Setup Autosell button
|
||||
autovendor.button = CreateFrame("Button", "pfMerchantAutoVendorButton", MerchantFrame)
|
||||
autovendor.button:SetSize(36, 36)
|
||||
autovendor.button.icon = autovendor.button:CreateTexture("ARTWORK")
|
||||
autovendor.button.icon = autovendor.button:CreateTexture(nil, "ARTWORK")
|
||||
autovendor.button.icon:SetTexture("Interface\\Icons\\Spell_Shadow_SacrificialShield")
|
||||
autovendor.button:SetScript("OnEnter", function()
|
||||
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
||||
|
||||
@@ -23,7 +23,7 @@ pfUI:RegisterModule("combopoints", function ()
|
||||
pfUI.combopoints[point]:SetPoint("CENTER", UIParent, "CENTER", (point - 3) * (combo_width + border*3), 10 )
|
||||
end
|
||||
|
||||
pfUI.combopoints[point].tex = pfUI.combopoints[point]:CreateTexture("OVERLAY")
|
||||
pfUI.combopoints[point].tex = pfUI.combopoints[point]:CreateTexture(nil, "OVERLAY")
|
||||
pfUI.combopoints[point].tex:SetAllPoints(pfUI.combopoints[point])
|
||||
|
||||
if point < 3 then
|
||||
|
||||
+26
-13
@@ -59,18 +59,14 @@ pfUI:RegisterModule("cooldown", function ()
|
||||
end
|
||||
end
|
||||
|
||||
local height, size
|
||||
local textcount = 0
|
||||
local function pfCreateCoolDown(cooldown, start, duration)
|
||||
textcount = textcount + 1
|
||||
local name = cooldown.GetName and cooldown:GetName() or "pfCooldown" .. textcount
|
||||
|
||||
cooldown.pfCooldownText = CreateFrame("Frame", name .. "Text", cooldown:GetParent())
|
||||
cooldown.pfCooldownText.cooldown = cooldown
|
||||
cooldown.pfCooldownText:SetAllPoints(cooldown)
|
||||
cooldown.pfCooldownText:SetFrameLevel(cooldown:GetParent():GetFrameLevel() + 2)
|
||||
cooldown.pfCooldownText.text = cooldown.pfCooldownText:CreateFontString(name .. "TextString", "OVERLAY")
|
||||
local function GetCooldownHeight(cooldown)
|
||||
return cooldown:GetParent() and cooldown:GetParent():GetHeight() or cooldown:GetHeight() or 0
|
||||
end
|
||||
|
||||
-- sizes the text to the cooldown's current height; the dynamic size follows
|
||||
-- the frame, so SetCooldown calls this again whenever that height changes
|
||||
local function pfUpdateCooldownFont(cooldown)
|
||||
local size
|
||||
if not cooldown.pfCooldownType then
|
||||
size = tonumber(C.appearance.cd.font_size_foreign)
|
||||
elseif cooldown.pfCooldownType == "BLIZZARD" then
|
||||
@@ -82,12 +78,27 @@ pfUI:RegisterModule("cooldown", function ()
|
||||
end
|
||||
|
||||
-- enforce dynamic font size
|
||||
if C.appearance.cd.dynamicsize == "1" and cooldown.GetParent then
|
||||
height = cooldown:GetParent() and cooldown:GetParent():GetHeight() or cooldown:GetHeight() or 0
|
||||
if C.appearance.cd.dynamicsize == "1" then
|
||||
local height = GetCooldownHeight(cooldown)
|
||||
cooldown.pfCooldownText.height = height
|
||||
size = math.max((height > 0 and height * .64 or 16), size)
|
||||
end
|
||||
|
||||
cooldown.pfCooldownText.text:SetFont(pfUI.media[C.appearance.cd.font], size, "OUTLINE")
|
||||
end
|
||||
|
||||
local textcount = 0
|
||||
local function pfCreateCoolDown(cooldown, start, duration)
|
||||
textcount = textcount + 1
|
||||
local name = cooldown.GetName and cooldown:GetName() or "pfCooldown" .. textcount
|
||||
|
||||
cooldown.pfCooldownText = CreateFrame("Frame", name .. "Text", cooldown:GetParent())
|
||||
cooldown.pfCooldownText.cooldown = cooldown
|
||||
cooldown.pfCooldownText:SetAllPoints(cooldown)
|
||||
cooldown.pfCooldownText:SetFrameLevel(cooldown:GetParent():GetFrameLevel() + 2)
|
||||
cooldown.pfCooldownText.text = cooldown.pfCooldownText:CreateFontString(name .. "TextString", "OVERLAY")
|
||||
|
||||
pfUpdateCooldownFont(cooldown)
|
||||
cooldown.pfCooldownText.text:SetPoint("CENTER", cooldown.pfCooldownText, "CENTER", 0, 0)
|
||||
cooldown.pfCooldownText:SetScript("OnUpdate", pfCooldownOnUpdate)
|
||||
end
|
||||
@@ -136,6 +147,8 @@ pfUI:RegisterModule("cooldown", function ()
|
||||
and start > 0 and duration > 0 and (not enable or enable > 0) then
|
||||
if( not this.pfCooldownText ) then
|
||||
pfCreateCoolDown(this, start, duration)
|
||||
elseif C.appearance.cd.dynamicsize == "1" and GetCooldownHeight(this) ~= this.pfCooldownText.height then
|
||||
pfUpdateCooldownFont(this)
|
||||
end
|
||||
|
||||
this.pfCooldownText.start = start
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
frame.color:SetHeight(12)
|
||||
CreateBackdrop(frame.color)
|
||||
frame.color:SetPoint("RIGHT" , -5, 1)
|
||||
frame.color.prev = frame.color.backdrop:CreateTexture("OVERLAY")
|
||||
frame.color.prev = frame.color.backdrop:CreateTexture(nil, "OVERLAY")
|
||||
frame.color.prev:SetAllPoints(frame.color)
|
||||
|
||||
local cr, cg, cb, ca = strsplit(",", category[config])
|
||||
|
||||
+35
-23
@@ -31,7 +31,6 @@ pfUI:RegisterModule("mapreveal", function ()
|
||||
end)
|
||||
|
||||
local explorecaches = {}
|
||||
local alreadyknown = {} -- per-zone accumulator: { [zone] = { [texName] = true } }
|
||||
|
||||
-- Own texture pool - separate from Blizzard's WorldMapOverlay textures
|
||||
local overlayPool = CreateTexturePool(WorldMapDetailFrame, "BORDER", nil, nil, function(_, tex)
|
||||
@@ -93,43 +92,45 @@ pfUI:RegisterModule("mapreveal", function ()
|
||||
-- clear stale caches
|
||||
for k in pairs(explorecaches) do explorecaches[k] = nil end
|
||||
|
||||
-- hide all our textures from last frame
|
||||
-- hide all our textures and icons from last frame
|
||||
overlayPool:ReleaseAll()
|
||||
explorePool:ReleaseAll()
|
||||
|
||||
local showExplore = C.appearance.worldmap.mapexploration == "1"
|
||||
local showReveal = C.appearance.worldmap.mapreveal == "1"
|
||||
if not showExplore and not showReveal then return end
|
||||
|
||||
local r,g,b,a = GetStringColor(C.appearance.worldmap.mapreveal_color)
|
||||
local mapFileName = GetMapInfo()
|
||||
if not mapFileName then mapFileName = "World" end
|
||||
|
||||
local numOverlays = GetNumMapOverlays()
|
||||
|
||||
-- accumulate explored overlays per zone (never clear, only add)
|
||||
if not alreadyknown[mapFileName] then alreadyknown[mapFileName] = {} end
|
||||
for i = 1, numOverlays do
|
||||
local texName = GetMapOverlayInfo(i)
|
||||
if texName then alreadyknown[mapFileName][string.upper(texName)] = true end
|
||||
end
|
||||
|
||||
local zoneKnown = alreadyknown[mapFileName]
|
||||
|
||||
-- hide explore icons
|
||||
explorePool:ReleaseAll()
|
||||
|
||||
-- ClassicAPI: full overlay list for the viewed zone (explored + unexplored),
|
||||
-- read straight from WorldMapOverlay.dbc. Replaces the hand-measured pfMapOverlayData.
|
||||
local zoneData = C_Map.GetMapOverlays() or {}
|
||||
|
||||
-- ClassicAPI: the unexplored subset of the viewed zone, using the engine's
|
||||
-- own explored-bit test. Replaces the alreadyknown accumulator, which
|
||||
-- replayed the explored-only GetMapOverlayInfo view. Keyed by the bare
|
||||
-- texture name, the same key the icon cache below uses.
|
||||
local unknown = {}
|
||||
if showExplore then
|
||||
for _, overlay in ipairs(C_MapExplorationInfo.GetUnexploredMapTextures() or {}) do
|
||||
if overlay.textureName and overlay.textureName ~= "" then
|
||||
unknown[string.upper(overlay.textureName)] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, overlay in ipairs(zoneData) do
|
||||
local name = overlay.textureName -- bare, e.g. "DRYGULCHRAVINE"
|
||||
local textureName = overlay.texturePath -- full engine path (for SetTexture)
|
||||
local textureWidth = overlay.textureWidth
|
||||
local textureHeight = overlay.textureHeight
|
||||
local offsetX = overlay.offsetX
|
||||
local offsetY = overlay.offsetY
|
||||
|
||||
-- explore magnifying glass icon. `alreadyknown` stores the FULL paths
|
||||
-- GetMapOverlayInfo returns, so compare with the full path, not the bare
|
||||
-- name.
|
||||
if C.appearance.worldmap.mapexploration == "1" and not zoneKnown[string.upper(textureName)] then
|
||||
-- explore magnifying glass icon for overlays the engine still
|
||||
-- counts as unexplored.
|
||||
if showExplore and unknown[string.upper(name)] then
|
||||
local explore = explorePool:Acquire()
|
||||
explore:SetPoint("TOPLEFT", "WorldMapDetailFrame", "TOPLEFT", offsetX + textureWidth/2, -offsetY - textureHeight/2)
|
||||
explore.name = mapFileName .. " (" .. name .. ")"
|
||||
@@ -147,7 +148,7 @@ pfUI:RegisterModule("mapreveal", function ()
|
||||
-- disambiguated from the actual BLP dimensions. No 256px grid
|
||||
-- math here — deriving the grid from textureWidth/Height is
|
||||
-- exactly what shears quirky overlays (e.g. Icepoint's Kaneq'nuun).
|
||||
if C.appearance.worldmap.mapreveal == "1" then
|
||||
if showReveal then
|
||||
for _, tile in ipairs(overlay.tiles) do
|
||||
local tex = overlayPool:Acquire()
|
||||
|
||||
@@ -174,4 +175,15 @@ pfUI:RegisterModule("mapreveal", function ()
|
||||
pfWorldMapFrame_Update()
|
||||
end
|
||||
|
||||
end)
|
||||
-- live refresh while the map is open: exploration changes arrive on this
|
||||
-- event. Zone switches, zoom and (re)opens still come through the hook
|
||||
-- above, so nothing is redrawn while the map is closed — the next open
|
||||
-- rebuilds from the current state.
|
||||
|
||||
EventRegistry:RegisterFrameEventAndCallback("MAP_EXPLORATION_UPDATED", function()
|
||||
if WorldMapFrame and WorldMapFrame:IsShown() then
|
||||
pfWorldMapFrame_Update()
|
||||
end
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ pfUI:RegisterModule("minimap", function ()
|
||||
this.highlight:SetAllPoints(this)
|
||||
this.highlight:SetFrameLevel(this:GetFrameLevel() + 1)
|
||||
|
||||
this.highlight.tex = this.highlight:CreateTexture("OVERLAY")
|
||||
this.highlight.tex = this.highlight:CreateTexture(nil, "OVERLAY")
|
||||
this.highlight.tex:SetTexture(pfUI.media["img:mail"])
|
||||
this.highlight.tex:SetPoint("TOPLEFT", MiniMapMailIcon, "TOPLEFT", -2, 2)
|
||||
this.highlight.tex:SetPoint("BOTTOMRIGHT", MiniMapMailIcon, "BOTTOMRIGHT", 2, -2)
|
||||
|
||||
@@ -524,9 +524,11 @@ nameplates:RegisterUnitEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", "target", "focu
|
||||
end
|
||||
-- The plates hold their own unit subscriptions now, so silencing this
|
||||
-- frame alone would leave them dispatching through logout -- exactly what
|
||||
-- this branch exists to prevent.
|
||||
-- this branch exists to prevent. Leaving the world destroys the units
|
||||
-- before PLAYER_LOGOUT fires, and a destroyed plate already dropped its
|
||||
-- events and lost its methods, so only the live ones need silencing.
|
||||
for plate in pairs(registry) do
|
||||
if plate.nameplate then
|
||||
if plate.nameplate and plate.nameplate.UnregisterAllEvents then
|
||||
plate.nameplate:UnregisterAllEvents()
|
||||
plate.nameplate:SetScript("OnEvent", nil)
|
||||
end
|
||||
@@ -863,7 +865,7 @@ nameplates:RegisterUnitEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", "target", "focu
|
||||
combopoints[i] = CreateFrame("Frame", nil, nameplate)
|
||||
combopoints[i]:Hide()
|
||||
combopoints[i]:SetFrameLevel(8)
|
||||
combopoints[i].tex = combopoints[i]:CreateTexture("OVERLAY")
|
||||
combopoints[i].tex = combopoints[i]:CreateTexture(nil, "OVERLAY")
|
||||
combopoints[i].tex:SetAllPoints()
|
||||
|
||||
if i < 3 then
|
||||
|
||||
@@ -25,7 +25,7 @@ pfUI:RegisterModule("nampower", function ()
|
||||
pfUI.spellqueue:SetPoint("CENTER", UIParent, "CENTER", 100, -100)
|
||||
end
|
||||
|
||||
pfUI.spellqueue.icon = pfUI.spellqueue:CreateTexture("OVERLAY")
|
||||
pfUI.spellqueue.icon = pfUI.spellqueue:CreateTexture(nil, "OVERLAY")
|
||||
pfUI.spellqueue.icon:SetAllPoints(pfUI.spellqueue)
|
||||
pfUI.spellqueue.icon:SetTexCoord(.08, .92, .08, .92)
|
||||
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ pfUI:RegisterModule("roll", function ()
|
||||
f.icon:SetWidth(esize)
|
||||
f.icon:SetHeight(esize)
|
||||
|
||||
f.icon.tex = f.icon:CreateTexture("OVERLAY")
|
||||
f.icon.tex = f.icon:CreateTexture(nil, "OVERLAY")
|
||||
f.icon.tex:SetTexCoord(.08, .92, .08, .92)
|
||||
f.icon.tex:SetAllPoints(f.icon)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ pfUI:RegisterModule("tracking", function ()
|
||||
pfUI.tracking:SetWidth(size)
|
||||
pfUI.tracking:SetHeight(size)
|
||||
|
||||
pfUI.tracking.icon = pfUI.tracking:CreateTexture("BACKGROUND")
|
||||
pfUI.tracking.icon = pfUI.tracking:CreateTexture(nil, "BACKGROUND")
|
||||
pfUI.tracking.icon:SetTexCoord(.08, .92, .08, .92)
|
||||
pfUI.tracking.icon:SetAllPoints(pfUI.tracking)
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ pfUI:RegisterSkin("Petition", function ()
|
||||
|
||||
local texture = "StationeryTest"
|
||||
if date("%m%d") == "0223" then texture = "Stationery_Val" end
|
||||
local tex_Left = PetitionFrame:CreateTexture("BACKGROUND")
|
||||
local tex_Left = PetitionFrame:CreateTexture(nil, "BACKGROUND")
|
||||
tex_Left:SetTexture("Interface\\Stationery\\"..texture.."1")
|
||||
tex_Left:SetPoint("TOPLEFT", 23, -81)
|
||||
tex_Left:SetWidth(tex_Left:GetWidth() + 10)
|
||||
tex_Left:SetHeight(330)
|
||||
local tex_Right = PetitionFrame:CreateTexture("BACKGROUND")
|
||||
local tex_Right = PetitionFrame:CreateTexture(nil, "BACKGROUND")
|
||||
tex_Right:SetTexture("Interface\\Stationery\\"..texture.."2")
|
||||
tex_Right:SetPoint("LEFT", tex_Left, "RIGHT", 0, 0)
|
||||
tex_Right:SetWidth(tex_Right:GetWidth() + 10)
|
||||
|
||||
@@ -35,13 +35,14 @@ pfUI:RegisterSkin("Pet Stable Master", function ()
|
||||
StripTextures(button)
|
||||
SkinButton(button, nil, nil, nil, _G[button:GetName().."IconTexture"])
|
||||
|
||||
button.Enable = function()
|
||||
button:SetBackdropColor()
|
||||
button.locked = false
|
||||
local b = button
|
||||
b.Enable = function()
|
||||
b:SetBackdropColor()
|
||||
b.locked = false
|
||||
end
|
||||
button.Disable = function()
|
||||
button:SetBackdropColor(1, .1, .1, .3)
|
||||
button.locked = true
|
||||
b.Disable = function()
|
||||
b:SetBackdropColor(1, .1, .1, .3)
|
||||
b.locked = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user