Это популярное сообщение. Malandrinus 615 Опубликовано 8 Июля 2009 Это популярное сообщение. Поделиться Опубликовано 8 Июля 2009 (изменено) В данной теме собраны сведения по скриптовой модели сталкера: функции и классы, методы и свойства, взаимосвязь классов и последовательность работы с ними, связь работы классов и файлов конфигураций. К наполнению темы приглашаются все желающие. В наполнении темы непосредственно участвовали и существенно мне помогли: @Monnoroch, @Kolmogor, @Unnamed Black Wolf, @меченый(стрелок), @IQDDD, @Kirag, @Taroz, @dan, @7.9, @Garry_Galler, @AKKK1, @Bak и много других людей. Скрытый текст Скрытый текст класс alife_simulator. Базовые операции с серверными объектами. Пространства имён. Глобальные функции для большого числа задач. "Создание своего класса" и "Наследование от экспортированных классов". Базовые сведения об объектно-ориентированном программировании для сталкера. Необходимо прочитать, для понимания темы про биндер и некоторых других. В одном посте: Общие слова об архитектуре и скриптовой модели сталкера "Класс object_binder" расширение онлайновых объектов, колбеки, сохранение состояния. "Класс net_packet" Регистрация скриптовых классов с помощью object_factory Серверные классы. Часть 1 Иерархия серверных классов, описание не закончено. Серверные классы. Часть 2 Картинка структуры наследования и несколько заключительных слов Клиентские классы Скрытый текст Класс game_object Интерфейс ко всем онлайновым (клиентским объектам) Класс hit для нанесения урона скриптом и другая информация (IQDDD) Некоторая информация по управлению путями патрулирования здесь (Kirag) и здесь (Taroz) Неполная информация по управлению памятью неписей с примером здесь (Bak) Физическая оболочка объектов (Garry_Galler) Пост о выборе (подборе) оружия НПС и стрельбы (*Shoker*) Скрытый текст Управление заданиями Класс CGameTask и другие вспомогательные классы и функции. Управление инфопорциями Функции, колбеки, форматы файлов Список специальных системных инфопорций (Unnamed Black Wolf) Система профилей и алгоритм генерации имён. Форматы файлов, функции Дополнительная информация по параметрам профилей terrain_sect (Kolmogor) Диалоги. Часть 1 Форматы файлов, базовые сведения Диалоги. Часть 2 Скриптовые диалоги Диалоги. Часть 3 Тематическая подборка функций управления диалогами Скрытый текст Функции времени Тематическая подборка функций, связанных с управлением игровым временем. Класс CTime Вспомогательный класс для управления игровым временем Полезная скриптовая функция с использованием CTime (Garry_Galler) Скрытый текст class ini_file (меченый(стрелок)) Класс FS и CSavedGameWrapper Бинарный доступ к файлам, в том числе в игровых архивах, управление сохранёнными играми. Скрипт уровня. Забытая фишка с колбеком на заход на уровень Класс vector Некоторая полезная информация о разных вещах (меченый(стрелок)) "Класс render_device" Направление и положение камеры, характеристики экрана, программная пауза игры и др. Некоторая информация о различиях между ТЧ и ЗП в системе оконных классов и колбеков. (lekzd) Неплохо бы развить эту тему! Некоторая полезная информация о скриптовых функциях из модуля _g.script. (lekzd) Также требует развития! Полезные функции для работы с графом игры (Garry_Galler) В одном посте: Класс profile_timer Отладочные измерения скорости работы фрагментов программы Класс client_spawn_manager Колбек на выход в онлайн без использования биндера. Работа с консолью. Класс CConsole Анимации цвета. Класс color_animator Всякие моргающие элементы в окнах и пр. Управление постэффектами. Скриптовые постэффекты. Класс effector Класс sound_object. Проигрывание звуков в игре в произвольном месте, от произвольного объекта, в голове актора. (Shadows) Пост удалён автором (прим. Kirgudu) Скрытый текст Оконные классы Некоторая общая информация о создании окон Список методов, XML-тегов и событий для оконных классов (ТЧ/ЧН/ЗП) (Norman Eisenherz) Представление материала в моих статьях оптимизировано для онлайнового просмотра. Если кому не хочется лазить по спойлерам, а нужно просмотреть текст какого-либо поста "потоком", то могу рекомендовать просмотр в режиме "текстовая версия". В этом же режиме удобно сохранять содержимое темы на диск. (прим. Malandrinus) Изменено 30 Июля пользователем Kirgudu 5 5 16 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Vano_Santuri 33 Опубликовано 17 Января 2010 Поделиться Опубликовано 17 Января 2010 malandrinus, я попробовал по 10 раз по 10 через некоторый промежуток времени, привязал к таймеру, все отлично, Просто делал динам.аномалии, принцип примитивный. Скрипт ищет нужные секции, и удаляет их (перебор каждого из 65565 айди и сравнения его с секциями, которые задал) и вторая чать просто спавнит их.Когда пробовал по 100 за раз , рано или поздно, происходили вылеты(лог есть, но только стак трэк и все), а сейчас через таймер амк сделал примитивный цикл, по 10 шт, пока все отлично, уже 125 раз на данный момент переспавним, оббегал всю локацию. Норм, и во время спавна (я туда посыл новости приписал) даже не подвисает нисколько. Единственно хотел спросить. Вергас как-то мне сказал, что если один скрипт (сам файл ил другое что-то) будет содержать очень много всяких функций, которые будут вызываться из разных мест, то будет переполнение стэков. Так вот у меня вопрос. Если я разделю один скрипт( 92 кб, там много чего) на несколько частей, то как это повлияет на работу скрипта\игры, будут ли тормоза? или лучше все в одном крипте хранить? Что-то кончается, что-то начинается... Ссылка на комментарий
Malandrinus 615 Опубликовано 17 Января 2010 Автор Поделиться Опубликовано 17 Января 2010 Vano_Santuri, По-моему никак это ни на что не повлияет. Дели или объединяй скрипты как тебе удобно. На мой взгляд, реально вызвать переполнение стека только если зациклить рекурсивный вызов. Типа такого: function fun() fun() -- сама себя вызывает до бесконечности end fun() -- здесь получишь вылет с сообщением "stack overflow" Для вылета в данном случае потребовалось 16 тыс. итераций. Я думаю, можно попытаться вызвать переполнение стека, если распаковать длинную таблицу и сунуть её как список аргументов. Но это всё нетривиальные случаи, как правило такой ситуации быть не должно. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Vano_Santuri 33 Опубликовано 21 Января 2010 Поделиться Опубликовано 21 Января 2010 (изменено) У меня возник такой очень интересный вопрос. Он не по функциям или классам, а скорее по структуре и архитектуре. Допустим у меня есть пачка функций. Нужно написать такую функцию, что когда я её вызываю , она рандомно выбирает любую функцию из той пачки и вызывает её. Можно примерчик? А то у меня фантазии не хватило, получилось сделать через if math.random(0,1)>0.5 then ........ и так в несколько этажей, очень неудобно. Можно ли как-нибудь бахнуть все функции списочком, присвоить им циферки, и чтоб функция выбирала циферку, и запускала функцию, которая соответствует выбранной цифре? Изменено 21 Января 2010 пользователем Vano_Santuri Что-то кончается, что-то начинается... Ссылка на комментарий
Monnoroch 6 Опубликовано 21 Января 2010 Поделиться Опубликовано 21 Января 2010 (изменено) local funcs = { [1] = function()....end, [2] = function()....end, [3] = function()....end, [4] = function()....end, [5] = function()....end } function call() funcs[math.random(#funcs)] end math.random(0,1) = math.random() - и вернет 0 или 1. нету смысла писать > 0.5 - это дольше обрабатывается чем == 1 ==== и все-таки вопрос-то не сюда,а в ковырялку. ==== нет,Ray, ну вот зачем ты это написал и дал человеку код,который гораздо сложнее того,что он просит,если я уже дал внятный ответ? === Ты преподом чтоли работаешь? Изменено 21 Января 2010 пользователем Monnoroch Ссылка на комментарий
Malandrinus 615 Опубликовано 21 Января 2010 Автор Поделиться Опубликовано 21 Января 2010 local funcs = { [1] = function()....end, ... } В данном случае индексы указывать не надо. Автонумерация от единицы и так получится. Т.е. достаточно как-то так: local funcs = { fun1, fun2, fun3, ... } Зато конструкция вида: local funcs = { [<ключ1>] = function1, [<ключ2>] = function2, [<ключ3>] = function3, ... } вполне заменяет недостающий оператор switch. Это может радикально ускорить выполнение некоторых фрагментов, если заменить этим убогие километровые списки из if - else. Что касается неподходящей темы, то я с этим не согласен. Не помню, говорил или нет, но желание было замутить здесь статейку другую по "advanced Lua", где в том числе обсуждались бы и такие вопросы. Потому что смотреть на код порой просто больно. Теми же таблицами похоже что сами разработчики научились пользоваться только в ЗП =) Добавлено через 13 мин.: Раз пошла такая пьянка. Комрады, не пишите плиз соединение нескольких строк так: res = a..b..c..d..e Это очень медленно, поскольку на каждую операцию конкатенации приходится вычисление суммарной длины и выделение памяти под новую строку. Вместо этого используйте string.format: res = string.format("%s%s%s%s%s",a,b,c,d,e) При таком способе вычисление суммарной длины и выделение новой памяти происходит всего один раз. Кроме того, статичные фрагменты можно разместить прямо в строке формата. Опять же, дополнительные возможности по форматированию. Способ первый даёт N^2 время вычисления, где N - число соединяемых строк. Способ второй - N. Регрессия производительности может быть совершенно чудовищная. Не говоря уже о фрагментации памяти. Так можно соединять и заранее неизвестное число строк. Если надо, напишу как именно. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Vano_Santuri 33 Опубликовано 23 Января 2010 Поделиться Опубликовано 23 Января 2010 (изменено) Ясно, только один момент : [<ключ1>] = function1, <ключ1> - что подрузумевается под этим? произвольное слово? Или что-то другое. И еще вопрос, допустим идет вызов функции на какое-то условие : function has_info() if db.actor:has_info("info") then ................. end end Вызов пошел, если поршень есть, то скрипт срабатывает, а вот если поршня еще нет, то скрипт не срабатывает? и возвращает false ? Или это ему надо еще дописать? И несет ли такая форма записи нагрузку на память? Изменено 23 Января 2010 пользователем Vano_Santuri Что-то кончается, что-то начинается... Ссылка на комментарий
Malandrinus 615 Опубликовано 23 Января 2010 Автор Поделиться Опубликовано 23 Января 2010 <ключ1> - что подрузумевается под этим? произвольное слово? Ключом может быть любая переменная, кроме значения nil: числа, строки, булевские, таблицы, функции и пользовательские объекты. И несет ли такая форма записи нагрузку на память?Вопрос некорректно поставлен. Какую-то нагрузку несёт любое шевеление. Другое дело, какую нагрузку несёт этот вариант по сравнению с каким-то другим. С чем ты его сравниваешь? возвращает false ? Или это ему надо еще дописать? пока ты не напишешь return true или return false (ну или что-то другое - все зависит от задачи) функция ничего возвращать не должна. Если замутили таки функцию и надо вернуть true/false, то довольно часто можно обойтись без возврата false. Если ничего не возвращать, то это эквивалентно возврату nil. А nil в свою очередь в логических выражениях однозначно интерпретируется как false (согласно синтаксису языка). Впрочем, в данном случае это будет скорее трюкачеством. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Malandrinus 615 Опубликовано 23 Января 2010 Автор Поделиться Опубликовано 23 Января 2010 Ray, совершенно согласен насчёт читабельности. Но я чего завёлся-то, такой код стимулирует по аналогии писать в вырожденном случае кошмарную конструкцию вида: if <лог. выр.> then return true else return false end Посему я бы написал тот фрагмент так: function has_info() local has_info = db.actor:has_info("info") if has_info then ................. end return has_info end Что в вырожденном случае (при отсутствии действия по условию) приводит к более вразумительному коду. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Malandrinus 615 Опубликовано 23 Января 2010 Автор Поделиться Опубликовано 23 Января 2010 Ray, стиль дурной, согласен. Но к ошибке в данном случае это не приведёт, поскольку как обычно локальные переменные перекрывают глобальные. Сама функция внутри себя становится недоступна, но в данном случае рекурсия не нужна. ЗЫ: Это индикатор =) К концу недели способность рожать "длинные мнемоничные идентификаторы" сильно снижается. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Garry_Galler 7 Опубликовано 29 Января 2010 Поделиться Опубликовано 29 Января 2010 (изменено) Внесу небольшую лепту для желающих получить список вертексов - гейм и левел. Скрытый текст Написал пару функций которые при активации формируют таблицу со списком - как вы ее потом будете использовать - это уже ваша проблема. Получаем набор вертексов для каждого уровня. (набор разумеется не весь - а только тех левел вертексов, которые ассоциированы c гейм вертексами в файле game_graph ) Скрытый текст local lvtab ={} function LevelVertexId() --for i =0, 3511 do --можно и так делать. Номера гейм вертексов можно узнать из файла game_graph который конвертируется в txt прогой ggtool и тотал коммандером. --метод game_graph():valid_vertex_id(i) в данном случае делает тоже самое - подтверждает что гейм вертекс с таким то номером существует. local i = 0 while game_graph():valid_vertex_id(i) do local lv = game_graph():vertex(i):level_vertex_id() --получаем левел вертекс по гейм вертексу --получаем имя уровня по его номеру из секции в game_graph local ln = alife():level_name(game_graph():vertex(i):level_id()) if not lvtab[ln] then lvtab[ln] ={} end table.insert(lvtab[ln], lv) --заполняем таблицу i = i+1 end end таблица заполняется в таком виде: ключ- имя уровня, значение - таблица с данными для этого уровня. [имя_уровня] ={номер, номер, номер и т.д} так как выводить всю таблицу скажем на экран возможным не представляется, я выводил только минимальные и максимальные значения вертексов для каждого уровня. Вот такой функцией, для которой нужно в файле ui_custom_msgs.xml создать блок с координатами вывода текста. типа такого <cs_debug x="200" y="180" width="600" height="100" complex_mode="1"> <text font="letterica16" r="240" g="217" b="182" a="255" align="l"/> </cs_debug> (функцию вывода данных я активировал через первую функцию) function diapason() local text ="" for k, v in pairs(lvtab) do local n = table_maxn(v) local min_v = math.min(unpack(v)) local max_v= math.max(unpack(v)) local str = "Уровень ["..k.."]" local num = "число индексов ["..n.."]" local str = string.format("%s %s %s %s", str, min_v, max_v, num) text= text..str.."\\n" end local hud = get_hud() hud:AddCustomStatic("cs_debug", true) hud:GetCustomStatic("cs_debug"):wnd():SetTextST(text) hud:GetCustomStatic("cs_debug").m_endTime = time_global()/1000 + 180 end По аналогии с функцией получения левел вертексов можно сделать и функцию получения гейм вертексов и так же заполнить таблицу. Скрытый текст local gvtab ={} function GameVertexId() local i = 0 while game_graph():valid_vertex_id(i) do local ln = alife():level_name(game_graph():vertex(i):level_id()) if not gvtab[ln] then gvtab[ln] ={} end table.insert(gvtab[ln], i) i = i+1 end this.diapason_gv() --вызываем функцию для вывода данных на экран end и точно такую же функцию для вывода минимального и максимального значения гейм вертексов для каждого уровня. Так как геймвертексы идут неразрывно - то мы имея этот диапазон получаем точный список гейм вертеков для каждого уровня - от первого значения до последнего. Всего в игре как вы поняли 3512 гейм вертексов - от нулевого до 3511-го. function diapason_gv() local text ="" for k, v in pairs(gvtab) do local n = table_maxn(v) local min_v = math.min(unpack(v)) local max_v= math.max(unpack(v)) local str = "Уровень ["..k.."]" local num = "число индексов ["..n.."]" local str = string.format("%s %s %s %s", str, min_v, max_v, num) text= text..str.."\\n" end local hud = get_hud() hud:AddCustomStatic("cs_debug", true) hud:GetCustomStatic("cs_debug"):wnd():SetTextST(text) hud:GetCustomStatic("cs_debug").m_endTime = time_global()/1000 + 180 end Выводится также мин. и макс. значения - чего в данном случае вполне достаточно. чуть не забыл - так как в сталкере не работает функция table.maxn() - которая возвращает кол-во целочисленных индексов в таблице, то я пользуюсь ее самопальным аналогом, (который считает индексы всех типов - хоть числовые, хоть строковые - причем для числовых не важно идут ли они в математическом порядке или вразнобой) вызывая там где надо table_maxn(имя таблицы) function table_maxn(tbl) local k = 0 for _, v in pairs(tbl) do k = k + 1 end return k end Полученные таким образом таблицы можно динамически использовать прямо в игре для соответствующих целей. Небольшое дополнение по методам: Скрытый текст game_graph() --метод определения файла game.graph vertex(*gvid*) --метод определения секции в данном файле (гейм_вертекс) level.vertex_position(*lvid*) возвращает векторную позицию по левел вертексу. Применим только к активной локации. game_graph():vertex(*gvid*):level_point() возвращает позицию по гейм вертексу - локальную. (точнее говоря возвращается позиция самого гейм вертекса из соответствующей ему секции в файле game.graph) Можно определять на любых локациях (активных/не активных). game_graph():vertex(*gvid*):game_point() также возвращает позицию по гейм вертексу - только мировую(относительно всей карты игры). game_graph():vertex(*gvid*):level_vertex_id() возвращает левел-вертекс по гейм-вертексу. alife():level_name(*level_id*) возвращает имя уровня по его числовому идентификатору. Аргументом может служить метод приведенный ниже. game_graph():vertex(*gvid*):level_id() возвращает числовой идентификатор уровня по гейм вертексу game_graph():valid_vertex_id(*gvid*) возвращает boolean - true\false -существует или нет геймвертекс Изменено 29 Июля пользователем Kirgudu Ссылка на комментарий
Malandrinus 615 Опубликовано 11 Февраля 2010 Автор Поделиться Опубликовано 11 Февраля 2010 (изменено) Сегодня опишу пару мелких, но полезных классов. Скрытый текст Класс предназначен для точного измерения времени выполнения фрагмента кода. Если мы попытаемся для этих целей использовать функции времени игры, то выясним, что в пределах работы скрипта время "замирает". Т.е. вызовы, скажем, game.time() дадут одинаковые значения. А значит воспользоваться этими функциями для измерения времени выполнения скрипта не выйдет. Поэтому и нужен отдельный механизм. Скрытый текст class profile_timer { profile_timer (); -- конструктор, как и для большинства других классов, доступен как глобальная функция profile_timer (profile_timer&); -- конструктор, создающий копию существующего таймера profile_timer* operator +(const profile_timer&, profile_timer); -- можно сложить два таймера, получится третий с суммарным временем void start(); -- запуск таймера, намерянное время обнуляется void stop(); -- остановка таймера float time() const; -- получение измеренного времени в микросекундах function __tostring(profile_timer&); -- вроде есть, но что возвращает - неясно. Но точно не строку bool operator <(const profile_timer&, profile_timer); -- сравнение двух таймеров по накопленному времени }; Использовать просто: local t = profile_timer() t:start() -- измеряемый фрагмент t:stop() log(t:time()) Скрытый текст Класс предназначен для установки колбеков на выход объектов в онлайн. Может быть полезен к примеру для двухфазного спавна когда надо сначала создать объект, а затем что-то сделать при его переходе в онлайн. Только надо учесть, что установленный колбек не сохраняется при сохранении/загрузке, поэтому годится в основном для спавна в инвентарь ГГ или рядом с ним. Экземпляр такого класса всего один и получается вызовом level.client_spawn_manager(). Скрытый текст class client_spawn_manager { void add(int <id отслеживаемого объекта>, -- на какой объект ставим коллбек int <id актора>, -- непонятный аргумент, я ставил его каким угодно, по всей видимости игнорируется, по крайней мере в сингле fun&); -- сам колбек void add(int <id отслеживаемого объекта>, int <id актора>, fun&, object); -- дополнительный аргумент для передачи в колбек void remove(int <id отслеживаемого объекта>, int <id актора>); -- убрать установленный колбек }; Здесь fun - это функция следующего вида: function spawn_callback( first, -- ранее переданный последний аргумент id, -- идентификатор клиентского объекта obj) -- клиентский объект, на который сработал колбек end Если колбек устанавливался второй функцией без дополнительного аргумента, то и в колбек будут переданы только id и obj. Пример: local function spawn_callback(first, id, obj) ... end local obj = sim:create("some_item", pos, lvid, gvid) level.client_spawn_manager():add( obj.id, -1, spawn_callback, 1.1) Изменено 25 Июля пользователем Kirgudu Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Monnoroch 6 Опубликовано 1 Марта 2010 Поделиться Опубликовано 1 Марта 2010 Что собой представляет такое данное: [[...]] ?Как с ним работать?И можно ли его читать из конфига вместо строки? Ссылка на комментарий
Malandrinus 615 Опубликовано 2 Марта 2010 Автор Поделиться Опубликовано 2 Марта 2010 (изменено) Monnoroch, Это всего лишь строки. Всё, что между квадратными скобками - это строковый литерал. Игнорируются все специальные символы. Переносы строк, табуляции и пр. интерпретируются без всяких изменений. Собственно длинный комментарий: --[[ ... ]] - это на самом деле тот-же короткий, просто два минуса комментируют "длинную строку", заключённую между [[...]] В качестве открывающей и закрывающей скобок можно использовать также скобки вида [===[...]===], где количество знаков "равно" - это так называемый "уровень" строки. Нужно это с единственной целью включать в строки также и возможные последовательности ']]', ']=]' и т.д. Просто выбираете уровень, для которого закрывающая скобка уж точно в вашей строке не попадётся. Добавлено: Выше я не совсем понятно написал. Специальные символы игнорируются не в том смысле, что пропускаются, а в том смысле, что не разбивают длинную строку. Т.е. попросту попадают в строковый литерал без изменений. К примеру, здесь в приведённой строке: [[начало строки продолжение на новой строке продолжение на новой строке после символа табуляции]] будут два символа переноса и один символ табуляции, что можно было бы иначе сделать так: "начало строки\nпродолжение на новой строке\n\tпродолжение на новой строке после символа табуляции" Изменено 2 Марта 2010 пользователем malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Monnoroch 6 Опубликовано 2 Марта 2010 Поделиться Опубликовано 2 Марта 2010 Спасиюо. Есть 2 ф-я чтения из конфига для строк: function r_string_wq(string, string);--возвращает строку function r_string(string, string);--возвращает строку Видимо одна из них читает такую длинную строку? Первая? Ссылка на комментарий
Malandrinus 615 Опубликовано 2 Марта 2010 Автор Поделиться Опубликовано 2 Марта 2010 Monnoroch, я в своё время по использованию никакой разницы не нашёл, хотя думал, что "wq" означает что-то вроде "without quotes". Может просто терпения не хватило найти разницу. Однако обе функции совершенно точно убивают пробелы и табуляции, а в ltx файле не бывает многострочных параметров, так что прочитать с их помощью длинную строку не получится. Если нужна длинная строка надо использовать связку с xml и translate_string. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Monnoroch 6 Опубликовано 2 Марта 2010 Поделиться Опубликовано 2 Марта 2010 (изменено) malandrinus, Хмм,а как правильно читать actor_visual у броника,чтобы после его же записать в нетпакет НПСу? local aTbl = amkII_rdpk.amkReadStalker(alife():object(oNpcId)) aTbl.sVisualName = system_ini():r_string_wq(sSect,"actor_visual") amkII_wrpk.amkWriteStalker(aTbl, alife():object(oNpcId)) Вот просто чтение и сразу запись. Я подозреваю,что надо както сконвертировать простую строку в эту. какие вообще операции можно с ней производить?И как? [[]]..[[]] - это можно?string.format() можно? Вообще,что с ней можно вытворять,кроме коментирования? Изменено 2 Марта 2010 пользователем Monnoroch Ссылка на комментарий
Unnamed Black Wolf 4 Опубликовано 3 Марта 2010 Поделиться Опубликовано 3 Марта 2010 ещё три точки может означать какой либо параметр.. Без ограничений и итп. и в виде [...] и передачи на функцию может послужить вызовом по имение данных из таблицы... Строковые функции большой раздел.. Можно из одной строки и скобок сделать нечто невообразимое. Формат и gsub посмотри.. по ману луа который malandrinus, давал тут, посмотри со второй по четвертую страницу .. Ссылка на комментарий
AKKK1 6 Опубликовано 23 Марта 2010 Поделиться Опубликовано 23 Марта 2010 malandrinus и всем кому интересно. нашел на диске статью Скрипты в игре «Сталкер» Документация для гейм-дизайнеров и скриптописателей В игре используется скриптовый язык Lua, поэтому необходимо воспользоваться его документацией для дальнейшего прочтения этого документа (S:\GameData\Scripts\manual.html) Из игры в Lua вынесены следующие классы и глобальные функции: a. Базовые функции на C++ i. log(<string_to_print>) 1. выводит в лог строку ii. flush() 1. сохраняет лог на диск, работает очень медленно, в Release версии вообще отключена iii. device() 1. получить экземпляр класса render_device (описание смотрите ниже) iv. system_ini() – возвращает указатель ini_file на system.ltx v. alife_simulator *alife() – возвращает указатель на симулятор vi. game.time() 1. получить игровое время в миллисекундах vii. level.object(<object_name>) 1. получить экземпляр класса game_object по имени объекта viii. level.actor() 1. получить экземпляр класса game_object актёра ix. level.get_weather() 1. возвращает строку – имя текущей погоды x. level.set_weather(<weather_name>) 1. устанавливает погоду xi. level.set_time_factor(<time_factor>) 1. устанавливает game time factor xii. level.get_time_factor() 1. возвращает текущий game time factor xiii. level.cover_in_direction(<vertex_id>,<direction>) 1. возвращает прикрытость в заданном узле в заданном направлении xiv. level.vertex_in_direction(<vertex_id>,<direction>,<max_distance>) 1. возвращает ноду в заданном напрвалении xv. level.rain_factor() 1. возвращает, насколько идёт дождь (0..1) xvi. level.patrol_path_exists(<patrol_path_name>) 1. возвращает, существует ли патрульный путь. xvii. level.vertex_position(<vertex_id>) – возвращает центр AI-ноды b. Базовые функции на Lua i. printf 1. форматированный вывод данных, аналог printf в C++ (с ограничениями) ii. wait() 1. ждать до следующего обновления скрипта iii. wait(<time_to_wait>) 1. ждать заданное в миллисекундах время до следующего обновления скрипта iv. wait_game(<game_time_to_wait>) 1. ждать заданное в миллисекундах игровое время до следующего обновления скрипта v. action(<object>,<action1>,…) 1. Добавить объекту object в очередь заданий новое с переданными под-action-ами (смотрите примеры) c. Классы C++ i. vector 1. класс трёхмерный вектор, имеет следующие члены, методы: x,y,z – компоненты вектора set – установить значения компонент вектора по заданным значениям (три числа, вектор) add – добавить вектор sub – отнять вектор mul – умножить покомпонентно на вектор div – поделить покомпонентно на вектор … - есть ещё штук 30 других, но вы вряд ли будете ими пользоваться........ Дмитрий Ясенев 12.10.2003 Надеюсь чем-то поможет полная версия http://ifolder.ru/16937470 Ссылка на комментарий
AKKK1 6 Опубликовано 25 Марта 2010 Поделиться Опубликовано 25 Марта 2010 (изменено) Информация для создателей скриптов Составитель: Andrey Fidrya (Zmey), af@svitonline.com В каждом скрипте должны быть: action:initialize() – вызывается в момент включения схемы по GOAP. Инициализировать переменные здесь НЕЛЬЗЯ. Нужно провести установку callback-ов, которые будет использовать скрипт. В самом конце функции нужно вызвать acton:reset_scheme() action:reset_scheme() – вызывается в момент включения схемы другим скриптом (gulag и т.п.), также вызывается из initialize при включении схемы по GOAP Вся инициализация должна производиться в reset_scheme(), а не в initialize()! action:finalize() – вызывается в момент выключения схемы по GOAP. Снять проставленные в initialize callback-и. function add_to_binder(npc, char_ini) – биндит схему, только если char_ini == nil (это значит, что биндинг запрошен другим скриптом), или сущестует секция с именем скрипта в custom_data, которая передана как char_ini. function set_scriptname(параметры) – настройка параметров скрипта. Параметры, вместо которых передан nil, берутся из customdata персонажа. Работа с customdata: При чтении полей customdata, если поле не найдено, нужно выдавать сообщение об ошибке, а не тихо отключать скрипт. Сделать это можно с помощью функции xr_utils.abort(“сообщение”, параметры), которая действует аналогично printf, но выводит сообщение в MessageBox и останавливает игру. Чтобы не переписывать парсинг заново в каждом скрипте, можно воспользоваться функциями из xr_utils: function conf_get_bool(char_ini, section, field, override, object, mandatory) function conf_get_string(char_ini, section, field, override, object, mandatory) function conf_get_number(char_ini, section, field, override, object, mandatory) Например: st.enabled = utils.conf_get_bool(char_ini, "guard", "enabled", enable, object, true) Пример использования можно посмотреть в xr_guard. Описание параметров – в xr_utils в месте, где определена функция. В случае возникновения вопросов - обращаться к Змею (af@svitonline.com). Перемещение: За перемещение отвечает movement manager. Пример использования – xr_walker.script. 1) В _init создается экземпляр movement manager-а: self.move_mgr = move_mgr.move_mgr() 2) В initialize грузим информацию о путях из их имен: self.path_walk_info = utils.path_parse_waypoints(self.st.path_walk) self.path_look_info = utils.path_parse_waypoints(self.st.path_look) 3) В reset_scheme инициализируем movement manager: function move_mgr:reset(path_walk, path_walk_info, path_look, path_look_info, team, mode, move_cb_info) Здесь team – команда для синхронизации нескольких персонажей (произвольная текстовая строка) mode – таблица, поля которой задают начальный режим перемещения: { crouch = true/false, run = true/false, danger=true/false } move_cb_info – таблица, поля которой задают информацию о callback-методе, который будет вызван, если персонаж прибыл в точку, в которой установлено значение ret: { obj = объект, func = функция } obj – ссылка на объект класса, которому принадлежит функция, или nil, если функция определена вне класса. func – ссылка на функцию, которая будет вызвана. Поля team, mode, move_cb задавать не обязательно. 4) В execute: self.move_mgr:update() 5) В finalize: self.move_mgr:finalize() Переключение скорости и режима перемещения до прибытия в первый вейпоинт. Для того, чтобы сменить режим движения до прибытия в первый вейпоинт пути (например, переключиться с ходьбы на бег при каких-то условиях), выполните в своем скрипте в любой момент после reset-а: // ВНИМАНИЕ – вызывать update_movement_state при last_index // не равном nil недопустимо! if self.move_mgr.last_index == nil then self.move_mgr.running = true / false self.move_mgr.danger = true / false self.move_mgr.crouch = true / false self.move_mgr:update_movement_state() end Примечание: в большинстве случаев переключать режим перемещения не понадобится. Рекомендуется задавать стартовый режим перемещения с помощью параметра mode функции reset(), а не менять его вышеописанным способом. Использование callback: Функция-callback может быть как свободной функцией, так и членом класса. Прототип свободной функции имеет следующий вид: function my_callback(self, mode, number) Прототип функции класса: function class:my_callback(mode, number) Здесь в качестве первого параметра (self) будет передано значение поля obj таблицы move_cb_info, т.е. фактически это объект, которому принадлежит функция-callback. Параметр mode может быть одним из: move_mgr.arrival_before_rotation – если поле ret было задано в path_walk и коллбек был вызван сразу же по прибытию персонажа в точку, ДО поворота. move_mgr.arrival_after_rotation – если поле ret было задано в path_look и коллбек был вызван после прибытия в точку path_walk и поворота в соответствующую точку path_look (в которой был задан ret). number – значение поля ret. В коллбеке можно прервать движение персонажа (остановить его, но нежелательно сбрасывать пути) и выполнять свои custom действия (апдейты movement manager-а при этом вызывать не нужно по понятным причинам). Для прерывания нормальной работы схемы с целью вмешательства в перемещение, нужно вернуть значение true из callback-а, после чего перестать вызывать апдейты. Если это не сделать – значения, которые Вы установите персонажу в коллбеке могут быть сбиты схемой сразу же по возврату из Вашего коллбека! Чтобы продолжить затем движение по маршруту, вызовите: self.move_mgr:update_movement_state() – это включит бег или ходьбу (в зависимости от настроек последней точки, в которой был персонаж) После чего продолжайте вызывать апдейты movement manager-а как обычно. Перед вызовом update_movement_state, можно также явно задать режим перемещения: self.move_mgr.running = true / false self.move_mgr.danger = true / false self.move_mgr.crouch = true / false Если коллбек выполняет задачи, никак не влияющие на перемещение и персонажа в целом (например, просто ставит info portion), то из коллбека нужно вернуть nil или false. Вызов коллбека тогда останется для схемы незамеченным. Взаимодействие path_walk c path_look: Прийдя на точку path_walk, где установлена какая-то комбинация флажков, сталкер найдет такую же комбинацию флажков в path_look и посмотрит в эту точку. Если же ни один флажок не установлен, сталкер пойдет дальше не останавливаясь. Проверка текущего состояния персонажа: Часто с персонажем должны взаимодействовать другие персонажи, например, follower-ы командира должны знать его состояние. Движется ли персонаж в данный момент можно узнать, опросив у move_mgr переменную moving. if self.move_mgr.moving then движется end При этом, если moving == true, можно узнать подробности о перемещении: if self.move_mgr.crouch then идет в присяде end if self.move_mgr.running then бежит end if self.move_mgr.danger then находится в состоянии danger end Если moving == false, то: if self.move_mgr.standing_crouch then сидит end if self.move_mgr.standing_danger then сидит в состоянии danger end Задание имен вейпоинтов: Имя вейпоинта должно иметь следующий вид: имя|поле=значение|поле=значение|… Первое слово является именем и игнорируется парсером. Остальные фразы, разделенные символом '|' будут обработаны. Пример имен: wp00|a=hide wp01 wp02|a=hide|s=weather и т.д. Примечание: Если задано имя поля, но не задано значение – автоматически парсер подставит true. Т.е. не надо писать “wp0|r=true|d=true”, достаточно просто написать “wp0|r|d”. Флаги пути path_walk: n = 0 .. 9999 – номер точки синхронизации. Рекомендуется первой точке задавать значение 0, остальным – числа по возрастанию с произвольным шагом. Прийдя в точку с большим n, сталкер будет ждать отстающих напарников. Примечание: сталкер дожидается опаздывающих напарников _только_ в точках остановки (т.е. только в тех местах, где точка path_walk имеет общие флаги с одной из точек path_look). Внимание – для поддержки зацикленных маршрутов, сталкеры на точке с минимальным n дожидаются сталкеров на точке с максимальным n. Поэтому минимальное количество точек синхронизации для корректной работы схемы должно составлять 3 точки или больше! s = имя_звуковой_схемы – пробегая через эту точку, сталкер включит указанную звуковую схему. Звук стартует ДО начала поворота и старта анимации. Для того, чтобы звук стартовал синхронно с анимацией – задавайте его в path_look соответствующей точки, а не в path_walk. Если нужно стартовать звук одновременно с ЛЮБОЙ из анимаций в этой точке, можно воспользоваться параметром sa. sp = с какой вероятностью будет проигран звук (по умолчанию 100) sa = true – ждать начала анимации в точке, прежде чем стартовать проигрывание звука (по умолчанию false). sc = true – разрешить проигрывать звуки схемы неоднократно (по умолчанию false). sf, st – временной интервал повторения фраз из выбранной звуковой схемы в секундах (по умолчанию от 5 до 10 сек). c = true – дальше перемещаться в присяде (по умолчанию false) r = true – дальше перемещаться бегом (по умолчанию false) d = true – перемещаться в состоянии danger (по умолчанию false) ds = имена_диалогов – имена диалогов, которые разрешено стартовать начиная с этой точки (разрешение действует до следующей точки). Имена задаются в виде текстовой строки, разделенной запятыми: ds=bandits_talk,weather_talk и т.д. ret = число – сразу же по прибытии в точку вызывает зарегистрированный при инициализации movement manager-а callback с этим числом в качестве второго аргумента. w = имя_walk_пути – переводит схему на новый path_walk. Рекомендуется также задать новый path_look с помощью параметра ”l”, иначе текущий path_look будет сброшен. Персонаж идет на стартовую точку с режимом перемещения, заданным в точке с параметром “w”. Настройки функции коллбека при переключении пути сохраняются. l = имя_look_пути - сбросит схему на новый path_look. Задавать параметр “l” нужно вместе с параметром ”w”, иначе “l” будет проигнорирован. По умолчанию path_look при смене path_walk будет сброшен. Флаги пути path_look: p = 100 – вероятность, с которой персонаж посмотрит именно в эту точку. Значения p всех возможных точек суммируются, т.е. если у одной точки p = 100, а у другой 300, то персонаж посмотрит в первую с вероятностью 25%! (т.е. 100 из 400). Рекомендуется задавать p так, чтобы их сумма составляла 100. По умолчанию у всех точек p = 100. a = анимация, которую проиграет персонаж, посмотрев в эту точку (по умолчанию idle). Для того, чтобы персонаж стоял в точке без анимации, задайте значение nil: “a=nil” c = true – смотреть в точку в присяде (по умолчанию используется значение одноименного поля из path_walk) d = true – смотреть в точку в состоянии danger (по умолчанию используется значение одноименного поля из path_walk) att = 1 или 2 – номер атаки (основная, вспомогательная). Можно использовать вместо анимации (например ”a=nil|att=1”), можно вместе с анимацией (”a=стреляем_в_потолок|att=1»). t = время, которое персонаж будет ждать, играя анимацию или стреляя (по умолчанию 5000). Если требуется ждать бесконечно долго (например, это финальная точка пути), нужно задать t равным “-1”. Примечание: если персонаж ждет синхронизации в точке, то он будет играть анимацию столько времени, сколько нужно для того, чтобы дождаться напарников, но только по прибытию всех напарников на точки засечет заданное в ”t” время. Исключение составляет стрельба – персонаж не станет стрелять сразу по прибытию в точку, а сперва дождется напарников, а потом уже начнет стрелять в течение заданного времени. s = имя - звук, который персонаж разово проиграет, посмотрев в эту точку. sp = с какой вероятностью будет проигран звук (по умолчанию 100) sl = имя_прожектора – если задано, то при повороте в указанную точку персонаж также повернет и прожектор в неё. ret = число – после поворота в целевую точку вызывает зарегистрированный при инициализации movement manager-а callback с числом ret в качестве второго аргумента. При этом время ожидания (поле t) игнорируется, т.е. после того как callback вызовет update_movement_state – персонаж сразу же пойдет дальше. Добавлено: Информация для создателей скриптов Составитель: Andrey Fidrya (Zmey), af@svitonline.com В каждом скрипте должны быть: action:initialize() – вызывается в момент включения схемы по GOAP. Инициализировать переменные здесь НЕЛЬЗЯ. Нужно провести установку callback-ов, которые будет использовать скрипт. В самом конце функции нужно вызвать acton:reset_scheme() action:reset_scheme() – вызывается в момент включения схемы другим скриптом (gulag и т.п.), также вызывается из initialize при включении схемы по GOAP Вся инициализация должна производиться в reset_scheme(), а не в initialize()! action:finalize() – вызывается в момент выключения схемы по GOAP. Снять проставленные в initialize callback-и. function add_to_binder(npc, char_ini) – биндит схему, только если char_ini == nil (это значит, что биндинг запрошен другим скриптом), или сущестует секция с именем скрипта в custom_data, которая передана как char_ini. function set_scriptname(параметры) – настройка параметров скрипта. Параметры, вместо которых передан nil, берутся из customdata персонажа. Работа с customdata: При чтении полей customdata, если поле не найдено, нужно выдавать сообщение об ошибке, а не тихо отключать скрипт. Сделать это можно с помощью функции xr_utils.abort(“сообщение”, параметры), которая действует аналогично printf, но выводит сообщение в MessageBox и останавливает игру. Чтобы не переписывать парсинг заново в каждом скрипте, можно воспользоваться функциями из xr_utils: function conf_get_bool(char_ini, section, field, override, object, mandatory) function conf_get_string(char_ini, section, field, override, object, mandatory) function conf_get_number(char_ini, section, field, override, object, mandatory) Например: st.enabled = utils.conf_get_bool(char_ini, "guard", "enabled", enable, object, true) Пример использования можно посмотреть в xr_guard. Описание параметров – в xr_utils в месте, где определена функция. В случае возникновения вопросов - обращаться к Змею (af@svitonline.com). Перемещение: За перемещение отвечает movement manager. Пример использования – xr_walker.script. 1) В _init создается экземпляр movement manager-а: self.move_mgr = move_mgr.move_mgr() 2) В initialize грузим информацию о путях из их имен: self.path_walk_info = utils.path_parse_waypoints(self.st.path_walk) self.path_look_info = utils.path_parse_waypoints(self.st.path_look) 3) В reset_scheme инициализируем movement manager: function move_mgr:reset(path_walk, path_walk_info, path_look, path_look_info, team, mode, move_cb_info) Здесь team – команда для синхронизации нескольких персонажей (произвольная текстовая строка) mode – таблица, поля которой задают начальный режим перемещения: { crouch = true/false, run = true/false, danger=true/false } move_cb_info – таблица, поля которой задают информацию о callback-методе, который будет вызван, если персонаж прибыл в точку, в которой установлено значение ret: { obj = объект, func = функция } obj – ссылка на объект класса, которому принадлежит функция, или nil, если функция определена вне класса. func – ссылка на функцию, которая будет вызвана. Поля team, mode, move_cb задавать не обязательно. 4) В execute: self.move_mgr:update() 5) В finalize: self.move_mgr:finalize() Переключение скорости и режима перемещения до прибытия в первый вейпоинт. Для того, чтобы сменить режим движения до прибытия в первый вейпоинт пути (например, переключиться с ходьбы на бег при каких-то условиях), выполните в своем скрипте в любой момент после reset-а: // ВНИМАНИЕ – вызывать update_movement_state при last_index // не равном nil недопустимо! if self.move_mgr.last_index == nil then self.move_mgr.running = true / false self.move_mgr.danger = true / false self.move_mgr.crouch = true / false self.move_mgr:update_movement_state() end Примечание: в большинстве случаев переключать режим перемещения не понадобится. Рекомендуется задавать стартовый режим перемещения с помощью параметра mode функции reset(), а не менять его вышеописанным способом. Использование callback: Функция-callback может быть как свободной функцией, так и членом класса. Прототип свободной функции имеет следующий вид: function my_callback(self, mode, number) Прототип функции класса: function class:my_callback(mode, number) Здесь в качестве первого параметра (self) будет передано значение поля obj таблицы move_cb_info, т.е. фактически это объект, которому принадлежит функция-callback. Параметр mode может быть одним из: move_mgr.arrival_before_rotation – если поле ret было задано в path_walk и коллбек был вызван сразу же по прибытию персонажа в точку, ДО поворота. move_mgr.arrival_after_rotation – если поле ret было задано в path_look и коллбек был вызван после прибытия в точку path_walk и поворота в соответствующую точку path_look (в которой был задан ret). number – значение поля ret. В коллбеке можно прервать движение персонажа (остановить его, но нежелательно сбрасывать пути) и выполнять свои custom действия (апдейты movement manager-а при этом вызывать не нужно по понятным причинам). Для прерывания нормальной работы схемы с целью вмешательства в перемещение, нужно вернуть значение true из callback-а, после чего перестать вызывать апдейты. Если это не сделать – значения, которые Вы установите персонажу в коллбеке могут быть сбиты схемой сразу же по возврату из Вашего коллбека! Чтобы продолжить затем движение по маршруту, вызовите: self.move_mgr:update_movement_state() – это включит бег или ходьбу (в зависимости от настроек последней точки, в которой был персонаж) После чего продолжайте вызывать апдейты movement manager-а как обычно. Перед вызовом update_movement_state, можно также явно задать режим перемещения: self.move_mgr.running = true / false self.move_mgr.danger = true / false self.move_mgr.crouch = true / false Если коллбек выполняет задачи, никак не влияющие на перемещение и персонажа в целом (например, просто ставит info portion), то из коллбека нужно вернуть nil или false. Вызов коллбека тогда останется для схемы незамеченным. Взаимодействие path_walk c path_look: Прийдя на точку path_walk, где установлена какая-то комбинация флажков, сталкер найдет такую же комбинацию флажков в path_look и посмотрит в эту точку. Если же ни один флажок не установлен, сталкер пойдет дальше не останавливаясь. Проверка текущего состояния персонажа: Часто с персонажем должны взаимодействовать другие персонажи, например, follower-ы командира должны знать его состояние. Движется ли персонаж в данный момент можно узнать, опросив у move_mgr переменную moving. if self.move_mgr.moving then движется end При этом, если moving == true, можно узнать подробности о перемещении: if self.move_mgr.crouch then идет в присяде end if self.move_mgr.running then бежит end if self.move_mgr.danger then находится в состоянии danger end Если moving == false, то: if self.move_mgr.standing_crouch then сидит end if self.move_mgr.standing_danger then сидит в состоянии danger end Задание имен вейпоинтов: Имя вейпоинта должно иметь следующий вид: имя|поле=значение|поле=значение|… Первое слово является именем и игнорируется парсером. Остальные фразы, разделенные символом '|' будут обработаны. Пример имен: wp00|a=hide wp01 wp02|a=hide|s=weather и т.д. Примечание: Если задано имя поля, но не задано значение – автоматически парсер подставит true. Т.е. не надо писать “wp0|r=true|d=true”, достаточно просто написать “wp0|r|d”. Флаги пути path_walk: n = 0 .. 9999 – номер точки синхронизации. Рекомендуется первой точке задавать значение 0, остальным – числа по возрастанию с произвольным шагом. Прийдя в точку с большим n, сталкер будет ждать отстающих напарников. Примечание: сталкер дожидается опаздывающих напарников _только_ в точках остановки (т.е. только в тех местах, где точка path_walk имеет общие флаги с одной из точек path_look). Внимание – для поддержки зацикленных маршрутов, сталкеры на точке с минимальным n дожидаются сталкеров на точке с максимальным n. Поэтому минимальное количество точек синхронизации для корректной работы схемы должно составлять 3 точки или больше! s = имя_звуковой_схемы – пробегая через эту точку, сталкер включит указанную звуковую схему. Звук стартует ДО начала поворота и старта анимации. Для того, чтобы звук стартовал синхронно с анимацией – задавайте его в path_look соответствующей точки, а не в path_walk. Если нужно стартовать звук одновременно с ЛЮБОЙ из анимаций в этой точке, можно воспользоваться параметром sa. sp = с какой вероятностью будет проигран звук (по умолчанию 100) sa = true – ждать начала анимации в точке, прежде чем стартовать проигрывание звука (по умолчанию false). sc = true – разрешить проигрывать звуки схемы неоднократно (по умолчанию false). sf, st – временной интервал повторения фраз из выбранной звуковой схемы в секундах (по умолчанию от 5 до 10 сек). c = true – дальше перемещаться в присяде (по умолчанию false) r = true – дальше перемещаться бегом (по умолчанию false) d = true – перемещаться в состоянии danger (по умолчанию false) ds = имена_диалогов – имена диалогов, которые разрешено стартовать начиная с этой точки (разрешение действует до следующей точки). Имена задаются в виде текстовой строки, разделенной запятыми: ds=bandits_talk,weather_talk и т.д. ret = число – сразу же по прибытии в точку вызывает зарегистрированный при инициализации movement manager-а callback с этим числом в качестве второго аргумента. w = имя_walk_пути – переводит схему на новый path_walk. Рекомендуется также задать новый path_look с помощью параметра ”l”, иначе текущий path_look будет сброшен. Персонаж идет на стартовую точку с режимом перемещения, заданным в точке с параметром “w”. Настройки функции коллбека при переключении пути сохраняются. l = имя_look_пути - сбросит схему на новый path_look. Задавать параметр “l” нужно вместе с параметром ”w”, иначе “l” будет проигнорирован. По умолчанию path_look при смене path_walk будет сброшен. Флаги пути path_look: p = 100 – вероятность, с которой персонаж посмотрит именно в эту точку. Значения p всех возможных точек суммируются, т.е. если у одной точки p = 100, а у другой 300, то персонаж посмотрит в первую с вероятностью 25%! (т.е. 100 из 400). Рекомендуется задавать p так, чтобы их сумма составляла 100. По умолчанию у всех точек p = 100. a = анимация, которую проиграет персонаж, посмотрев в эту точку (по умолчанию idle). Для того, чтобы персонаж стоял в точке без анимации, задайте значение nil: “a=nil” c = true – смотреть в точку в присяде (по умолчанию используется значение одноименного поля из path_walk) d = true – смотреть в точку в состоянии danger (по умолчанию используется значение одноименного поля из path_walk) att = 1 или 2 – номер атаки (основная, вспомогательная). Можно использовать вместо анимации (например ”a=nil|att=1”), можно вместе с анимацией (”a=стреляем_в_потолок|att=1»). t = время, которое персонаж будет ждать, играя анимацию или стреляя (по умолчанию 5000). Если требуется ждать бесконечно долго (например, это финальная точка пути), нужно задать t равным “-1”. Примечание: если персонаж ждет синхронизации в точке, то он будет играть анимацию столько времени, сколько нужно для того, чтобы дождаться напарников, но только по прибытию всех напарников на точки засечет заданное в ”t” время. Исключение составляет стрельба – персонаж не станет стрелять сразу по прибытию в точку, а сперва дождется напарников, а потом уже начнет стрелять в течение заданного времени. s = имя - звук, который персонаж разово проиграет, посмотрев в эту точку. sp = с какой вероятностью будет проигран звук (по умолчанию 100) sl = имя_прожектора – если задано, то при повороте в указанную точку персонаж также повернет и прожектор в неё. ret = число – после поворота в целевую точку вызывает зарегистрированный при инициализации movement manager-а callback с числом ret в качестве второго аргумента. При этом время ожидания (поле t) игнорируется, т.е. после того как callback вызовет update_movement_state – персонаж сразу же пойдет дальше Изменено 25 Марта 2010 пользователем AKKK1 1 Ссылка на комментарий
Malandrinus 615 Опубликовано 25 Марта 2010 Автор Поделиться Опубликовано 25 Марта 2010 AKKK1, всё это из билда 1935. К сожалению, бОльшая часть этой информации непосредственно не применима к последним билдам. Хотя несомненная польза есть - помогает хоть какие-то идеи получить. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти