Перейти к содержанию

Дайджесты за январь-февраль

Обновления гайдов и аддонов

Январь Февраль

Мониторинг серверов и редактор аддонов

Представляем вам две легенды. То, о чем можно было только мечтать, стало реальностью.

Мониторинг серверов Редактор аддонов

Подсказки из игры на вашем сайте

Теперь вы можете отображать сведения о внутриигровых элементах простым наведением курсора мыши.

Подробнее

Апдейтер аддонов

Представляем вам программу для автообновления аддонов и делимся подробностями.

Подробнее Скачать

Помогите с созданием Аддона


worm

Рекомендуемые сообщения

Спасибо. Со стрингами действительно ооочень путаюсь. До конца так и не понял в чем разница. (как понял string то что мы пишем а WString то что в игре пишут)

Со звуком жаль( лет 6-7 назад в одной браузерке сидел. там по просьбе на приват и тд сделали звоночки. Очень удобно. ты чего-нить делаешь. бац написали и ты не пропустишь сообщение)

Как писал ранее я не большой любитель аддонов. Стоит по минимуму и то в последнее время поставил т.к. игра развивается. Это отступление к тому что не знаю может даже и есть такой аддон уже. Суть такова. Летом еще как то сказал что хорошо бы разрабы сделали чекбоксики на выбор инстансов. А вот сейчас поскольку и время появилось и научится хотел. поплыл я в эту сторону).

