ColR_iT 171 Опубликовано 26 Июня 2012 kratos888. 1. Функцию то ты используешь, но по всей видимости не до конца понимаешь как она работает. Чтобы story_id читался, нужно перевести НПС оффлайн и обратно, либо сейв-лоад. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 17 Сентября 2012 Такой вопрос: как работает класс profile_timer? Считает ли он время выполнения посторонней функции при вызове её из измеряемого участка кода? Например: local timer = profile_timer() timer:start() -- здесь код... -- здесь вызов функции -- здесь опять код... timer:stop() Будет ли учтено время работы вызываемой функции? Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 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 Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 8 Октября 2012 (изменено) Viнt@rь как и когда срабатывает этоКак - нужно спросить у разработчиков. Когда - когда вызовешь.как я понял, это вызов функции при повисании логики/биндера актораСмотря в контексте чего ставится этот колбек.как его можно использовать в своих целях... но что бы результат был такой жеКакой результат? По сути, метод add_call пространства имён level есть колбек аргументами которого являются две функции. Первая вызывается периодически и должна возвращать false, если нужно продолжать апдейт, как только вернёт true - апдейт заканчивается и выполняется функция переданная вторым аргументом. Вообще метод перегруженный. Можешь глянуть в lua_help.script и в справочнике было какое-то описание этому. Изменено 8 Октября 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 11 Октября 2012 serega-gamer, причину тебе уже назвали. Но хотелось бы ещё добавить, что не очень то у тебя код оптимизированный получился. Может лучше так!? local function check_condition (item_in_slot) return item_in_slot:condition() < 1 and item_in_slot:condition() >= 0.2 end function repair_wpn_1() local item_in_slot = db.actor:item_in_slot(2) local act_rank = ranks.get_obj_rank_name(db.actor) local cond_standard = { ["novice"] = (item_in_slot:condition() + (math.random(20)+20)/100), ["experienced"] = (item_in_slot:condition() + (math.random(20)+30)/100), ["veteran"] = (item_in_slot:condition() + (math.random(20)+40)/100), ["master"] = (item_in_slot:condition() + (math.random(20)+50)/100), } for i = 0, db.actor:object_count() - 1 do local item = db.actor:object(i) if item:id() ~= item_in_slot:id() and item:section() == item_in_slot:section() then if check_condition (item_in_slot) then item_in_slot:set_condition(cond_standard[act_rank]) this.repair_wpn_sound() alife():release(alife():object(item:id()), true) return end end end end Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 13 Декабря 2012 Dennis_Chikin, объектом к которому "прикручен" биндер. Нет, вызываются методы конечно движком, но, так сказать, виновник этого - объект. В общем вот здесь всё весьма подробно расписано: >>ClicK Me<<. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 3 Января 2013 proper70 И еще: в файле gulag_escape.script я нашел такую строку (правда, она закомментена):-- online = true, а что будет, если ее раскомментить? Этот параметр, в некотором смысле, аналогичен секции spawner в custom_data. Т.е. если стоят условия, то он определяет параметры выхода в онлайн, если же поставить true, то любой НПС будучи на данной работе всегда будет находиться в онлайне.В целом информация очень интересная. От меня лично - благодарю. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 6 Января 2013 proger_Dencheek, интересно, чем же твоя функция лучше? Парой дополнительных проверок и возможностью указывать количество предметов для передачи? Боюсь, что в данном случае "твоя" функция так же не поможет... riddik121, вероятнее всего ты не правильно передаешь в функцию "кто-есть-кто". Вызывая на реплике НПС, ты передаёшь предмет от актора к актору. Попробуй вызвать функцию так: function anarhist_pkm_done(first_speaker, second_speaker) dialogs.relocate_item_section(first_speaker, "wpn_pkm", "out") end Что касается функции по универсальнее, то позволь тебе предложить следующее: --# Функция трансфера предметов в указанном количестве. --# Избавился от необходимости вставлять квестовый предмет в таблицу quest_section. --# Теперь "квестовость" предмета определяется по наличию поля quest_item, со значением true, в секции предмета. --# victim - ['userdata'] от кого (type == "in") либо кому (type == "out") передавать предмет; --# section - ['string'] секция передаваемого предмета; --# type - ['string'] тип передачи ("in" - актору, "out" - от актора); --# count - ['number'] количество предметов для передачи (по умолчанию - 1); --# hide - ['boolean'] показывать ли факт передачи в виде сообщения в окне диалога (true - скрыть). function relocate_item_section (victim, section, type, count, hide) local actor = db.actor local ini = system_ini() --# Определим является ли передаваемый предмет квестовым. local item_is_quest = ini:section_exist(section) and ini:line_exist(section, "quest_item") and ini:r_bool(section, "quest_item") if actor and victim then --# Передвать нужно от НПС актору. if type == "in" then --# Если предмет квестовый, то ... if item_is_quest then --# Передадим предмет(ы). transfer_item_between_npc (victim, actor, section, count) --# Иначе просто заспавним в нужном количестве. else spawn_to_inventory (section, actor, count) end --# Передавать нужно от актора НПСу. elseif type == "out" then --# Передадим их НПС. transfer_item_between_npc (actor, victim, section, count) end --# Нужно ли явно сообщать о передачи в окне диалога? if not hide then news_manager.relocate_item(actor, type, section) end end end --# Функция спавна предметов в инвентарь. --# section - ['string'] секция предмета, который будем спавнить; --# whom - ['userdata'] кому будем спавнить (по умолчанию актору); --# count - ['number'] сколько будем спавнить (по умолчанию 1). --# Если каким-то образом section равен nil/false, либо предмет не является инвентарным, спавн происходить не будет. function spawn_to_inventory (section, whom, count) --# Проверим передана ли секция, и предмет инвентарный. if not section or not system_ini():line_exist(section, "inv_name") then return end --# Определим кому спавнить, если whom не равен 'userdata', то спавнить будем в инвентарь актора. local actor = type(whom) == "userdata" and whom or db.actor --# Спавним в указанном количестве, либо в одном экземпляре, если count не передан. for i=1, count or 1 do alife():create(section, actor:position(), actor:level_vertex_id(), actor:game_vertex_id(), actor:id()) end end --# Функция передачи предметов от одного НПС к другому в указанном количестве. --# who - ['userdata'] кто передаёт; --# whom - ['userdata'] кому передавать; --# section - ['string'] секция предмета; --# count - ['number'] количество предметов (если не указано, то 1). function transfer_item_between_npc (who, whom, section, count) --# Если нет от кого и кому передавать, то выйдем. if not who and not whom then return end --# Передадим указанное количество предметов, если не передан count, то передадим один предмет. for i = 1, count or 1 do who:transfer_item(who:object(section), whom) end end 3 Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 6 Января 2013 riddik121, это зависит от того, кто говорит фразу, в которой вызвана функция. Вообще первым аргументом передаётся говорящий, вторым - оппонент. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 6 Января 2013 proger_Dencheek, а когда это родная функция требовала "объявления first_speaker, second_speaker"? И у просившего проблемы как раз не с аргументами, а с определением того, на кокой реплике вызывать функцию, либо кого именно передавать в неё. P.S. Постарайся в следующий раз давать конкретный ответ на вопрос, а не распространять копи-паст. На этом оффтоп окончен. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 14 Января 2013 (изменено) Desertir, если уж на то пошло, то в Lua нет классов, в Lua есть таблицы с помощью которых эмулируется ООП, причём заметьте - весьма удачно. Самый банальный пример, который не излагает всей сути объектного программирования, но показывает суть... Car = {_model = "", _year = 0, _type = ""} function Car:setData (model, year, type) self._model = model self._year = year self._type = type end function Car:getData () print (self._model.."; "..self._year.."; "..self._type) end local Tarantayka = Car Tarantayka:setData("ZAZ", 1970, "SUV") Tarantayka:getData() Подправил... Вот так будет нагляднее. Вот здесь: >>ClicK Me<<, на пятой странице, весьма доступно описан этот момент. Изменено 14 Января 2013 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 14 Января 2013 Другого ООП в Lua нет, всё реализуется посредством таблиц. Перейди по ссылке, что я дал, там есть все ответы на твои вопросы. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 15 Января 2013 Это не то, чтобы "полезный" вариант, это единственный вариант реализации ООП в Lua. Что касается сабжа - неужто те, классы, которые реализуют различные менеджеры, так "тормозят"? Время их работы никчёмно, и разница в десять раз на одном миллионе итераций смотрится просто жалко, к тому же класс profile_timer считает время МИКРОсекундах, получается приблизительно полсекунды на весь процесс - это также не делает из этого бесполезной тратой времени и ресурсов. ИМХО, овчинка выделки не стоит. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 15 Января 2013 Даже если и возникнет желание, давайте его обсуждать не здесь, создайте по соседству тему, кто желает, будем обсуждать там, а то мы и так здесь нафилософствовали... Далее, пожалуйста, по существу: конкретный вопрос - конкретный ответ. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 16 Января 2013 Shredder, а вот с оптимизацией примера логики проколочка... Это только затормозит работу. Причина проста - выборка из таблицы с одним элементом происходит быстрее, чем с несколькими. Опять же таки разница во времени ничтожна, поэтому это скорее не на оптимизацию похоже, а на приведение в божеский вид... Хотя где-где, а в логике есть что оптимизировать, например если взглянуть на функцию cfg_get_switch_conditions в файле xr_logic.script, то можно прийти к не до умению с вопросом: почему именно так? Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 17 Января 2013 Shredder, после этой функции будет вызвана ещё одна - pick_section_from_condlist, которая будет проверять эти самые условия и перебирать она будет все элементы, именно вот здесь, проверка единственного значения в таблице будет быстрее проверки из четырёх, ко всему в последствии, в саму функцию check_npc_name, передадутся четыре параметра, где вновь будет идти их перебор. ИМХО, как сказал Саша, всё это настолько мелочно, что бороться за производительность, жертвуя читабельностью кода, - глупо. Одна загрузка модели с анимациями займёт больше времени, чем 1М итераций с инициализацией переменной. Скорее, нужно просто сделать по "человечески" чтобы код был понятнее и глядя на него становилось ясно, что он делает, плюс по возможности использовать какие-то техники оптимизации кода, что тоже будет не плохо. Одним словом - нужно искать компромисс. malandrinus, да, я знаю, что она вызывается при инициализации схемы, т.е. в момент перехода на какую-то секцию. Почему я упоминул её - она максимально выбивается из общего вида, такое чувство, что её дописывали потом, при этом делал это уже посторонний человек. Непонятное именование переменных, минимум оптимизации - всё это можно было бы сделать иначе, культурнее и быстрее. --# Табличка соответствия что - чем парсить. local tbl_condition = { ["on_actor_dist_le"] = cfg_get_number_and_condlist, ["on_actor_dist_le_nvis"] = cfg_get_number_and_condlist, ["on_actor_dist_ge"] = cfg_get_number_and_condlist, ["on_actor_dist_ge_nvis"] = cfg_get_number_and_condlist, ["on_timer"] = cfg_get_number_and_condlist, ["on_game_timer"] = cfg_get_number_and_condlist, ["on_signal"] = cfg_get_string_and_condlist, ["on_actor_in_zone"] = cfg_get_string_and_condlist, ["on_actor_not_in_zone"] = cfg_get_string_and_condlist, ["on_info"] = cfg_get_condlist, ["on_actor_inside"] = cfg_get_condlist, ["on_actor_outside"] = cfg_get_condlist, ["on_npc_in_zone"] = cfg_get_npc_and_zone, ["on_npc_not_in_zone"] = cfg_get_npc_and_zone } function cfg_get_switch_conditions (ini, section, npc) --# Табличка будет хранить парсеные условия. local parse_tbl = {} --# Индекс условия в табличке parse_tbl. local num = 1 --# Разберём таблицу соответствий tbl_condition. for field, func in pairs(tbl_condition) do --# Здесь: --# field - поле, которое будем парсить; --# func - имя функции, которой будем парсить. --# Проверка того, что выбранный параметр существует в нашей секции. --# По сути нужна для оптимизации, чтобы не обрабатываеть лишнее. if section and ini:section_exist(section) and ini:line_exist(section, field) then --# Порядковый номер одноимённых условий. local i = 1 --# Распарсим поле field при помощи соответствующей функции func. local cond = func(ini, section, field, npc) --# Пока таблица cond существует, т.е. указанное поле парсится, будем вносить услвоия в таблицу parse_tbl. while cond ~= nil do --# Вносим условие в таблицу. parse_tbl[num] = cond --# Увеличиваем индекс. num = num + 1 --# Проверим есть ли одноимённые условия? cond = func(ini, section, field..i, npc) --# Посмотрим есть ли ещё одноимённые условия, вдруг их больше одного!? i = i + 1 end end end --# Возвращаем распарсенные услвоия в виде таблицы. return parse_tbl end Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 17 Января 2013 (изменено) Clayman, какие полигоны в абстрактной сфере? Это всего лишь точка, вокруг которой программно описывается сфера с указанным радиусом, визуального отображения нет, т.е. модель отсутствует. Изменено 17 Января 2013 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 17 Января 2013 Ребята, предлагаю прекратить полемику, сильно смахивающую на оффтоп, касательно данной темы и либо закончить, либо открыть соседнюю тему по данному вопросу. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 27 Января 2013 (изменено) *Shoker*, если не секрет конечно, по средством какого метода ты пытаешься развернуть объект при спавне? Изменено 27 Января 2013 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 19 Марта 2013 (изменено) Wookie, для класса io существует метод lines, принимающий в качестве аргумента имя файла, и возвращает функцию итератор, которая при вызове возвращает по одной строку из указанного файла, как только достигнет конца файла - вернёт nil, при этом файл будет закрыт.Точно не помню, но кажется можно вызывать и без аргумента, в таком случае будет обрабатываться стандартный поток ввода, по окончании итерации ничего закрываться не будет. for line in io.lines("filenNme") do ... end Это работает на чистом Lua, но и на ЗП должно работать. Изменено 19 Марта 2013 пользователем ColR_iT 1 Поделиться этим сообщением Ссылка на сообщение