mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-13 17:00:49 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe22dfc456 | ||
|
|
5eaab2784f | ||
|
|
f41d5ac6d0 | ||
|
|
af8780bb41 | ||
|
|
ea37f41db1 | ||
|
|
6f36da7aa1 | ||
|
|
149d5dd362 | ||
|
|
0156d9dfec |
+47
-21
@@ -92,25 +92,24 @@ gfind = string.gmatch or string.gfind
|
|||||||
mod = math.mod or mod
|
mod = math.mod or mod
|
||||||
|
|
||||||
-- [ strsplit ]
|
-- [ strsplit ]
|
||||||
-- Splits a string using a delimiter. Thin wrapper that delegates to
|
-- Splits a string using a delimiter. Self-contained on purpose: it does NOT
|
||||||
-- ClassicAPI's C-level strsplit, kept as a pfUI.api entry point for
|
-- delegate to the global strsplit / string.split, because third-party addons
|
||||||
-- backwards compatibility with addons that call pfUI.api.strsplit.
|
-- clobber those (e.g. BigWigs' SpellRequests redefines string:split to return
|
||||||
-- Note: unlike the old Lua implementation, empty fields are preserved
|
-- a table, which would make this return a single table instead of r,g,b,a and
|
||||||
-- (e.g. "a,,b" -> "a", "", "b"), matching real strsplit semantics.
|
-- break color/version parsing depending on load order). Delimiter chars are
|
||||||
|
-- treated as a set (any one char splits), and empty fields are preserved
|
||||||
|
-- ("a,,b" -> "a", "", "b"), matching real strsplit semantics.
|
||||||
-- 'delimiter' [string] characters that will be interpreted as delimiter
|
-- 'delimiter' [string] characters that will be interpreted as delimiter
|
||||||
-- characters (bytes) in the string.
|
-- characters (bytes) in the string.
|
||||||
-- 'subject' [string] String to split.
|
-- 'subject' [string] String to split.
|
||||||
-- return: [list] a list of strings.
|
-- return: [list] a list of strings.
|
||||||
local stringsplit = _G.string.split
|
local format, sgsub = string.format, string.gsub
|
||||||
function pfUI.api.strsplit(delimiter, subject)
|
function pfUI.api.strsplit(delimiter, subject)
|
||||||
if not subject then return nil end
|
if not subject then return nil end
|
||||||
delimiter = delimiter or ":"
|
|
||||||
if stringsplit then
|
|
||||||
return stringsplit(delimiter, subject)
|
|
||||||
end
|
|
||||||
local fields = {}
|
local fields = {}
|
||||||
local pattern = string.format("([^%s]+)", delimiter)
|
delimiter = delimiter or ":"
|
||||||
string.gsub(subject, pattern, function(c) fields[table.getn(fields)+1] = c end)
|
local pattern = format("([^%s]+)", delimiter)
|
||||||
|
sgsub(subject, pattern, function(c) fields[table.getn(fields)+1] = c end)
|
||||||
return unpack(fields)
|
return unpack(fields)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -998,16 +997,36 @@ end
|
|||||||
|
|
||||||
-- [ GetStringColor ]
|
-- [ GetStringColor ]
|
||||||
-- Queries the pfUI setting strings and extract its color codes
|
-- Queries the pfUI setting strings and extract its color codes
|
||||||
-- returns r,g,b,a
|
-- returns r,g,b,a as numbers
|
||||||
local color_cache = {}
|
local color_cache = setmetatable({}, {
|
||||||
function pfUI.api.GetStringColor(colorstr)
|
__index = function(t, k)
|
||||||
if not color_cache[colorstr] then
|
local color = { pfUI.api.strsplit(",", k) }
|
||||||
local r, g, b, a = pfUI.api.strsplit(",", colorstr)
|
for i = 1, table.getn(color) do
|
||||||
color_cache[colorstr] = { r, g, b, a }
|
color[i] = tonumber(color[i])
|
||||||
|
end
|
||||||
|
rawset(t, k, color)
|
||||||
|
return color
|
||||||
end
|
end
|
||||||
|
})
|
||||||
|
function pfUI.api.GetStringColor(colorstr)
|
||||||
return unpack(color_cache[colorstr])
|
return unpack(color_cache[colorstr])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- [ GetStringColorObject ]
|
||||||
|
-- Like GetStringColor, but returns a cached ColorMixin instead of raw values.
|
||||||
|
-- The object is a shared per-string singleton, so treat it as read-only.
|
||||||
|
-- returns a ColorMixin
|
||||||
|
local color_object_cache = setmetatable({}, {
|
||||||
|
__index = function(t, k)
|
||||||
|
local color = CreateColor(pfUI.api.GetStringColor(k))
|
||||||
|
rawset(t, k, color)
|
||||||
|
return color
|
||||||
|
end
|
||||||
|
})
|
||||||
|
function pfUI.api.GetStringColorObject(colorstr)
|
||||||
|
return color_object_cache[colorstr]
|
||||||
|
end
|
||||||
|
|
||||||
-- [ rgbhex ]
|
-- [ rgbhex ]
|
||||||
-- Returns color format from color info
|
-- Returns color format from color info
|
||||||
-- 'r' [table | number] color table or r color component
|
-- 'r' [table | number] color table or r color component
|
||||||
@@ -1015,12 +1034,13 @@ end
|
|||||||
-- 'b' [number] optional b color component
|
-- 'b' [number] optional b color component
|
||||||
-- 'a' [number] optional alpha component
|
-- 'a' [number] optional alpha component
|
||||||
-- returns color string in the form of '|caarrggbb'
|
-- returns color string in the form of '|caarrggbb'
|
||||||
local _r, _g, _b, _a
|
local rgbhex_cache = {}
|
||||||
function pfUI.api.rgbhex(r, g, b, a)
|
function pfUI.api.rgbhex(r, g, b, a)
|
||||||
|
local _r, _g, _b, _a
|
||||||
if type(r) == "table" then
|
if type(r) == "table" then
|
||||||
if r.r then
|
if r.r then
|
||||||
_r, _g, _b, _a = r.r, r.g, r.b, (r.a or 1)
|
_r, _g, _b, _a = r.r, r.g, r.b, (r.a or 1)
|
||||||
elseif table.getn(r) >= 3 then
|
elseif r[3] ~= nil then
|
||||||
_r, _g, _b, _a = r[1], r[2], r[3], (r[4] or 1)
|
_r, _g, _b, _a = r[1], r[2], r[3], (r[4] or 1)
|
||||||
end
|
end
|
||||||
elseif tonumber(r) then
|
elseif tonumber(r) then
|
||||||
@@ -1028,7 +1048,13 @@ function pfUI.api.rgbhex(r, g, b, a)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if _r and _g and _b and _a then
|
if _r and _g and _b and _a then
|
||||||
return CreateColor(_r, _g, _b, _a):GenerateHexColorMarkup()
|
local key = ((Round(_r*255)*256 + Round(_g*255))*256 + Round(_b*255))*256 + Round(_a*255)
|
||||||
|
local hex = rgbhex_cache[key]
|
||||||
|
if not hex then
|
||||||
|
hex = "|c" .. C_ColorUtil.GenerateTextColorCode({ r = _r, g = _g, b = _b, a = _a })
|
||||||
|
rgbhex_cache[key] = hex
|
||||||
|
end
|
||||||
|
return hex
|
||||||
end
|
end
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ libthrottle.defaults = {
|
|||||||
nameplates_target = "custom",
|
nameplates_target = "custom",
|
||||||
nameplates_castbar = "custom",
|
nameplates_castbar = "custom",
|
||||||
nameplates_mass = "custom",
|
nameplates_mass = "custom",
|
||||||
tooltip_cursor = "custom",
|
tooltip_cursor = "fastest",
|
||||||
chat_tab = "custom",
|
chat_tab = "custom",
|
||||||
swingtimer = "custom",
|
swingtimer = "custom",
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ libthrottle:SetScript("OnEvent", function()
|
|||||||
-- Set defaults for custom fields if missing
|
-- Set defaults for custom fields if missing
|
||||||
if not _G.pfUI_throttle.nameplates_target_custom then _G.pfUI_throttle.nameplates_target_custom = "50" end
|
if not _G.pfUI_throttle.nameplates_target_custom then _G.pfUI_throttle.nameplates_target_custom = "50" end
|
||||||
if not _G.pfUI_throttle.nameplates_custom then _G.pfUI_throttle.nameplates_custom = "10" end
|
if not _G.pfUI_throttle.nameplates_custom then _G.pfUI_throttle.nameplates_custom = "10" end
|
||||||
if not _G.pfUI_throttle.nameplates_castbar_custom then _G.pfUI_throttle.nameplates_castbar_custom = "50" end
|
if not _G.pfUI_throttle.nameplates_castbar_custom then _G.pfUI_throttle.nameplates_castbar_custom = "100" end
|
||||||
if not _G.pfUI_throttle.nameplates_mass_custom then _G.pfUI_throttle.nameplates_mass_custom = "7" end
|
if not _G.pfUI_throttle.nameplates_mass_custom then _G.pfUI_throttle.nameplates_mass_custom = "7" end
|
||||||
if not _G.pfUI_throttle.tooltip_cursor_custom then _G.pfUI_throttle.tooltip_cursor_custom = "10" end
|
if not _G.pfUI_throttle.tooltip_cursor_custom then _G.pfUI_throttle.tooltip_cursor_custom = "10" end
|
||||||
if not _G.pfUI_throttle.chat_tab_custom then _G.pfUI_throttle.chat_tab_custom = "10" end
|
if not _G.pfUI_throttle.chat_tab_custom then _G.pfUI_throttle.chat_tab_custom = "10" end
|
||||||
|
|||||||
+3
-5
@@ -90,7 +90,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
cb:SetAlpha(1)
|
cb:SetAlpha(1)
|
||||||
cb.fadeout = nil
|
cb.fadeout = nil
|
||||||
|
|
||||||
cb.bar:SetStatusBarColor(strsplit(",", C.appearance.castbar[isChannel and "channelcolor" or "castbarcolor"]))
|
cb.bar:SetStatusBarColor(GetStringColor(C.appearance.castbar[isChannel and "channelcolor" or "castbarcolor"]))
|
||||||
|
|
||||||
local rank = ""
|
local rank = ""
|
||||||
if spellID then
|
if spellID then
|
||||||
@@ -103,8 +103,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
if tex and cb.showicon then
|
if tex and cb.showicon then
|
||||||
local size = cb:GetHeight()
|
local size = cb:GetHeight()
|
||||||
cb.icon:Show()
|
cb.icon:Show()
|
||||||
cb.icon:SetHeight(size)
|
cb.icon:SetSize(size, size)
|
||||||
cb.icon:SetWidth(size)
|
|
||||||
cb.icon.texture:SetTexture(tex)
|
cb.icon.texture:SetTexture(tex)
|
||||||
cb.bar:SetPoint("TOPLEFT", cb.icon, "TOPRIGHT", cb.spacing, 0)
|
cb.bar:SetPoint("TOPLEFT", cb.icon, "TOPRIGHT", cb.spacing, 0)
|
||||||
else
|
else
|
||||||
@@ -169,8 +168,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
-- icon
|
-- icon
|
||||||
cb.icon = CreateFrame("Frame", nil, cb)
|
cb.icon = CreateFrame("Frame", nil, cb)
|
||||||
cb.icon:SetPoint("TOPLEFT", 0, 0)
|
cb.icon:SetPoint("TOPLEFT", 0, 0)
|
||||||
cb.icon:SetHeight(16)
|
cb.icon:SetSize(16, 16)
|
||||||
cb.icon:SetWidth(16)
|
|
||||||
|
|
||||||
cb.icon.texture = cb.icon:CreateTexture(nil, "OVERLAY")
|
cb.icon.texture = cb.icon:CreateTexture(nil, "OVERLAY")
|
||||||
cb.icon.texture:SetAllPoints()
|
cb.icon.texture:SetAllPoints()
|
||||||
|
|||||||
+99
-31
@@ -61,11 +61,20 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
|
|
||||||
local raidGuidCache = {} -- guid -> name (rebuilt on RAID_ROSTER_UPDATE/PARTY_MEMBERS_CHANGED)
|
local raidGuidCache = {} -- guid -> name (rebuilt on RAID_ROSTER_UPDATE/PARTY_MEMBERS_CHANGED)
|
||||||
|
|
||||||
-- Resolve a unit token to its cast/channel info via C_Spell. Returns a
|
-- Per-GUID cast state, populated by nampower's SPELL_START_OTHER events and
|
||||||
-- compact struct (spellName / icon / startTime / endTime / duration /
|
-- cleared on SPELL_FAILED_OTHER / plate removal / expiry. This replaces the
|
||||||
-- isChannel) or nil when the unit isn't casting. Callers already hold the
|
-- old per-tick C_Spell poll on every visible plate: cast detection is now
|
||||||
-- nameplate token, so there's no GUID->token round-trip.
|
-- event driven, and GetCastInfo just reads this cache.
|
||||||
local function GetCastInfo(unit)
|
local castState = {}
|
||||||
|
-- guid -> nameplate, maintained on NAME_PLATE_UNIT_ADDED/_REMOVED so a cast
|
||||||
|
-- event can find its plate in O(1) and only cache casts we actually show.
|
||||||
|
local plateByGuid = {}
|
||||||
|
local targetPlateGuid = nil
|
||||||
|
|
||||||
|
-- One-shot C_Spell poll. Only used to seed a plate that spawns while its
|
||||||
|
-- unit is already mid-cast (its SPELL_START_OTHER fired before the plate
|
||||||
|
-- existed). Never called per frame.
|
||||||
|
local function PollCastInfo(unit)
|
||||||
if not unit then return nil end
|
if not unit then return nil end
|
||||||
local name, _, texture, startMs, endMs, _, _, _, spellID = C_Spell.UnitCastingInfo(unit)
|
local name, _, texture, startMs, endMs, _, _, _, spellID = C_Spell.UnitCastingInfo(unit)
|
||||||
local isChannel
|
local isChannel
|
||||||
@@ -84,6 +93,20 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
isChannel = isChannel,
|
isChannel = isChannel,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Read a unit's current cast from the event-driven cache (keyed by GUID).
|
||||||
|
-- Returns the cached struct while the cast is still active, else nil (and
|
||||||
|
-- prunes the expired entry). Same struct shape and callers as before, minus
|
||||||
|
-- the per-tick poll.
|
||||||
|
local function GetCastInfo(unit)
|
||||||
|
if not unit then return nil end
|
||||||
|
local guid = UnitGUID(unit)
|
||||||
|
if not guid then return nil end
|
||||||
|
local info = castState[guid]
|
||||||
|
if info and info.endTime > GetTime() then return info end
|
||||||
|
if info then castState[guid] = nil end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
local debuffCache = {} -- guid -> { [spellID] = { start, duration } }
|
local debuffCache = {} -- guid -> { [spellID] = { start, duration } }
|
||||||
-- Reusable per-plate debuff display buffer (avoid GC churn from per-call table creation)
|
-- Reusable per-plate debuff display buffer (avoid GC churn from per-call table creation)
|
||||||
@@ -156,7 +179,7 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
now = 0,
|
now = 0,
|
||||||
hasTarget = false,
|
hasTarget = false,
|
||||||
targetGuid = nil,
|
targetGuid = nil,
|
||||||
hasMouseover = false,
|
mouseoverGuid = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- cache default border color
|
-- cache default border color
|
||||||
@@ -453,6 +476,11 @@ nameplates:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
|||||||
nameplates:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
nameplates:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
||||||
nameplates:RegisterEvent("UNIT_AURA")
|
nameplates:RegisterEvent("UNIT_AURA")
|
||||||
nameplates:RegisterEvent("UNIT_FLAGS")
|
nameplates:RegisterEvent("UNIT_FLAGS")
|
||||||
|
-- nampower cast lifecycle for other units (gated by NP_EnableSpell{Start,Go}
|
||||||
|
-- Events, enabled by libdebuff). Drives castbars event-first instead of
|
||||||
|
-- polling C_Spell on every plate each tick. Mirrors castbar.lua's target bar.
|
||||||
|
nameplates:RegisterEvent("SPELL_START_OTHER")
|
||||||
|
nameplates:RegisterEvent("SPELL_FAILED_OTHER")
|
||||||
|
|
||||||
nameplates:SetScript("OnEvent", function()
|
nameplates:SetScript("OnEvent", function()
|
||||||
-- Stop event handling during logout to prevent crash 132
|
-- Stop event handling during logout to prevent crash 132
|
||||||
@@ -470,6 +498,7 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
CacheConfig()
|
CacheConfig()
|
||||||
this:SetGameVariables()
|
this:SetGameVariables()
|
||||||
RebuildRaidGuidCache()
|
RebuildRaidGuidCache()
|
||||||
|
targetPlateGuid = UnitExists("target") and UnitGUID("target") or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Handle friendly zone nameplate disable feature
|
-- Handle friendly zone nameplate disable feature
|
||||||
@@ -529,8 +558,16 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
-- token itself for token-based UnitX reads (stable per plate lifetime).
|
-- token itself for token-based UnitX reads (stable per plate lifetime).
|
||||||
local plate = C_NamePlate.GetNamePlateForUnit(arg1)
|
local plate = C_NamePlate.GetNamePlateForUnit(arg1)
|
||||||
if plate and plate.nameplate then
|
if plate and plate.nameplate then
|
||||||
plate.nameplate.cachedGuid = UnitGUID(arg1)
|
local guid = UnitGUID(arg1)
|
||||||
|
plate.nameplate.cachedGuid = guid
|
||||||
plate.nameplate.unit = arg1
|
plate.nameplate.unit = arg1
|
||||||
|
if guid then
|
||||||
|
plateByGuid[guid] = plate.nameplate
|
||||||
|
-- Seed: the unit may already be mid-cast (its SPELL_START_OTHER fired
|
||||||
|
-- before this plate existed). One poll here catches that; ongoing
|
||||||
|
-- casts arrive via the event.
|
||||||
|
castState[guid] = PollCastInfo(arg1)
|
||||||
|
end
|
||||||
nameplates.OnShow(plate)
|
nameplates.OnShow(plate)
|
||||||
end
|
end
|
||||||
visiblePlateCount = visiblePlateCount + 1
|
visiblePlateCount = visiblePlateCount + 1
|
||||||
@@ -544,6 +581,8 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
if debuffCache[guid] then debuffCache[guid] = nil end
|
if debuffCache[guid] then debuffCache[guid] = nil end
|
||||||
if threatMemory[guid] then threatMemory[guid] = nil end
|
if threatMemory[guid] then threatMemory[guid] = nil end
|
||||||
if combatColorCache[guid] then combatColorCache[guid] = nil end
|
if combatColorCache[guid] then combatColorCache[guid] = nil end
|
||||||
|
if castState[guid] then castState[guid] = nil end
|
||||||
|
if plateByGuid[guid] then plateByGuid[guid] = nil end
|
||||||
local plate = C_NamePlate.GetNamePlateForUnit(arg1)
|
local plate = C_NamePlate.GetNamePlateForUnit(arg1)
|
||||||
if plate and plate.nameplate and plate.nameplate.cachedGuid == guid then
|
if plate and plate.nameplate and plate.nameplate.cachedGuid == guid then
|
||||||
plate.nameplate.cachedGuid = nil
|
plate.nameplate.cachedGuid = nil
|
||||||
@@ -563,6 +602,41 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
elseif event == "SPELL_START_OTHER" then
|
||||||
|
-- nampower: arg2=spellId, arg3=casterGuid, arg6=castTime(ms),
|
||||||
|
-- arg7=channel duration(ms, 0 if not a channel), arg8=spellType
|
||||||
|
-- (1 = channel). Cache the cast only for a unit we have a plate for, so
|
||||||
|
-- the table stays bounded to on-screen casters.
|
||||||
|
local casterGuid = arg3
|
||||||
|
local plate = casterGuid and plateByGuid[casterGuid]
|
||||||
|
if plate then
|
||||||
|
local isChannel = arg8 == 1
|
||||||
|
local durationMs = isChannel and arg7 or arg6
|
||||||
|
if durationMs and durationMs > 0 then
|
||||||
|
local spellId = arg2
|
||||||
|
local now = GetTime()
|
||||||
|
castState[casterGuid] = {
|
||||||
|
spellName = C_Spell.GetSpellName(spellId),
|
||||||
|
spellID = spellId,
|
||||||
|
icon = C_Spell.GetSpellTexture(spellId),
|
||||||
|
startTime = now,
|
||||||
|
endTime = now + durationMs / 1000,
|
||||||
|
duration = durationMs / 1000,
|
||||||
|
isChannel = isChannel,
|
||||||
|
}
|
||||||
|
plate.castUpdate = true -- bypass the throttle so the bar shows now
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif event == "SPELL_FAILED_OTHER" then
|
||||||
|
-- nampower: arg1=casterGuid, arg2=spellId. Clear on interrupt/failure.
|
||||||
|
local casterGuid = arg1
|
||||||
|
if casterGuid and castState[casterGuid] then
|
||||||
|
castState[casterGuid] = nil
|
||||||
|
local plate = plateByGuid[casterGuid]
|
||||||
|
if plate then plate.castUpdate = true 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
|
||||||
@@ -578,6 +652,7 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
end
|
end
|
||||||
|
|
||||||
elseif event == "PLAYER_TARGET_CHANGED" then
|
elseif event == "PLAYER_TARGET_CHANGED" then
|
||||||
|
targetPlateGuid = UnitExists("target") and UnitGUID("target") or nil
|
||||||
-- Flag the target's plate for update
|
-- Flag the target's plate for update
|
||||||
local plate = C_NamePlate.GetNamePlateForUnit("target")
|
local plate = C_NamePlate.GetNamePlateForUnit("target")
|
||||||
if plate and plate.nameplate then
|
if plate and plate.nameplate then
|
||||||
@@ -607,7 +682,7 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
-- PERF: Cache GetTime() once per frame
|
-- PERF: Cache GetTime() once per frame
|
||||||
frameState.now = now
|
frameState.now = now
|
||||||
frameState.hasTarget, frameState.targetGuid = UnitExists("target")
|
frameState.hasTarget, frameState.targetGuid = UnitExists("target")
|
||||||
frameState.hasMouseover = UnitExists("mouseover")
|
frameState.mouseoverGuid = UnitGUID("mouseover")
|
||||||
|
|
||||||
-- propagate events to all nameplates
|
-- propagate events to all nameplates
|
||||||
if this.eventcache then
|
if this.eventcache then
|
||||||
@@ -824,8 +899,7 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
|
|
||||||
RebuildOfftanks()
|
RebuildOfftanks()
|
||||||
|
|
||||||
nameplate:SetWidth(plate_width)
|
nameplate:SetSize(plate_width, plate_height)
|
||||||
nameplate:SetHeight(plate_height)
|
|
||||||
nameplate:SetPoint("TOP", parent, "TOP", 0, 0)
|
nameplate:SetPoint("TOP", parent, "TOP", 0, 0)
|
||||||
|
|
||||||
nameplate.name:SetFont(font, font_size, font_style)
|
nameplate.name:SetFont(font, font_size, font_style)
|
||||||
@@ -854,23 +928,20 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
|
|
||||||
nameplate.guild:SetFont(font, font_size, font_style)
|
nameplate.guild:SetFont(font, font_size, font_style)
|
||||||
|
|
||||||
nameplate.glow:SetWidth(C.nameplates.width + 60)
|
nameplate.glow:SetSize(C.nameplates.width + 60, C.nameplates.heighthealth + 30)
|
||||||
nameplate.glow:SetHeight(C.nameplates.heighthealth + 30)
|
|
||||||
nameplate.glow:SetVertexColor(glowr, glowg, glowb, glowa)
|
nameplate.glow:SetVertexColor(glowr, glowg, glowb, glowa)
|
||||||
|
|
||||||
nameplate.raidicon:ClearAllPoints()
|
nameplate.raidicon:ClearAllPoints()
|
||||||
nameplate.raidicon:SetPoint("BOTTOM", nameplate.health, "TOP", C.nameplates.raidiconoffx, C.nameplates.raidiconoffy)
|
nameplate.raidicon:SetPoint("BOTTOM", nameplate.health, "TOP", C.nameplates.raidiconoffx, C.nameplates.raidiconoffy)
|
||||||
nameplate.level:SetFont(font, font_size, font_style)
|
nameplate.level:SetFont(font, font_size, font_style)
|
||||||
nameplate.raidicon:SetWidth(C.nameplates.raidiconsize)
|
nameplate.raidicon:SetSize(C.nameplates.raidiconsize, C.nameplates.raidiconsize)
|
||||||
nameplate.raidicon:SetHeight(C.nameplates.raidiconsize)
|
|
||||||
|
|
||||||
for i=1,16 do
|
for i=1,16 do
|
||||||
UpdateDebuffConfig(nameplate, i)
|
UpdateDebuffConfig(nameplate, i)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i=1,5 do
|
for i=1,5 do
|
||||||
nameplate.combopoints[i]:SetWidth(combo_size)
|
nameplate.combopoints[i]:SetSize(combo_size, combo_size)
|
||||||
nameplate.combopoints[i]:SetHeight(combo_size)
|
|
||||||
nameplate.combopoints[i]:SetPoint("TOPRIGHT", nameplate.health, "BOTTOMRIGHT", -(i-1)*(combo_size+default_border*3), -default_border*3)
|
nameplate.combopoints[i]:SetPoint("TOPRIGHT", nameplate.health, "BOTTOMRIGHT", -(i-1)*(combo_size+default_border*3), -default_border*3)
|
||||||
CreateBackdrop(nameplate.combopoints[i], default_border)
|
CreateBackdrop(nameplate.combopoints[i], default_border)
|
||||||
end
|
end
|
||||||
@@ -928,7 +999,7 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
end
|
end
|
||||||
|
|
||||||
local target = plate.istarget
|
local target = plate.istarget
|
||||||
local mouseover = UnitExists("mouseover") and plate.original.glow:IsShown() or nil
|
local mouseover = plate.cachedGuid and plate.cachedGuid == frameState.mouseoverGuid or nil
|
||||||
local unitstr = target and "target" or mouseover and "mouseover" or plate.cachedGuid or nil
|
local unitstr = target and "target" or mouseover and "mouseover" or plate.cachedGuid or nil
|
||||||
|
|
||||||
-- resolve player vs npc from plate's own unit so libunitscan can't return
|
-- resolve player vs npc from plate's own unit so libunitscan can't return
|
||||||
@@ -1316,7 +1387,7 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
local update
|
local update
|
||||||
local original = nameplate.original
|
local original = nameplate.original
|
||||||
local name = original.name:GetText()
|
local name = original.name:GetText()
|
||||||
local mouseover = state and state.hasMouseover and original.glow:IsShown() or nil
|
local mouseover = nameplate.cachedGuid and nameplate.cachedGuid == frameState.mouseoverGuid or nil
|
||||||
|
|
||||||
-- trigger queued event update
|
-- trigger queued event update
|
||||||
if hasEventUpdate then
|
if hasEventUpdate then
|
||||||
@@ -1570,7 +1641,7 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
-- Relative 0..duration range to avoid float precision loss with large
|
-- Relative 0..duration range to avoid float precision loss with large
|
||||||
-- absolute timestamps.
|
-- absolute timestamps.
|
||||||
nameplate.castbar:SetMinMaxValues(0, duration)
|
nameplate.castbar:SetMinMaxValues(0, duration)
|
||||||
nameplate.castbar:SetStatusBarColor(strsplit(",", C.appearance.castbar[(isChannel and "channelcolor" or "castbarcolor")]))
|
nameplate.castbar:SetStatusBarColor(GetStringColor(C.appearance.castbar[(isChannel and "channelcolor" or "castbarcolor")]))
|
||||||
if castInfo.icon then
|
if castInfo.icon then
|
||||||
nameplate.castbar.icon.tex:SetTexture(castInfo.icon)
|
nameplate.castbar.icon.tex:SetTexture(castInfo.icon)
|
||||||
nameplate.castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)
|
nameplate.castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)
|
||||||
@@ -1590,20 +1661,17 @@ nameplates:RegisterEvent("UNIT_FLAGS")
|
|||||||
if not nameplate.castbar.isShown then nameplate.castbar.isShown = true; nameplate.castbar:Show() end
|
if not nameplate.castbar.isShown then nameplate.castbar.isShown = true; nameplate.castbar:Show() end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Dedicated frame that updates ONLY the target plate castbar.
|
-- Dedicated frame that updates ONLY the target plate castbar. Unthrottled:
|
||||||
-- Uses nameplates_castbar throttle from libthrottle.
|
-- now that casts are event-driven, this just reads the cache + SetValue, so
|
||||||
|
-- it animates the fill every frame for the smoothest sweep on the bar the
|
||||||
|
-- player watches most. (Non-target plates stay throttled via the central
|
||||||
|
-- loop's nameplates_castbar gate.)
|
||||||
nameplates.castbarFrame = CreateFrame("Frame", nil, UIParent)
|
nameplates.castbarFrame = CreateFrame("Frame", nil, UIParent)
|
||||||
nameplates.castbarFrame:SetScript("OnUpdate", function()
|
nameplates.castbarFrame:SetScript("OnUpdate", function()
|
||||||
if not cfg.showcastbar then return end
|
if not cfg.showcastbar or not targetPlateGuid then return end
|
||||||
local now = GetTime()
|
local nameplate = plateByGuid[targetPlateGuid]
|
||||||
local throttle = pfUI.throttle:Get("nameplates_castbar")
|
if not nameplate then return end
|
||||||
if (this.tick or 0) > now then return end
|
nameplates.UpdateCastbar(nameplate, GetTime())
|
||||||
this.tick = now + throttle
|
|
||||||
|
|
||||||
local frame = C_NamePlate.GetNamePlateForUnit("target")
|
|
||||||
if not frame or not frame.nameplate then return end
|
|
||||||
|
|
||||||
nameplates.UpdateCastbar(frame.nameplate, now)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- set nameplate game settings
|
-- set nameplate game settings
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@ pfUI:RegisterModule("newitem", function ()
|
|||||||
|
|
||||||
pfUI.newitem = {}
|
pfUI.newitem = {}
|
||||||
|
|
||||||
local color = CreateColor(strsplit(",", C.appearance.bags.newitem_color))
|
local r, g, b, a = pfUI.api.GetStringColor(C.appearance.bags.newitem_color)
|
||||||
|
|
||||||
function pfUI.newitem:UpdateSlot(bag, slot)
|
function pfUI.newitem:UpdateSlot(bag, slot)
|
||||||
if bag < 0 or bag > 4 then return end
|
if bag < 0 or bag > 4 then return end
|
||||||
@@ -18,7 +18,7 @@ pfUI:RegisterModule("newitem", function ()
|
|||||||
local glow = frame:CreateTexture(nil, "OVERLAY")
|
local glow = frame:CreateTexture(nil, "OVERLAY")
|
||||||
glow:SetTexture("Interface\\Buttons\\UI-ActionButton-Border")
|
glow:SetTexture("Interface\\Buttons\\UI-ActionButton-Border")
|
||||||
glow:SetBlendMode("ADD")
|
glow:SetBlendMode("ADD")
|
||||||
glow:SetVertexColor(color:GetRGBA())
|
glow:SetVertexColor(r, g, b, a)
|
||||||
glow:SetPoint("CENTER", frame, "CENTER")
|
glow:SetPoint("CENTER", frame, "CENTER")
|
||||||
glow:Hide()
|
glow:Hide()
|
||||||
glow.RefreshSize = function(g)
|
glow.RefreshSize = function(g)
|
||||||
|
|||||||
+44
-26
@@ -23,36 +23,54 @@ pfUI:RegisterModule("tooltip", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if C.tooltip.position == "cursor" then
|
if C.tooltip.position == "cursor" then
|
||||||
|
-- Cursor mode makes the tooltip follow the mouse. The client has no
|
||||||
|
-- mouse-move event, so following means polling GetCursorPosition() via an
|
||||||
|
-- invisible follower frame that the tooltip anchors to. The follower is
|
||||||
|
-- only shown while a tooltip is visible -- an OnUpdate fires only while its
|
||||||
|
-- frame is shown, so the poll stops the moment the tooltip hides instead
|
||||||
|
-- of running forever.
|
||||||
|
local follower, Reposition
|
||||||
|
if C.tooltip.cursoralign ~= "native" then
|
||||||
|
local size = tonumber(C.tooltip.cursoroffset) * 2
|
||||||
|
follower = CreateFrame("Frame", nil, UIParent)
|
||||||
|
follower:SetSize(size, size)
|
||||||
|
follower:Hide()
|
||||||
|
|
||||||
|
Reposition = function()
|
||||||
|
local scale = UIParent:GetScale()
|
||||||
|
local x, y = GetCursorPosition()
|
||||||
|
follower:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x/scale, y/scale)
|
||||||
|
if C.tooltip.cursoralign == "top" then
|
||||||
|
follower:SetWidth(GameTooltip:GetWidth())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
follower:SetScript("OnUpdate", function()
|
||||||
|
-- throttle - cursor following doesn't need to be every frame
|
||||||
|
if (this.tick or 0) > GetTime() then return end
|
||||||
|
this.tick = GetTime() + (pfUI.throttle and pfUI.throttle:Get("tooltip_cursor") or 0.1)
|
||||||
|
Reposition()
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- stop polling as soon as the tooltip is gone
|
||||||
|
pfUI.tooltip:SetScript("OnHide", function() follower:Hide() end)
|
||||||
|
end
|
||||||
|
|
||||||
function _G.GameTooltip_SetDefaultAnchor(tooltip, parent)
|
function _G.GameTooltip_SetDefaultAnchor(tooltip, parent)
|
||||||
tooltip:SetOwner(parent, "ANCHOR_CURSOR")
|
tooltip:SetOwner(parent, "ANCHOR_CURSOR")
|
||||||
if C.tooltip.cursoralign ~= "native" then
|
if not follower then return end
|
||||||
-- create mouse follow frame
|
|
||||||
if not tooltip.cursor then
|
|
||||||
tooltip.cursor = CreateFrame("Frame", nil, UIParent)
|
|
||||||
local size = tonumber(C.tooltip.cursoroffset) * 2
|
|
||||||
tooltip.cursor:SetSize(size, size)
|
|
||||||
tooltip.cursor:SetScript("OnUpdate", function()
|
|
||||||
-- throttle - cursor following doesn't need to be every frame
|
|
||||||
if (this.tick or 0) > GetTime() then return end
|
|
||||||
this.tick = GetTime() + (pfUI.throttle and pfUI.throttle:Get("tooltip_cursor") or 0.1)
|
|
||||||
|
|
||||||
local scale = UIParent:GetScale()
|
-- position the follower right away so the tooltip doesn't flash at a
|
||||||
local x, y = GetCursorPosition()
|
-- stale spot before the first OnUpdate tick
|
||||||
this:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x/scale, y/scale)
|
follower:Show()
|
||||||
if C.tooltip.cursoralign == "top" then
|
Reposition()
|
||||||
tooltip.cursor:SetWidth(tooltip:GetWidth())
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- adjust tooltip to mouse frame
|
if C.tooltip.cursoralign == "top" then
|
||||||
if C.tooltip.cursoralign == "top" then
|
tooltip:SetPoint("BOTTOMLEFT", follower, "TOPLEFT", 0, 0)
|
||||||
tooltip:SetPoint("BOTTOMLEFT", tooltip.cursor, "TOPLEFT", 0, 0)
|
elseif C.tooltip.cursoralign == "left" then
|
||||||
elseif C.tooltip.cursoralign == "left" then
|
tooltip:SetPoint("BOTTOMRIGHT", follower, "LEFT", 0, 0)
|
||||||
tooltip:SetPoint("BOTTOMRIGHT", tooltip.cursor, "LEFT", 0, 0)
|
elseif C.tooltip.cursoralign == "right" then
|
||||||
elseif C.tooltip.cursoralign == "right" then
|
tooltip:SetPoint("BOTTOMLEFT", follower, "RIGHT", 0, 0)
|
||||||
tooltip:SetPoint("BOTTOMLEFT", tooltip.cursor, "RIGHT", 0, 0)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user