Вопросы по Lua, XML, WoW API.
Автор | Сообщение |
---|---|
|
0
При написании своих аддонов или модификации под себя существующих часто возникают различные вопросы касательно 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
Цитата: Но есть вопрос, что если я хочу что-бы из таблицы подставлялись только ключи с определенным значением, то есть например только CC если я правильно понял вопрос, то все что тебе нужно это добавить еще одно условие, т. е. Код: if a[1]==k then break заменить на Код: if a[1]==k and v == "CC" then break по второму вопросу Цитата: 1 ключ "отзывался" на несколько значений, типа как тегов Почитай тут: Первая часть, про матрицы, как раз, что тебе нужно. Вкратце: каждый элемент таблицы тоже может являться таблицей, т. е. можно написать что-то вроде Код: 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
Спасибо, проверка
Код: 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
Смотри какой расклад, если ты хочешь проверять только определенные виды дебафов (например 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
Да, с этим вопросом понятно.
В аддоне, в зависимости от происходящего, может быть от одной до двух десятков проверок цели на ауры. Для ситуации когда идет пара десятков проверок, в плане производительности, стоит делать каждую проверку как в примерах выше Код: 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
Думаю, разница есть (с таблицей должно работать быстрее)
Насколько разница будет велика и будет ли она критична - лучше замерить. |
15 июл 2011, 10:58 |
|
|
0
Делал проверку наличия на цели аур из таблицы. Было такой работающий вариант, уже писал в первом посте:
Код: 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
я бы на твоем месте возвращал k, тогда вместо print("На нас сайленс"); можно было бы выводить какой конкретно сайленс висит, а если никакой не висит то возвращать false или 0
|
15 июл 2011, 19:02 |
|
|
0
Сенк, хорошая идея, сделал, работает:
Код: 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
Как я понимаю в близзовском коде интерфейса есть глобальная переменная отвечающая за цветовую раскраску классов, то есть например дающая те цвета в которые окрашиваются неймплейты если включить опцию окраски их по цвету класса.
Вопрос - можно-ли эту глобальную переменную изменить, что-бы например при загрузке какой-то аддон переопределял цвета для каждого класса и затем все элементы интерфейса которые берут цвета из этой глобальной переменной близов использовали именно измененные цвета. Также помимо цвета классов интересуют и стандартная раскраска вражеской (красный), дружеской (зеленый), с выключенным пвп режимом (синий), нейтральный (желтый), что-бы эти стандартные значения цветов тоже глобально переопределить. Или-же присваивать значения глобальным переменным близов нельзя и для изменения этих цветовых схем нужно в каждом аддоне определять класс цели и вручную в зависимости от него устанавливать свои цвета для нужных фреймов? Добавлено спустя 3 минуты 19 секунд: Еще на днях разобрался с тем как получить возможность редактировать близовские неймплейты, как это делают Aloft, Tidy Plates и т.д., если кому-то нужно могу рассказать. Добавлено спустя 6 минут 52 секунды: А, и вот еще - хочу изменить те Tooltips которые появляются в нижнем правом углу экрана когда наводишь на игрока или нпс, там где пишется ник, гильдия, звание и еще некоторый хлам. Конкретно интересует возможность полностью отключить этот тултип, но при этом что-бы остальные тултипы, от итемов, элементов интерфейса, заклинаний продолжали показываться, то есть отключать нужно только тултипы от игроков и нпс. Так-же не откажусь от возможности скрыть только отдельные элементы этой подсказки, например убрать зеленую полоску хп с самого низа. Аддоны которые модифицируют эти тултипы я уже нашел, буду смотреть, разбираться с кодом как они это делают. В основном вопрос в том, является-ли этот тултип от игроков и нпс уникальным фреймом, или-же все эти подсказки являются как-бы одним фреймом, и для того, что-бы скрыть тултипы от игроков и нпс, а оставить остальные нужно будет писать код который будет по содержимому тултипа распознавать чем именно он является и в зависимости от этого скрывать. Если-же этот фрейм является отдельным фреймом то для его скрытия там пару строчек кода нужно всего. Добавлено спустя 4 минуты 56 секунд: Иииииииии.. Ээ.. Есть вообще сайты с активным ру addon-developer community? |
01 авг 2011, 16:10 |
|
|
0
Очень часто как 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
И так, у нас есть простой "аддон":
Код: 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
Посмотрел, что такое userdata, это в общем связанно с работой С функций ведущей программы, вытянуть сведения из нее, теми средствами, что я пытался, нельзя.
Не понимаю следующее, на вики статья Код: 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 проигнорированы. Собственно это мне нужно для другой цели, я пишу аддон для отображения аур. Все это я думаю делать через таблицы. И для начала просто решил организовать вывод, например, всех дебаффов на цели, просто в ряд расставить их, а далее начинать добавлять разный функционал. Вот этот код должен был это делать: Код: 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
Отрицание писал(а): То есть мы создали таблицу (массив), ее первое значение используется как 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
Спасибо, исправил, заработало. Прямо не ожидал, что так накосячить могу. Когда заработало, заметил, что не организовал удаление текстур закончившихся аур в пустых фреймах, исправил это: Код: 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
Отображаем все баффы и дебаффы на цели, выглядит так:
#724 Код: Код: 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
Баффы и дебаффы на цели и на игроке:
Код: 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 используется знак ";" в конце строки?
Если знаете в каком параграфе об этом пишется, или в общем где прочитать об этом, просто линканите. |
10 авг 2011, 23:39 |
|
|
0
Отрицание писал(а): Для чего в Lua используется знак ";" в конце строки? Если знаете в каком параграфе об этом пишется, или в общем где прочитать об этом, просто линканите. |
11 авг 2011, 00:02 |
|
|
0
Цитата: a=nil ; print( type(a) ) ; ... Из последнего однострочного примера можно «выудить» еще одно сведение о Lua – об использовании точки с запятой. В Lua этот символ можно применять для разделения операторов, при записи их в одну строку. Во всех остальных случаях использование ";" необязательно (в том числе и в приведенном примере – последний символ строки в принципе не нужен). Спасибо. |
11 авг 2011, 01:37 |
|