Купер 2 677 Опубликовано 12 Мая Поделиться Опубликовано 12 Мая 1. Применительно +/- к оригиналу: здесь. Сразу осваивать и разбираться в механике работы. Оптимальнее вряд ли что сделать получится. 2. Кастомные варианты движков, где это всё реализовано непосредственно внутри возможностями того или иного движка. 1 Ссылка на комментарий
Это популярное сообщение. Zander_driver 10 321 Опубликовано 13 Мая Это популярное сообщение. Поделиться Опубликовано 13 Мая (изменено) 06.05.2024 в 14:38, Balavnik сказал: А где-то можно список получить этих методов? lua_help.script, или форумы, или исходники движка на котором работаешь, (Последнее - самое надежное. Остальные могут врать). Но кроме этого.. Есть надежный метод проверить наличие определенного метода у определенного объекта. function check_obj_has_method(obj, method_name) if not obj then return false end if obj and obj[method_name] and type(obj[method_name]) == 'function' then return true end return false end -- Пример использования: local actor = db.actor check_obj_has_method(actor, 'section') -- вернет true check_obj_has_method(actor, 'id') -- вернет true check_obj_has_method(actor, 'section_name') -- вернет false check_obj_has_method(obj, 'section') -- Вернет false, т.к. obj не определен в данной области видимости. Ну или просто if obj and obj.какой_то_метод and type(obj.какой_то_метод) == 'function' then obj:какой_то_метод(аргументы) -- Вызываем наш метод. else -- Тут можно сообщить в лог, что у этого объекта нет такого метода, и как-то иначе эту ситуацию обработать. end Такими проверками легко можно избавиться от любых вылетов по вызовам несуществующих методов у чего-нибудь. Будь то клиентские, серверные, или еще какие-нибудь объекты. Да хоть вектора. И да, такой метод проверки применим к любому движку, на любой платформе сталкера. Изменено 13 Мая пользователем Zander_driver Добавил пример использования функции 2 2 3 Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Ссылка на комментарий
Balavnik 86 Опубликовано 16 Мая Поделиться Опубликовано 16 Мая Каким образом лучше всего отслеживать события? Например, поднятие актором определённого предмета двигает поршень. Думаю, в bind_stalker прописывать не лучшая идея. Устал. Ссылка на комментарий
mole venomous 3 242 Опубликовано 16 Мая Поделиться Опубликовано 16 Мая 43 минуты назад, Balavnik сказал: в bind_stalker прописывать не лучшая идея Прописывать можно где угодно. Но коллбек on_item_take именно в bind_stalker и вызов будет там. 2 Здесь могла быть ваша реклама. Ссылка на комментарий
Balavnik 86 Опубликовано 16 Мая Поделиться Опубликовано 16 Мая @mole venomous А не будет ли это шибко сильно тормозить игру? Я просто хочу таким макаром обработать +- 70 объектов. Устал. Ссылка на комментарий
Zander_driver 10 321 Опубликовано 16 Мая Поделиться Опубликовано 16 Мая 2 часа назад, Balavnik сказал: Каким образом лучше всего отслеживать события? А что такое, по твоему, биндер вообще? Это скриптовой объект, который позволяет скриптам отслеживать события забинденного объекта. Т.е. он буквально вот для этого и создан. В биндерах находятся (могут находиться) обработчики всех событий которые могут происходить с объектом и отслеживаются движком. 1 час назад, Balavnik сказал: А не будет ли это шибко сильно тормозить игру? А каким образом? Код метода-обработчика вызывается только при срабатывании соответствующего колбека события. На каждом фрейме вызывается только update. 1 час назад, Balavnik сказал: обработать +- 70 объектов. Все в on_item_take? switch case по секции в помощь, Ну или по тому признаку по которому они у тебя различаются. Еще можно таблицу функций сделать с ключами-секциями, и по секции вызывать нужную из обработчика on_item_take. Как угодно можно. 1 1 Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Ссылка на комментарий
Balavnik 86 Опубликовано 20 Мая Поделиться Опубликовано 20 Мая (изменено) Вырезаны ли функции работы с файловой системой? Хочу считать количество смертей актора. Какими командами можно редактировать user.ltx? Изменено 20 Мая пользователем Balavnik Устал. Ссылка на комментарий
Norman Eisenherz 276 Опубликовано 20 Мая Поделиться Опубликовано 20 Мая 1. Библиотека io – чтение и запись текстовых файлов (есть ЧН/ЗП, про OGSR не знаю). 2. Написать в консоли help, искать примеры по названиям. 1 Мини-моды: ТЧ ЧН ЗП Шпаргалка Ссылка на комментарий
Купер 2 677 Опубликовано 20 Мая Поделиться Опубликовано 20 Мая @Balavnik , для оригинала ТЧ здесь про пространство имён IO недавно обсуждалось. См. здесь или здесь. Пример использования, например, здесь. 1 1 Ссылка на комментарий
Kirgudu 1 151 Опубликовано 20 Мая Поделиться Опубликовано 20 Мая 4 часа назад, Norman Eisenherz сказал: про OGSR не знаю В OGSR тоже есть. Везде есть, кроме оригинала ТЧ и основанных на нём без расширения или редактирования движка модов. 3 Инструмент Ссылка на комментарий
Balavnik 86 Опубликовано 21 Мая Поделиться Опубликовано 21 Мая (изменено) Товарищи, parent_id ящика в оффлайне как получить? Что-то не нашел нигде инфы. Прикладываю код. Суть: спавн объекта секции(пока водки) в ящике по известному sid. Пока не выходит реализовать. Скрытый текст function spawn_remkom(first_speaker, second_speaker) local sim = alife() local obj = level.object_by_sid(5003) alife():create("vodka",vector():set(39.420829772949,-0.10841239988804,25.139078140259), 1, obj:game_vertex_id(), obj:id()) end Изменено 21 Мая пользователем Balavnik Устал. Ссылка на комментарий
Kirgudu 1 151 Опубликовано 21 Мая Поделиться Опубликовано 21 Мая @Balavnik function spawn_remkom(first_speaker, second_speaker) local sobj = alife():story_object(5003) alife():create("vodka", vector(), 0, 0, sobj.id) end Примечание: при спавне в контейнере точные координаты и вертексы указывать не обязательно, можно обойтись значениями по умолчанию. 1 2 Инструмент Ссылка на комментарий
Norman Eisenherz 276 Опубликовано 31 Мая Поделиться Опубликовано 31 Мая [ЧН 1.5.10] При захвате смарта выдается два типовых сообщения "Спасибо за помощь, приходи за наградой". Тест показывает, что сообщения выдаются из [task_objects.script]: Spoiler --' Контратаку запустиь не получилось, выполняем квест. if self.actor_helped then self.last_check_task = "complete" --' Кидаем озвучку. for kk,vv in pairs(self.board.smarts[target_obj.id].squads) do if(self.play_regard=="") then xr_sound.set_sound_play(vv.commander_id, "alife_defence_actor_help", self.community, self.target) -- здесь elseif(self.play_regard~="nil") then xr_sound.set_sound_play(vv.commander_id, self.play_regard, self.community, self.target) end break end target_obj.combat_manager.combat_quest = "nil" else self.last_check_task = "reversed" target_obj.combat_manager.combat_quest = "nil" end Дальше странное: • в переборе отрядов есть break, который почему-то не действует • если добавить отсечку через логический флаг при запуске одного сообщения, второе сообщение все равно будет выдано • если добавить счетчик, он покажет 1 для обоих сообщений Почему выдается два сообщения? 1 Мини-моды: ТЧ ЧН ЗП Шпаргалка Ссылка на комментарий
Kirgudu 1 151 Опубликовано 31 Мая Поделиться Опубликовано 31 Мая @Norman Eisenherz могу предположить только одно. В той же функции check_task немного выше есть условие if self.state == "counter_attack", в котором выдаётся ровно то же самое сообщение. Раз break и отсечка по флагу не срабатывает, единственное, что приходит в голову - это что последовательно срабатывает выдача сообщений из разных частей условия, с действующей контратакой и без оной. Рекомендую расставить флаги и логирование в обеих частях и проверить. Если я прав, дальше надо будет подумать, почему сначала запускается контратака, потом (видимо) практически сразу отменяется. Могу ошибиться, но на ранних этапах работы над OGSM CS 1.8 (народный патч) что-то такое мы встречали... но в последнее время это уже не проявлялось. Точно уже не помню, давно это было. 1 1 Инструмент Ссылка на комментарий
Norman Eisenherz 276 Опубликовано 31 Мая Поделиться Опубликовано 31 Мая Дублировал запуск звука тестовыми сообщениями – обе реплики выдаются из указанного места почти одновременно. Может xr_sound не успевает зарегистрировать звук до запуска следующего… Мини-моды: ТЧ ЧН ЗП Шпаргалка Ссылка на комментарий
Norman Eisenherz 276 Опубликовано 1 Июня Поделиться Опубликовано 1 Июня [ЧН 1.5.10] Задача: исправить заголовок сообщения, которое выдается вместе с приветствием sound_start через одноименный звуку текст. Условия: приветствие Левши перед входом на завод выдается через конфиг логики [configs\scripts\yantar\yan_scene_6_stalker_5.ltx], при этом в заголовке сообщения не указывается имя NPC, хотя сообщение выдается от определенного объекта NPC с привязкой id. (Кроме Левши, такой подход применяется для торговцев – без дублирования субтитрами.) Решение через скрипты: переименовать текст для вывода отдельно от звука, отследить запуск реплики yan_levsha_hello_actor в [xr_meet.script] и добавить свое сообщение с заголовком и оформлением. Проблемы: приходится проверять все приветствия, и после перезагрузки текст выводится повторно – видимо, нужна еще привязка где-то в [xr_sound.script]. Возможно ли сделать вывод текста непосредственно через логику NPC, причем так, чтобы оно отобразилось только один раз при запуске звука приветствия? Добавление действия в строку victim вызывает ожидаемый спам сообщения на каждом апдейте, который можно порезать через логический флаг и инфо-поршни задания, но это уже костыли. Spoiler [meet@1] meet_state = 30 | hello_wpn@yan_levsha_hello_actor | 10 | guard@yan_levsha_hello_actor meet_state_wpn = 15 | backoff@meet_weapon_wait use_wpn = false sound_start = yan_levsha_hello_actor sound_start_wpn = meet_weapon_wait victim = 30 | actor victim_wpn = 30 | actor use = true use_wpn = true meet_dialog = yan_levsha_hello_dialog Мини-моды: ТЧ ЧН ЗП Шпаргалка Ссылка на комментарий
Kirgudu 1 151 Опубликовано 2 Июня Поделиться Опубликовано 2 Июня 5 часов назад, Norman Eisenherz сказал: Возможно ли сделать вывод текста непосредственно через логику NPC Возможно. В xr_meet.init_meet(npc, ini, section, st, scheme) добавить новый параметр для идентификатора кастомного сообщения, указав в соотв. блоках как дефолтное значение "nil", так и парсинг строки из конфига. В xr_meet.action_meet_wait:execute() при ненулевом значении прочитанного выше параметра добавить вывод сообщения параллельно со звуком и с учётом его условий. Оригинальное сообщение при этом отвязать от звука, а в секцию логики [meet@1] добавить строку с новым параметром. Это, конечно, не действия только с логикой, как, вероятно, хотелось, зато универсальное решение, которым можно будет воспользоваться и в других случаях. 1 Инструмент Ссылка на комментарий
Norman Eisenherz 276 Опубликовано 2 Июня Поделиться Опубликовано 2 Июня 1. Это примерно то же решение через скрипты с отсеиванием всех других приветствий. Хочется сделать правку именно в логике Левши. 2. Убрал звук start_sound – все равно выдается старое сообщение. Подозреваю, что отсюда: meet_state = 30 | hello_wpn@yan_levsha_hello_actor … Добавил в секцию [camper@wait_cut5] (ждать диалога после убийства шального снорка) строку on_timer = 3000 | %=play_sound(…)% – выдается только новое сообщение, повтора после перезагрузки нет. Вроде получилось… Мини-моды: ТЧ ЧН ЗП Шпаргалка Ссылка на комментарий
Kirgudu 1 151 Опубликовано 2 Июня Поделиться Опубликовано 2 Июня 1 час назад, Norman Eisenherz сказал: Это примерно то же решение через скрипты с отсеиванием всех других приветствий. Хочется сделать правку именно в логике Левши. Скорее решение наоборот. Не отсеивание ненужного с избыточными проверками "а то ли это", а адресная обработка нового параметра, который, разумеется, будет добавлен только там, где нужно. Впрочем, условия для этой "нужности" достаточно специфические, почти разовые, так что решил сделать по-другому - и ладно. @monk в Final Stroke вообще пошёл третьим путём: сократил расстояние (чтоб Левша не орал издалека) и убрал субтитры (за ненужностью, ибо лицом к лицу). Подходов может быть много, главное чтобы выбранный способ удовлетворял автора. 1 Инструмент Ссылка на комментарий
Black_Raven_03 29 Опубликовано 6 Июня Поделиться Опубликовано 6 Июня (изменено) Доброго времени суток, прошу помощи! Делаю правку к Новому Арсеналу 7 (движок ОГСР от сен 2020, без возможности смены версии) с таким кодом: local sect = wpn:section() local sil_sect = get_string( sect, "silencer_name" ) if not sil_sect then return end local sil_obj = level.object_by_id(0) db.actor:inventory_for_each( function( temp_sil, db.actor) if temp_sil and db.actor:is_in_ruck(temp_sil) and temp_sil:is_silencer() and temp_sil:section() == sil_sect then sil_obj = temp_sil end end ) , на что получаю ошибку "invalid key to next" Вопрос: а куда копать-то? Правка: сделал через iterate_inventory - больше не вылетает... Изменено 6 Июня пользователем Black_Raven_03 Дополнение Скрытый текст AMD FX-8100 (Bulldozer) , 16GB DDR3-1600, AFOX GeForce GTX1050Ti и нормально сталкерим в НА5.1, НА7, OGSE-0693, OGSR, НС2016, OLR, OFFLIFE, CoC, LADC, CoP Gunslinger, ShoC GA, Legend Return, Anomaly, CS OGSM! Мозг состоит на 80 процентов из жидкости, и мало того, что она тормозная, так многим еще конкретно не долили...@Denikius136 Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти