mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-21 23:26:56 +00:00
ClassicAPI flavor TOCs, and drop the multi-client scaffolding (#53)
* nameplates: source totem icons from UnitCreatedBySpell
Read the totem's icon from the totem-drop spell (UnitCreatedBySpell +
GetSpellTexture) instead of the self-aura at index 1 plus a
UNIT_SPELLCAST_SUCCEEDED capture for active totems. The drop spell is a
broadcast descriptor field present for every summoned unit in range, so
it resolves immediately for passive and active totems alike and gives the
totem's own icon rather than the attack-spell proxy. Drops the
UNIT_SPELLCAST_SUCCEEDED registration and handler.
Re-read the spell each render and key the cached texture on the spell id
so an in-place totem swap (same unit, new drop spell -- no plate re-add)
refreshes the icon without needing the plate to leave and re-enter view.
* CAPI min bumped to 1.13.1
* Gracefully disable pfUI when ClassicAPI is missing
Add API_Check.lua as the first TOC entry. When the ClassicAPI DLL is
absent or below the minimum version it sets pfUI_disabled and stands up
an inert stub so the rest of the addon no-ops instead of flooding load
errors: modules and skins register their bodies into no-ops, and the
setfenv'd api/lib files run inside an environment where CreateFrame and
any missing global resolve to a null object -- so no real frames or live
handlers are created and missing API calls just return null. pfUI.lua
bails early on pfUI_disabled.
* auras: scan through GetAuraSlots instead of by-index loops
Every aura scan loop (unit frame buffs/debuffs, dispel indicators, buff and
custom indicators, player buff frame, buffwatch bars, tooltip buff row) now
enumerates a unit's auras once with C_UnitAuras.GetAuraSlots and reads each
aura by slot id via the positional C_UnitAuras.UnitAuraBySlot. The by-index
getters re-walk the aura array from slot 0 on every call, so a per-button
loop over them was quadratic in the aura count; one enumeration plus a
by-slot read per aura is linear.
pfUI.api.ScanAuraSlots(unit, filter, buf, max) wraps GetAuraSlots' fill-a-
table form (table as the 5th argument) so no vararg Lua frame is involved:
Lua 5.0 allocates an `arg` table for every vararg call, which showed up as
nameplate OnUpdate/OnEvent memory growth in the first cut of this change.
Single by-index reads in tooltip and click handlers are unchanged (one call
each, and SetUnitAura takes the same index).
Requires the ClassicAPI build that adds GetAuraSlots' fill form; on an older
DLL the 5th argument is ignored and ScanAuraSlots would read the first slot
id as the count.
* Show Faction/Race icons in chat
* Load pfUI through ClassicAPI's flavor TOCs
ClassicAPI redirects the read of pfUI\pfUI.toc to a flavored file whenever
the DLL is installed, so which TOC the client opens already answers whether
ClassicAPI is there. Split the manifest three ways and let that do the work:
pfUI.toc fallback, reached only when ClassicAPI is missing;
loads API_Check.lua and nothing else
pfUI_ClassicAPI.toc full addon, every non-Turtle client
pfUI_Turtle.toc full addon plus init\turtle.xml, on Turtle
The fallback TOC declares no SavedVariables. It used to, while API_Check.lua
reset pfUI_profiles to an empty table on the disabled path -- which truncated
the player's profiles on logout.
With the missing-DLL case handled by TOC selection, API_Check.lua drops the
null object stub that kept the other ~140 files quiet, along with
pfUI_disabled and the now unreachable early return in pfUI.lua. It keeps the
version gate, which still matters: the flavor redirect landed in ClassicAPI
v1.11.0, below the v1.13.1 pfUI needs, so an old DLL still gets served a
flavor TOC. pfUI.lua also loses a verbatim duplicate of the whole check.
Turtle-only files move to init\turtle.xml: modules\turtle-wow.lua (its
TURTLE_WOW_VERSION guard is now redundant) and the lft, turtle_shop,
barbershop, transmog and ebc skins. turtle-wow registers last instead of
75th of 84; the only ordering it relies on is pfUI.chat, registered 8th.
pfSellData moves to env\selldata.lua, listed only in pfUI_ClassicAPI.toc,
since turtle-wow.lua replaces the table wholesale on Turtle. env\tables.lua
keeps an empty declaration so sellvalue.lua has something to index when the
turtle-wow module is disabled.
The release workflow pinned PFUI_CLASSIC_API_LATEST in pfUI.lua, which has
not held that constant since it moved to API_Check.lua, so the pin was
silently doing nothing. It also switches to brues-code/packager@vCAPI, which
recognizes the _ClassicAPI and _Turtle suffixes and applies the TOC build
type filters to them.
* Split the vendor price tables into their own manifests
Turtle's pfSellData moves out of modules\turtle-wow.lua into
env\selldata_turtle.lua, matching env\selldata.lua for the stock list, and
each is pulled in by the manifest for its client: init\stock.xml from
pfUI_ClassicAPI.toc, init\turtle.xml from pfUI_Turtle.toc. Either way it
loads after init\env.xml and replaces the empty pfSellData declared there.
Turtle's prices used to be assigned inside the turtle-wow module body, which
put them on pfUI.env and skipped them entirely when that module was
disabled. At file scope they land on _G and apply either way.
* Drop the vanilla compat layer
compat\vanilla.lua named the handful of things that differed between clients
back when pfUI targeted several. Only one client remains, so every constant
had exactly one value. Inline each at its use site and delete the file,
init\compat.xml, and both TOC entries.
COOLDOWN_FRAME_TYPE -> "Model"
LOOT_BUTTON_FRAME_TYPE -> "LootButton"
MINIMAP_TRACKING_FRAME -> _G.MiniMapTrackingFrame
FRIENDS_NAME_LOCATION -> "ButtonTextNameLocation"
EVENTS_MINIMAP_ZONE_UPDATE -> the event list, in panel.lua
MICRO_BUTTONS -> a local in panel.lua
NAMEPLATE_OBJECTORDER -> a local in nameplates.lua
ACTIONBAR_SECURE_TEMPLATE_BAR/_BUTTON -> nil, so the argument goes away
NAMEPLATE_FRAMETYPE and PLAYER_BUFF_START_ID had no readers left.
RunMacroText moves to pfUI.lua. compat\vanilla.lua was setfenv'd into the
pfUI environment, so the function only ever existed on pfUI.env; at file
scope it lands on _G as a real export instead. Nothing in pfUI calls it, and
ClassicAPI neither defines nor looks for a RunMacroText global -- it does
the same throwaway edit box natively in src/macro/Execute.cpp and only
defers to a global RunMacro.
* bump CAPI min to 11303
* auras: uncap the self-debuff tooltip lookup
With selfdebuff on, the displayed debuff list is PLAYER-filtered while
GameTooltip:SetUnitAura indexes the unfiltered HARMFUL list, so both
handlers map one to the other by matching name + sourceGUID. That mapping
scanned slots 1..16 only.
The unfiltered harmful list is not capped at 16. Once a unit's 16 debuff
slots are full the server parks further debuffs in buff slots, and
C_UnitAuras classifies by the aura's polarity flag rather than its slot
range, so it reports those as harmful too -- verified live at 18 harmful on
a 20-aura target. Past the sixteenth the lookup found nothing and fell
through to the raw filtered index, opening the wrong tooltip or none.
Both now enumerate however many harmful auras the unit actually has, via
ScanAuraSlots, which also drops the per-index rescan the by-index accessor
was doing. Each handler gets its own slot buffer: OnEnter can fire while a
refresh is showing/hiding frames under the cursor, so sharing the refresh
buffer could clobber a scan mid-walk.
The nameplate module still collects at most 16 debuffs per plate. That one
is a display cap matching its 16 configured icon frames, not an aura-count
assumption, so it is left alone.
* bump CAPI min to 11304
This commit is contained in:
@@ -23,12 +23,12 @@ jobs:
|
||||
IFS=. read -r MAJOR MINOR PATCH <<<"$LATEST"
|
||||
PACKED=$((MAJOR * 10000 + MINOR * 100 + PATCH))
|
||||
echo "Pinning PFUI_CLASSIC_API_LATEST to $LATEST ($PACKED)"
|
||||
sed -i "s/^\([[:space:]]*\)local PFUI_CLASSIC_API_LATEST = .*/\1local PFUI_CLASSIC_API_LATEST = $PACKED/" pfUI.lua
|
||||
grep 'local PFUI_CLASSIC_API_' pfUI.lua
|
||||
sed -i "s/^\([[:space:]]*\)local PFUI_CLASSIC_API_LATEST = .*/\1local PFUI_CLASSIC_API_LATEST = $PACKED/" API_Check.lua
|
||||
grep 'local PFUI_CLASSIC_API_' API_Check.lua
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Package and release to GitHub
|
||||
uses: BigWigsMods/packager@v2
|
||||
uses: brues-code/packager@vCAPI
|
||||
env:
|
||||
GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
do
|
||||
-- ClassicAPI dependency gate.
|
||||
--
|
||||
-- Which TOC the client opened already answers "is ClassicAPI here?". Whenever
|
||||
-- the DLL is loaded it redirects the read of `pfUI\pfUI.toc` to
|
||||
-- `pfUI_Turtle.toc` (Turtle clients) or `pfUI_ClassicAPI.toc` (everything
|
||||
-- else). Reaching this file from the plain `pfUI.toc` therefore means
|
||||
-- ClassicAPI is absent -- and that TOC deliberately loads nothing but this
|
||||
-- file, so there is nothing to disable, only a notice to show.
|
||||
--
|
||||
-- The flavor TOCs still need a version gate of their own: the redirect has
|
||||
-- existed since ClassicAPI v1.11.0, well below the API surface pfUI relies
|
||||
-- on. There pfUI does load, and will throw wherever it reaches for something
|
||||
-- the installed DLL doesn't have yet -- the popup names the cause so those
|
||||
-- errors aren't a mystery.
|
||||
local PFUI_CLASSIC_API_MIN = 11304 -- (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
|
||||
|
||||
local headline, detail
|
||||
if not CLASSIC_API_VERSION then
|
||||
headline = "|cff33ffccpf|cffffffffUI|r has been disabled."
|
||||
detail = "The ClassicAPI DLL isn't loaded. Download the latest release from:"
|
||||
elseif CLASSIC_API_VERSION < PFUI_CLASSIC_API_MIN then
|
||||
headline = "|cff33ffccpf|cffffffffUI|r cannot run on this ClassicAPI."
|
||||
detail = "ClassicAPI " .. FormatVersion(PFUI_CLASSIC_API_MIN) .. " or newer is required -- any errors alongside this one are the APIs it is missing. Download the latest release from:"
|
||||
end
|
||||
|
||||
if detail then
|
||||
local function ShowRequiredPopup()
|
||||
StaticPopupDialogs["PFUI_CLASSICAPI_REQUIRED"] = {
|
||||
text = headline .. "\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(
|
||||
headline .. " " .. 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
|
||||
+59
@@ -204,6 +204,26 @@ function pfUI.api.UnitHasBuff(unit, name)
|
||||
return C_UnitAuras.GetAuraDataBySpellName(unit, name, "HELPFUL") ~= nil or nil
|
||||
end
|
||||
|
||||
-- [ ScanAuraSlots ]
|
||||
-- Fills `buf` with the slot ids of the auras on `unit` that match `filter` and
|
||||
-- returns how many (buf[1..n]; entries past n are cleared), so a module can
|
||||
-- keep one buffer and refill it every refresh. Read each aura with
|
||||
-- C_UnitAuras.UnitAuraBySlot(unit, buf[i]) (positional, no table) or
|
||||
-- GetAuraDataBySlot. One enumeration walks the aura array once, where a
|
||||
-- by-index loop (UnitAura(unit, i)) re-walks it from the start for every i.
|
||||
-- Uses GetAuraSlots' fill-a-table form (table as the 5th argument) instead of
|
||||
-- its vararg return: Lua 5.0 builds an `arg` table for every vararg call, so
|
||||
-- collecting the returns in a Lua helper would allocate once per scan.
|
||||
-- unit [string] unit token
|
||||
-- filter [string] aura filter ("HELPFUL", "HARMFUL|PLAYER", ...)
|
||||
-- buf [table] reusable buffer, filled in place
|
||||
-- max [number] optional cap on the slot count (nil = all)
|
||||
-- return: [number] count of slot ids written to buf
|
||||
function pfUI.api.ScanAuraSlots(unit, filter, buf, max)
|
||||
local _, n = C_UnitAuras.GetAuraSlots(unit, filter, max, nil, buf)
|
||||
return n
|
||||
end
|
||||
|
||||
-- [ IsPlayerGuid ]
|
||||
-- Returns whether a GUID or unit token refers to the local player.
|
||||
-- guid [string] A unit GUID (or unitID) to test.
|
||||
@@ -242,6 +262,45 @@ function pfUI.api.GetUnitColor(unitstr)
|
||||
return classColor:GenerateHexColorMarkup(), classColor:GetRGB()
|
||||
end
|
||||
|
||||
-- [ GetRaceIcon ]
|
||||
-- Builds an inline race icon texture from the shared races atlas.
|
||||
-- 'raceKey' [string] englishRace key (e.g. "NightElf")
|
||||
-- 'sex' [int] unit sex (3 = female)
|
||||
-- return: [string] inline texture escape, or an empty string
|
||||
function pfUI.api.GetRaceIcon(raceKey, sex)
|
||||
if not raceKey then return "" end
|
||||
local gender = sex == 3 and "FEMALE" or "MALE"
|
||||
local coords = RACE_ICON_TCOORDS[strupper(raceKey) .. "_" .. gender]
|
||||
if not coords then return "" end
|
||||
return string.format(
|
||||
"|TInterface\\Glues\\CharacterCreate\\UI-CharacterCreate-Races:0:0:0:0:512:512:%d:%d:%d:%d|t",
|
||||
coords[1] * 512, coords[2] * 512, coords[3] * 512, coords[4] * 512)
|
||||
end
|
||||
|
||||
-- inline faction emblems (cropped from the target-frame PvP banners)
|
||||
local FACTION_ICON = {
|
||||
Alliance = "|TInterface\\TargetingFrame\\UI-PVP-Alliance:0:0:0:0:64:64:5:37:3:35|t",
|
||||
Horde = "|TInterface\\TargetingFrame\\UI-PVP-Horde:0:0:0:0:64:64:5:37:3:35|t",
|
||||
}
|
||||
|
||||
-- [ GetFactionIcon ]
|
||||
-- Resolves an inline faction emblem from the englishRace key stored in L["race"].
|
||||
-- 'raceKey' [string] englishRace key (e.g. "Orc")
|
||||
-- return: [string] inline texture escape, or an empty string
|
||||
function pfUI.api.GetFactionIcon(raceKey)
|
||||
local info = raceKey and L["race"][raceKey]
|
||||
if not info then return "" end
|
||||
return FACTION_ICON[info.faction] or ""
|
||||
end
|
||||
|
||||
-- [ GetPlayerRaceIcons ]
|
||||
-- Returns the faction and race emblems of the player character.
|
||||
-- return: [string] both inline textures, or an empty string
|
||||
function pfUI.api.GetPlayerRaceIcons()
|
||||
local _, raceKey = UnitRace("player")
|
||||
return pfUI.api.GetFactionIcon(raceKey) .. pfUI.api.GetRaceIcon(raceKey, UnitSex("player"))
|
||||
end
|
||||
|
||||
-- [ strvertical ]
|
||||
-- Creates vertical text using linebreaks. Multibyte char friendly.
|
||||
-- 'str' [string] String to columnize.
|
||||
|
||||
@@ -817,6 +817,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("chat", "text", "playerlinks", "1")
|
||||
pfUI:UpdateConfig("chat", "text", "detecturl", "1")
|
||||
pfUI:UpdateConfig("chat", "text", "classcolor", "1")
|
||||
pfUI:UpdateConfig("chat", "text", "playericons", "0")
|
||||
pfUI:UpdateConfig("chat", "text", "whosearchunknown", "0")
|
||||
pfUI:UpdateConfig("chat", "text", "playerlevel", "0")
|
||||
pfUI:UpdateConfig("chat", "left", "width", "380")
|
||||
|
||||
+51
-30
@@ -4,6 +4,17 @@ setfenv(1, pfUI:GetEnvironment())
|
||||
pfUI.uf = CreateFrame("Frame", nil, UIParent)
|
||||
pfUI.uf.frames = {}
|
||||
|
||||
-- Reusable buffer for C_UnitAuras.GetAuraSlots slot ids (filled by
|
||||
-- ScanAuraSlots, api.lua). Each aura scan in RefreshUnit fills it once, then
|
||||
-- reads every aura by slot id: one array walk per scan instead of one per index.
|
||||
-- Scans run back to back and consume the buffer before the next refill.
|
||||
local auraSlots = {}
|
||||
|
||||
-- Separate buffer for the tooltip handlers. They run from OnEnter, which can
|
||||
-- fire while RefreshUnit is showing/hiding icons under the cursor, so they must
|
||||
-- not share the refresh buffer.
|
||||
local tooltipSlots = {}
|
||||
|
||||
-- ============================================================================
|
||||
-- GUID-based Roster Tracking for Smart Updates
|
||||
-- Only updates frames where the unit actually changed, not ALL 40 frames
|
||||
@@ -88,16 +99,21 @@ local function DebuffOnEnter()
|
||||
local parent = this:GetParent()
|
||||
|
||||
-- selfdebuff filters the displayed list to player-cast harmful auras, but
|
||||
-- SetUnitAura's index has to be into the engine's full HARMFUL list. Look
|
||||
-- up the displayed aura via the PLAYER filter, then scan engine slots for
|
||||
-- one whose name + sourceGUID match.
|
||||
-- SetUnitAura's index has to be into the unfiltered HARMFUL list. Look up
|
||||
-- the displayed aura via the PLAYER filter, then find its position in the
|
||||
-- unfiltered list by name + sourceGUID.
|
||||
--
|
||||
-- The unfiltered list is NOT capped at 16: once a unit's 16 debuff slots
|
||||
-- are full the server parks further debuffs in buff slots, and C_UnitAuras
|
||||
-- reports those as harmful too. So enumerate however many the unit has.
|
||||
if parent.config and parent.config.selfdebuff == "1" then
|
||||
local ownAura = C_UnitAuras.GetAuraDataByIndex(unitstr, this.id, "HARMFUL|PLAYER")
|
||||
if ownAura then
|
||||
for gameSlot = 1, 16 do
|
||||
local check = C_UnitAuras.GetDebuffDataByIndex(unitstr, gameSlot)
|
||||
local n = ScanAuraSlots(unitstr, "HARMFUL", tooltipSlots)
|
||||
for i = 1, n do
|
||||
local check = C_UnitAuras.GetAuraDataBySlot(unitstr, tooltipSlots[i])
|
||||
if check and check.name == ownAura.name and check.sourceGUID == ownAura.sourceGUID then
|
||||
GameTooltip:SetUnitAura(unitstr, gameSlot, "HARMFUL")
|
||||
GameTooltip:SetUnitAura(unitstr, i, "HARMFUL")
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -761,7 +777,7 @@ function pfUI.uf:UpdateConfig()
|
||||
if not f.buffs[i].cd then
|
||||
if cooldown_anim == 1 then
|
||||
-- Animation enabled: Use Model frame with CooldownFrameTemplate
|
||||
f.buffs[i].cd = CreateFrame(COOLDOWN_FRAME_TYPE, f.buffs[i]:GetName() .. "Cooldown", f.buffs[i], "CooldownFrameTemplate")
|
||||
f.buffs[i].cd = CreateFrame("Model", f.buffs[i]:GetName() .. "Cooldown", f.buffs[i], "CooldownFrameTemplate")
|
||||
else
|
||||
-- Animation disabled: Use regular Frame with dummy functions
|
||||
f.buffs[i].cd = CreateFrame("Frame", f.buffs[i]:GetName() .. "Cooldown", f.buffs[i])
|
||||
@@ -834,7 +850,7 @@ function pfUI.uf:UpdateConfig()
|
||||
if not f.debuffs[i].cd then
|
||||
if cooldown_anim == 1 then
|
||||
-- Animation enabled: Use Model frame with CooldownFrameTemplate
|
||||
f.debuffs[i].cd = CreateFrame(COOLDOWN_FRAME_TYPE, f.debuffs[i]:GetName() .. "Cooldown", f.debuffs[i], "CooldownFrameTemplate")
|
||||
f.debuffs[i].cd = CreateFrame("Model", f.debuffs[i]:GetName() .. "Cooldown", f.debuffs[i], "CooldownFrameTemplate")
|
||||
else
|
||||
-- Animation disabled: Use regular Frame with dummy functions
|
||||
f.debuffs[i].cd = CreateFrame("Frame", f.debuffs[i]:GetName() .. "Cooldown", f.debuffs[i])
|
||||
@@ -1635,11 +1651,13 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
|
||||
-- buffs
|
||||
if unit.buffs and ( component == "all" or component == "aura" ) then
|
||||
-- one GetAuraSlots enumeration per refresh, then a positional read per
|
||||
-- slot id: allocates nothing and never re-walks the aura array per icon
|
||||
ScanAuraSlots(unitstr, "HELPFUL", auraSlots, unit.config.bufflimit)
|
||||
for i=1, unit.config.bufflimit do
|
||||
if not unit.buffs[i] then break end
|
||||
|
||||
-- positional UnitBuff allocates nothing (vs a table per icon per refresh)
|
||||
local name, icon, count, _, duration, expirationTime, _, _, _, spellId = C_UnitAuras.UnitBuff(unitstr, i)
|
||||
local name, icon, count, _, duration, expirationTime, _, _, _, spellId = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
|
||||
if name then
|
||||
unit.buffs[i].texture:SetTexture(icon)
|
||||
@@ -1723,6 +1741,13 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
reposition = true
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- effects on you). One GetAuraSlots enumeration per refresh; the i-th slot
|
||||
-- is the i-th aura of the filtered list, so `i` stays the tooltip index.
|
||||
local filter = (unit.label ~= "player" and selfdebuff == "1") and "HARMFUL|PLAYER" or "HARMFUL"
|
||||
ScanAuraSlots(unitstr, filter, auraSlots, unit.config.debufflimit)
|
||||
|
||||
for i=1, unit.config.debufflimit do
|
||||
if not unit.debuffs[i] then break end
|
||||
|
||||
@@ -1739,12 +1764,8 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
invert_h * ((row+buffrow)*(multiply*default_border + unit.config.debuffsize + 1) + (multiply*default_border + 1)))
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- effects on you).
|
||||
-- positional UnitDebuff allocates nothing; PLAYER predicate honored for selfdebuff
|
||||
local filter = (unit.label ~= "player" and selfdebuff == "1") and "PLAYER" or nil
|
||||
local name, icon, count, dispelType, duration, expirationTime = C_UnitAuras.UnitDebuff(unitstr, i, filter)
|
||||
-- positional read by slot id allocates nothing
|
||||
local name, icon, count, dispelType, duration, expirationTime = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if name then
|
||||
texture, stacks, dtype = icon, count, dispelType
|
||||
else
|
||||
@@ -1834,8 +1855,9 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
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)
|
||||
local n = ScanAuraSlots(unitstr, "HARMFUL", auraSlots)
|
||||
for i=1,n do
|
||||
local name, _, _, dispelType = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if name and dispelType and dispelType ~= "" then present[dispelType] = true end
|
||||
end
|
||||
|
||||
@@ -1925,9 +1947,9 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
|
||||
local pos = 1
|
||||
if table.getn(unit.indicators) > 0 then
|
||||
local i = 1
|
||||
while true do
|
||||
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitBuff(unitstr, i)
|
||||
local n = ScanAuraSlots(unitstr, "HELPFUL", auraSlots)
|
||||
for i=1,n do
|
||||
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if not name then break end
|
||||
local texLower = string.lower(icon)
|
||||
local timeleft = expirationTime > 0 and (expirationTime - GetTime()) or nil
|
||||
@@ -1948,14 +1970,13 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
break
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
if table.getn(unit.indicator_custom) > 0 then
|
||||
local ai = 1
|
||||
while true do
|
||||
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitBuff(unitstr, ai)
|
||||
local n = ScanAuraSlots(unitstr, "HELPFUL", auraSlots)
|
||||
for i=1,n do
|
||||
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if not name then break end
|
||||
local timeleft = expirationTime > 0 and (expirationTime - GetTime()) or nil
|
||||
local lowerName = string.lower(name)
|
||||
@@ -1966,12 +1987,12 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
break
|
||||
end
|
||||
end
|
||||
ai = ai + 1
|
||||
end
|
||||
|
||||
local debuffFilter = unit.config.selfdebuff == "1" and "PLAYER" or nil
|
||||
for i=1,16 do -- scan for custom debuffs
|
||||
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitDebuff(unitstr, i, debuffFilter)
|
||||
local debuffFilter = unit.config.selfdebuff == "1" and "HARMFUL|PLAYER" or "HARMFUL"
|
||||
n = ScanAuraSlots(unitstr, debuffFilter, auraSlots)
|
||||
for i=1,n do -- scan for custom debuffs
|
||||
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if name then
|
||||
local timeleft = expirationTime > 0 and (expirationTime - GetTime()) or nil
|
||||
for _, filter in pairs(unit.indicator_custom) do
|
||||
@@ -2233,7 +2254,7 @@ function pfUI.uf:AddIcon(frame, pos, icon, timeleft, stacks, start, duration)
|
||||
-- Check if parent frame has cooldown animation enabled
|
||||
local parent_cooldown_anim = frame.config and tonumber(frame.config.cooldown_anim) or 1
|
||||
if parent_cooldown_anim == 1 then
|
||||
frame.icon[pos].cd = CreateFrame(COOLDOWN_FRAME_TYPE, nil, frame.icon[pos])
|
||||
frame.icon[pos].cd = CreateFrame("Model", nil, frame.icon[pos])
|
||||
else
|
||||
frame.icon[pos].cd = CreateFrame("Frame", nil, frame.icon[pos])
|
||||
frame.icon[pos].cd.AdvanceTime = DoNothing
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
-- load pfUI environment
|
||||
setfenv(1, pfUI:GetEnvironment())
|
||||
|
||||
-- [[ Constants ]]--
|
||||
EVENTS_MINIMAP_ZONE_UPDATE = {"PLAYER_ENTERING_WORLD", "MINIMAP_ZONE_CHANGED"}
|
||||
|
||||
MICRO_BUTTONS = {
|
||||
'CharacterMicroButton', 'SpellbookMicroButton', 'TalentMicroButton',
|
||||
'QuestLogMicroButton', 'SocialsMicroButton', 'WorldMapMicroButton',
|
||||
'MainMenuMicroButton', 'HelpMicroButton',
|
||||
}
|
||||
|
||||
NAMEPLATE_OBJECTORDER = { "border", "glow", "name", "level", "levelicon", "raidicon" }
|
||||
|
||||
NAMEPLATE_FRAMETYPE = "Button"
|
||||
|
||||
MINIMAP_TRACKING_FRAME = _G.MiniMapTrackingFrame
|
||||
|
||||
FRIENDS_NAME_LOCATION = "ButtonTextNameLocation"
|
||||
|
||||
COOLDOWN_FRAME_TYPE = "Model"
|
||||
LOOT_BUTTON_FRAME_TYPE = "LootButton"
|
||||
|
||||
PLAYER_BUFF_START_ID = -1
|
||||
|
||||
ACTIONBAR_SECURE_TEMPLATE_BAR = nil
|
||||
ACTIONBAR_SECURE_TEMPLATE_BUTTON = nil
|
||||
|
||||
--[[ Vanilla API Extensions ]]--
|
||||
|
||||
do -- RunMacroText
|
||||
local obj = { ["GetText"] = function(self) return self.text end }
|
||||
obj = setmetatable(obj, {__index = function(tab,key)
|
||||
local value = function() return end
|
||||
rawset(tab,key,value)
|
||||
return value
|
||||
end})
|
||||
|
||||
function RunMacroText(text)
|
||||
obj.text = text
|
||||
ChatEdit_ParseText(obj, 1)
|
||||
end
|
||||
end
|
||||
Vendored
-2358
File diff suppressed because it is too large
Load Diff
Vendored
+2377
File diff suppressed because it is too large
Load Diff
Vendored
+2991
File diff suppressed because it is too large
Load Diff
@@ -72,7 +72,6 @@
|
||||
<Include file="..\modules\totems.lua"/>
|
||||
<Include file="..\modules\macrotweak.lua"/>
|
||||
<Include file="..\modules\macroicons.lua"/>
|
||||
<Include file="..\modules\turtle-wow.lua"/>
|
||||
<Include file="..\modules\superwow.lua"/>
|
||||
<Include file="..\modules\innervatecall.lua"/>
|
||||
<Include file="..\modules\nampower.lua"/>
|
||||
|
||||
+1
-7
@@ -35,12 +35,6 @@
|
||||
<Include file="..\skins\blizzard\tooltips.lua"/>
|
||||
<Include file="..\skins\blizzard\tabard.lua"/>
|
||||
<Include file="..\skins\blizzard\itemtext.lua"/>
|
||||
<Include file="..\skins\blizzard\lft.lua"/>
|
||||
<Include file="..\skins\blizzard\turtle_shop.lua"/>
|
||||
|
||||
<!-- Turtle WoW -->
|
||||
<Include file="..\skins\blizzard\barbershop.lua"/>
|
||||
<Include file="..\skins\blizzard\transmog.lua"/>
|
||||
<Include file="..\skins\blizzard\ebc.lua"/>
|
||||
|
||||
<!-- Turtle WoW skins live in init\turtle.xml (pfUI_Turtle.toc only). -->
|
||||
</Ui>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Include file="..\compat\vanilla.lua"/>
|
||||
<Include file="..\env\tables_stock.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,14 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<!-- Turtle WoW only: pulled in by pfUI_Turtle.toc, which ClassicAPI selects
|
||||
when it detects a Turtle client. Everything in here targets frames that
|
||||
only a Turtle client ever creates. -->
|
||||
<Include file="..\env\tables_turtle.lua"/>
|
||||
|
||||
<Include file="..\skins\blizzard\lft.lua"/>
|
||||
<Include file="..\skins\blizzard\turtle_shop.lua"/>
|
||||
<Include file="..\skins\blizzard\barbershop.lua"/>
|
||||
<Include file="..\skins\blizzard\transmog.lua"/>
|
||||
<Include file="..\skins\blizzard\ebc.lua"/>
|
||||
|
||||
<Include file="..\modules\turtle-wow.lua"/>
|
||||
</Ui>
|
||||
@@ -1016,7 +1016,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
local id = (bar-1)*12+button
|
||||
local exists = _G[button_name] and true or nil
|
||||
local f = _G[button_name] or CreateFrame("Button", button_name, parent, ACTIONBAR_SECURE_TEMPLATE_BUTTON)
|
||||
local f = _G[button_name] or CreateFrame("Button", button_name, parent)
|
||||
|
||||
-- no button available, create a new one
|
||||
if not exists then
|
||||
@@ -1042,7 +1042,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
f.slot = id
|
||||
|
||||
-- cooldown
|
||||
f.cd = CreateFrame(COOLDOWN_FRAME_TYPE, f:GetName() .. "Cooldown", f, "CooldownFrameTemplate")
|
||||
f.cd = CreateFrame("Model", f:GetName() .. "Cooldown", f, "CooldownFrameTemplate")
|
||||
f.cd.pfCooldownStyleAnimation = 1
|
||||
f.cd.pfCooldownType = "NOGCD"
|
||||
f.cd.pfCooldownSize = cd_size
|
||||
@@ -1233,7 +1233,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
-- create frame
|
||||
local init = not bars[i]
|
||||
bars[i] = bars[i] or CreateFrame("Frame", "pfActionBar" .. barnames[i], UIParent, ACTIONBAR_SECURE_TEMPLATE_BAR)
|
||||
bars[i] = bars[i] or CreateFrame("Frame", "pfActionBar" .. barnames[i], UIParent)
|
||||
bars[i]:SetID(i)
|
||||
|
||||
-- autohide
|
||||
|
||||
+1
-1
@@ -396,7 +396,7 @@ pfUI:RegisterModule("bags", function ()
|
||||
if tpl == "BankItemButtonGenericTemplate" then
|
||||
local bankslot = pfUI.bags[bag].slots[slot].frame
|
||||
local name = "pfBag" .. bag .. "item" .. slot .. "Cooldown"
|
||||
bankslot.cd = CreateFrame(COOLDOWN_FRAME_TYPE, name, bankslot, "CooldownFrameTemplate")
|
||||
bankslot.cd = CreateFrame("Model", name, bankslot, "CooldownFrameTemplate")
|
||||
bankslot.cd:SetAllPoints(bankslot)
|
||||
bankslot.cd.pfCooldownStyleAnimation = 1
|
||||
bankslot.cd.pfCooldownType = "ALL"
|
||||
|
||||
+16
-1
@@ -7,6 +7,15 @@ pfUI:RegisterModule("buff", function ()
|
||||
|
||||
local br, bg, bb, ba = GetStringColor(pfUI_config.appearance.border.color)
|
||||
|
||||
-- Player aura slot ids, enumerated once per refresh pass (ScanPlayerAuraSlots)
|
||||
-- and read per button by its aura index: one GetAuraSlots walk per range
|
||||
-- instead of a by-index walk per button.
|
||||
local helpfulSlots, harmfulSlots = {}, {}
|
||||
local function ScanPlayerAuraSlots()
|
||||
ScanAuraSlots("player", "HELPFUL", helpfulSlots, 32)
|
||||
ScanAuraSlots("player", "HARMFUL", harmfulSlots, 16)
|
||||
end
|
||||
|
||||
local function RefreshBuffButton(buff)
|
||||
if buff.btype == "HELPFUL" then
|
||||
if C.buffs.separateweapons == "1" then
|
||||
@@ -23,7 +32,8 @@ pfUI:RegisterModule("buff", function ()
|
||||
CreateBackdropShadow(buff)
|
||||
end
|
||||
|
||||
local name, icon, count, dispelType, _, expirationTime, _, _, _, spellId = C_UnitAuras.UnitAura("player", buff.id, buff.btype)
|
||||
local slots = buff.btype == "HELPFUL" and helpfulSlots or harmfulSlots
|
||||
local name, icon, count, dispelType, _, expirationTime, _, _, _, spellId = C_UnitAuras.UnitAuraBySlot("player", slots[buff.id])
|
||||
|
||||
--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
|
||||
@@ -166,6 +176,8 @@ pfUI:RegisterModule("buff", function ()
|
||||
pfUI.buff.wepbuffs.count = 0
|
||||
end
|
||||
|
||||
ScanPlayerAuraSlots()
|
||||
|
||||
for i=1,32 do
|
||||
RefreshBuffButton(pfUI.buff.buffs.buttons[i])
|
||||
end
|
||||
@@ -246,6 +258,9 @@ pfUI:RegisterModule("buff", function ()
|
||||
end
|
||||
end)
|
||||
|
||||
-- CreateBuffButton refreshes each new button from the slot buffers
|
||||
ScanPlayerAuraSlots()
|
||||
|
||||
-- Weapon Buffs
|
||||
pfUI.buff.wepbuffs = CreateFrame("Frame", "pfWepBuffFrame", UIParent)
|
||||
pfUI.buff.wepbuffs.count = 0
|
||||
|
||||
+28
-10
@@ -73,9 +73,16 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
return anchor
|
||||
end
|
||||
|
||||
local function GetBuffData(unit, id, type, selfdebuff)
|
||||
local filter = (selfdebuff and type == "HARMFUL") and "HARMFUL|PLAYER" or type
|
||||
local name, icon, count, dispelType, _, expirationTime = C_UnitAuras.UnitAura(unit, id, filter)
|
||||
-- reusable GetAuraSlots buffer, filled once per RefreshBuffBarFrame
|
||||
local auraSlots = {}
|
||||
|
||||
-- Separate buffer for the tooltip handler: OnEnter can fire while a refresh
|
||||
-- is showing/hiding bars under the cursor, so it must not share the above.
|
||||
local tooltipSlots = {}
|
||||
|
||||
-- Reads one aura by the slot id GetAuraSlots returned (nil slot -> nil).
|
||||
local function GetBuffData(unit, slot)
|
||||
local name, icon, count, dispelType, _, expirationTime = C_UnitAuras.UnitAuraBySlot(unit, slot)
|
||||
if not name then return end
|
||||
local remaining = expirationTime > 0 and (expirationTime - GetTime()) or 0
|
||||
return remaining, icon, name, count, dispelType
|
||||
@@ -113,17 +120,22 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
GameTooltip:SetUnitAura("player", this.id, this.type)
|
||||
elseif this.type == "HARMFUL" then
|
||||
-- selfdebuff filters the displayed list to player-cast harmful auras, but
|
||||
-- SetUnitAura's index has to be into the engine's full HARMFUL list. Look
|
||||
-- up the displayed aura via the PLAYER filter, then scan engine slots for
|
||||
-- one whose name + sourceGUID match.
|
||||
-- SetUnitAura's index has to be into the unfiltered HARMFUL list. Look up
|
||||
-- the displayed aura via the PLAYER filter, then find its position in the
|
||||
-- unfiltered list by name + sourceGUID.
|
||||
--
|
||||
-- The unfiltered list is NOT capped at 16: once a unit's 16 debuff slots
|
||||
-- are full the server parks further debuffs in buff slots, and
|
||||
-- C_UnitAuras reports those as harmful too. So enumerate what it has.
|
||||
local config = this.parent and this.parent.config
|
||||
if config and config.selfdebuff == "1" then
|
||||
local ownAura = C_UnitAuras.GetAuraDataByIndex(this.unit, this.id, "HARMFUL|PLAYER")
|
||||
if ownAura then
|
||||
for gameSlot = 1, 16 do
|
||||
local check = C_UnitAuras.GetDebuffDataByIndex(this.unit, gameSlot)
|
||||
local n = ScanAuraSlots(this.unit, "HARMFUL", tooltipSlots)
|
||||
for i = 1, n do
|
||||
local check = C_UnitAuras.GetAuraDataBySlot(this.unit, tooltipSlots[i])
|
||||
if check and check.name == ownAura.name and check.sourceGUID == ownAura.sourceGUID then
|
||||
GameTooltip:SetUnitAura(this.unit, gameSlot, "HARMFUL")
|
||||
GameTooltip:SetUnitAura(this.unit, i, "HARMFUL")
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -234,9 +246,15 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
local function RefreshBuffBarFrame(frame)
|
||||
-- reinitialize all active buffs
|
||||
local selfdebuff = frame.config.selfdebuff == "1"
|
||||
local filter = (selfdebuff and frame.type == "HARMFUL") and "HARMFUL|PLAYER" or frame.type
|
||||
|
||||
-- one GetAuraSlots enumeration per refresh instead of a by-index walk per
|
||||
-- bar; the i-th slot is the i-th aura of the filtered list, so `i` stays
|
||||
-- the index the tooltip / cancel handlers pass to the by-index API
|
||||
ScanAuraSlots(frame.unit, filter, auraSlots, 32)
|
||||
|
||||
for i=1,32 do
|
||||
local timeleft, texture, name, stacks, dtype = GetBuffData(frame.unit, i, frame.type, selfdebuff)
|
||||
local timeleft, texture, name, stacks, dtype = GetBuffData(frame.unit, auraSlots[i])
|
||||
timeleft = timeleft or 0
|
||||
|
||||
if texture and name and name ~= "" and BuffIsVisible(frame.config, name) then
|
||||
|
||||
+6
-2
@@ -827,7 +827,7 @@ pfUI:RegisterModule("chat", function ()
|
||||
local real, _ = strsplit(":", name)
|
||||
local color = unknowncolorhex
|
||||
local match = false
|
||||
local _, class = C_PlayerCache.GetPlayerInfoByName(real)
|
||||
local _, class, _, raceKey, sex = C_PlayerCache.GetPlayerInfoByName(real)
|
||||
-- local guid = GetCurrentChatGUID()
|
||||
-- if guid then
|
||||
-- _, class = GetPlayerInfoByGUID(guid)
|
||||
@@ -845,8 +845,12 @@ pfUI:RegisterModule("chat", function ()
|
||||
end
|
||||
|
||||
if C.chat.text.tintunknown == "1" or match then
|
||||
local icon = ""
|
||||
if match and C.chat.text.playericons == "1" then
|
||||
icon = GetFactionIcon(raceKey) .. GetRaceIcon(raceKey, sex)
|
||||
end
|
||||
text = string.gsub(text, "|Hplayer:"..name.."|h%["..real.."%]|h(.-:-)",
|
||||
left..color.."|Hplayer:"..name.."|h" .. color .. real .. "|h|r"..right.."%1")
|
||||
left..icon..color.."|Hplayer:"..name.."|h" .. color .. real .. "|h|r"..right.."%1")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2867,6 +2867,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Generate Playerlinks"], C.chat.text, "playerlinks", "checkbox")
|
||||
CreateConfig(nil, T["Enable URL Detection"], C.chat.text, "detecturl", "checkbox")
|
||||
CreateConfig(nil, T["Enable Class Colors"], C.chat.text, "classcolor", "checkbox")
|
||||
CreateConfig(nil, T["Show Faction & Race Icons"] .. " " .. GetPlayerRaceIcons(), C.chat.text, "playericons", "checkbox")
|
||||
CreateConfig(nil, T["Enable Player Levels"], C.chat.text, "playerlevel", "checkbox")
|
||||
CreateConfig(nil, T["Who Search Unknown Classes (|cffffaaaaExperimental|r)"], C.chat.text, "whosearchunknown", "checkbox")
|
||||
CreateConfig(nil, T["Colorize Unknown Classes"], C.chat.text, "tintunknown", "checkbox")
|
||||
|
||||
+1
-1
@@ -511,7 +511,7 @@ pfUI:RegisterModule("loot", function ()
|
||||
end
|
||||
|
||||
function pfUI.loot:CreateSlot(id)
|
||||
local frame = CreateFrame(LOOT_BUTTON_FRAME_TYPE, 'pfLootButton'..id, pfUI.loot)
|
||||
local frame = CreateFrame("LootButton", 'pfLootButton'..id, pfUI.loot)
|
||||
frame:RegisterForClicks('LeftButtonUp', 'RightButtonUp')
|
||||
frame:SetPoint("LEFT", border*2, 0)
|
||||
frame:SetPoint("RIGHT", -border*2, 0)
|
||||
|
||||
+26
-34
@@ -116,6 +116,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
-- Reusable per-plate debuff display buffer (avoid GC churn from per-call table creation)
|
||||
local debuffDisplayBuf = {} -- [i] = { effect, texture, stacks, dtype, duration, timeleft }
|
||||
for i = 1, 16 do debuffDisplayBuf[i] = {} end
|
||||
local auraSlots = {} -- reusable GetAuraSlots buffer for the per-plate aura scan
|
||||
local threatMemory = {} -- guid -> true if mob had player targeted
|
||||
-- local debuffSeen = {} -- reusable table for debuff tracking (avoid GC churn)
|
||||
|
||||
@@ -296,18 +297,23 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
return plate.creatureType
|
||||
end
|
||||
|
||||
-- Totem icon, read straight from the game:
|
||||
-- * Passive totems self-cast their provided buff, so they carry exactly one
|
||||
-- aura whose icon IS the totem's icon (Totem::Summon TOTEM_PASSIVE).
|
||||
-- * Active totems (Searing/Magma/Fire Nova) cast at enemies and hold no
|
||||
-- self-aura, so their icon arrives via UNIT_SPELLCAST_SUCCEEDED (cached
|
||||
-- into plate.totemIcon by the event handler); nil here until then.
|
||||
-- Totem icon: UnitCreatedBySpell returns the totem-drop spell, whose icon IS
|
||||
-- the totem's icon. It's a broadcast descriptor field the client has for every
|
||||
-- summoned unit in range, so it resolves immediately for passive and active
|
||||
-- totems alike -- no self-aura read or attack-cast capture needed.
|
||||
--
|
||||
-- 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)
|
||||
if C.nameplates.totemicons ~= "1" then return nil end
|
||||
if CreatureType(plate) ~= 11 then return nil end
|
||||
if plate.totemIcon then return plate.totemIcon end
|
||||
local aura = C_UnitAuras.GetBuffDataByIndex(plate.cachedGuid, 1)
|
||||
if aura then plate.totemIcon = aura.icon end
|
||||
local spellId = UnitCreatedBySpell(plate.cachedGuid)
|
||||
if spellId ~= plate.totemSpell then
|
||||
plate.totemSpell = spellId
|
||||
plate.totemIcon = spellId and C_Spell.GetSpellTexture(spellId) or nil
|
||||
end
|
||||
return plate.totemIcon
|
||||
end
|
||||
|
||||
@@ -427,7 +433,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
plate.debuffs[index].cd.SetSequenceTime = DoNothing
|
||||
else
|
||||
-- Use CooldownFrameTemplate for animation
|
||||
plate.debuffs[index].cd = CreateFrame(COOLDOWN_FRAME_TYPE, plate.platename.."Debuff"..index.."Cooldown", plate.debuffs[index], "CooldownFrameTemplate")
|
||||
plate.debuffs[index].cd = CreateFrame("Model", plate.platename.."Debuff"..index.."Cooldown", plate.debuffs[index], "CooldownFrameTemplate")
|
||||
plate.debuffs[index].cd:SetAllPoints(plate.debuffs[index])
|
||||
plate.debuffs[index].cd:SetFrameLevel(6)
|
||||
end
|
||||
@@ -499,7 +505,6 @@ nameplates:RegisterEvent("UNIT_SPELLCAST_START")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_STOP")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
|
||||
nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
|
||||
nameplates:SetScript("OnEvent", function()
|
||||
@@ -588,6 +593,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
plate.nameplate.unit = arg1
|
||||
plate.nameplate.creatureType = nil -- recompute for the new unit
|
||||
plate.nameplate.totemIcon = nil
|
||||
plate.nameplate.totemSpell = nil
|
||||
if guid then
|
||||
plateByGuid[guid] = plate.nameplate
|
||||
-- Seed: the unit may already be mid-cast (its UNIT_SPELLCAST_START
|
||||
@@ -665,22 +671,6 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
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
|
||||
-- ClassicAPI: fires with arg1 == "nameplateN" when a unit's aura set
|
||||
-- changes (add/remove/modify). Flag the matching plate so OnUpdate does a
|
||||
@@ -781,6 +771,8 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
DisableObject(nameplate.original.healthbar)
|
||||
DisableObject(nameplate.original.castbar)
|
||||
|
||||
local NAMEPLATE_OBJECTORDER = { "border", "glow", "name", "level", "levelicon", "raidicon" }
|
||||
|
||||
for i, object in pairs({parent:GetRegions()}) do
|
||||
if NAMEPLATE_OBJECTORDER[i] and NAMEPLATE_OBJECTORDER[i] == "raidicon" then
|
||||
nameplate[NAMEPLATE_OBJECTORDER[i]] = object
|
||||
@@ -1119,7 +1111,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
local TotemIcon = TotemPlate(plate)
|
||||
|
||||
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.glow:Hide()
|
||||
@@ -1323,11 +1315,12 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
if unitstr then
|
||||
local filter = cfg.owndebuffs and "HARMFUL|PLAYER" or "HARMFUL"
|
||||
local now = GetTime()
|
||||
-- positional UnitAura writes straight into the reusable buffer, so the
|
||||
-- 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)
|
||||
-- one GetAuraSlots enumeration, then positional by-slot reads straight
|
||||
-- into the reusable buffer: the per-plate scan allocates nothing (no
|
||||
-- per-aura table, no result array) and walks the aura array once
|
||||
local n = ScanAuraSlots(unitstr, filter, auraSlots, 16)
|
||||
for i = 1, n do
|
||||
local aname, icon, count, dispelType, duration, expirationTime = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if not aname then break end
|
||||
debuffCount = debuffCount + 1
|
||||
local b = debuffDisplayBuf[debuffCount]
|
||||
@@ -1337,7 +1330,6 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
b.dtype = dispelType
|
||||
b.duration = duration
|
||||
b.timeleft = (expirationTime and expirationTime > 0) and (expirationTime - now) or nil
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
for i = 1, 16 do
|
||||
|
||||
+10
-4
@@ -457,7 +457,7 @@ pfUI:RegisterModule("panel", function()
|
||||
|
||||
do -- Zone
|
||||
local widget = CreateFrame("Frame", "pfPanelWidgetZone", UIParent)
|
||||
for _,event in pairs(EVENTS_MINIMAP_ZONE_UPDATE) do
|
||||
for _,event in pairs({"PLAYER_ENTERING_WORLD", "MINIMAP_ZONE_CHANGED"}) do
|
||||
widget:RegisterEvent(event)
|
||||
end
|
||||
widget.Tooltip = function()
|
||||
@@ -777,9 +777,15 @@ pfUI:RegisterModule("panel", function()
|
||||
pfUI.panel.microbutton:SetSize(145, 23)
|
||||
pfUI.panel.microbutton:SetFrameStrata("MEDIUM")
|
||||
|
||||
for i=1,table.getn(MICRO_BUTTONS) do
|
||||
local anchor = _G[MICRO_BUTTONS[i-1]] or pfUI.panel.microbutton
|
||||
local button = _G[MICRO_BUTTONS[i]]
|
||||
local microButtons = {
|
||||
'CharacterMicroButton', 'SpellbookMicroButton', 'TalentMicroButton',
|
||||
'QuestLogMicroButton', 'SocialsMicroButton', 'WorldMapMicroButton',
|
||||
'MainMenuMicroButton', 'HelpMicroButton',
|
||||
}
|
||||
|
||||
for i=1,table.getn(microButtons) do
|
||||
local anchor = _G[microButtons[i-1]] or pfUI.panel.microbutton
|
||||
local button = _G[microButtons[i]]
|
||||
button:ClearAllPoints()
|
||||
button:SetParent(pfUI.panel.microbutton)
|
||||
if i == 1 then
|
||||
|
||||
@@ -81,7 +81,7 @@ pfUI:RegisterModule("socialmod", function ()
|
||||
if not info or not info.name or info.name == _G.UNKNOWN then break end
|
||||
local name = info.name
|
||||
local friendName = _G["FriendsFrameFriendButton"..i.."ButtonTextName"]
|
||||
local friendLoc = _G["FriendsFrameFriendButton"..i..FRIENDS_NAME_LOCATION]
|
||||
local friendLoc = _G["FriendsFrameFriendButton"..i.."ButtonTextNameLocation"]
|
||||
local friendInfo = _G["FriendsFrameFriendButton"..i.."ButtonTextInfo"]
|
||||
local caption = friendName or friendLoc
|
||||
|
||||
|
||||
+11
-7
@@ -189,6 +189,7 @@ pfUI:RegisterModule("tooltip", function ()
|
||||
-- Icons come from a ClassicAPI object pool: ReleaseAll hides the whole
|
||||
-- set each refresh, then we Acquire and re-anchor left-to-right.
|
||||
local BUFF_SIZE, BUFF_SPACING, BUFF_MAX = 20, 2, 32
|
||||
local auraSlots = {} -- reusable GetAuraSlots buffer for UpdateBuffs
|
||||
pfUI.tooltip.buffs = CreateFrame("Frame", "pfTooltipBuffs", GameTooltip)
|
||||
pfUI.tooltip.buffs:SetPoint("BOTTOMLEFT", GameTooltipStatusBar, "TOPLEFT", 0, default_border + 2)
|
||||
pfUI.tooltip.buffs:SetHeight(BUFF_SIZE)
|
||||
@@ -239,17 +240,20 @@ pfUI:RegisterModule("tooltip", function ()
|
||||
end
|
||||
|
||||
local prev, count = nil, 0
|
||||
for i = 1, BUFF_MAX do
|
||||
local aura = C_UnitAuras.GetBuffDataByIndex(unit, i)
|
||||
if not aura then break end
|
||||
-- one GetAuraSlots enumeration + positional by-slot reads: no per-aura
|
||||
-- table and no per-index re-walk of the aura array
|
||||
local n = ScanAuraSlots(unit, "HELPFUL", auraSlots, BUFF_MAX)
|
||||
for i = 1, n do
|
||||
local name, texture, applications, _, _, expirationTime = C_UnitAuras.UnitAuraBySlot(unit, auraSlots[i])
|
||||
if not name then break end
|
||||
|
||||
count = count + 1
|
||||
local icon = pfUI.tooltip.buffpool:Acquire()
|
||||
icon.texture:SetTexture(aura.icon)
|
||||
icon.stacks:SetText(aura.applications and aura.applications > 1 and aura.applications or "")
|
||||
icon.texture:SetTexture(texture)
|
||||
icon.stacks:SetText(applications and applications > 1 and applications or "")
|
||||
|
||||
icon.expirationTime = aura.expirationTime
|
||||
local timeleft = aura.expirationTime and aura.expirationTime > 0 and (aura.expirationTime - GetTime()) or 0
|
||||
icon.expirationTime = expirationTime
|
||||
local timeleft = expirationTime and expirationTime > 0 and (expirationTime - GetTime()) or 0
|
||||
icon.timer:SetText(timeleft > 0 and GetColoredTimeString(timeleft) or "")
|
||||
|
||||
if prev then
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ pfUI:RegisterModule("totems", function ()
|
||||
self.bar[i].cdbg = self.bar[i].cdbg or CreateFrame("Frame", nil, self.bar[i])
|
||||
self.bar[i].cdbg:SetSize(self.iconsize - 3, self.iconsize - 3)
|
||||
self.bar[i].cdbg:SetPoint("CENTER", self.bar[i], "CENTER", 0, 0)
|
||||
self.bar[i].cd = self.bar[i].cd or CreateFrame(COOLDOWN_FRAME_TYPE, "pfTotemsBar"..i.."Cooldown", self.bar[i].cdbg, "CooldownFrameTemplate")
|
||||
self.bar[i].cd = self.bar[i].cd or CreateFrame("Model", "pfTotemsBar"..i.."Cooldown", self.bar[i].cdbg, "CooldownFrameTemplate")
|
||||
self.bar[i].cd.pfCooldownStyleAnimation = 1
|
||||
self.bar[i].cd.pfCooldownType = "ALL"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pfUI:RegisterModule("tracking", function ()
|
||||
|
||||
MINIMAP_TRACKING_FRAME:UnregisterAllEvents()
|
||||
MINIMAP_TRACKING_FRAME:Hide()
|
||||
_G.MiniMapTrackingFrame:UnregisterAllEvents()
|
||||
_G.MiniMapTrackingFrame:Hide()
|
||||
|
||||
local rawborder, border = GetBorderSize()
|
||||
local size = tonumber(C.appearance.minimap.tracking_size)
|
||||
|
||||
+1
-2958
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,8 @@ function SlashCmdList.RELOAD(msg, editbox)
|
||||
ReloadUI()
|
||||
end
|
||||
|
||||
local addonName = ...
|
||||
|
||||
SLASH_PFUI1 = '/pfui'
|
||||
function SlashCmdList.PFUI(msg, editbox)
|
||||
pfUI.gui:SetShown(not pfUI.gui:IsShown())
|
||||
@@ -13,79 +15,12 @@ function SlashCmdList.GM(msg, editbox)
|
||||
ToggleHelpFrame(1)
|
||||
end
|
||||
|
||||
pfUI = CreateFrame("Frame", nil, UIParent)
|
||||
local pfUI = CreateFrame("Frame", addonName, UIParent)
|
||||
pfUI:RegisterEvent("ADDON_LOADED")
|
||||
|
||||
-- setup bootvar
|
||||
pfUI.bootup = true
|
||||
|
||||
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 = 11204 -- (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
|
||||
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
|
||||
|
||||
pfUI_playerDB = pfUI_playerDB or {}
|
||||
pfUI_config = pfUI_config or {}
|
||||
pfUI_init = pfUI_init or {}
|
||||
@@ -117,35 +52,24 @@ pfUI.env = {}
|
||||
-- the flag; one that lacks it should drop the flag and get the safe fallback.
|
||||
pfUI.handlesHookScript = true
|
||||
|
||||
if not pfUI.disabled then
|
||||
pfUI.events = Mixin({}, CallbackRegistryMixin)
|
||||
pfUI.events:OnLoad()
|
||||
pfUI.events:SetUndefinedEventsAllowed(true)
|
||||
end
|
||||
pfUI.events = Mixin({}, CallbackRegistryMixin)
|
||||
pfUI.events:OnLoad()
|
||||
pfUI.events:SetUndefinedEventsAllowed(true)
|
||||
|
||||
-- check if macro addons are loaded (disables macrotweak/macroscan)
|
||||
function pfUI:MacroAddonsLoaded()
|
||||
return IsAddOnLoaded("Supermacro") or IsAddOnLoaded("SuperCleveRoidMacros") or IsAddOnLoaded("UltimaMacros")
|
||||
end
|
||||
|
||||
-- detect current addon path
|
||||
local tocs = { "", "-master", "-tbc", "-wotlk" }
|
||||
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
|
||||
pfUI.name = addonName
|
||||
pfUI.path = "Interface\\AddOns\\" .. addonName
|
||||
|
||||
-- handle/convert media dir paths
|
||||
pfUI.media = setmetatable({}, { __index = function(tab,key)
|
||||
local value = tostring(key)
|
||||
if strfind(value, "img:") then
|
||||
if value:find("img:") then
|
||||
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\\")
|
||||
else
|
||||
value = string.gsub(value, "Interface\\AddOns\\pfUI\\", pfUI.path .. "\\")
|
||||
@@ -154,9 +78,7 @@ pfUI.media = setmetatable({}, { __index = function(tab,key)
|
||||
return value
|
||||
end})
|
||||
|
||||
-- cache client version
|
||||
local _, _, _, client = GetBuildInfo()
|
||||
pfUI.client = client or 11200
|
||||
pfUI.client = INTERFACE_VERSION
|
||||
|
||||
-- setup pfUI namespace
|
||||
setmetatable(pfUI.env, {__index = getfenv(0)})
|
||||
@@ -390,14 +312,13 @@ function pfUI:CheckNewModules()
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
return func
|
||||
end
|
||||
|
||||
function pfUI:RegisterModule(name, func, arg3)
|
||||
if pfUI.disabled then return end
|
||||
if pfUI.module[name] then return end
|
||||
func = BackwardsCompatRegister(func, arg3)
|
||||
pfUI.module[name] = func
|
||||
@@ -408,7 +329,6 @@ function pfUI:RegisterModule(name, func, arg3)
|
||||
end
|
||||
|
||||
function pfUI:RegisterSkin(name, func, arg3)
|
||||
if pfUI.disabled then return end
|
||||
if pfUI.skin[name] then return end
|
||||
func = BackwardsCompatRegister(func, arg3)
|
||||
pfUI.skin[name] = func
|
||||
@@ -429,7 +349,6 @@ function pfUI:LoadSkin(s)
|
||||
end
|
||||
|
||||
pfUI:SetScript("OnEvent", function()
|
||||
if pfUI.disabled then return end
|
||||
|
||||
-- make sure to initialize and set our fonts
|
||||
-- each time an addon got loaded but only
|
||||
@@ -443,7 +362,7 @@ pfUI:SetScript("OnEvent", function()
|
||||
-- "@project-version@" until release tooling substitutes it — mark those
|
||||
-- explicitly as "dev" instead of pretending they're a real numbered build.
|
||||
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.string = "dev"
|
||||
else
|
||||
@@ -577,3 +496,18 @@ function pfUI.SetupCVars()
|
||||
end
|
||||
UIParentLoadAddOn("Blizzard_CombatText")
|
||||
end
|
||||
|
||||
do -- RunMacroText
|
||||
local obj = setmetatable({ ["GetText"] = function(self) return self.text end }, {
|
||||
__index = function(tab,key)
|
||||
local value = function() return end
|
||||
rawset(tab,key,value)
|
||||
return value
|
||||
end
|
||||
})
|
||||
|
||||
function RunMacroText(text)
|
||||
obj.text = text
|
||||
ChatEdit_ParseText(obj, 1)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,11 +8,9 @@
|
||||
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
|
||||
## X-Website: https://github.com/brues-code/pfUI
|
||||
|
||||
pfUI.lua
|
||||
# ClassicAPI-less fallback. ClassicAPI redirects this read to pfUI_Turtle.toc
|
||||
# (Turtle clients) or pfUI_ClassicAPI.toc (everything else), so the client only
|
||||
# ever reaches THIS file when the DLL is missing. Load the notice and nothing
|
||||
# else.
|
||||
|
||||
init\env.xml
|
||||
init\compat.xml
|
||||
init\api.xml
|
||||
init\libs.xml
|
||||
init\skins.xml
|
||||
init\modules.xml
|
||||
API_Check.lua
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
## Interface: 11200
|
||||
## Title: |cff33ffccpf|cffffffffUI
|
||||
## Author: Shagu - modified by me0wg4ming & brues
|
||||
## Notes: A complete user interface replacement.
|
||||
## Notes-ruRU: Полная замена пользовательского интерфейса.
|
||||
## Version: @project-version@
|
||||
## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle
|
||||
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
|
||||
## X-Website: https://github.com/brues-code/pfUI
|
||||
|
||||
# Selected by ClassicAPI on every non-Turtle client. Turtle clients get
|
||||
# pfUI_Turtle.toc instead, which trades init\stock.xml for init\turtle.xml.
|
||||
|
||||
API_Check.lua
|
||||
|
||||
pfUI.lua
|
||||
|
||||
init\env.xml
|
||||
init\stock.xml
|
||||
init\api.xml
|
||||
init\libs.xml
|
||||
init\skins.xml
|
||||
init\modules.xml
|
||||
@@ -0,0 +1,24 @@
|
||||
## Interface: 11200
|
||||
## Title: |cff33ffccpf|cffffffffUI
|
||||
## Author: Shagu - modified by me0wg4ming & brues
|
||||
## Notes: A complete user interface replacement.
|
||||
## Notes-ruRU: Полная замена пользовательского интерфейса.
|
||||
## Version: @project-version@
|
||||
## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle
|
||||
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
|
||||
## X-Website: https://github.com/brues-code/pfUI
|
||||
|
||||
# Selected by ClassicAPI on Turtle WoW, where it wins over pfUI_ClassicAPI.toc.
|
||||
# Same list with init\stock.xml swapped for init\turtle.xml: the modules, skins
|
||||
# and vendor prices that only mean anything on a Turtle client.
|
||||
|
||||
API_Check.lua
|
||||
|
||||
pfUI.lua
|
||||
|
||||
init\env.xml
|
||||
init\api.xml
|
||||
init\libs.xml
|
||||
init\skins.xml
|
||||
init\modules.xml
|
||||
init\turtle.xml
|
||||
Reference in New Issue
Block a user