По логике уже написал и работает выбор Инстансов. Вроде такого аддона тут не нашел. Но в графической части слабоват еще. Вот и получается что оптимальнее перепаять Автокормежку в этом плане.(( да и заодно присобачить автопринятие на инстанс по выбору.

Вот что пока получилось


--------------------------------------------------------------------------------
-- GLOBAL Объяввляем глобальные переменные и функции
--------------------------------------------------------------------------------
Global( "DB", {} ) -- массив с действиями на Инстансы (снять заявку, без действия)
Global( "DBTelep", {} ) -- массив с принятием приглашения на Инстанс (принять, самому решать)

Global( "elapsed_counter", 0 ) -- переменная счетчик для принятие приглашения (в сек)
Global( "MAX_WAITING_TIME", 15 ) -- переменная через сколько секунд принять приглашение

Global( "ReventId", nil ) -- переменная с информацией об Инстансе на которое пришло приглашение


--------------------------------------------------------------------------------
-- EVENT HANDLERS Тело с функциями (основное рабочее пространство)
--------------------------------------------------------------------------------
-- Функция запускает функцию принятия приглашения в Инстантс
function DoneTeleportRequest( eventParams )
-- Выставляем начальное значение таймера когда пришло приглашение (вообще можно по другому наверное сделать но это потом)
elapsed_counter = 0
-- Регестрируем (вызываем) функцию принятия приглашения в Инстантс по событию таймера
common.RegisterEventHandler( OnEventSecondTimer, "EVENT_SECOND_TIMER" )

-- Переменная с id Инстанса на которое пришло приглашение. (Подругому незнаю как передать его в др функцию)
ReventId = eventParams.eventId

-- LogInfo( "eventId=", eventParams.eventId,"timeoutMs=", eventParams.timeoutMs )
end


-- Функция принятия приглашения в Инстантс
function OnEventSecondTimer( eventParams )
-- переменная-счетчик прибавляет 1 каждый раз когда вызывается функция. А вызывается раз в секунду по "EVENT_SECOND_TIMER"
elapsed_counter = elapsed_counter + 1
-- критерии по которым должно было сработать автоприглашение (не в группе, не в отряде и счетчик больше установл значения, т.е. дотикал). Временно отключил
--if (group.GetMembers() == nil) and (not raid.IsExist()) and (elapsed_counter >= MAX_WAITING_TIME) then

-- Временный массивчик с данными (включать или не включать автоприглашение) Вообще можно было стелать как MAX_WAITING_TIME = 90 и просто бы не сработало.
DBTelep["Арена смерти"] = 1
DBTelep["Гоблинобол"] = 1

-- Получаем информацию об Инстансе по его id
local eventInfo = matchMaking.GetEventInfo( ReventId )
-- userMods.FromWString(eventInfo.name) - Переводим из локализуемого такста в нормальный Название Инстанса для сравнения (точнее для подстановки в массив)
-- По ключу (название Инстанса) в массиве смотрим значение и сравниваем его (1 - включить автопринятие)
if (DBTelep[userMods.FromWString(eventInfo.name)] == 1) then
-- Если счетчик больше MAX_WAITING_TIME то прошло время и срабатывает функция вступления
if (elapsed_counter >= MAX_WAITING_TIME) then
-- Снимаем регистраци (прекращаем вызывать) функцию принятия приглашения в Инстантс по событию таймера
common.UnRegisterEventHandler( OnEventSecondTimer, "EVENT_SECOND_TIMER" )
-- Запускаем функцию принятия приглашения (true - принять, false - отказаться)
matchMaking.InstancedEventTeleportReply( true )
end
-- Выводим другое если чтобы тормознуть функцию вызываемую "EVENT_SECOND_TIMER" в случае если ненадо автопринятие
elseif (DBTelep[userMods.FromWString(eventInfo.name)] == 0) or (DBTelep[userMods.FromWString(eventInfo.name)] == nil) then
-- Снимаем регистраци (прекращаем вызывать) функцию принятия приглашения в Инстантс по событию таймера
common.UnRegisterEventHandler( OnEventSecondTimer, "EVENT_SECOND_TIMER" )
end

--LogInfo( "eventId=", ReventId, "timeoutMs=", eventParams.timeoutMs, "elapsed_counter=", elapsed_counter )
end



--------------------------------
-- ////////////
--------------------------------


-- Функция выделения нужных Инстансов (точнее снятие выделения с ненужных)
function UnSelectInstance()
-- Сотрим может ли аватар вообще участвовать в инстанс-ивентах (true - может, false - нет)
if matchMaking.CanUseMatchMaking() then
-- Включаем получение и отслеживание информации о существующих в игре инстанс-ивентах (true - вкл, false - выкл). Без этого ругается когда список с Инстансами не открыт
matchMaking.ListenEvents( true )

-- Смотрим может ли аватар в данный момент в принципе встать в очередь на какой-нибудь инстанс-ивент (true - может, false - нет). Лишняя проверка но лучше перебдеть чем отмываться
if matchMaking.CanJoinInstancedEvents() then
-- Получаем массив (список) с id существующих инстанс-ивентов. (Для нашего персонажа)
local Events = matchMaking.GetEvents()
-- Так и не понял как работает но механика следющая: перебирается весь массив пока не закончится. Нам это и нужно
for _, eventId in Events do
-- Если значение в массиве не пустое т.е. id Инстанса есть то работаем дальше
if eventId then
-- Смотрим существует ли ещё описание инстанс-ивента с указанным id (true - да, false - нет). Очередная проверка которая может и не нужна
if matchMaking.IsEventIdExist( eventId ) then
-- Создаем массив с информацией об Инстансе по его id
local eventInfo = matchMaking.GetEventInfo( eventId )

-- Временный массивчик с данными (1 - снять галку,2 - ставить галку в первую очередь, 3 - во вторую, 0 - игнорить Но поскольку не пашет то работаем только по 1)
DB["Арена смерти"] = 1
DB["Гоблинобол"] = 1
DB["Доминион"] = 0
DB["Дикий хутор"] = 2
DB["Ведьмин яр"] = 3

-- По ключу (название Инстанса) в массиве смотрим значение и сравниваем его (1 - снять галочку с данного Инстанса)
if (DB[userMods.FromWString(eventInfo.name)] == 1) then
-- Проверяем по информации об Инстансе. Стоит ли Юзер на данный Инстанс (true - да, false - нет). Очередная проверка а то ругается(
if (eventInfo.isAvatarJoined == true) then
-- Включаем функцию по снятию галочки с конкретного Инстанса
matchMaking.LeaveInstancedEventQueue( eventId )
end
-- По ключу (название Инстанса) в массиве смотрим значение и сравниваем его (2 - поставить галочку на данный Инстанс)
elseif (DB[userMods.FromWString(eventInfo.name)] == 2) then
--matchMaking.JoinInstancedEvent( eventId ) -- Вот та Хня из примера по логике должна ставить галочку на нужном Инстансе но не пашет
-- По ключу (название Инстанса) в массиве смотрим значение и сравниваем его (3 - поставить галочку на данный Инстанс когда по 2 надоело) Но немного не так все (на бущее м.б.)
elseif (DB[userMods.FromWString(eventInfo.name)] == 3) and (matchMaking.IsAvatarJoinedAnyEvent() == false) then
--matchMaking.JoinInstancedEvent( eventId )
end
end
end
end
end
-- А хз зачем. В ругом примере научусь тормозить хотя както надо остановить функцию.
--common.UnRegisterEventHandler(UnSelectInstance, "EVENT_MATCH_MAKING_EVENT_QUEUE_REMOVED")
end

end




--------------------------------
-- ////////////
--------------------------------


-- Функция вывода информации в Лог-файл
function LogInfo( ... )
common.LogInfo( common.GetAddonName(), unpack( GetStringListByArguments( arg ) ) )
end


-- Функция преобразования символов для функции вывода информации в Лог-файл
function GetStringListByArguments( argList )
local newArgList = {}

for i = 1, argList.n do
local arg = argList[i]
if common.IsWString( arg ) then
newArgList[i] = arg
else
newArgList[i] = tostring( arg )
end
end

return newArgList
end


--LuaFullDateTime
--local date = common.GetDateTimeFromMs( 123456789012345 )
--LogInfo( "date: ", date.d, ".", date.m, ".", date.y )


-- Функция отсылает данные об аддоне в аддон AddonManager
function OnAMMemUsageRequest()
userMods.SendEvent( "U_EVENT_ADDON_MEM_USAGE_RESPONSE", { sender = common.GetAddonName(), memUsage = gcinfo() } )
end


--------------------------------------------------------------------------------
-- INITIALIZATION Создаем Главную функцию запускающую другие в зависимости от определенных событий в игре
--------------------------------------------------------------------------------
function Init()
-- Вызываем функцию для работы с аддоном AddonManager
common.RegisterEventHandler( OnAMMemUsageRequest, "U_EVENT_ADDON_MEM_USAGE_REQUEST" )

-- Запускаем функцию принятия Приглашения в Инстантс когда возникает событие приглашения
common.RegisterEventHandler(DoneTeleportRequest, "EVENT_MATCH_MAKING_EVENT_TELEPORT_REQUEST")

-- Запускаем функцию выделения нужных Инстансов (точнее снятие выделения с ненужных) по таймеру
--common.RegisterEventHandler(DoneTeleportRequestW, "EVENT_SECOND_TIMER")
-- Запускаем функцию выделения нужных Инстансов (точнее снятие выделения с ненужных) по действие когда Инстантс был выделен
common.RegisterEventHandler(UnSelectInstance, "EVENT_MATCH_MAKING_EVENT_QUEUE_ADDED")
end
--------------------------------------------------------------------------------
-- Запускаем функцию с запускалками
Init()
--------------------------------------------------------------------------------

Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 95
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

for KEY, VALUE in TABLE do
CODE
end

Перебирает таблицу TABLE, и для каждого KEY (ключ) и VALUE (значение TABLE[KEY]) выполняет код.

Если TABLE это некая функция, возвращающая таблицу, то функция сработает только один раз. Т.е. вызывается функция, возвращает таблицу, и таблица уже перебирается.

Как работает for в случае если передавать ей больше переменных я не знаю, но описание гласит:

for var_1, ..., var_n in explist do block end

Потом по повводу matchMaking.JoinInstancedEvent - такой функции у нас нету. Ранее была, но была выпилена с одним из обновлений. Увы. Каждый раз при обновлении можешь смотреть не обновился ли файл ModdingDocs.zip, и если обновился - распаковывать и смотреть что у нас отобрали на этот раз.

И я не понял про "тормозить функцию". Зачем её тормозить? Как тормозить? Чего хочется добиться в результате торможения?

Ссылка на комментарий
Поделиться на другие сайты

Не обязательно в своем аддоне писать функции типа LogInfo

подключаешь в AddonDesc

<Item href="/Mods/SampleCommon/SampleAddonBase.lua" />

и просто пользуешься.

Ссылка на комментарий
Поделиться на другие сайты

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

Подумал а ведь наверное можно попробовать сделать чтобы не снимало выделение а полностью их игнорировало. Хмм надо проверить будет)

UnTargetPet.rar

Изменено пользователем worm
Ссылка на комментарий
Поделиться на другие сайты

Нет, нельзя. Скрипт выделяющий по табу работает с функциями которые нам недоступны или доступны не в полном объеме.

Например "табать" по щелчку мышки можно, а вот "табать" по кнопке - уже нет, т.к. выделить цель мы можем только по нажатию мыши.

Ссылка на комментарий
Поделиться на другие сайты

Добрый вечер. возник ряд вопросов.

 local res = string.find (val, "\\")
local ind = string.sub(val,1,res-1)
local state = string.sub(val,res+1)
mountList[ind] = state == '1'

вверху строковые функции В принципе все понятно главное потыкать а вот последняя строка. Понятно что запихивается в массив ключ и значение но причем тут "==1". Как правильно это читается?

и еще

появление и скрытие кнопки у кормежки выходит реагирует не на событие а на отображение текстур (виджетов) конюшни

if wt.ContextStable:IsVisible() and not wt.stableButton:IsVisible() then

где\как поглядеть это? название, свойства?

Ссылка на комментарий
Поделиться на другие сайты

Если state = 1 присваиваем true, если не равно 1, присваиваем false.

MountList[ind] = not state -- тоже вариант

Ссылка на комментарий
Поделиться на другие сайты

Да второй вариант с not не для данного случая. Это для случая если бы state имело бы значения true or false.

Ссылка на комментарий
Поделиться на другие сайты

Добрый вечер. возник ряд вопросов.

 local res = string.find (val, "\\")
local ind = string.sub(val,1,res-1)
local state = string.sub(val,res+1)
mountList[ind] = state == '1'

вверху строковые функции В принципе все понятно главное потыкать а вот последняя строка. Понятно что запихивается в массив ключ и значение но причем тут "==1". Как правильно это читается?

mountList[ind] = state == '1'

а = б - это операция присваивания.

в == г - это логическое выражение.

В нашем случае а = в == г следует читать как "а равно результату логического выражения в == г". Т.е. в случае если в == г, то а будет присвоено значение "true", истина. Если в ~= г(не равно), то а будет присвоено значение "false", ложь.

Операторы == ~= > < возвращают значение true (если условие выполняется) или false (если не выполняется).

1 == 2 --> false

5 > 4 --> true

5 ~= 5 --> false

Оператор AND возвращает первое ложное значение (слева-направо, при этом если первое значение ложное, то второе даже не вычисляется), иначе последнее неложное (т.е. то что справа если оба не ложны).

5 AND 1 == 2 --> false

1 == 2 AND 5 --> false

true AND 5 --> 5

5 AND 4 > 1 --> true

4 > 1 AND 5 --> 5

5 AND "boogie" --> "boogie"

Оператор OR возвращает первое неложное значение(в таком случае остальные даже не вычисляются), иначе последнее ложное. Например:

5 OR 3 --> 5

true OR MakeError() --> true (MakeError не выполняется)

false OR nil OR "wookie" --> "wookie"

5 AND 5 > 6 OR 6 > 5 AND 7 --> 7

Примеры забавных действий:

NewValue = Config AND Config.StoredValue OR PredefinedValue OR "Default Value"

Если существует переменная Config, и существует поле StoredValue, то переменной NewValue будет присвоено значение Config.StoredValue. Иначе если существует значение PredefinedValue то переменной NewValue будет присвоено значение PredefinedValue, иначе ей будет присвоено значение "Default Value".

VariableExists = Variable AND true OR false

Переменной VariableExists будет присвоено значение true если переменная Variable существует, иначе false. Т.е. результатом этого действия будет гарантированное присваивание этой переменной значения true или false.

появление и скрытие кнопки у кормежки выходит реагирует не на событие а на отображение текстур (виджетов) конюшни

if wt.ContextStable:IsVisible() and not wt.stableButton:IsVisible() then

где\как поглядеть это? название, свойства?

Как поглядеть что? Название, свойства чего? В процитированном куске кода:

if --если

wt.ContextStable:IsVisible() -- true если виджет виден, false если не виден. Виджет стойла.

and -- И

not -- НЕ

wt.stableButton:IsVisible() -- true если виджет виден, false если не виден. Виджет кнопки.

then -- Тогда код выполняется

Т.е. если первый виджет виден, и второй не виден, тогда выполнить... В ином случае если хотя бы одно условие не выполняется, сработает код после else (в ином случае), или, если его нет, ничего не произойдет и продолжится дальнейшее выполнение программы.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо огромное) Теперь понятно)

if wt.ContextStable:IsVisible() and not wt.stableButton:IsVisible() then где\как поглядеть это? название, свойства?

Да пытаюсь понять откуда узнать как называется виджет чтобы именно отловить это действие. Получается если видна конюшня но не видна кнопка показать кнопку. иначе если кнопка видна но не видна конюшня скрыть кнопку. Идея понятно но как например такое реализовать для списка с инстансами? надо wt.ContextStable заменить на что-то(

Ссылка на комментарий
Поделиться на другие сайты

Идея понятно но как например такое реализовать для списка с инстансами? надо wt.ContextStable заменить на что-то(

wt.ContextStable это переменная хранящая ссылку на виджет стойла. Чтобы получить ссылку на виджет надо воспользоваться функцией GetChildUnchecked( self, name, recursive )

Например у тебя в главной форме есть ребенок - виджет окно. Чтобы получить к нему доступ, иметь возможность менять его свойства и т.п. тебе нужна ссылка на него. Она получается следующим образом:

MyWidget = mainForm:GetChildUnchecked( "MyWidget's Name", false)

И теперь можно делать MyWidget:Show(true) и т.п., т.к. теперь в переменной MyWidget хранится ссылка на твой виджет.

Можно не хранить ссылку на виджет, а каждый раз получать её снова. Например:

mainForm:GetChildUnchecked( "MyWidget's Name", false):Show(true)

mainForm:GetChildUnchecked( "MyWidget's Name", false):Show(false)

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

В твоем коде ты можешь посмотреть откуда берется ссылка на кнопку и стойло. Она берется через детей stateMainForm и детей их детей и детей детей их детей.

В случае если имя виджета гарантированно уникально можно просто сказать "найди мне в стейтМейнФорме виджет "ЙцУкКеЕнГаР", однако имеется шанс получить не то что хотелось.

Ссылка на комментарий
Поделиться на другие сайты

В твоем коде ты можешь посмотреть откуда берется ссылка на кнопку и стойло. Она берется через детей stateMainForm и детей их детей и детей детей их детей.

Все дело в том что я и не знаю как посмотреть. Если бы лежало в папке то тыкаешь файлик смотришь ссылки идешь дальше но как быть когда это в игре? там не потыкаешь файлик(

  wt.ContextStable = W('ContextStable',stateMainForm):GetChildChecked("MainPanel", false )

я понимаю что он смотрит цепочку включения детей. Находит и выводит. Но я не знаю как узнать это имя ('ContextStable'.. Выходит както можно залезть в игру и почитать имя виджетов. Скачал AoTextureViewer_0.6.1 он не пашет. и выходит что я не могу посмотреть имя нужного мне виджета

Ссылка на комментарий
Поделиться на другие сайты

Так сопли частично откладываются.) Скачал аддон который все в игре показывает.. перепровязал на сумку появление кнопки. но все таки не нашел как обзывается кнопка с выбором инстансов. создадим отдельно тогда кнопочку. Главное механика понятна

Изменено пользователем worm
Ссылка на комментарий
Поделиться на другие сайты

Все дело в том что я и не знаю как посмотреть. Если бы лежало в папке то тыкаешь файлик смотришь ссылки идешь дальше но как быть когда это в игре? там не потыкаешь файлик(

 wt.ContextStable = W('ContextStable',stateMainForm):GetChildChecked("MainPanel", false )

я понимаю что он смотрит цепочку включения детей. Находит и выводит. Но я не знаю как узнать это имя ('ContextStable'.. Выходит както можно залезть в игру и почитать имя виджетов. Скачал AoTextureViewer_0.6.1 он не пашет. и выходит что я не могу посмотреть имя нужного мне виджета

2 аддона есть на виджеты:

Ссылка на комментарий
Поделиться на другие сайты

Уряя есть много глюков но уже хоть худо бедно работает.. Теперь доработка доработка)

Натыкал заплаток. теперь ошибки не выдает))

SelectInstance.rar

Изменено пользователем worm
Ссылка на комментарий
Поделиться на другие сайты

Здравствуйте. А есть ли такой аддон чтобы по щелчку на виджите отображалось его название? В Inspect Widgets вроде все отображается но хоть убей не могу найти пару виджетов

Ссылка на комментарий
Поделиться на другие сайты

Нельзя отловить щелчок по чужому виджету.

Скажи что не можешь найти, может поможем.

Ссылка на комментарий
Поделиться на другие сайты

Да больше понять хотелось. вопросы то они еще и с запасом на будущие.

интересуют виджеты или виджет на проверку о готовности и приглашения в инстанс. на лут нашел.

Вот кстати вопрос если виджет гасить так

wt.RollGreedNeed:Show( false )

то он потом ведь снова запустится при следующем запуске события или его надо как-то после гашения активизировать?

Ссылка на комментарий
Поделиться на другие сайты

может ты еще думаешь что компьютер сам думает???

какого события? как он сам запустится?

Ссылка на комментарий
Поделиться на другие сайты

Да больше понять хотелось. вопросы то они еще и с запасом на будущие.

интересуют виджеты или виджет на проверку о готовности и приглашения в инстанс. на лут нашел.

Вот кстати вопрос если виджет гасить так

wt.RollGreedNeed:Show( false )

то он потом ведь снова запустится при следующем запуске события или его надо как-то после гашения активизировать?

:Show( false ) просто скрывает виджет. Вот он виден - вот он нет.

Более того, виджеты могут динамически создаваться и удаляться.

Ссылка на комментарий
Поделиться на другие сайты

Доброго времени суток) Возникло еще 2 вопроса.(

1. Можно ли в аддоне сделать текстовые формы для ввода данных? Просто не встречал аддона с текстовым вводом. И если можно то возникает вопрос как узнать свойство виджета отвечающее за передачу данных

2. Где почитать как создавать кнопки на подобие чекбокса. Пытался разобраться в том чекбоксе что есть. Вроде все понятно. Но где графика под него непосредственно, и что в .bin файлах зашито не знаю как посмотреть( По логике выходит что в bin-файлах и есть графика на кнопку?

Просто зажегся еще одной штукой интересной но для реализации надо понять как эти два момента работают(

Ссылка на комментарий
Поделиться на другие сайты

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...

Важная информация

Пользуясь сайтом, вы принимаете Условия использования