Вопросы по Lua, XML, WoW API.  
Автор Сообщение

0
Сообщение Вопросы по Lua, XML, WoW API.
При написании своих аддонов или модификации под себя существующих часто возникают различные вопросы касательно Lua, XML, WoW API, использования библиотек Ace и т.д. Думаю можно сделать общую тему для таких вопросов.

Мои текущие вопросы:
Работа с таблицами. Возьмем для примера часть таблицы спеллов из LoseControl:
Код:

local spellIds = {
   -- Death Knight
   [47481] = "CC",      -- Gnaw (Ghoul)
   [49203] = "CC",      -- Hungering Cold
   [47476] = "Silence",   -- Strangulate
   [45524] = "Snare",   -- Chains of Ice (can also be a root with Chilblains but no way to differentiate?)
   [55666] = "Snare",   -- Desecration
   [50040] = "Snare",   -- Chilblains
}


Далее в LoseControl эта таблица переводится в другую таблицу, это делается за тем, что-бы вместо айди спеллов получить их локализированные текстовые имена из клиента:

Код:

local abilities = {} -- localized names are saved here
for k, v in pairs(spellIds) do
   local name = GetSpellInfo(k)
   if name then
      abilities[name] = v
   else -- Thanks to inph for this idea. Keeps things from breaking when Blizzard changes things.
      log(addonName .. " unknown spellId: " .. k)
   end
end


В итоге мы имеем таблицу где в качестве ключей (k) хранятся названия абилок, а в качестве значений (v) хранится их "тип", СС, Silence, Snare и т.д.
Теперь мы делаем функцию проверки цели на наличие на ней ауры которая совпадает по названию с любым из значений таблицы.
Как это делается в LoseControl я не совсем понял, поэтому здесь мой код:

Код:

for k,v in pairs(abilities)
do
      local i=1
   while(i<=40)
      do a={UnitDebuff("target",i)} if a[1]==k then break else i=i+1
      end
   end

   if (i<=40) then
   print("Условие i<=40 верно, на цели есть дебаф: ".. i ..".\nА теперь таблица: ".. k ..".");
   end
end


Здесь все работает, если на цели есть дебаф имя которого совпадает с одним из ключей таблицы то мы получаем значение i более или равным 40, а если совпадений нет, то i<40. Но есть вопрос, что если я хочу что-бы из таблицы подставлялись только ключи с определенным значением, то есть например только CC. Как это сделать?
И следующий вопрос, возможно-ли сделать, что-бы 1 ключ "отзывался" на несколько значений, типа как тегов?

Я слышал там еще бывают какие-то метатаблицы, массивы, может нужно использовать что-то из них?


13 июл 2011, 19:54
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Цитата:

Но есть вопрос, что если я хочу что-бы из таблицы подставлялись только ключи с определенным значением, то есть например только CC


если я правильно понял вопрос, то все что тебе нужно это добавить еще одно условие, т. е.
Код:
if a[1]==k then break

заменить на
Код:
if a[1]==k and v == "CC" then break


по второму вопросу
Цитата:

1 ключ "отзывался" на несколько значений, типа как тегов
,
Почитай тут:
http://www.lua.org/pil/11.2.html
Первая часть, про матрицы, как раз, что тебе нужно.
Вкратце: каждый элемент таблицы тоже может являться таблицей, т. е. можно написать что-то вроде
Код:
local spellIds = {
   -- Death Knight
   [47481] = {"CC", "Silence"},      -- Gnaw (Ghoul)
   [49203] = "CC",      -- Hungering Cold
   [47476] = "Silence",   -- Strangulate
   [45524] = "Snare",   -- Chains of Ice (can also be a root with Chilblains but no way to differentiate?)
   [55666] = "Snare",   -- Desecration
   [50040] = "Snare",   -- Chilblains
}


Но тогда тебе не поможет мой предыдущий совет, надо будет вместо простого and v = "CC" добавить внутри еще одну проверку с обходом этого массива "тегов" и проверки, есть ли в нем нужный "тег".

Остается открытым вопрос, не будет ли оно тормозить при таком количестве циклов


13 июл 2011, 20:41
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Спасибо, проверка
Код:
and v == "CC"

делает нужное, но есть одно уточнение. При таком варианте получается, что если нужного дебаффа на цели нет, то все k значения из таблицы будут перебраны в каждом из 40 циклов, пока не будет получено i>40. Я-же думал что есть какой-то способ изначально извлечь из таблицы только те k значения у которых определенное v и в дальнейшем перебирать в 40-ка циклах только эту отдельную часть k значений из таблицы. Или-же я не правильно понимаю механику работы всего этого?
И еще как вариант, если просто поменять местами очередность проверок, типа
Код:
if v=="CC" and a[1]==k

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

А нельзя как-то установить эту проверку на определенное v для k значений вообще где-то тут?
Код:
for k,v in pairs(abilities)


13 июл 2011, 21:49
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Смотри какой расклад, если ты хочешь проверять только определенные виды дебафов (например CC, сало и т.д.) то тебе лучше сделать изначальную таблицу наоборот, это решит сразу 2 проблемы:
1. ты сможешь проверять только 1 тип дебаффов
2. ты сможешь сделать "теги" - один спелл отнести к двум типам.

Как это сделать? Изменить способ формирования изначальной таблицы. т.е. вместо
Код:
local spellIds = {
   -- Death Knight
   [47481] = "CC",      -- Gnaw (Ghoul)
   [49203] = "CC",      -- Hungering Cold
   [47476] = "Silence",   -- Strangulate
   [45524] = "Snare",   -- Chains of Ice (can also be a root with Chilblains but no way to differentiate?)
   [55666] = "Snare",   -- Desecration
   [50040] = "Snare",   -- Chilblains
}

написать
Код:
local spellIds = {
   "CC" = { --- DK
                47481, -- Gnaw (Ghoul)
                49203  -- Hungering Cold
                -- другие классы тоже сюда дописать
               },
   "Snare" = {
                    45524,
                    55666,
                    50040
        }
}


ну и т.д., принцип понятен я думаю.

Соответственно потом ты уже делаешь не
Код:
for k,v in pairs(abilities)
do
      local i=1
   while(i<=40)


а только по конкретному типу, например
Код:
for k,v in pairs(abilities["CC"])
do
      local i=1
   while(i<=40)


ну и надо убдет код, который получает локализованные названия абилок, тоже переписать чтобы он с новой структурой данных правильно работал


15 июл 2011, 09:04
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Да, с этим вопросом понятно.

В аддоне, в зависимости от происходящего, может быть от одной до двух десятков проверок цели на ауры. Для ситуации когда идет пара десятков проверок, в плане производительности, стоит делать каждую проверку как в примерах выше
Код:
local i=1 while(i<=40) do a={UnitBuff("target",i)} if a[1]=="Божественный щит" then break else i=i+1 end end
if (i<=40) then print("Цель в бабле.")

то есть каждый раз запрашивать ауры от клиента, или может стоит перед началом всех проверок запросить 1 раз от клиента все ауры, записать их в таблицу, и дальше работать с этой таблицей в аддоне?
Есть разница в производительности между запросом от аддона к игре и запросом внутри самого аддона?


15 июл 2011, 10:30
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Думаю, разница есть (с таблицей должно работать быстрее)

Насколько разница будет велика и будет ли она критична - лучше замерить.


15 июл 2011, 10:58
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Делал проверку наличия на цели аур из таблицы. Было такой работающий вариант, уже писал в первом посте:
Код:
for k,v in pairs(silence_auras)
do
      local i=1
   while(i<=40)
      do a={UnitDebuff("target",i)} if a[1]==k then break else i=i+1
      end
   end

   if (i<=40) then
   print("Условие i<=40 верно, на цели есть дебаф: ".. i ..".\nА теперь таблица: ".. k ..".");
   end
end

но полученная переменная i, по значению которой определяется есть аура или нет существует только внутри блока do end, а мне нужно как-то вывести это значение из блока и сохранить что-бы использовать в дальнейшем. Сделал так:
Код:
function calculate_silence()
for k,v in pairs(silence_auras)
   do
   i=1 while(i<=40) do a={UnitDebuff("player",i)} if a[1]==k then break else i=i+1 end end      
      if (i<=40) then
      return 3
      end
   end   
end

local qwerty = calculate_silence()
if (qwerty == 3) then
print("На нас сайленс");
end

Все работает, но не крутил-ли я лишнего? Может можно как-то проще ее вытащить?


15 июл 2011, 18:50
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
я бы на твоем месте возвращал k, тогда вместо print("На нас сайленс"); можно было бы выводить какой конкретно сайленс висит, а если никакой не висит то возвращать false или 0


15 июл 2011, 19:02
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Сенк, хорошая идея, сделал, работает:
Код:
function calculate_silence()
for k,v in pairs(silence_auras)
   do
   i=1 while(i<=40) do a={UnitDebuff("player",i)} if a[1]==k then break else i=i+1 end end     
      if (i<=40) then
      return k
      end
   end   
end

local is_silence_on_me = calculate_silence()
if (is_silence_on_me ~= nil) then
print("На нас сайленс: " ..is_silence_on_me.. ".");
end


Я тут еще начинал делать таблицу всех аур, что-бы только 1 раз их из клиента запрашивать, а затем уже работать с данными внутри аддона, разобрался с простейшим примером
Код:
mt = {}
mt[1] = {UnitAura("target",1)}
mt[2] = {UnitAura("target",2)}
mt[3] = {} mt[2][1] = 8 mt[2][2] = 7

for i = 1,3 do
for k, v in pairs(mt[i]) do
   print(k .. " = " .. v .. "\n");
end
end

Он работает, но вот тут возник вопрос, при таком варианте, что значением ключа является функция запроса аур из клиента
Код:
mt[1] = {UnitAura("target",1)}

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


15 июл 2011, 20:34
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Как я понимаю в близзовском коде интерфейса есть глобальная переменная отвечающая за цветовую раскраску классов, то есть например дающая те цвета в которые окрашиваются неймплейты если включить опцию окраски их по цвету класса.
Вопрос - можно-ли эту глобальную переменную изменить, что-бы например при загрузке какой-то аддон переопределял цвета для каждого класса и затем все элементы интерфейса которые берут цвета из этой глобальной переменной близов использовали именно измененные цвета.
Также помимо цвета классов интересуют и стандартная раскраска вражеской (красный), дружеской (зеленый), с выключенным пвп режимом (синий), нейтральный (желтый), что-бы эти стандартные значения цветов тоже глобально переопределить.

Или-же присваивать значения глобальным переменным близов нельзя и для изменения этих цветовых схем нужно в каждом аддоне определять класс цели и вручную в зависимости от него устанавливать свои цвета для нужных фреймов?

Добавлено спустя 3 минуты 19 секунд:
Еще на днях разобрался с тем как получить возможность редактировать близовские неймплейты, как это делают Aloft, Tidy Plates и т.д., если кому-то нужно могу рассказать.

Добавлено спустя 6 минут 52 секунды:
А, и вот еще - хочу изменить те Tooltips которые появляются в нижнем правом углу экрана когда наводишь на игрока или нпс, там где пишется ник, гильдия, звание и еще некоторый хлам. Конкретно интересует возможность полностью отключить этот тултип, но при этом что-бы остальные тултипы, от итемов, элементов интерфейса, заклинаний продолжали показываться, то есть отключать нужно только тултипы от игроков и нпс. Так-же не откажусь от возможности скрыть только отдельные элементы этой подсказки, например убрать зеленую полоску хп с самого низа.
Аддоны которые модифицируют эти тултипы я уже нашел, буду смотреть, разбираться с кодом как они это делают. В основном вопрос в том, является-ли этот тултип от игроков и нпс уникальным фреймом, или-же все эти подсказки являются как-бы одним фреймом, и для того, что-бы скрыть тултипы от игроков и нпс, а оставить остальные нужно будет писать код который будет по содержимому тултипа распознавать чем именно он является и в зависимости от этого скрывать. Если-же этот фрейм является отдельным фреймом то для его скрытия там пару строчек кода нужно всего.

Добавлено спустя 4 минуты 56 секунд:
Иииииииии.. Ээ.. Есть вообще сайты с активным ру addon-developer community?


01 авг 2011, 16:10
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Очень часто как event handlers используются анонимные фреймы.
Первый вопрос - в плане там экономии памяти например, разница между использованием анонимного и обычного фрейма практически ничтожна для современных компьютеров или есть какие-то нюансы?
Второй вопрос - можно ли, и если можно, то как прикрепить к анонимному фрейму два различных обработчика, например OnUpdate и OnEvent.

Вот например анонимный фрейм к которому установлен обработчик OnUpdate, как к нему еще можно добавить OnEvent?
Код:

CreateFrame("Frame"):SetScript('OnUpdate', function(self, elapsed)
   if(self.elapsed and self.elapsed > 10) then
      do
      CombatLogClearEntries()
      end
      self.elapsed = 0
   else
      self.elapsed = (self.elapsed or 0) + elapsed
   end
end)


03 авг 2011, 15:08
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
И так, у нас есть простой "аддон":
Код:
local ChoAuraFrame = CreateFrame("Frame", "ChoAuraMainFrame", WorldFrame)
ChoAuraFrame:RegisterEvent("PLAYER_TARGET_CHANGED");
ChoAuraFrame:RegisterEvent("UNIT_AURA");

local function updateAuraFrames (self, event, arg1)

print(self)
print("Event: "..event)
print(arg1)

end

ChoAuraFrame:SetScript('OnEvent', updateAuraFrames)

После ознакомления с теоретическим описанием API CreateFrame, PLAYER_TARGET_CHANGED, UNIT_AURA, что я ожидал увидеть в работе от этого кода:
Когда у нас изменяется цель, мы берем в нее кого-то нового или очищаем таргет, срабатывает первый эвент, PLAYER_TARGET_CHANGED и в чат должны вывестись три сообщения.
В первом должен быть фрейм вызвавший срабатывание функции. Я думал, что под этим подразумевается имя фрейма, но на деле вместо имени всегда выводит как значение сообщение о том, что значение является таблицей.
Во втором должно быть имя эвента вызвавшего функцию, тут все ок.
В третьем должно быть, цитата с вики:
Цитата:

arg1 - up if you click the target directly, down if you press Escape to clear the target selection, LeftButton if you select the target using static frames in the UI, nil if the target moves out of range and is lost.

но у меня это значение всегда nil для этого эвента.

Когда у нашей цели или у нас или у еще некоторого списка юнитов (группа, арена и т.д.) появляется новая или заканчивается имевшаяся аура срабатывает второй эвент и так-же должны вывестись три сообщения.
В первом, и втором все обстоит также как с эвентом PLAYER_TARGET_CHANGED. Третий работает правильно, выводя юнита у которого изменилась аура.
Вот примеры того, что мы видим в чате для первого и второго эвента:
Цитата:

table: 18545E18
Event: PLAYER_TARGET_CHANGED
nil

table: 18545E18
Event: UNIT_AURA
target

Теперь вопросы. Почему не работает третий аргумент в PLAYER_TARGET_CHANGED тут вряд ли кто-то может знать, поэтому этот вопрос опустим. Второй вопрос, мне из любопытства хочется просмотреть содержимое, увидеть структуру этой таблицы выводимой вместо self.
Что я пытался для этого сделать:

Вместо "print(self)" использовал обход значений таблицы:
Код:
for k,v in pairs(self)
   do
   print("Key: ".. k)
   print(v)
end

Получил:
Цитата:

Key: 0
userdata: 0C543390

Хм.. выходит, что если в Луа стандартный индекс в таблице начинается не с нуля, а с единицы, то это на самом деле не таблица, раз у нее ключ 0, а список значений, как у оператора variable arguments (...)? Или-же ноль в данном случае вручную определенный ключ для этого списка значений.


Добавлено спустя 29 минут 55 секунд:

Так, раз self является таблицей, у этой таблицы есть один key равный 0, и value равное множеству значений которые не организованны в таблицу (на сколько я понимаю именно в таком случае выводится userdata, когда мы пытаемся как одно значение вывести множество перечисляемых значений), значит нам нужно это множество значений в свою очередь организовать в таблицу, что-бы далее можно было их обойти.

Пишем так:
Код:
local test = {self[0]} -- Создаем новую таблицу (массив), значениями которой должны стать значения соответствующие ключу 0 в таблице self, по идее я все правильно написал тут

for k,v in pairs(test)
   do
   print("Key: ".. k)
   print(v)
end


И мы получаем:
Цитата:

Key: 1
userdata: 1908AB1C

То есть фейл, не работает. Что дальше делать пока не знаю.


03 авг 2011, 21:06
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Посмотрел, что такое userdata, это в общем связанно с работой С функций ведущей программы, вытянуть сведения из нее, теми средствами, что я пытался, нельзя.

Не понимаю следующее, на вики статья http://www.wowpedia.org/API_CreateFrame, там есть пример кода, этот код выводит по центру экрана картинку с гербами фракций:
Код:
local f = CreateFrame("Frame",nil,UIParent)
f:SetFrameStrata("BACKGROUND")
f:SetWidth(128) -- Set these to whatever height/width is needed
f:SetHeight(64) -- for your Texture

local t = f:CreateTexture(nil,"BACKGROUND")
t:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Factions.blp")
t:SetAllPoints(f)
f.texture = t

f:SetPoint("CENTER",0,0)
f:Show()

В этом коде я не понимаю назначение одной строчки - "f.texture = t". Если ее убрать то все внешне работает точно так-же, никаких ошибок не выводится.
Но не в этом главное.
В этом коде используются две переменные, f и t. В теории вместо этих t и f можно использовать значения каких-то ключей в таблице, вот так на пример:
Код:
local testTableInTable = {}

testTableInTable[1] = CreateFrame("Frame",nil,UIParent)
testTableInTable[1]:SetFrameStrata("BACKGROUND")
testTableInTable[1]:SetWidth(128) -- Set these to whatever height/width is needed
testTableInTable[1]:SetHeight(64) -- for your Texture

testTableInTable[2] = testTableInTable[1]:CreateTexture(nil,"BACKGROUND")
testTableInTable[2]:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Factions.blp")
testTableInTable[2]:SetAllPoints(f)
testTableInTable[1].texture = testTableInTable[2]

testTableInTable[1]:SetPoint("CENTER",0,0)
testTableInTable[1]:Show()

То есть мы создали таблицу (массив), ее первое значение используется как f, второе как t.
Но теперь, если мы запустим этот код, то увидим, что картинка растянута полностью на все разрешение экрана, то есть я предполагаю, что строки
Код:
testTableInTable[1]:SetWidth(128) -- Set these to whatever height/width is needed
testTableInTable[1]:SetHeight(64) -- for your Texture

проигнорированы.

Собственно это мне нужно для другой цели, я пишу аддон для отображения аур. В нем будут блеклисты, где можно "забанить" определенные ауры, что-бы их не показывало, будут списки аур которые будут сливаться в одну, то есть например если на цели одновременно кидни и троудаун, то будет сравниваться их длительность и выводится иконка только того, кто будет длится дольше, так-же из всех замедлений будет можно будет выводить только самое длительное, плюс вывод определенных групп дебафов всегда на определенное место (первым в списке например), и определенного размера, и т.д. Он будет объединять в себе Power Auras, Lose Control, стандартные баффы, и блекджек с шлюхами.

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

Код:
local tableOfTargetDebuff = {}
local tableOfTargetDebuffFrames = {}

for i=1,40
   do
      if i == 1 then            
         local f = CreateFrame("Frame", nil, UIParent)
         f:SetFrameStrata("BACKGROUND")
         f:SetWidth(40)
         f:SetHeight(40)

         local t = f:CreateTexture(nil,"BACKGROUND")
         t:SetAllPoints(f)
         f:SetPoint("CENTER",0,0)
         f:Show()

         tableOfTargetDebuffFrames[i] = {}
         tableOfTargetDebuffFrames[i][1] = f
         tableOfTargetDebuffFrames[i][2] = t         
      elseif i > 1 then         
         local f = CreateFrame("Frame", nil, tableOfTargetDebuffFrames[i - 1][1])
         f:SetFrameStrata("BACKGROUND")
         f:SetWidth(40)
         f:SetHeight(40)

         local t = f:CreateTexture(nil,"BACKGROUND")
         t:SetAllPoints(f)
         f:SetPoint("CENTER", tableOfTargetDebuffFrames[i - 1][1], "CENTER", -40, 0);
         f:Show()

         tableOfTargetDebuffFrames[i] = {}
         tableOfTargetDebuffFrames[i][1] = f
         tableOfTargetDebuffFrames[i][2] = t         
      end
   end

local function setAuraFromTable()
for i=1,#tableOfTargetDebuff
   do
   tableOfTargetDebuffFrames[i][2]:setTexture(tableOfTargetDebuff[i])
   end
wipe(tableOfTargetDebuff)
end

local function CA_EventHandlerFunction (self, event, arg1)
local exists = UnitExists("target");
   if exists == 1 then
      do
      for i=1,40
         do
         local a={UnitAura("target", i, "HARMFUL")}
            if a[3] then
            --print("First loop: "..a[3])
            table.insert(tableOfTargetDebuff, a[3])
            end
         end
      end
   elseif exists == nil then
   wipe(tableOfTargetDebuff)
   end
setAuraFromTable()
end

local CA_EventHandler = CreateFrame("Frame", nil, UIParent)
CA_EventHandler:RegisterEvent("PLAYER_TARGET_CHANGED");
CA_EventHandler:RegisterEvent("UNIT_AURA");
CA_EventHandler:SetScript('OnEvent', CA_EventHandlerFunction)


Но он не делает.
Вот эта строка и ошибка в ней которая ломает аддон.
Код:
tableOfTargetDebuffFrames[i][2]:setTexture(tableOfTargetDebuff[i])

attempt to call method 'setTexture' (a nil value)

То есть t не сохраняется должным образом в tableOfTargetDebuffFrames[i][2]. Если устанавливать текстуры при создании фреймов, то есть устанавливать текстуру для t, то все работает, а если это t сохранить в tableOfTargetDebuffFrames[i][2], и затем попытаться установить текстуру для tableOfTargetDebuffFrames[i][2], то получаем ошибку.


05 авг 2011, 23:27
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Отрицание писал(а):

То есть мы создали таблицу (массив), ее первое значение используется как f, второе как t.
Но теперь, если мы запустим этот код, то увидим, что картинка растянута полностью на все разрешение экрана, то есть я предполагаю, что строки
Код:
testTableInTable[1]:SetWidth(128) -- Set these to whatever height/width is needed
testTableInTable[1]:SetHeight(64) -- for your Texture

проигнорированы.


Ошибка в строке
Код:

testTableInTable[2]:SetAllPoints(f)

Должно быть
Код:

testTableInTable[2]:SetAllPoints(testTableInTable[1])


Отрицание писал(а):

Но он не делает.
Вот эта строка и ошибка в ней которая ломает аддон.
Код:
tableOfTargetDebuffFrames[i][2]:setTexture(tableOfTargetDebuff[i])


setTexture должно быть с большой буквы.


06 авг 2011, 08:32
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
:chok
Спасибо, исправил, заработало. Прямо не ожидал, что так накосячить могу.
Когда заработало, заметил, что не организовал удаление текстур закончившихся аур в пустых фреймах, исправил это:
Код:
local function setAuraFromTable()
for i=1,40
   do
      if tableOfTargetDebuff[i] == nil then
      tableOfTargetDebuffFrames[i][2]:SetTexture(0,0,0,0)
      else
      tableOfTargetDebuffFrames[i][2]:SetTexture(tableOfTargetDebuff[i])
      end
   end
wipe(tableOfTargetDebuff)
end


06 авг 2011, 15:37
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Отображаем все баффы и дебаффы на цели, выглядит так:

#691


Код:
Код:
DB = Test_saving_value

local PlayerAurasTable = {}
local TargetAurasTable = {}
local PlayerAuraFramesTable = {}
local TargetAuraFramesTable = {}

local f = CreateFrame("Frame", nil, UIParent)
f:SetFrameStrata("BACKGROUND")
f:SetWidth(40)
f:SetHeight(40)
f:SetPoint("CENTER",0,0)
f:Show()      
local TargetFrameAnchor = f

for i=1,80
do
   if i == 1 or i == 41 then
      local f = CreateFrame("Frame", nil, TargetFrameAnchor)
      local t = f:CreateTexture(nil,"BACKGROUND")
        t:SetAllPoints(f)         
        TargetAuraFramesTable[i] = {}
        TargetAuraFramesTable[i][1] = f
        TargetAuraFramesTable[i][2] = t         
    else
        local f = CreateFrame("Frame", nil, TargetAuraFramesTable[i - 1][1])
      local t = f:CreateTexture(nil,"BACKGROUND")
        t:SetAllPoints(f)
        TargetAuraFramesTable[i] = {}
        TargetAuraFramesTable[i][1] = f
        TargetAuraFramesTable[i][2] = t         
    end
end

local function setAuraFromTable()
for i=1,80
   do
      if i == 1 then
         if TargetAurasTable[i] == nil then
         TargetAuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         TargetAuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         TargetAuraFramesTable[i][1]:SetWidth(30)
         TargetAuraFramesTable[i][1]:SetHeight(30)
         TargetAuraFramesTable[i][1]:SetPoint("CENTER", TargetFrameAnchor, "CENTER", -30, 0);
         TargetAuraFramesTable[i][1]:Show()
         TargetAuraFramesTable[i][2]:SetTexture(TargetAurasTable[i])
         end
      elseif i > 1 and i <=40 then
         if TargetAurasTable[i] == nil then
         TargetAuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         TargetAuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         TargetAuraFramesTable[i][1]:SetWidth(30)
         TargetAuraFramesTable[i][1]:SetHeight(30)
         TargetAuraFramesTable[i][1]:SetPoint("CENTER", TargetAuraFramesTable[i - 1][1], "CENTER", -30, 0);
         TargetAuraFramesTable[i][1]:Show()
         TargetAuraFramesTable[i][2]:SetTexture(TargetAurasTable[i])
         end
      elseif i == 41 then
         if TargetAurasTable[i] == nil then
         TargetAuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         TargetAuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         TargetAuraFramesTable[i][1]:SetWidth(30)
         TargetAuraFramesTable[i][1]:SetHeight(30)
         TargetAuraFramesTable[i][1]:SetPoint("CENTER", TargetFrameAnchor, "CENTER", 30, 0);
         TargetAuraFramesTable[i][1]:Show()
         TargetAuraFramesTable[i][2]:SetTexture(TargetAurasTable[i])
         end
      elseif i > 41 then
         if TargetAurasTable[i] == nil then
         TargetAuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         TargetAuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         TargetAuraFramesTable[i][1]:SetWidth(30)
         TargetAuraFramesTable[i][1]:SetHeight(30)
         TargetAuraFramesTable[i][1]:SetPoint("CENTER", TargetAuraFramesTable[i - 1][1], "CENTER", 30, 0);
         TargetAuraFramesTable[i][1]:Show()
         TargetAuraFramesTable[i][2]:SetTexture(TargetAurasTable[i])
         end
      end
   end
wipe(TargetAurasTable)
wipe(PlayerAurasTable)
end

local function EventHandlerFunction (self, event, arg1)
local AurasTable = AurasTable
local Unit = Unit
   if event == "PLAYER_TARGET_CHANGED" then
      do
      local exists = UnitExists("target");
         if exists == nil then
         wipe(TargetAurasTable)
         setAuraFromTable()
         return
         else
         AurasTable = TargetAurasTable
         Unit = "target"
         end
      end
   elseif event == "UNIT_AURA" then
      do
      Unit = arg1
         if arg1 == "player" then
         AurasTable = PlayerAurasTable
         elseif arg1 == "target" then
         AurasTable = TargetAurasTable
         end
      end
   end         
for i=1,40
   do
   local a={UnitAura(Unit, i, "HARMFUL")}
      if a[3] then
      table.insert(AurasTable, i, a[3])
      end
   end
for i=41,80
   do
   local a={UnitAura(Unit, i-40, "HELPFUL")}
      if a[3] then
      table.insert(AurasTable, i, a[3])
      end
   end
setAuraFromTable()
end

local EventHandlerFrame = CreateFrame("Frame", nil, UIParent)
EventHandlerFrame:RegisterEvent("PLAYER_TARGET_CHANGED");
EventHandlerFrame:RegisterEvent("UNIT_AURA");
EventHandlerFrame:SetScript('OnEvent', EventHandlerFunction)


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


07 авг 2011, 21:25
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Баффы и дебаффы на цели и на игроке:
Код:
local PlayerAurasTable = {}
local TargetAurasTable = {}
local PlayerAuraFramesTable = {}
local TargetAuraFramesTable = {}

local f = CreateFrame("Frame", nil, UIParent)
f:SetFrameStrata("BACKGROUND")
f:SetWidth(40)
f:SetHeight(40)
f:SetPoint("CENTER", 0, -280)
f:Show()      
local PlayerFrameAnchor = f

local f = CreateFrame("Frame", nil, UIParent)
f:SetFrameStrata("BACKGROUND")
f:SetWidth(40)
f:SetHeight(40)
f:SetPoint("CENTER", 0, -150)
f:Show()      
local TargetFrameAnchor = f

for a=1,2
   do
   local AuraFramesTable
   local FrameAnchor
      if a == 1 then
         do
         AuraFramesTable = TargetAuraFramesTable
         FrameAnchor = TargetFrameAnchor
         end
      elseif a == 2 then
         do
         AuraFramesTable = PlayerAuraFramesTable
         FrameAnchor = PlayerFrameAnchor
         end
      end
   for i=1,80
      do
         if i == 1 or i == 41 then
         local f = CreateFrame("Frame", nil, FrameAnchor)
         local t = f:CreateTexture(nil,"BACKGROUND")
         t:SetAllPoints(f)         
         AuraFramesTable[i] = {}
         AuraFramesTable[i][1] = f
         AuraFramesTable[i][2] = t         
         else
         local f = CreateFrame("Frame", nil, AuraFramesTable[i - 1][1])
         local t = f:CreateTexture(nil,"BACKGROUND")
         t:SetAllPoints(f)
         AuraFramesTable[i] = {}
         AuraFramesTable[i][1] = f
         AuraFramesTable[i][2] = t         
         end
      end
   end


local function setAuraFromTable(Unit)
local AuraFramesTable
local AurasTable
local FrameAnchor
   if Unit == "target" then
      do
      AuraFramesTable = TargetAuraFramesTable
      AurasTable = TargetAurasTable
      FrameAnchor = TargetFrameAnchor
      end
   elseif Unit == "player" then
      do
      AuraFramesTable = PlayerAuraFramesTable
      AurasTable = PlayerAurasTable
      FrameAnchor = PlayerFrameAnchor
      end
   end   
for i=1,80
   do
      if i == 1 then
         if AurasTable[i] == nil then
         AuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         AuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         AuraFramesTable[i][1]:SetWidth(30)
         AuraFramesTable[i][1]:SetHeight(30)
         AuraFramesTable[i][1]:SetPoint("CENTER", FrameAnchor, "CENTER", -30, 0);
         AuraFramesTable[i][1]:Show()
         AuraFramesTable[i][2]:SetTexture(AurasTable[i])
         end
      elseif i > 1 and i <=40 then
         if AurasTable[i] == nil then
         AuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         AuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         AuraFramesTable[i][1]:SetWidth(30)
         AuraFramesTable[i][1]:SetHeight(30)
         AuraFramesTable[i][1]:SetPoint("CENTER", AuraFramesTable[i - 1][1], "CENTER", -30, 0);
         AuraFramesTable[i][1]:Show()
         AuraFramesTable[i][2]:SetTexture(AurasTable[i])
         end
      elseif i == 41 then
         if AurasTable[i] == nil then
         AuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         AuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         AuraFramesTable[i][1]:SetWidth(30)
         AuraFramesTable[i][1]:SetHeight(30)
         AuraFramesTable[i][1]:SetPoint("CENTER", FrameAnchor, "CENTER", 30, 0);
         AuraFramesTable[i][1]:Show()
         AuraFramesTable[i][2]:SetTexture(AurasTable[i])
         end
      elseif i > 41 then
         if AurasTable[i] == nil then
         AuraFramesTable[i][2]:SetTexture(0,0,0,0)
         else
         AuraFramesTable[i][1]:SetFrameStrata("BACKGROUND")
         AuraFramesTable[i][1]:SetWidth(30)
         AuraFramesTable[i][1]:SetHeight(30)
         AuraFramesTable[i][1]:SetPoint("CENTER", AuraFramesTable[i - 1][1], "CENTER", 30, 0);
         AuraFramesTable[i][1]:Show()
         AuraFramesTable[i][2]:SetTexture(AurasTable[i])
         end
      end
   end
wipe(AurasTable)
end

local function FillingAurasTable(Unit, AurasTable)
for i=1,40
   do
   local a={UnitAura(Unit, i, "HARMFUL")}
      if a[3] then
      table.insert(AurasTable, i, a[3])
      end
   end
for i=41,80
   do
   local a={UnitAura(Unit, i-40, "HELPFUL")}
      if a[3] then
      table.insert(AurasTable, i, a[3])
      end
   end
setAuraFromTable(Unit)
end

local function EventHandlerFunction (self, event, arg1)
local AurasTable
local Unit
   if event == "PLAYER_ENTERING_WORLD" then
      do
      Unit = "player"
      AurasTable = PlayerAurasTable
      end
   elseif event == "PLAYER_TARGET_CHANGED" then
      do
      local exists = UnitExists("target");
         if exists == nil then
         Unit = "target"
         wipe(TargetAurasTable)
         setAuraFromTable(Unit)
         return
         else
         Unit = "target"
         AurasTable = TargetAurasTable         
         end
      end
   elseif event == "UNIT_AURA" then
      do
      Unit = arg1
         if arg1 == "player" then
         AurasTable = PlayerAurasTable
         elseif arg1 == "target" then
         AurasTable = TargetAurasTable
         end
      end
   end
FillingAurasTable(Unit, AurasTable)
end

local EventHandlerFrame = CreateFrame("Frame", nil, UIParent)
EventHandlerFrame:RegisterEvent("PLAYER_ENTERING_WORLD");
EventHandlerFrame:RegisterEvent("PLAYER_TARGET_CHANGED");
EventHandlerFrame:RegisterEvent("UNIT_AURA");
EventHandlerFrame:SetScript('OnEvent', EventHandlerFunction)


08 авг 2011, 16:45
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Для чего в Lua используется знак ";" в конце строки?
Если знаете в каком параграфе об этом пишется, или в общем где прочитать об этом, просто линканите.


10 авг 2011, 23:39
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Отрицание писал(а):

Для чего в Lua используется знак ";" в конце строки?
Если знаете в каком параграфе об этом пишется, или в общем где прочитать об этом, просто линканите.

клац


11 авг 2011, 00:02
Профиль

0
Сообщение Вопросы по Lua, XML, WoW API.
Цитата:

a=nil ; print( type(a) ) ;
...

Из последнего однострочного примера можно «выудить» еще одно сведение о Lua – об использовании точки с запятой. В Lua этот символ можно применять для разделения операторов, при записи их в одну строку. Во всех остальных случаях использование ";" необязательно (в том числе и в приведенном примере – последний символ строки в принципе не нужен).

Спасибо.


11 авг 2011, 01:37
Профиль
Начать новую тему Ответить на тему


Перейти:  

брюки
На сайте использованы материалы, принадлежащие Blizzard Entertainment. Копирование материалов возможно только c разрешения портала. В противном случае это будет называться уже другим словом.
Рейтинг@Mail.ru