PHP код:
local addon, ns = ...
local p = ns:NewModule("Procs")
-- массив с настройками
local cfg = {
["auras"] = { -- название типа проков
["size"] = 35, -- размер иконок этого типа проков
["Filter"] = { -- айди проков , которые хотим отображать
[67773] = true,
[67708] = true,
},
["point"] = {a = "CENTER", b = "CENTER", x = 0, y = 80}, -- позиции относительно центра экрана
["cols"] = 10, -- количество иконок в ряду
["spacing"] = 2, -- промежутки между иконками
["num"] = 10, -- максимальное количество отображаемых иконок
['growth-x'] = "RIGHT", -- направление роста
["initialAnchor"] = "TOPRIGHT", -- начальная позиция иконок
["stackSize"] = 16, -- размер текста стаков
["spellSize"] = 14, -- размер названия спела (выключено но не стирать)
["timeSize"] = 14 -- размер таймера
}
}
-- немного луа апи, говорят быстрее работает но хзхз
local floor = math.floor
local tinsert, GetTime = table.insert, GetTime
-- массив в котором храним созданные типы проков
local headers = {}
-- разумеется нужно создавать иконки
local createAuraIcon = function(icons, index)
local button = CreateFrame("frame", nil, icons)
button:SetWidth(icons.size)
button:SetHeight(icons.size)
local icon = button:CreateTexture(nil, "BORDER")
icon:SetAllPoints(button)
local spell = button:CreateFontString(nil, "OVERLAY")
spell:SetFont("Fonts\\FRIZQT__.TTF", icons.spellSize, "OUTLINE")
spell:SetPoint("TOP", button, "BOTTOM", 0, -icons.spellSize)
spell:Hide()
local timer = button:CreateFontString(nil, "OVERLAY")
timer:SetFont("Fonts\\FRIZQT__.TTF", icons.timeSize, "OUTLINE")
timer:SetPoint("TOP", button, "BOTTOM", 0, -2)
local count = button:CreateFontString(nil, "OVERLAY")
count:SetFont("Fonts\\FRIZQT__.TTF", icons.stackSize, "OUTLINE")
count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 0)
tinsert(icons, button)
button.parent = icons
button.icon = icon
button.count = count
button.spell = spell
button.timer = timer
return button
end
-- таймер для вывода времени прока
local OnUpdate
do
local format = ns.FormatTime
OnUpdate = function(self)
local endTime = self.timeLeft - GetTime()
if endTime > 0 then -- нам не нужны отрицательные значения для таймера прока (пинг\низкий фпс и тд способствуют)
self.timer:SetText(
format(self.timeLeft - GetTime())
)
end
end
end
-- обновление иконок
local updateIcon = function(icons, index, offset, filter, visible)
local name, rank, texture, count, dtype, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID = UnitAura("player", index, filter)
if(name) then
local n = visible + offset + 1
local icon = icons[n]
if(not icon) then
icon = createAuraIcon(icons, n)
end
local show = icons.Filter[spellID] -- фильтр из конфига выше
if(show) then
if(duration and duration > 0) then
icon.timeLeft = timeLeft
icon:SetScript("OnUpdate", OnUpdate)
elseif duration==0 then
icon:SetScript("OnUpdate", nil)
end
icon.spell:SetText(name)
icon.icon:SetTexture(texture)
icon.count:SetText((count > 1 and count))
icon:Show()
return 1
else
return 0
end
end
end
-- разделяем иконки на активные и не активные, не активные прячем , активные обновляем
local filterIcons = function(icons, filter, limit, offset, dontHide)
if(not offset) then offset = 0 end
local index = 1
local visible = 0
while(visible < limit) do
local result = updateIcon(icons, index, offset, filter, visible)
if(not result) then
break
elseif(result == 1) then
visible = visible + 1
end
index = index + 1
end
if(not dontHide) then
for i = visible + offset + 1, #icons do
icons[i]:Hide()
end
end
return visible
end
-- обработчик событий и формирование строк и столбцов
local UNIT_AURA = function(self, event, unit)
if unit and unit~="player" then return end -- незачем обрабатывать ауры игрока если измнение аур было для другого юнита. просто прерываем выполнение функции.
for name, header in pairs(headers) do
if header then
filterIcons(header, 'HELPFUL', header.num)
local sizex = header.size + (header['spacing-x'] or header.spacing or 0)
local sizey = header.size + (header['spacing-y'] or header.spacing or 0)
local anchor = header.initialAnchor or "BOTTOMLEFT"
local growthx = (header["growth-x"] == "LEFT" and -1) or 1
local growthy = (header["growth-y"] == "DOWN" and -1) or 1
local cols = floor(header.cols + .5)
for i = 1, #header do
local button = header[i]
if(not button) then break end
local col = (i - 1) % cols
local row = floor((i - 1) / cols)
button:ClearAllPoints()
button:SetPoint(anchor, header, anchor, col * sizex * growthx, row * sizey * growthy)
end
end
end
end
function p:Init()
-- инициализация , создаем категории иконок по конфигу (который в самом начале кода)
for key, value in pairs(cfg) do
local header = CreateFrame("frame", UIParent)
if type(value)=="table" then
for name, cfg in pairs(value) do
header[name] = cfg
end
header:SetSize(header.size, header.size)
header:SetPoint(header.point.a, UIParent, header.point.b, header.point.x, header.point.y)
end
headers[key] = header
end
self:RegisterEvent("UNIT_AURA", UNIT_AURA)
self:RegisterEvent("PLAYER_ENTERING_WORLD", UNIT_AURA)
end
PHP код:
["auras"] = { -- название типа проков
["size"] = 35, -- размер иконок этого типа проков
["Filter"] = { -- айди проков , которые хотим отображать
[67773] = true,
[67708] = true,
},
["point"] = {a = "CENTER", b = "CENTER", x = 0, y = 80}, -- позиции относительно центра экрана
["cols"] = 10, -- количество иконок в ряду
["spacing"] = 2, -- промежутки между иконками
["num"] = 10, -- максимальное количество отображаемых иконок
['growth-x'] = "RIGHT", -- направление роста
["initialAnchor"] = "TOPRIGHT", -- начальная позиция иконок
["stackSize"] = 16, -- размер текста стаков
["spellSize"] = 14, -- размер названия спела (выключено но не стирать)
["timeSize"] = 14 -- размер таймера
}
и изменяя ключ массива (в данном случае ["auras"] можно создавать практически нечем не ограниченное количество категорий для тайминга аур игрока.