4. Programming.
Итак, начинаем наполнять файл oUF_Test.lua
Для удобства советую разделять части кода комментариями, код становится качественнее, читабельнее и, что самое главное, понятней. Понятней Вам. Но замечу, что в слишком частые комментарии не стоит убиваться, разделяйте по смыслу, блок настроек медиа файлов под один комментарий, блок размеров под другой и т.д.
Ниже покажу самые распространенные способы, как закомментировать код.
1. Это самый распространенный способ и мне он очень нравится, мало занимает места, комментирует целую строку, да и приятен глазу.
2.
PHP код:
------------------------------------------------------------------------
-- Бла бла бла
------------------------------------------------------------------------
Можно и так, но советую все же комментировать так особо большие куски с 1 смыслом.
Так же есть способ закомментировать код, то есть спрятать его, делается так
PHP код:
--[[
Кусок кода который комментируется.
]]
PHP код:
--[[ бла бла бла ]]--
Главное преимущество такого способа это скрыть код, допустим, вы что-то пишите и у вас это не получается закончить, просто закомментируйте подобным образом, не будет мешаться глазу да и ошибок LUA выдавать не будет.
Переходим к коду. Далее я решил разбить все это дело на смысловые куски, так более понятней. Let's start!
PHP код:
local font = [=[Interface\AddOns\oUF_Test\media\Simple.TTF]=]
local texture = [=[Interface\AddOns\oUF_Test\media\Statusbar]=]
local font_size = 11
local font_style = 'THINOUTLINE'
Начнём с этого, как видите это медиа-блок, тут у нас путь к шрифту, текстурке, размер шрифта и его стиль, советую всегда начинать именно так, потому что если это затерять где-то в середине кода, то будут неприятные ошибки в стиле "собстно вы у нас тут написали текстуру, а текстуры то нет, не порядок". Зачем это? Это допустим нужно, когда надо где-то прописать текстуру, шрифт или еще что, что бы не писать по 20 раз полный путь пользуемся этим. Хочу сказать по части пути, можно прописывать в "", можно в ' ', мне больше нравится такой вариант, через слэши [=[]=].
PHP код:
local sfix = CreateFrame("Frame")
sfix:RegisterEvent("PLAYER_LOGIN")
sfix:SetScript("OnEvent", function()
SetCVar("useUiScale", 1)
SetCVar("uiScale", 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))
end)
Пропишем скрипт на правильный UIScale по Вашему разрешению. Зачем он? Я буду использовать Backdrop, он очень чувствителен к значению скейла, малейшие неполадки и он искажется. Еще очень важная часть про UIScale, когда он правильный, то и координаты будут верные и размер фреймов будет верный, соответственно, при изменении значения Scale через игровые опции, пропадут ровные линии, покосится шрифт и еще много других неприятных вещей.
Подробнее узнать о UI Scale можно тут.
PHP код:
_G["BuffFrame"]:Hide()
_G["BuffFrame"]:UnregisterAllEvents()
_G["BuffFrame"]:SetScript("OnUpdate", nil)
Спрячем близзард-баффы и дебаффы, можно делать и так:
PHP код:
_G["BuffFrame"]:Hide()
Тут есть 1 НО, вторым вариантом мы просто спрячем их, если же брать первый, то мы объявляем функцию OnUpdate неизвестной и убираем все эвенты связанные с аурами, то есть ресурсы на баффы больше тратятся не будут по сравнению со 2ым вариатом, выигрываем копейки памяти, но и это очень неплохо.
PHP код:
local backdrop = {
bgFile = [=[Interface\Buttons\WHITE8x8]=],
edgeFile = [=[Interface\Buttons\WHITE8x8]=], edgeSize = 1,
insets = {top = 0, bottom = 0, right = 0, left = 0}
}
Делаем бэкдроп. Что это? Это наша подложка фрейма, на деле будет выглядеть как 1пиксельная граница для всех элементов.
Мы берем текстуры из клиента WoW, это белый квадрат 8 на 8. Размер границы ставим 1. Insets это как бы ''вогнутость" нашей границы, если значение > 0 то граница выгибается наружу и мы получаем её в виде 3х пикселей, в данном случае у нас она 1 пиксельная поэтому оставим 0.
Что такое Backdrop (очень подробно) написано тут.
Про edgeFile читаем тут.
PHP код:
local CreateBackdrop = function(parent)
local bg = CreateFrame("Frame", nil, parent)
bg:SetPoint('TOPLEFT', parent, 'TOPLEFT', -1, 1)
bg:SetPoint('BOTTOMRIGHT', parent, 'BOTTOMRIGHT', 1, -1)
bg:SetFrameLevel(parent:GetFrameLevel() - 1)
bg:SetBackdrop(backdrop)
bg:SetBackdropColor(0, 0, 0, 0.6)
bg:SetBackdropBorderColor(0, 0, 0, 1)
return bg
end
Делаем функцию для этого бэкдропа, что бы каждый раз не прописывать к фреймам:
PHP код:
***:SetBackdrop(backdrop)
***:SetBackdropColor(r, g, b)
***:SetBackdropBorderColor(r, g, b)
PHP код:
local CreateFontString = function(frame, fsize, fstyle, sfont)
local fstring = frame:CreateFontString(nil, 'OVERLAY')
fstring:SetFont(font, font_size, font_style)
fstring:SetShadowColor(0, 0, 0, 0)
return fstring
end
То же самое что и в случае с бэкдропом, только тут шрифт, что бы не прописывать 100 раз путь к шрифту просто внесём пути шрифта в функцию.
PHP код:
***:SetShadowColor(0, 0, 0, 0)
Этим убираем тень у шрифта.
PHP код:
local menu = function(self)
local unit = self.unit:gsub("(.)", string.upper, 1)
if _G[unit.."FrameDropDown"] then
ToggleDropDownMenu(1, nil, _G[unit.."FrameDropDown"], "cursor")
elseif self.unit:match("party") then
ToggleDropDownMenu(1, nil, _G["PartyMemberFrame"..self.id.."DropDown"], "cursor")
else
FriendsDropDown.unit = self.unit
FriendsDropDown.id = self.id
FriendsDropDown.initialize = RaidFrameDropDown_Initialize
ToggleDropDownMenu(1, nil, FriendsDropDown, "cursor")
end
end
Меню по правой кнопки мыши с инвайтами и прочим. Это только функция, как помним, функцию надо прописать что бы она появилась, это позже.
Дальше будет блок аур, их настройка, вид.
Код:
local FormatTime = function(s)
Прописываем формат времени на баффах, дебаффах (аурах), можно делать до десятых долей секунд.
local DAY, HOUR, MINUTE = 86400, 3600, 60
if s >= DAY then
return format('%dd', floor(s/DAY + 0.5)), s % DAY
elseif s >= HOUR then
return format('%dh', floor(s/HOUR + 0.5)), s % HOUR
elseif s >= MINUTE then
return format('%dm', floor(s/MINUTE + 0.5)), s % MINUTE
end
return floor(s + 0.5), s - floor(s)
end
UpdateAuraTimer = function(self, elapsed)
Тут как будет отображаться этот формат вывода времени.
if self.timeLeft then
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then
if not self.first then
self.timeLeft = self.timeLeft - self.elapsed
else
self.timeLeft = self.timeLeft - GetTime()
self.first = false
end
if self.timeLeft > 0 then
local time = FormatTime(self.timeLeft)
Не забываем прописать формат времени.
self.remaining:SetText(time)
if self.timeLeft < 5 then
Если срок действия ауры < 5 секунд
значит цвет текста на аурах будет красный.
self.remaining:SetTextColor(1, 0.2, 0.2)
else
Для остальных случаев белый.
self.remaining:SetTextColor(1, 1, 1)
end
else
self.remaining:Hide()
self:SetScript("OnUpdate", nil)
end
self.elapsed = 0
end
end
end
CreateAuraTimer = function(icon, duration, expTime)
icon.first = true
if duration and duration > 0 then
icon.remaining:Show()
icon.timeLeft = expTime
icon:SetScript("OnUpdate", UpdateAuraTimer)
Прописываем обновление иконок аур.
else
icon.remaining:Hide()
icon.timeLeft = 0
icon:SetScript("OnUpdate", nil)
end
end
PostUpdateDebuff = function(self, unit, icon, index)
Создаём вид дебаффов.
local name, _, _, _, dtype, duration, expTime = UnitAura(unit, index, icon.filter)
local c = DebuffTypeColor[dtype] or DebuffTypeColor.none
Делаем границу аур по цвету дебаффа.
icon.bg:SetBackdropBorderColor(c.r, c.g, c.b)
icon.icon:SetDesaturated(true)
Делаем не свои ауры серыми, удобно мониторить свои дебаффы на цели.
CreateAuraTimer(icon, duration, expTime)
end
PostUpdateBuff = function(self, unit, icon, index)
Аналогично с дебаффами только баффы.
local name, _, _, _, dtype, duration, expTime = UnitAura(unit, index, icon.filter)
CreateAuraTimer(icon, duration, expTime)
end
local CancelAura = function(self, button)
Отменяем ауры правой кнопкой мыши.
if button == "RightButton" and not self.debuff then
CancelUnitBuff("player", self:GetID())
end
end
PostCreateAuraIcon = function(self, button)
button.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)
button.icon:SetDrawLayer('ARTWORK')
Прописываем иконку ауры.
button.overlay:SetTexture(nil)
Задаем нулевое значение текстуры для аур,
мы ведь пользуемся бэкдропом.
button.remaining = CreateFontString(button)
button.remaining:SetPoint('CENTER', 1, 1)
Время аур по центру.
button.count:SetFont(font, font_size, font_style)
button.count:SetPoint('TOPRIGHT', button, 3, 19)
В правом верхнем углу стаки аур.
button.bg = CreateBackdrop(button)
Бэкдроп.
if unit == "player" then
Прописываем чтобы только игроку можно было отменять ауры правой кнопкой мыши.
button:SetScript("OnMouseUp", CancelAura)
end
end