Struck 61 Опубликовано 5 Октября 2012 Поделиться Опубликовано 5 Октября 2012 (изменено) Как получить доступ к полям таблицы вида: local tbl1 = { tbl2 = { tbl3 = {"section"}}} Циклами делать не хочется, делаю вот так local section = tbl1[tbl2]["tbl3"][[tbl2]["tbl3"][1]] но вылетает. Изменено 5 Октября 2012 пользователем Struck Ссылка на комментарий
Artos 99 Опубликовано 5 Октября 2012 Поделиться Опубликовано 5 Октября 2012 (изменено) Struck, научись, плз, задавать вопросы, о чем уже писалось тебе. Во-первых, если вылетает - то и приводи строки лога о вылете. Во-вторых, данный топик по скриптам, т.е. по сценариям, а не по общим вопросам использования Lua. Для подобных вопросов имеется топик "Язык Lua. Общие вопросы программирования." Ну и ... не стОит пытаться бездумно употреблять символы, надеясь что получиться рабочий код. Почитай основы / мануалы по Lua, лишним не будет. Подсказка: local section = tbl1.tbl2.tbl3[1] Изменено 5 Октября 2012 пользователем Artos 1 "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
*Shoker* 322 Опубликовано 6 Октября 2012 Поделиться Опубликовано 6 Октября 2012 Попросили спросить, нашли ли аналог функции main_input_reciver для ЗП. То есть эта функция позволяет вернуть текущее открытое ui-окно в скрипт. Помню очень давно читал что вроде нашли аналог но щас тот пост уже найти проблематично... Или если его нету, то есть ли способ вывести поверх инвентаря текст? Зарание спасибо. Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Shredder 49 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 В Xray - Extension такая возможность имеется: GUIListBox():GetMainInputReceiver(), только окно, возвращаемое этой функцией доступно на следующем апдейте. Ссылка на комментарий
volazar 9 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 (изменено) Все доброго дня! Возможно ли проверить наличие у актора нескольких предметов, обращаясь к таблице? Т.е по такому типу: local check_list = { [1] = { i = {"item1", "item2"}}, [2] = { i = {"item3", "item4"}}, ....... } function check(p) local list = check_list[p] for _, v in pairs (list.i) do local item = db.actor:object(v) if item then ... end end end Однако проверяется только 1 предмет - item1. Чувствую, что нужно "грызть" for _, v in pairs (list.i) do, однако мозгов не хватает. Изменено 7 Октября 2012 пользователем volazar Ссылка на комментарий
Shredder 49 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 Я бы так сделал: function check(p) local list = check_list[p] local founded = 0 for k,v in ipairs (list.i) do local item = db.actor:object(v) if item then founded = founded + 1 end end return founded == #list.iend 1 Ссылка на комментарий
volazar 9 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 (изменено) Shredder, не совсем то получилось. Попробую объяснить подробнее: Если у актора есть 2 итема в рюкзаке (по первому полю таблицы), то совершаем какое то действие. Для проверки, поставил вызов на постоянный апдейт и добавил выдачу СМС при условии, что все ок. Что имеем: спавним 1 итем - сразу приходит СМС. Убираем его и спавним 2 итем - СМС приходит. Спавним 1 и 2 итем, СМС есть. Выкидываем 1 или 2 итем - СМС есть. Выкидываем все итемы - СМС нету. Подбираем 1 любой итем - СМС есть. Т.е если в рюкзаке есть какой то любой из этих 2 итемов - тогда действие. //////////////////////////// А нужно так: если мы имеем в рюкзаке именно 2 итема (а не 1 какой то из них), то только тогда действие. Изменено 7 Октября 2012 пользователем volazar Ссылка на комментарий
*Shoker* 322 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 (изменено) Как вариант: local check_list = { [1] = { i = {"item1", "item2"}}, [2] = { i = {"item3", "item4"}}, ....... } function check(p) local list = check_list[p] local valid = true for _, v in pairs (list.i) do local item = db.actor:object(v) if item == nil then --> Не нашли предмета в инвентаре valid = false --> ставим флажок в false break --> останавливаем цикл end end if valid then --> если флажок true, то значит оба предмета есть в инвентаре --\\ тут вызываешь свою функцию end end А в твоём коде ошибка в "if item then" У тебя условие будет выполняться столько раз, сколько предметов из списка у тебя есть в инвентаре, ведь цикл найдя 1 предмет пошлёт тебе СМС, и пойдёт дальше выполняться, а там если найдёт 2 предмет, то снова пошлёт тебе СМС. Изменено 7 Октября 2012 пользователем *Shoker* 1 Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
volazar 9 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 *Shoker*, хм, действительно. Как всегда невнимательность... Спасибо! Ссылка на комментарий
_Призрак_ 11 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 local tbl = { ["ammo_9x18_ap"] = 3, ["wpn_pm"] = 2 } check_items(tbl) function check_items(t) db.actor:iterate_inventory( function (dummy, oItem) if t[oItem:section()] and t[oItem:section()]~=0 then t[oItem:section()] = t[oItem:section()]-1 end end ,nil) for k,v in pairs(t) do if v!=0 then return false end end return true end Freedom Ссылка на комментарий
Artos 99 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 Напоминание: для портянок кодов используем спойлеры! "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
ColR_iT 171 Опубликовано 7 Октября 2012 Поделиться Опубликовано 7 Октября 2012 (изменено) Ну и я свою "ляпту" внесу. --# Таблица предметов, которые нужно раздобыть и в последствии отдать. local need_item = {"bread",8,"kolbasa",6,"conserva",10} --# Функция принимает в качестве аргумента таблицу вида: --# {"section_name", count, "section_name", count, ...} function predmety_yazhik_complete (p) local actor = db.actor --# Разобъём аргумент (таблицу) на пары, где twain - это секция предмета, который проверяем, а twain+1 - его количество. for twain = 1, #p, 2 do --# Для каждой пары секция - количество заведём один счётчик, который будет считать количесвто предметов в инвенторе. local cnt = 0 --# Перебираем инвентарь ГГ. actor:iterate_inventory( function (dummy, item) --# Если секция совпала, то увеличим сумму. if item:section() == p[twain] then cnt = cnt + 1 end end, nil) --# Если общая сумма указанного предмета меньше нужной, т.е. не хватает, то заканчиваем счёт и возвращаем соответствующее значение. if cnt < p[twain+1] then return false end end --# Если все предметы есть в указанном количестве - вернём true. return true end Вернёт true если в инвентаре присутствует указанное количество указанных предметов. P.S. И правда, ребята, прячьте код под спойлер. В шапке об этом ведь написано. Изменено 7 Октября 2012 пользователем ColR_iT Ссылка на комментарий
Shredder 49 Опубликовано 8 Октября 2012 Поделиться Опубликовано 8 Октября 2012 Зачем такая таблица? local need_item = {"bread",8,"kolbasa",6,"conserva",10} Ведь local need_item = {bread = 8,kolbasa = 6,conserva = 10} гораздо удобнее Ссылка на комментарий
Artos 99 Опубликовано 8 Октября 2012 Поделиться Опубликовано 8 Октября 2012 (изменено) Shredder, учитывая, что ответ на вопрос уже дан, предлагаю или переносить дальнейшее по 'табличной' теме в топик по Lua, или все же говорить именно о скриптинге, а не предпочтениях и всевозможных способах... уже не имеющик к исходному вопросу никакого отношения. Но, если уж затронул "удобства", то применительно именно к игре - вот тебе пара первых пришедших на ум аргументов почему НЕ удобнее: Многие параметры задаются в конфиг-файлах (*.ltx), в которых вполне обычной выглядит запись типа: [items] need_item = bread, 8, kolbasa, 6, conserva, 10 - которую проще считать именно в табличку 1-го вида, а не 2-го, и далее уже распарсить готовыми 'штатными' функциями. Этот же формат встречается и в 'штатной' логике или all.spawn'е (те же респавнеры, к примеру), где параметры различного типа передаются именно списком... Т.о. что удобнее и на каком этапе - зависит и от исходных данных (их формата), и от контекста задачи и конечно же от субъективных предпочтений. Дабы не разводить дальнейший флуд, с твоего позволения, Artos, напишу в этом же посте, некое пояснение от меня почему именно этот способ выбрал я. Во-первых, в таком виде данные в таблице хранятся как обычный массив - а это: 1. Меньше памяти выделяется для её инициализации. 2. Lua порядком быстрее работает с массивами, нежели с хеш-таблицами. Во-вторых, как уже сказали, это моё субъективное предпочтение - я поделился им. ColR_iT Изменено 8 Октября 2012 пользователем ColR_iT "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Viнt@rь 50 Опубликовано 8 Октября 2012 Поделиться Опубликовано 8 Октября 2012 (изменено) В сендбоксе от xStream, в скрипте xs_sandbox и в системе таймеров(слотов/сигналов) от Malandrinus в скрипте ogse_signals заприметил очень интересную строчку(заприметил то давно, но сильный интерес она вызвала сейчас) - level.add_call(hanged_calls_check, function()end), как и когда срабатывает это(как я понял, это вызов функции при повисании логики/биндера актора), и как его можно использовать в своих целях, при этом не используя системы этих авторов, но что бы результат был такой же(ЗЫ, у меня используется своя система таймеров, но никаких модульных систем типа слотов/сигналов и тп, не используется) Изменено 8 Октября 2012 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
ColR_iT 171 Опубликовано 8 Октября 2012 Поделиться Опубликовано 8 Октября 2012 (изменено) Viнt@rь как и когда срабатывает этоКак - нужно спросить у разработчиков. Когда - когда вызовешь.как я понял, это вызов функции при повисании логики/биндера актораСмотря в контексте чего ставится этот колбек.как его можно использовать в своих целях... но что бы результат был такой жеКакой результат? По сути, метод add_call пространства имён level есть колбек аргументами которого являются две функции. Первая вызывается периодически и должна возвращать false, если нужно продолжать апдейт, как только вернёт true - апдейт заканчивается и выполняется функция переданная вторым аргументом. Вообще метод перегруженный. Можешь глянуть в lua_help.script и в справочнике было какое-то описание этому. Изменено 8 Октября 2012 пользователем ColR_iT Ссылка на комментарий
Artos 99 Опубликовано 9 Октября 2012 Поделиться Опубликовано 9 Октября 2012 (изменено) Vint@rь, странно, что этот метод(функцию) ты только сейчас заметил ;-) Как уже написал ColR_iT, описание есть в "Справочнике по функциям и классам". Учитывая некоторую неоднозначность восприятия, можно дать такое упрощенное пояснение: 1. Аргументов у этого метода в простейшем случае два: precondition и action : level.add_call(precondition, action) , но есть и иные варианты (см. в lua_help). 2. Этот метод запускает новый автономный поток Lua (thread), который не зависим(!) от привычного actor_binder:update(delta) и прочих потоков, т.е. будучи запущенным, этот поток вызывается в каждом игровом цикле после каждого апдейта актора (не зависимо завис апдейт или нет!) - и запускает проверку условия (precondition). 3. Этот метод по сути устанавливает коллбэк на вызов проверки условия (precondition) и по результату проверки значения возвращаемого precondition запускает (при true) заданное действие (action) и прекращает свою работу, уничтожая поток. При false - происходит тихое завершение цикла, до следующего игрового апдейта. Т.о. в игре можно, например, организовать независимые циклы для апдейтов тех или иных схем/классов/... или различные варианты мониторинга зависших сторонних потоков. Практическое применение также давно можно видеть в действии. Например, давно в моде SIMBION различные апдейты рестрикторов, погоды, новостей, оффлайн-алайфа и т.п. переведены именно на независимые апдейты на базе level.add_call. Можно видеть их использование и в модулях m_netpk и se_stor. Как сказано выше - это дает независимость от зависаний акторского апдейта да и подразгружает его, хотя конечно же все равно Lua выполняет все потоки 'последовательно'... Ну а в упомянутых тобою скриптах от xStream и Malandrinus, этот метод, будучи независимым от сторонних потоков, как раз и выполняет роль "сторожа" (не только акторского биндера), контролируя "не зависли ли какие потоки", для которых заданы условия в precondition. СтОит ли использовать этот метод "в свои целях"? Все опять же зависит от цели... Если аналогично "сторожить", или организовать свой автономный апдейтик для скрипта/класса - то конечно стОит, а вот для таймеров... тут очень неочевидно. По сути, если завис апдейт актора - толку от работающих таймеров мало. Пишу это, не смотря на то, что у самого модуль таймеров именно на этом методе апдейтится. ;-) Следует иметь ввиду, что доп.поток - это и доп.ресурсы... Небольшое 'warning!': В ЗП (CoP) это метод похоже имеет особенности... В модуле m_oflife (оффлайн-алафф) использование его для апдейта coroutine прерывается пока по непонятной для меня причине. Изменено 9 Октября 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Viнt@rь 50 Опубликовано 9 Октября 2012 Поделиться Опубликовано 9 Октября 2012 (изменено) ColR_iT, Artos, спс ColR_iT Какой результат? ну в смысле польза Можешь глянуть в lua_help.script и в справочнике было какое-то описание этому. да, я глядел, правда давненько это было Artos Vint@rь, странно, что этот метод(функцию) ты только сейчас заметил ;-) заметил то я его давно, вот интерес(надобность), появился только сейчас СтОит ли использовать этот метод "в свои целях"? Все опять же зависит от цели... Если аналогично "сторожить", или организовать свой автономный апдейтик для скрипта/класса - то конечно стОит, а вот для таймеров... В своих целях в виде "сторожа", мб помнишь я писал про зависания биндера у меня?? вот для отлова этой "байды" , а про свои таймера упомянул только из за того, что у меня не используются скрипты от xStream и Malandrinus Практическое применение также давно можно видеть в действии. Например, давно в моде SIMBION различные апдейты рестрикторов, погоды, новостей, оффлайн-алайфа и т.п. переведены именно на независимые апдейты на базе level.add_call. Можно видеть их использование и в модулях m_netpk и se_stor. Как сказано выше - это дает независимость от зависаний акторского апдейта да и подразгружает его, хотя конечно же все равно Lua выполняет все потоки 'последовательно'... Пишу это, не смотря на то, что у самого модуль таймеров именно на этом методе апдейтится. ;-) а вот это погляну)) особенно по поводу таймеров, хотя ведь даже апдейт этой новой нити зависит от FPS???(где-то читал просто что частота апдейта на прямую зависит от FPS игрока) и тут возникает вопрос, тогда какие плюсы/минусы для таймеров с использованием такого метода? Изменено 9 Октября 2012 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
Artos 99 Опубликовано 9 Октября 2012 Поделиться Опубликовано 9 Октября 2012 Я бы по другому сформулировал: "FPS напрямую зависит от апдейтов актора", а точнее полностью им соответствует, т.е. сколько раз в секунду обновился биндер актора - столько FPS (обновлений экрана в секунду) и имеешь. Ну а то, что написал выше, о том, что созданный методом level.add_call "поток вызывается в каждом игровом цикле после каждого апдейта актора" - как раз и говорит о том, что апдейты на таком потоке будут также полностью соответствовать циклам апдейта актора, а значит и FPS. Конечно случай, когда поток биндера актора завис и исключен из циклов - не рассматриваю, это уже "фатальный" случай... По поводу плюсов/минусов можно рассуждать немало, все зависит опять же от конечных целей. Один минус, который стОит иметь ввиду уже указал - доп.ресурсы на обслуживание доп.потока. Хотя им скорее всего можно пренебречь. Из плюсов: - при разработке и/или отладке, когда те или иные потоки могут зависать (в особенности актрский), не лишним иметь возможность 'видеть' какие потоки работают, а какие зависли. Если все завязано на один поток, то довольно не просто разобраться в ситуации завис из-за таймера или иного события. - (эксклюзивный случай) если некими методами "оживлять" зависшие потоки (например, это делает LuaCap by alpet), то некие потери имеет только зависший поток и его функционал, а те же таймеры продолжают "тикають как часики"... Однако, для самого является до сих пор загадкою: "Почему разработчики GSC слили в один поток, например, обновление той же погоды иль классов (рестрикторы и т.п.)?" , хотя ранее были автономные потоки. 1 "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 9 Октября 2012 Поделиться Опубликовано 9 Октября 2012 (изменено) Artos, обновления актора если и связаны с FPS рендера, то опосредованно, и уж точно их частота не одинаковая. Это совершенно точно. Более того, рендер и все его дела, в том числе и обновления с независимой частотой, как раз происходят в отдельном потоке Windows. Это в сущности единственный многопоточный момент в движке - отдельный поток для рендера. Что же касается апдейтов актора и их связи с частотой апдейтов level.add_call. Я давно не занимался этими измерениями, но смутно помню, что частота апдейтов актора может быть равна или меньше частоте вызовов от level.add_call. Вроде как на старом компьютере и под патчем 1.0004 апдейты шли медленней, а сейчас (весьма быстрая машина и 1.0006) вроде как равны. Кроме того, частота апдейтов актора вообще говоря подчиняется общему правилу для апдейтов всех объектов, т.е. чем дальше от актора, тем медленней. Соответственно актор и его инвентарь обновляются с одной и той же, максимальной, частотой. И более определённо я могу сказать насчёт природы вызовов level.add_call и также колбека fastcall. Они вызываются с одинаковой частотой и, насколько я знаю, эта частота просчёта игровой физики. Есть основания думать, что оба этих вызова исходно предназначались для скриптовой обвязки управления физическими объектами. Изменено 9 Октября 2012 пользователем malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти