Вопросы по Lua, XML, WoW API.
Автор | Сообщение |
---|---|
|
0
Переработал под себя Leatrix_Tooltip. Одна из настроек - не показывать тултипы от тотемов и разнообразных видов петов. Для того, что-бы определить, что у нас под мышкой именно эти объекты, показ тултипа от которых нужно заблокировать, делаем поиск определенных слов во второй строке тултипа, где они и должны быть:
Код: if string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "тотем") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "питомец") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "прислужник") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "страж") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "спутник") then И вот какое-то длинноватое условие вышло, можно-ли не писать отдельно для каждого из ключевых слов это: "string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())),"? Есть способы сократить эту запись, кроме создания таблицы из этих ключевых слов и итерации по ней? Добавлено спустя 27 минут 22 секунды: И еще. При использовании обработчика "OnUpdate" можно настроить частоту его вызова, так-как по умолчанию он будет вызываться при каждом обновлении экрана, что совершенно не требуется. Например вот здесь этот обработчик будет запускать код только 1 раз в 10 секунд: Код: local f = CreateFrame("Frame", nil, UIParent) f:SetScript('OnUpdate', function(self, elapsed) if(self.elapsed and self.elapsed > 10) then do print("Прошло 10 секунд.") end self.elapsed = 0 else self.elapsed = (self.elapsed or 0) + elapsed end end) А вот как работают обработчики OnEvent? Например мы повесили запуск функции от события UNIT_AURA, но если взять ситуацию на бг, когда одну цель могут бить десяток человек, и хилить несколько, плюс это событие запускается и от ваших аур, и от аур членов всего рейда, то может выйти еще большая частота запуска события чем при OnUpdate, при чем такая частота совершенно бессмысленна. Там есть какой-от встроенный ограничитель частоты запуска события, или это тоже нужно что-то вручную выписывать как с OnUpdate? |
13 авг 2011, 17:36 |
|
|
0
Отрицание писал(а): Переработал под себя Leatrix_Tooltip. Одна из настроек - не показывать тултипы от тотемов и разнообразных видов петов. Для того, что-бы определить, что у нас под мышкой именно эти объекты, показ тултипа от которых нужно заблокировать, делаем поиск определенных слов во второй строке тултипа, где они и должны быть: Код: if string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "тотем") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "питомец") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "прислужник") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "страж") or string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())), "спутник") then И вот какое-то длинноватое условие вышло, можно-ли не писать отдельно для каждого из ключевых слов это: "string.match((string.lower(_G["GameTooltipTextLeft2"]:GetText())),"? Есть способы сократить эту запись, кроме создания таблицы из этих ключевых слов и итерации по ней? Добавлено спустя 27 минут 22 секунды: И еще. При использовании обработчика "OnUpdate" можно настроить частоту его вызова, так-как по умолчанию он будет вызываться при каждом обновлении экрана, что совершенно не требуется. Например вот здесь этот обработчик будет запускать код только 1 раз в 10 секунд: Код: local f = CreateFrame("Frame", nil, UIParent) f:SetScript('OnUpdate', function(self, elapsed) if(self.elapsed and self.elapsed > 10) then do print("Прошло 10 секунд.") end self.elapsed = 0 else self.elapsed = (self.elapsed or 0) + elapsed end end) А вот как работают обработчики OnEvent? Например мы повесили запуск функции от события UNIT_AURA, но если взять ситуацию на бг, когда одну цель могут бить десяток человек, и хилить несколько, плюс это событие запускается и от ваших аур, и от аур членов всего рейда, то может выйти еще большая частота запуска события чем при OnUpdate, при чем такая частота совершенно бессмысленна. Там есть какой-от встроенный ограничитель частоты запуска события, или это тоже нужно что-то вручную выписывать как с OnUpdate? Можно вынести Код: string.lower(_G["GameTooltipTextLeft2"]:GetText()) в переменную, и потом вызывать string.match для этой переменной сколько нужно раз, так и работать будет быстрее... По второму вопросу: нет встроенного ограничения. |
13 авг 2011, 18:48 |
|
|
0
Killshot писал(а): Можно вынести Код: string.lower(_G["GameTooltipTextLeft2"]:GetText()) в переменную, и потом вызывать string.match для этой переменной сколько нужно раз, так и работать будет быстрее... Да, так лучше будет, только я еще думал о чем-то типа variable arguments (...), в функциях, то есть что-бы написать строку string.lower(_G["GameTooltipTextLeft2"]:GetText()) только 1 раз, и в этом одном написании сделать проверку сразу всех строк, ну если например через таблицу это делать, то так: Код: patternTable = { "тотем", "спутник", "питомец", "страж", "создание", "прислужник", } local string = string.lower(_G["GameTooltipTextLeft2"]:GetText()) for i=1,6 do string.match(string, patternTable[i]) end |
13 авг 2011, 19:11 |
|
|
0
Есть таблица, например
Код: local qwerty = {} qwerty.q = 1 qwerty.w = 2 И есть переменная, строка "qwerty", то есть Код: local somevalue = "qwerty" Как используя эту переменную обратится к нашей таблице и извлечь из нее какую-либо запись? То есть нужен эквивалент запроса Код: local somevaluetwo = qwerty.q Только вместо прямого обращения по имени таблицы (qwerty) подставить строку из переменной somevalue потому-что в общем коде это будет выглядеть очень красиво, там много таких таблиц, а эта переменная somevalue является аргументом передаваемым в функцию и должна определять из какой именно таблицы мы берем значения. Не предлагать вариант: Код: if somevalue == "qwerty" then linktotable = qwerty end Потому-что такой вариант уже есть. И не предлагать вложить все эти таблицы в одну общую, что-бы запрос мог выглядеть так: Код: local somevaluetwo = globaltable[somevalue].q Потому-что так тоже уже было и мне кажется унылым создавать дополнительный уровень вложенности ради этого. Если-бы таблицы были глобальными, то они уже были-бы вложены в _G, но они локальные, и делать их глобальными не нужно. |
20 дек 2011, 17:34 |
|
|
0
"qwerty" это значение а qwerty это символическое описание обьекта (таблицы), не получится, так как ты хотел
|
21 дек 2011, 12:02 |
|
|
0
Да, я понимаю разницу, но думал может есть какая-то функция, типа как tostring и tonumber, но что-бы она превратила строку в обращение к переменной имя которой совпадает с символами в этой строке. Как-то так.
Пока остановился на последнем описанном варианте, вложил все таблицы в одну общую, и тогда можно обращаться к ним так: Код: local globaltable = { qwerty1 = { qwerty.q = 1 qwerty.w = 2 } qwerty2 = { qwerty.q = 3 qwerty.w = 4 } } local pointervalue = "qwerty1" print(globaltable[pointervalue].q) -- Выведет 1 |
22 дек 2011, 00:42 |
|
|
0
Уважаемые Знатоки!
Кто-нибудь может подсказать, в чем может быть ошибка в следующем коде из аддона Код: стр. 319 --> local function updateScores() local index=1 local status, pattern, temp for i = 1, MAX_BATTLEFIELD_QUEUES do status, temp = GetBattlefieldStatus(i) if ( status == "active" ) and ( temp == "Eye of the Storm" ) then index = 2 pattern = "(%d+)/(.+)" elseif ( status == "active" ) and ( temp == "Alterac Valley" ) then pattern = ":(%d+)" else pattern = "(%d+)/(.+)" end end _, _, temp = GetWorldStateUIInfo(index) if temp then стр. 335 --> allianceScoreText:SetText(temp:match(pattern)) else allianceScoreText:SetText(nil) end _, _, temp = GetWorldStateUIInfo(index+1) if temp then стр. 342 --> hordeScoreText:SetText(temp:match(pattern)) else hordeScoreText:SetText(nil) end end Код ошибки: Код: 11x TFScoreBoard\scoreboard.lua:335: bad argument #1 to 'match' (string expected, got nil) TFScoreBoard\scoreboard.lua:335: in function Предположу, что та же ошибка, что и в строчке 335 будет в строчке 342. |
19 янв 2012, 15:50 |
|
|
0
Попробуй так:
_, _, _, temp = GetWorldStateUIInfo ... |
19 янв 2012, 23:12 |
|
|
0
Killshot писал(а): Попробуй так: _, _, _, temp = GetWorldStateUIInfo ... Уже пробежался по всему файлу и заменил все аргументы и функции в соответствии с последними изменениями в игре (по крайней мере надеюсь, что заменил). Но дело, похоже, не в этой строчке, а в, как мыслю, в том, что allianceScoreText:SetText(temp:match(pattern)) ожидает "строку", а получает "nil". В строках/шаблонах я не мыслю, поэтому и прошу помощи здесь =) |
20 янв 2012, 00:04 |
|
|
0
Тогда попробуй заменить MAX_BATTLEFIELD_QUEUES на GetMaxBattlefieldID(). И еще "Eye of the Storm" и "Alterac Valley" должны быть русскими аналогами если используется русский языковой пакет.
|
20 янв 2012, 06:02 |
|
|
0
Killshot писал(а): Тогда попробуй заменить MAX_BATTLEFIELD_QUEUES на GetMaxBattlefieldID(). И еще "Eye of the Storm" и "Alterac Valley" должны быть русскими аналогами если используется русский языковой пакет. Я же сказал, что заменил все что можно в файле в соответствии с последними изменениями в WOW LUA, в том числе и MAX_BATTLEFIELD_QUEUES на GetMaxBattlefieldID() =) Играю на EU. |
20 янв 2012, 09:30 |
|
|
0
Atuin писал(а): Killshot писал(а): Тогда попробуй заменить MAX_BATTLEFIELD_QUEUES на GetMaxBattlefieldID(). И еще "Eye of the Storm" и "Alterac Valley" должны быть русскими аналогами если используется русский языковой пакет. Я же сказал, что заменил все что можно в файле в соответствии с последними изменениями в WOW LUA, в том числе и MAX_BATTLEFIELD_QUEUES на GetMaxBattlefieldID() =) Играю на EU. Тогда должно работать. |
20 янв 2012, 13:12 |
|
|
0
Ты вызываешь для объекта temp метод match с аргументом pattern. То есть где-то в коде аддона должен быть описан метод match, и где-то в нем ты можешь введя дополнительную проверку обойти этот "nil", например, что-бы в случае если там не строка, а nil, то метод просто ничего не делал. Но это, возможно вызовет не совсем корректную работу аддона.
Найди эту функцию match и скопируй ее сюда, что там она делает? Добавлено спустя 9 минут 57 секунд: Кстати в статье по апи GetWorldStateUIInfo два несоответствия, во первых там не сказано, что будет возвращать функция для альтерака, двух пиков и т.д., может для них она возвращает nil? Во вторых 1 или 2 это запрос для орды либо альянса, не совсем понимаю, зачем ты запрашиваешь инфо по орде находять на оке, а для остальных бг - для альянса? Можно-ли вообще запрашивать инфо для чужой фракции? Может nil потому-что ты запрашиваешь инфо орды будучи альянсом, или наоборот? |
21 янв 2012, 18:52 |
|
|
0
Отрицание писал(а): Ты вызываешь для объекта temp метод match с аргументом pattern. То есть где-то в коде аддона должен быть описан метод match, и где-то в нем ты можешь введя дополнительную проверку обойти этот "nil", например, что-бы в случае если там не строка, а nil, то метод просто ничего не делал. Но это, возможно вызовет не совсем корректную работу аддона. Найди эту функцию match и скопируй ее сюда, что там она делает? Это встроенная в lua интерпретатор функция для работы со строками. |
22 янв 2012, 20:37 |
|
|
0
Точно, сфейлил, сам-же использовал ее пару постов назад.
Попробуй заменить это Код: if temp then allianceScoreText:SetText(temp:match(pattern)) else allianceScoreText:SetText(nil) end На это Код: if temp then assert(type(temp) == "string", "Unexpected data type in temp") assert(pattern, "Pattern is nil") allianceScoreText:SetText(temp:match(pattern)) else allianceScoreText:SetText(nil) end Что-бы попытаться как-то уточнить, с чем проблема, соответственно новую ошибку отпиши сюда. Или еще вариант, отдельно попробуй другой синтаксис match, ну так на всякий случай, вдруг что? Вместо allianceScoreText:SetText(temp:match(pattern)) Вот это allianceScoreText:SetText(string.match(temp, pattern)) А теперь вопрос от меня, кто нибудь работал с библиотекой CallbackHandler? Ее используют почти все крупные аддоны. Можете объяснить ее суть? Типа она организовывает коммуникацию между аддонами? Ну и как мне обращаться через эту библиотеку к какому-то другому аддону, или там объекту в нем? |
24 янв 2012, 21:12 |
|
|
0
Отрицание писал(а): Точно, сфейлил, сам-же использовал ее пару постов назад. Попробуй заменить это Код: if temp then allianceScoreText:SetText(temp:match(pattern)) else allianceScoreText:SetText(nil) end На это Код: if temp then assert(type(temp) == "string", "Unexpected data type in temp") assert(pattern, "Pattern is nil") allianceScoreText:SetText(temp:match(pattern)) else allianceScoreText:SetText(nil) end Что-бы попытаться как-то уточнить, с чем проблема, соответственно новую ошибку отпиши сюда. Или еще вариант, отдельно попробуй другой синтаксис match, ну так на всякий случай, вдруг что? Вместо allianceScoreText:SetText(temp:match(pattern)) Вот это allianceScoreText:SetText(string.match(temp, pattern)) Советы не пригодились. Аддон починил. Вроде как работает на всех БГ теперь. Выложил на wowinterface.com В любом случае, спасибо за участие в дискурсе |
25 янв 2012, 10:22 |
|
|
0
есть код:
Код: local setStyleAura = function(bname, index, isDebuff) local button = _G[bname..index] local icon = _G[bname..index.."Icon"] local cd = _G[bname..index.."Cooldown"] local count = _G[bname..index.."Count"] local border = _G[bname..index.."Border"] if button.bd==nil then button.bd = button:CreateTexture(bname..index.."Overlay", "BORDER") button.bd:SetAllPoints(button) button.bd:SetTexture("Interface\\Addons\\media\\texture\\border") --button.bd:SetTexCoord(1 / 128, 35 / 128, 207 / 256, 240 / 256) button.bd:SetDesaturated(1) end if border then border:Hide() button.bd:SetVertexColor(unpack({border:GetVertexColor()})) border.Show = function() end end if icon then icon:SetTexCoord(.1, .9, .1, .9) icon:SetPoint("TOPLEFT", button, "TOPLEFT", 3, -3) icon:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -3, 3) if cd then cd:SetAllPoints(icon) end end if count then count:SetDrawLayer("OVERLAY") count:ClearAllPoints() count:SetFont(count:GetFont(), 10, "OUTLINE") count:SetPoint("TOPRIGHT", button, 0, 0) end end выдрал из SuperClassic'а Fernira, будет ли этот код стилизовать иконки бафов, дебафов стандартных таргет и фокус фреймов, если я его запихну в отдельный аддон и подсуну свою текстуру бордера? или надо что то допилить? или возможно ли сделать небольшой аддон, наподобие rActionButtonStyler, который бы стилизовал экшенбары, бафы, дебафы у минимапы, бафы, дебафы на таргете и фокусе дефолтного ui ? знаю есть Masque который вместе с BlizzFacade стилизует все, но опять же кроме бафов, дебафов на фреймах |
27 янв 2012, 08:44 |
|
|
0
ребята подскажите пожалуйста. Хочу использовать макрос по mod:Shift. Но кнопка забиндена на дополнительную клавиатуру (т.е. на num1). Вобщем такая фишка если нажимать shift+num1, то это эквивалентно нажатию кнопки 'end', как сделать чтобы было нормально? :)
P.S. сам создать свою тему не могу в виду ограничений на создание тем, наиболее близкой посчитал эту тему, не ругайте сильно. буду очень благодарен за совет как можно решить эту проблему(с модификаторами ctrl и alt все работает нормально) |
28 янв 2012, 14:27 |
|
|
0
Подскажите пожалуйста.
Есть аддон Holy Power Notifier Его код. -- -- Holy Power Notifier - Tells you when you've got Holy Power. -- Gilbert - Tichondrius US -- -- Stop now if the player isn't a Paladin. if select(2, UnitClass('player')) ~= "PALADIN" then DisableAddOn("HolyPowerNotifier") return end -- Set up our frame local frame, events = CreateFrame("Frame"), {} local texture = frame:CreateTexture() frame:SetPoint("CENTER",0,80) frame:SetWidth(128) frame:SetHeight(180) texture:SetAllPoints(frame) texture:SetTexture("Interface\\Addons\\HolyPowerNotifier\\holypower.tga") frame:Hide() -- Our command line option function HolyPowerNotifier(input) local value = tonumber(input) if not value or value < 1 or value > 3 then print ("|cffffff00Usage: /hpn 1-3") print ("|cffffff00Sets the number of Holy Power you must have for the frame to be visible.") print ("|cffffff00Current threshold: "..HolyPowerCount) else HolyPowerCount = value print ("|cffffff00Holy Power threshold set to "..value) end end -- Blizzard resets Holy Power to zero when zoning, but doesn't send -- a UNIT_POWER event. We'll clear the frame on zoning. function events:PLAYER_ENTERING_WORLD(...) frame:Hide(); -- Check if our variable is set as well. if not HolyPowerCount then HolyPowerCount = 3 end end -- Watch for UNIT_POWER events. function events:UNIT_POWER(source,type) -- Make sure its our power, and that it's Holy Power if source == "player" and type == "HOLY_POWER" then local power = UnitPower("player",9) -- Check if it's at the threshold if power >= HolyPowerCount then frame:Show() else frame:Hide() end end end -- Register our events frame:SetScript("OnEvent", function(self,event,...) events[event](self,...) end) for k,v in pairs(events) do frame:RegisterEvent(k) end -- Register our slash commands SLASH_HOLYPOWERNOTIFIER1 = '/hpn' SlashCmdList["HOLYPOWERNOTIFIER"] = HolyPowerNotifier Как сделать данную иконку ярче, ярко желтой. |
30 янв 2012, 03:25 |
|
|
0
Elixin писал(а): ребята подскажите пожалуйста. Хочу использовать макрос по mod:Shift. Но кнопка забиндена на дополнительную клавиатуру (т.е. на num1). Вобщем такая фишка если нажимать shift+num1, то это эквивалентно нажатию кнопки 'end', как сделать чтобы было нормально? :) P.S. сам создать свою тему не могу в виду ограничений на создание тем, наиболее близкой посчитал эту тему, не ругайте сильно. буду очень благодарен за совет как можно решить эту проблему(с модификаторами ctrl и alt все работает нормально) Если играть с выключенным режимом Num Lock (когда лампочка не горит), то ты просто биндишь этот макрос не на Num 1, а на End и у тебя все работает. Другой вариант это разбить макрос на два. В первом пишешь все то, где не используется шифт, и биндишь его на Num 1, при этом сможешь там еще использовать ctrl или alt модификаторы в этом макросе. А во втором пишешь то, что должно юзатся через шифт, но в самом макросе это условие не указываешь, то есть если у тебя было в твоем макросе "/cast [mod:shift] Первый спелл; Второй спелл", то во втором макросе ты просто пишешь "/cast Первый спелл" и биндишь его на Shift+End. Если ты играешь на дефолт юи и не хочется видеть на панельках два макроса вместо одного, то есть аддон который позволяет биндить макросы без вынесения их на экшен бары, правда название забыл, если нужно найду. Ну еще что-то типа кейлоггера написать можно, или попытаться в винде как-то вырубить эту функцию, но это искать лень. Добавлено спустя 10 минут 57 секунд: Fiction писал(а): Как сделать данную иконку ярче, ярко желтой. Она и так ярко желтая, куда ярче? А вообще 2 варианта, первое, после строки texture:SetTexture("Interface\\Addons\\HolyPowerNotifier\\holypower.tga") Вставляешь еще одну строку: texture:SetVertexColor(1, 1, 0) Тут можешь поэкспериментировать, первое число это количество красного цвета, второе - зеленого, третье - синего. На сколько я помню максимально желтый в системе RGB это максимум красного и зеленого (а максимум тут единица, т.е. 1 это 100%, а 0.5 это 50%), то есть если я не ошибся то это и есть максимально желтый. А если хочется сделать текстуру светлее тоном, то нужно открыть в фотошопе эту текстуру, и подвигать ползунки на яркость-контрастность сделав ее светлее и сохранить. Добавлено спустя 9 минут 51 секунду: Metampsi писал(а): выдрал из SuperClassic'а Fernira, будет ли этот код стилизовать иконки бафов, дебафов стандартных таргет и фокус фреймов, если я его запихну в отдельный аддон и подсуну свою текстуру бордера? или надо что то допилить? или возможно ли сделать небольшой аддон, наподобие rActionButtonStyler, который бы стилизовал экшенбары, бафы, дебафы у минимапы, бафы, дебафы на таргете и фокусе дефолтного ui ? знаю есть Masque который вместе с BlizzFacade стилизует все, но опять же кроме бафов, дебафов на фреймах То, что ты выдрал это поидее функция которая за 1 запуск скинит 1 заданный ей баф/дебафф. Это значит, что, к примеру, что-бы сделать скин для всех дебаффов возле фрейма цели (которых может быть до 40 штук), ты должен запустить функцию 40 раз, каждый раз задавая ей имя одного из этих сорока фреймов. И для каждого из 40 фреймов рейда ты тоже должен обработать этой функцией каждый из фреймов отображения аур, то есть например 40 умножить на 10. Это собственно очень просто, если точно знать имена всех фреймов и знать при каких условиях они создаются, если все сразу создаются при загрузке, то можно сразу и поскинить, а вот если они создаются динамически по мере необходимости, то нужно еще привязывать к функциям создающим фреймы аур свою функцию которая их скинит. |
30 янв 2012, 10:32 |
|