Kirgudu 1 264 Опубликовано 23 Октября 2022 (изменено) 13 часов назад, mole venomous сказал: почему так Потому что db.actor:object(dropped) ищет не конкретный предмет, а первый попавшийся предмет с секцией, равной секции dropped. Ты заметил, что после первого выкидывания остаются в инвентаре только те предметы, количество которых больше 1? Можно предположить, например, что функция drop_item удаляет предмет не одномоментно, а с некоторым запаздыванием, и когда ты ищешь следующий предмет с такой же секцией, всё время находится первый из них, который уже должен был удалиться к тому времени. Чтобы этого избежать, можно попробовать перейти на работу с идентификаторами вместо секций: table.insert(tActorItems,item:id()) -- запоминаем идентификатор вместо секции db.actor:drop_item(level.object_by_id(dropped)) -- ищем объект по идентификатору В остальном код будет идентичным. Изменено 23 Октября 2022 пользователем Kirgudu 1 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 7 Ноября 2022 5 часов назад, Norman Eisenherz сказал: Есть ли разница, в каком именно скрипте указан код с подменой функций? Есть разница в том, в каком порядке загружаются и инициализируются твой скрипт и целевой. Если целевой скрипт, в котором находится подменяемая функция, загружается первым, тогда твоя подмена сработает. А вот если вторым - всё, что ты наприсваивал предварительно в своём скрипте, будет полностью переписано в _G исходным кодом целевого скрипта, когда до него дойдёт очередь. Об этом. кстати, уже написано в постах по приведённым ссылкам. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 7 Ноября 2022 Правильный формат описан в тех постах. Используй вызов prefetch("модуль_с_подменяемой_функцией") в _g.start_game_callback() для принудительной заблаговременной загрузки. И вообще убедись путём логирования в консоль, что выполнение происходит в нужном тебе порядке. Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 8 Ноября 2022 1 час назад, Norman Eisenherz сказал: какие дополнительные возможности дает подмена на ходу по сравнению с прямым редактированием исходных скриптов? Редактирование исходного скрипта - постоянно, до конца игры изменённый функционал, подмена на лету - изменённый функционал автоматически откатывается к стандартному при ближайшей загрузке. Нужно это или нет в конкретном моде, можно решить самостоятельно. Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 8 Ноября 2022 (изменено) Изменения, внесённые подменой, учитываются в процессе игры, но только от загрузки, во время которой произошла подмена, до следующей загрузки из сохранения (когда, в свою очередь, может произойти очередная подмена). Для кого-то это может быть существенной разницей, если полезно для осуществления тех или иных сюжетных/игровых решений. Аналогичного результата можно добиться (не)сохраняемыми флагами, условиями и т. п., но это уж кому что удобней и привычней. Изменено 8 Ноября 2022 пользователем Kirgudu 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 15 Ноября 2022 55 минут назад, Norman Eisenherz сказал: Откуда эта проверка вызывается и куда возвращает true/false? См. элементы function_fail в game_tasks_by_vendor.xml Вызывается движком. Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 15 Ноября 2022 @Norman Eisenherz всё здесь: xrGame\GameTask.cpp 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 22 Ноября 2022 20.11.2022 в 00:47, Norman Eisenherz сказал: В чем может быть проблема? В невнимательности. Аргумент, передаваемый в метод alife():spawn_id(), должен прописываться в all.spawn как spawn_story_id = xxx. А story_id может использоваться в методе alife():story_object() для получения объекта, но не его spawn_id. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 23 Ноября 2022 Внимательно стоит читать не только документацию по игре в случае её наличия, но и посты, на которые сам же ссылаешься, например, тут: https://www.amk-team.ru/forum/topic/6138-cs-kovyryaemsya-v-faylah/?do=findComment&comment=1443031 Всё в ЧН работает, проверено личным опытом модостроя, а Malandrinus в своём посте разжевал вопрос так, что дальше некуда. Не нужно путать spawn_id, задаваемый отдельным параметром в секции объекта в all.spawn и тот виртуальный spawn_id, который является порядковым номером этой секции объекта и который при распаковке, например, средствами acdc (с SDK не работал, но, возможно, там тоже) можно увидеть в квадратных скобках в начале секции. Поскольку при перепаковке all.spawn этот номер может измениться, единственно правильным способом получить его при исполнении будет вызов метода alife():spawn_id(spawn_story_id), где spawn_story_id, в свою очередь, также прописан отдельным параметром в секции объекта в all.spawn. Никакие spawn_id, прописанные там же отдельным параметром, не должны использоваться в данном механизме ни в ТЧ, ни в ЧН, ни в ЗП, а story_id можно использовать только для поиска уже заспавненного объенкта перед его удалением, но не для повторного спавна. Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 25 Ноября 2022 https://github.com/OGSR/OGSR-Engine/commit/1e0477aff92a233ca6fd062a546f54229f2b0bcb Qui quaerit, reperit. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 25 Ноября 2022 (изменено) @dsh было, было и в основной ветке, видимо, дополнение признали полезным и затянули. https://github.com/OGSR/OGSR-Engine/commit/544daa9962efb142b6e2b058e045846f96dc5608 Легко найти по истории, уже второй коммит с конца:https://github.com/OGSR/OGSR-Engine/commits/main/ogsr_engine/xrGame/alife_spawn_registry.cpp Офф: я впервые в ваши правки движка заглянул так-то; даже при взгляде наискосок попадаются любопытные вещи. Если б ещё было время заниматься модостроем, да по-прежнему сохранялся высокий интерес... но нет. Хватит того, что периодически могу дать ответ по легаси скриптам. Изменено 25 Ноября 2022 пользователем Kirgudu 1 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 12 Февраля 2023 1 час назад, Jekyll сказал: local table = {1,2,3,4,5} (условно) math.max(table) - не работает (вылет - number expected, got table) local t = {1,2,3,4,5} local m = math.max(unpack(t)) 4 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 3 Марта 2023 Оператор #, кстати, вполне успешно вернёт длину строки, но это ничему не поможет. Предположим, что загадочная функция gts - это game.translate_string. Предположим даже, что функция show_news действительно вызывается, но тогда непонятно, как в неё передаётся переменная item, ведь show_news объявлена за пределами on_trade, а область видимости переменной item - внутри on_trade. Скорее всего, как писали выше, передавать item в функцию таки необходимо. Но и это ещё не всё. local name = system_ini():r_string(item:section(), "inv_name") - здесь переменной name присвоится строка. Одна строка. #name отработает и даст длину, math.random(#name) - случайный индекс в пределах длины строки. Однако name[math.random(#name)] вернёт nil, поскольку получить один символ из строки посредством обращения к индексу в Lua нельзя - у символов в строках просто нет индекса. Для этого необходимо использовать функцию string.sub. Но даже если бы удалось получить символ, то после применения загадочной local ww = gts(n) в переменную ww попадёт ровно тот же символ без всякого перевода. Ибо вряд ли в xml с текстами найдутся записи, идентификаторами которых служат одиночные символы латинского алфавита... 2 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 3 Марта 2023 (изменено) @Colder Вот поэтому и стоит для начала сделать то, о чём писали выше: 19 часов назад, mole venomous сказал: Вообще не понял... Может, стоит для начала рандомно определить оружие? Нужно получить список имён оружия и вывести его в новости. Какого оружия, где? В слоте? В инвентаре? На уровне? Вообще любого в игре? Передаваемого покупателю/продавцу (если отталкиваться от on_trade? Если берёшь в работу один единственный предмет, который передаётся в параметр item функции on_trade, то о каких множественных строках, перебор которых ты хочешь сделать, может идти речь? И т. д. Цель непонятна, условия непонятны, а гадать, что именно требуется сделать, - неблагодарное занятие. Изменено 3 Марта 2023 пользователем Kirgudu 2 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 3 Марта 2023 (изменено) Перебирает все предметы в игре (на всех локациях), помещает уникальные записи оружия в таблицу, затем выводит в новость случайное название из этой таблицы: local weapon_names, weapon_sections, cnt, sini, al = {}, {}, 0, system_ini(), alife() for i=1, 65535 do local obj = al:object(i) if obj and isWeapon(obj) then local section = obj.section_name and obj:section_name() if section and (not weapon_names[section]) and sini:section_exist(section) and sini:line_exist(section, "inv_name") then local name = sini:r_string(section, "inv_name") weapon_names[section] = name table.insert(weapon_sections, section) cnt = cnt + 1 end end end if cnt > 0 then local news_text = "%c[ui_gray_1]"..game.translate_string(weapon_names[weapon_sections[math.random(cnt)]]) db.actor:give_game_news(news_text, "ui\\cop\\ui_cop_iconstotal", Frect():set(415,0,83,47), 0, 5000) end Вот только затратная это штука благодаря перебору. Куда проще было бы пройтись по всем конфигам и вычитать из них секции с оружием по какому-то признаку, но я так никогда не делал, не могу подсказать способ. Изменено 3 Марта 2023 пользователем Kirgudu 1 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 4 Марта 2023 (изменено) 10 часов назад, AndrewMor сказал: Мне вот не подошел Аналогично, но с советом целиком и полностью согласен. Но я на работе настолько наедаюсь программированием (full stack от БД до фронта), что лезть и в движок Сталкера тупо не хотелось, хотя при нужде могу просто посмотреть, что там в нужном месте написано. Для меня чистые Lua скрипты на ванильном движке - это редкий отдых. @Zander_driver почему бы просто не выложить куда-нибудь в инструментарий мододела? Кому надо - найдёт и возьмёт не сейчас, так позже. Я вот тоже обязательно полюбопытствую, а может и воспользуюсь однажды. Изменено 4 Марта 2023 пользователем Kirgudu 1 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 13 Марта 2023 3 часа назад, phalcor сказал: Для серверного объекта способ нашёл Не очень понимаю, как такое может сработать, ведь свойства checked_characters нет в оригинальном модуле Артоса для работы с нет-пакетами (который тут, судя по всему, и используется). 3 часа назад, phalcor сказал: А как тоже самое сделать для клиентского объекта Воспользоваться аналогичным кодом, но поменять свойство character_name. Это, однако, не поможет, поскольку имя персонажа в журнале, диалогах и при наведении курсора берётся из профиля. Можно, конечно, и профиль на лету поменять - для этого в нетпакете есть свойства specific_character и character_profile, но и они не охватывают всё, к тому же сие чревато другими последствиями, такими как замена визуала и т. п. Имхо, без редактирования движка на все 100 задачу не выполнить. 1 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 13 Марта 2023 @phalcor можно попробовать воспользоваться встроенной в модуль функцией автоматического перевода объекта онлайн-оффлайн-онлайн: m_netpk.do_switchings(id) Она в публичный интерфейс автором не выведена, поскольку предназначена в первую очередь для изменения абстрактной части из коллбэка, но дёрнуть её напрямую ничто не мешает. 1 1 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 2 Апреля 2023 @Norman Eisenherz не подтверждаю. https://disk.yandex.ru/d/TfcsZSLsZNf9zQ Здесь скрипт (дополнил логом в функциях init, update, load и save), лог и сейвы - до использования уже мёртвой псевдособаки, после, и после загрузки. По логу видны манипуляции с тремя объектами: убитой псевдособакой, Сидоровичем (который, емнип, тоже монстр по биндеру) и, наверное, плотью, которую на старте в аномалию засасывает. Сидоровича использовал во время первого диалога, собаку при обыске, плоть - нет. И до и после загрузки видно 2 положительных флага и один отрицательный, как ожидалось. Возможно, разница в движках; пользуюсь купленной 15 лет назад в Стиме версией игры. @imcrazyhoudini не значит, поскольку для того, чтобы отработало inherited::Load(section), необходимо, чтобы класс CScriptBinder наследовал другой, родительский класс, который в актуальной версии не указан. Возможно, там и было что-то ранее, но вопрос возврата всего явно лежит не в плоскости данной темы. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 17 Апреля 2023 @Norman Eisenherz Имхо, никак, потому что здесь как раз наследование, инициализация базового класса со всеми его инкапсулированными свойствами и т. д. В цитируемом посте речь, к. м. к., шла о более простом варианте класса, типа такого: class "WeatherManager" function WeatherManager:__init() self.weather_change_day = 0 self.update_time = 0 self.update_level = "" end function WeatherManager:reset() -- ... end function WeatherManager:select_weather(now) -- ... end Который можно было бы переписать как: self = {} function reset() -- содержимое не меняется end function select_weather(now) -- содержимое не меняется end self.weather_change_day = 0 self.update_time = 0 self.update_level = "" Но зачем вообще вопрос и желание - непонятно. Академический интерес? 3 Инструмент Поделиться этим сообщением Ссылка на сообщение