Kirgudu 1 264 Опубликовано 22 Декабря 2023 (изменено) @Zander_driver, оговорился. Не будет работать запись в абстрактную часть пакета, которая возможна только при выходе в онлайн. А это - STATE_Write. Изменено 22 Декабря 2023 пользователем Kirgudu Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 22 Декабря 2023 (изменено) Вот как раз чтобы не писать руками в каждом необходимом случае. Один раз поправил нужные биндеры - и затем хоть сотню разных однотипных объектов в разных местах кода и с разными условиями перемещай, коллбэк сделает всё за тебя. Не знаю. Мне это кажется достаточно удобным. Зависит от требований к масштабируемости. Изменено 22 Декабря 2023 пользователем Kirgudu Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 22 Декабря 2023 2 минуты назад, div сказал: @Kirgudu, а вес (массу) m_netpk для npc поменять нельзя, так же? Масса, емнип, есть только для физических объектов в state части их пакета. Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 26 Января 2024 @Pir@t@s дописать и использовать свои функции, например что-то вроде такого: Скрытый текст function stop_timer(name) for a = 1,100,1 do if load_variable("xt"..a, nil) == name then del_variable("xt"..a) del_variable("xd"..a) del_variable("xp"..a) return true end end return false end function stop_g_timer(name) for a = 1,100,1 do if load_variable("gt"..a, nil) == name then del_variable("gt"..a) del_variable("gd"..a) del_variable("gp"..a) return true end end return false end 1 2 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 28 Января 2024 @Colder 1. форматируй код так, чтобы закрывающий элемент был на одном уровне с открывающим. Трудновато читать твои примеры взглядом, лишний раз это делать не хочется. 2. Где вызывается функция cashback()? В какой момент? Ни малейших следов вызова не представлено, опять с тобой приходится играть в гадалки. 3. По существу: при первой итерации у тебя local actor_last_money = 0, поэтому ты сваливаешься в условие "if cashback < 1 then" со всеми вытекающими. 2 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 28 Января 2024 @Balavnik именно в тот лог и выводит. А вообще, было предложено 4 варианта (3 без модифицированных движков), но вопрос почему-то возник только по одному из них. Остальные, видимо, не пробовал? В конце концов, если приспичило использовать именно printf, но штатный вариант по каким-то причинам не срабатывает, можно сделать переопределение самым топорным и древним вариантом, на который уже указывал @Zander_driver. local console printf = function(fmt,...) if not console then console = get_console() end console:execute("load ~:"..string.format(fmt,...)) end И добавить это в самый конец _g.script. 3 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 4 Мая 2024 Для серверных объектов - obj.id, для клиентских - obj:id(). Относится к любым игровым объектам, которыми можно манипулировать, в том числе НПС. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 15 Мая 2024 @Norman Eisenherz куда именно добавлял второй класс: в <character> (npc_profile.xml) или <specific_character> (например, character_desc_garbage.xml)? В упомянутом посте речь идёт о втором. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 16 Мая 2024 (изменено) 4 часа назад, Balavnik сказал: Получается просто пробежать for по data.upd Можно проще. В m_netpk есть встроенный метод print, который выведет в лог все имеющиеся свойства конкретного нет-пакета: local pk = get_netpk(obj) pk:print() Единственное, для вывода в лог там используется метод table.print. Если правильно помню, в штатном lua его нет, поэтому потребуется также подключить артосовский расширитель lua_extension (lua_helper) или аналог. Изменено 16 Мая 2024 пользователем Kirgudu 1 3 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 17 Мая 2024 (изменено) 12 часов назад, Zander_driver сказал: Ну вот это я уже не знал/забыл Я тоже не знал до поры до времени. В своё время полез внутрь для исправления разных выявленных недочётов, ну и заметил. В модулях Артоса есть довольно много полезных вещей, не выставленных публично и не описанных ни в какой инструкции, но для того, чтобы их найти, надо, конечно, изучить модули глазами от и до. @Balavnik, дополню свой предыдущий ответ, поскольку вчера забыл о ещё одной возможности m_netpk. Как я уже сказал, можно использовать встроенный метод print() (также не забыть при этом подключить lua_extension/lua_helper от Артоса для поддержки table.print): local pk = get_netpk(obj) pk:print() Таким способом ты выведешь в лог все текущие значения свойств данного конкретного нет-пакета. Скрытый текст ! Cannot find saved game ~:print_table:m_netpk:netpacket(af_gold_fish26566):~~~~~~~> ! Cannot find saved game ~:netpacket.level_vertex_id = [49746] ! Cannot find saved game ~:netpacket.spawn_story_id = [-1] ! Cannot find saved game ~:netpacket.upgrades. = <<zero_table>> ! Cannot find saved game ~:netpacket.distance = [0] ! Cannot find saved game ~:netpacket.condition = [1] ! Cannot find saved game ~:netpacket.game_vertex_id = [135] ! Cannot find saved game ~:netpacket.visual_name = [dynamics\artefacts\af_gold_fish] ! Cannot find saved game ~:netpacket.object_flags = [-65] ! Cannot find saved game ~:netpacket.visual_flags = [0] ! Cannot find saved game ~:netpacket.upd.num_items = [0] ! Cannot find saved game ~:netpacket.story_id = [-1] ! Cannot find saved game ~:netpacket.custom_data = [<<userdata>>] ! Cannot find saved game ~:netpacket.direct_control = [1] ! Cannot find saved game ~:print_table:m_netpk:netpacket(af_gold_fish26566):~~~~~~~< Но что если тебе нужно узнать не текущее содержимое, а полный возможный состав нет-пакета данного типа объекта и какого типа каждое его свойство? Для этого существует метод dumpDesc(), явно описанный в инструкции к модулю (см. пункт 3.2). Этот метод возвращает строку с полным читабельным описанием нет-пакета, которую, в свою очередь, можно самостоятельно вывести в лог. Но так как строка скорее всего будет слишком длинной для вывода в один приём, потребуется дополнительная обвязка для разбиения на части: local pk = get_netpk(obj) -- получаем нет-пакет объекта local description = pk:dumpDesc() -- получаем его описание -- бьём на части по 200 символов максимум и выводим в лог local console = get_console() local pattern = "(."..string.rep(".?", 199)..")" for line in description:gmatch("[^\n]+") do for part in line:gmatch(pattern) do console:execute("load ~:"..part) end end Результат: Скрытый текст ! Cannot find saved game ~:<<< dump of cse_alife_item_artefact desctiption >>> ! Cannot find saved game ~:;-- cse_alife_object part --- ! Cannot find saved game ~: game_vertex_id => u16 ! Cannot find saved game ~: distance => f32 ! Cannot find saved game ~: direct_control => u32 ! Cannot find saved game ~: level_vertex_id => u32 ! Cannot find saved game ~: object_flags => h32 ! Cannot find saved game ~: custom_data => cd ! Cannot find saved game ~: story_id => s32 ! Cannot find saved game ~: spawn_story_id => s32 ! Cannot find saved game ~:;-- cse_visual part --- ! Cannot find saved game ~: visual_name => sz ! Cannot find saved game ~: visual_flags => u8 ! Cannot find saved game ~:;-- cse_alife_dynamic_object_visual part --- ! Cannot find saved game ~:;-- cse_alife_inventory_item part --- ! Cannot find saved game ~: condition => f32 ! Cannot find saved game ~: upgrades => l32szv ! Cannot find saved game ~: upd.num_items => h8 ! Cannot find saved game ~: upd.force => f32v3 ! Cannot find saved game ~: upd.torque => f32v3 ! Cannot find saved game ~: upd.ph_position => f32v3 ! Cannot find saved game ~: upd.ph_rotation => q8v4 ! Cannot find saved game ~: upd.ph_angular_vel => q8v3 ! Cannot find saved game ~: upd.ph_linear_vel => q8v3 ! Cannot find saved game ~: upd.enabled => b8 ! Cannot find saved game ~:;-- cse_alife_item_artefact part --- ! Cannot find saved game ~:<<< dump end >>> Изменено 17 Мая 2024 пользователем Kirgudu 1 2 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 17 Мая 2024 24 минуты назад, Balavnik сказал: За что отвечает xr_motivator? Они действительно служат примерно одним и тем же целям, только xr_motivator используется для сталкеров, тогда как bind_stalker - для героя. См. разницу между bind_stalker.init() и bind_stalker.actor_init(), которые прописаны в свойстве script_binding в, соответственно, m_stalker.ltx и actor.ltx Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 24 Мая 2024 Параметр name можно менять произвольно, это то внутреннее имя объекта, которое в игре будет возвращаться при вызове метода obj:name(). Единственное вероятное (не проверял) требование - имя должно быть уникальным. Параметр section_name, как можно догадаться из названия, должен совпадать с секцией нужного типа. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 25 Мая 2024 (изменено) 3 часа назад, CiberZold сказал: проблем с игрой не было в плане вылетов, иди что она ругалась на 2 объекта с одинаковым именем Проблем с игрой не было, а вот у потенциального разработчика-последователя, который ожидает при получении объекта по имени, что там всего один такой экземпляр, причём конкретный, хотя их на самом деле два, - проблемы будут. 1 час назад, Zander_driver сказал: Клиентский получают из level.object_by_id(id) - вот для него надо подождать 1 кадр как минимум, после спавна. @Balavnik, дополню ответ коллеги по цеху. Гарантированным способом дождаться момента, когда клиентский объект уже точно есть, является использование функционала класса level.client_spawn_manager(), в экземпляр которого добавляется коллбэк (функция, вызываемая при некоем событии), срабатывающий при выходе только что заспавненного объекта в онлайн. Пример (отформатировал вызов построчно для наглядности): local sobj = alife():create(section, position, lvid, gvid) if sobj ~= nil then level.client_spawn_manager():add( sobj.id, -- id известного нам серверного объекта 65535, -- параметр игнорируется, обычно ставлю такое значение для простоты function (id, obj) -- функция-коллбэк, здесь job - клиентский объект, id - его id, равный sobj.id -- что-то делаем с obj end ) end Важно при этом помнить, что коллбэк этот существует ровно до момента ближайшей загрузки из сэйва/перехода на другую локацию, после которых уже не сработает. Поэтому применять этот метод получится при спавне только на той же локации, что и герой, ну и желательно в alife-радиусе. Подробнее про класс client_spawn_manager(), в том числе про альтернативную перегрузку метода add(), рекомендую почитать в уже много раз упоминавшемся "справочнике" здесь и здесь. Изменено 25 Мая 2024 пользователем Kirgudu 1 4 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 26 Мая 2024 1 минуту назад, Norman Eisenherz сказал: Стоит уточнять, что это OGSR. Дико плюсую, ибо я уже почти набил отличающийся ответ по оригиналу ТЧ. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 28 Мая 2024 @abramcumner я бы уточнил, что речь идёт (скорее всего) о псевдониме "$app_data_root$". Он ведь не обязан идти первой строкой. @dPlayer мануала не встречал, но он вроде как и не требуется особо. Есть фиксированный и не описанный явно псевдоним "$fs_root$", путь для которого берётся движком. Все остальные псевдонимы в оригинальном fsgame являются дочерними по отношению к "$fs_root$". Упомянутый выше псевдоним "$app_data_root$" может и наследовать и быть самостоятельным - в зависимости от источника игры и частных настроек. А вообще, ограничений там никаких нет, и любой псевдоним можно описывать как по относительному пути, так и по абсолютному. Для портативности нужно чтобы пути всех псевдонимов были относительными. 4 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 29 Мая 2024 Первый параметр - рекурсия включена/выключена (для операций с массивом файлов, например, чтением их списка в папке), второй - уведомление (движка) об изменениях включено/выключено. Где и в каких сценариях используется второй параметр, сказать не могу, не изучал. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 29 Мая 2024 28 минут назад, dPlayer сказал: Как применить понятие рекурсия к списку файлов непонятно, ну да ладно)))) Эммм... "с учётом вложенных папок" пойдёт? ) 30 минут назад, dPlayer сказал: К файлу юзер.лтх нельзя выходит применить сохранение в какую-то отдельную папку? Если не ошибаюсь, user.ltx сохраняется в "$app_data_root$". 1 1 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 5 Июня 2024 Совершенно верно. Это фикс замены визуала на дефолтный от Артоса и Шокера. 2 1 Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 5 Июня 2024 1 час назад, Zander_driver сказал: Если бы ты писал это лет 12 назад, я бы с тобой даже согласился. Ну даже 10 пожалуй. Как ни крути, а придётся согласиться и сегодня. Ведь этим способом по-прежнему можно менять предмет в слоте. А методы в "нормальных" движках - всего лишь добавленная альтернатива, но не безусловная замена. Инструмент Поделиться этим сообщением Ссылка на сообщение
Kirgudu 1 264 Опубликовано 8 Июня 2024 2 часа назад, DarkSnowder сказал: А то и Дирех обновлял, и С++ Метод ненаучного тыка в действии. А всего-то надо было внимательно прочесть, что написано на своём же собственном скриншоте ошибки. 1 Инструмент Поделиться этим сообщением Ссылка на сообщение