Изначально я хотел посвятить вторую часть более глубокому изучению групп, индикаций, вещей которые можно отслеживать стандартными средствами аддона. Но потом я подумал, что любой заинтересованный рейдер или пвп-шник может самостоятельно посмотреть различные выпадающие менюшки, поставить всякие галочки и посмотреть, что из этого получится. По сути, полноценный гайд с рассмотрением всего-всего займет слишком много времени, но по сути не нужен, так как, если вы разобрались с основами, более подробно рассмотреть опции индикаций можно самостоятельно.

Вместо этого в этом гайде я хотел бы поговрить о вещах, в которых самомстоятельно разобраться будет гораздо труднее, а именно об использовании lua-скриптов в индикациях. Базовый инструментарий позволяет добится хорошего результата, но если вы захотите углубиться в детали аддона и захотите упростить себе ротацию, вы в какой-то момент заметите, что стандартные средства не позволяют вам сделать некоторые полезные вещи. Один такой пример уже был в предыдущем гайде. Другой пример, стандартные средства не позволяют создать индикацию со сложным условием типа: условие_а И (условие_б ИЛИ условие_в), которые на практике встречаются очень часто.

Этот гайд будет всего лишь введением в скрипты weakauras, готовых примеров в данном гайде не будет. На самом деле, это гайд будет всего лишь прелюдией к следующему гайду, где будет отслеживаться вообще все, что нужно для выполнения ротации по одиночной цели. Следущий гайд будет выполнен на примерах для arcane-мага.

Итак, откроем weakauras, создадим новую индикацию (иконку) и перейдем во вкладку “Триггер”. Существует четыре типа триггера: “Аура”, “Статус”, “Событие” и “Самостоятельно”. Вы наерняка уже создали несколько триггеров с типами “Аура” и “Статус”. Сегодня мы выберем тип “Самостоятельно”. Вы увидите следующую картинку:

https://pp.vk.me/c622731/v622731186/367a7/_KefdTeMWIA.jpg

Обратите внимание не небольше окошки внутри окна редактирования триггера. Именно там будут располагаться наши кусочки кода. Триггер можно настроить по-разному, чаще всего я использую тип события: “Статус”, проверять: “Каждый кадр”. Если сделать таким образом, условия триггера будут проверяться каждый кадр, как легко догадаться. Обычно это именно то, что нам нужно.

Если вы прокрутите вниз, увидите несколько опций:
1. Свой триггер
2. Свой детриггер
3. Информация о продолжительности
4. Название инфо
5. Информация о значке
6. Информация о текстуре
7. Информация о стаках

Самым важным является первый пункт. Именно он определеяет, когда наша индикация будет верна. Внутри должен располагаться скрипт, а если точнее, функция, написанная на языке lua. Например, вот такая:

function()

    return true;

end


Для того, чтобы набрать или вставить текст, нажмите красную кнопку “Расширенный редактор текста”

https://pp.vk.me/c622731/v622731186/367af/yQyB-0WKYt8.jpg

Примечание: ставить точку с запятой не обязательно, но я их ставлю, потому что привык.

После этого мы откроем редактирование детриггера и напишем там точно такую же функцию, которая всегда возвращает true.

Что же будет происходить, если мы закроем окно weakauras? Каждый кадр игровая машина будет запускать функцию, которую мы написали в качестве триггера и проверять, возвращает ли она true или false. Если она возвращает true, иконка будет отображаться на экране. В противном случае запускается функция детриггера, и если она возвращает истину, отображение иконки прекращается. В 99% случаев детриггер всегда будет возвращать истину, так что не очень заморачивайтесь на этот счет.

Коротко об остальных опциях. Информация о продолжительности - в этой секции должна быть функция, которая возвращает два числа и истину/ложь, например return 5,10,true. Эта секция обычно используется с полоской прогресса и текстурами прогресса чтобы показать заполненность текстуры или полоски.

Информация о значке. Возвращает сроку - путь к иконке. Вместо того, чтобы показывать одну и ту же иконку, вы можете сделать, чтобы иконка менялась в зависимости от обстоятельств.

Информация о текстуре. То же самое, только вместо пути до иконки путь до текстуры.

Если вы перейдете во вкладку “Индикация” и в графе “Текст” напишите %c (символ процента - латинская C), вы сможете прописать функцию, которая будет возвращать строку - тот текст, который будет отображаться на иконке.

https://pp.vk.me/c622731/v622731186/367b7/gt_IKsnXYgI.jpg

Вы можете регулировать не только сам текст, но и, например, цвет шрифта.

Ладно, мы поняли, в weakauras можно использовать собственные функции для создания триггеров, но как нам, допустим, отследить дебафф или здоровье или сделать другие подобные вещи? В этом нам поможет следующий сайт:

http://wowprogramming.com/

где можно найти описания всех функций для интерфейса вов. Например, функция, отслеживающая бафф:

http://wowprogramming.com/docs/api/UnitBuff

На практике это будет выглядеть следующим образом:

local arcanePower, _, _, _, _, _, arcanePower_expires = UnitBuff("player", "Мощь тайной магии");

Ключевое слово local означает, что мы создаем локальную переменную. Функция имеет два аргумента. Первый - на ком мы отслеживаем бафф, в данном случае “player” - игрок. Второй, собственно, название баффа - Мощь тайной магии. Обратите внимание, функция UnitBuff возвращает несколько значений, а именно 16. Нам же нужно только первое и седьмое. Первое - просто проверка на наличие баффа, если баффа нет, оно будет иметь значение nill. Седьмое - время, когда бафф закончится. Не сколько осталось до окончания, и именно тот момент времени когда он закончится. Как нам отследить, сколько времени осталось до окончания баффа? Сделаем следующее, вставим следующие строчки:

time = GetTime();

arcanePower, _, _, _, _, _, arcanePower_expires = UnitBuff("player", "Мощь тайной магии");

if arcanePower then
    arcanePower_timeLeft = arcanePower_expires - time;
end


тогда значение переменной arcanePower_timeLeft будет равняться оставшемуся времени действия баффа в секундах. GetTime() - функция, которая возвращает текущее время.

Для того, чтобы отслеживать дебафф на цели поступаем аналогичным образом, только используем функцию UnitDebuff

livingBomb, _, _, _, _, _, livingBombExpires = UnitDebuff("target", "Живая бомба","", "PLAYER");
       
if livingBomb then
    g_livingBomb_timeLeft = livingBombExpires - time;
end


Обратите внимание, что функция принимает четыре аргумента. Четвертый, "PLAYER", означает, что бедут отслеживаться только дебафф, наложенный игроком. Если не важно, кто наложил дебафф, делаем просто UnitDebuff("target", "Живая бомба").

Для отслеживания кулдаунов используется функция GetSpellCooldown.

time = GetTime();

readySpell = false;
startSpellCooldown, durationSpellCooldown = GetSpellCooldown('Пламенный взрыв');

if (startSpellCooldown == 0) then
    readySpell = true;
    SpellCooldown_timeleft = 0;
else
    SpellCooldown_timeleft = durationSpellCooldown - time + startSpellCooldown;
end


С отслеживанием кулдаунов способностей есть одна важная тонкость. Когда игровая машина запускает функцию GetSpellCooldown, она проверяет наличие способности в вашей книге заклинаний. Если такой способности не будет, интерфейс выдаст ошибку. Например, способность Пламенный Взрыв есть у магов специализации Огонь, но отсутствует у магов специализации Лед и Тайная магия. Поэтому индикация, внутри которой используется эта функция, должна включаться только в том случае, если выбрана специализация огонь.

https://pp.vk.me/c622731/v622731186/367bf/5TBfWaRkG1s.jpg

Для отслеживания ресурса класса используется следующая конструкция:

local mana = UnitPower("player");
local _, manaregen = GetPowerRegen();


У каждого класса свой ресурс, т.е. если ваш персонаж ("player") заклинатель, это будет мана. Если охотник - концентрация. Если разбойник, монах или кот - энергия и так далее. GetPowerRegen() возвращает количество ресурса, которое персонаж восстановит за секунду, с учетом бонуса от хасты. Следует заметить, что обе функции возвращают абсолютные значения, поэтому, если вы хотите оперировать процентами ресурса, значения нужно дополнительно разделить на определенное число.

С отслеживанием маны есть небольшое неудобство: ее уровень “колеблется” в небольших пределах, что иногда бывает неудобно. Как это предотвартить, я расскажу позже, если будет время.

Иногда одна и та же индикация применяется при различных наборах талантов. Поэтому важно отслеживать взятые таланты внутри кода. Делается с помощью функции GetTalentRowSelectionInfo(). Посмотрите на конструкцию ниже:

select(2,GetTalentRowSelectionInfo(X)

Она вернет номер таланта, который находится в тире с номером X. Например:

select(2,GetTalentRowSelectionInfo(1) - талант на уровне 15
select(2,GetTalentRowSelectionInfo(7) - талант на уровне 100

Логично предположить, что если у вас, например, взят маговский талант пропадание, то эта функция должна возвращать 1, если Молниеностность, то 2, а если Плавучая льдина, то 3, см. калькулятор талантов:

http://eu.battle.net/wow/ru/tool/talent … aa!.......

Оказвается, что если у вас в первом тире взят первый талант, то функция вернет число 21689, если второй, то 16012, если третий, то 16013. Общая таблица для мага специализации Тайная магия будет выглядеть следующим образом:

1 тир : 21689 16012 16013
2 тир : 16023 16024 16025
3 тир : 16019 16020 16021
4 тир : 16027 16028 16029
5 тир : 19299 19300 19301
6 тир : 16031 16032 16033
7 тир : 21630 21144 21145

Почему так? Хуй его знает. У разных классов и спеков таблицы будут разные. Проверка на наличие определенного таланта может осуществляться с помощью следующей конструкции:

local talent_supernova_on = false;
   
if select(2,GetTalentRowSelectionInfo(5))==19301 then
    talent_supernova_on = true;
end


Существует еще большое количество других полезных функций. Естественно, перечислять их все в этом гайде нет ни возможности, ни смысла. К счастью, на сайте wowprogramming.com возможен поиск по ключевым словам.

На этом вторая часть гайда заканчивается. В следующем гайде мы рассмотрим построения удобных индикаций для отслеживания правильности ротации и всяких других полезных штук.

Надеюсь, этот гайд вам помог. Свои вопросы и пожелания пишите в комментариях.