Это популярное сообщение. 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 Ссылка на комментарий
GeJorge 2 Опубликовано 10 Ноября 2013 Поделиться Опубликовано 10 Ноября 2013 Касательно level.physics_world() для ЗП. Целиком рабочая. Использую эту функцию для джетпака: function set_gravity(val) --/установка гравитации. if string.find(tostring(val),"+") then local val=level.physics_world():gravity()+tonumber(string.sub(val,2)) level.physics_world():set_gravity(val) elseif string.find(tostring(val),"-") then local val=level.physics_world():gravity()-tonumber(string.sub(val,2)) level.physics_world():set_gravity(val) else level.physics_world():set_gravity(val) end end function restore_gravity() --/восстановление обычной гравитации. local defv=19.620 level.physics_world():set_gravity(defv) end P.S. Для своего джетпака юзаю таймер, по истечении которого restore_gravity(). 19.620 - значение гравитации по умолчанию. Может иметь значение со знаком минус. В этом случае гравитация вверх-тормашками, и табор уходит в небо. 1 http://sigerous.ru/forum/2-5073-1 Ссылка на комментарий
Это популярное сообщение. Malandrinus 615 Опубликовано 14 Ноября 2013 Автор Это популярное сообщение. Поделиться Опубликовано 14 Ноября 2013 Может кто-то уже знает, а я только сейчас раскопал вот какую штуку. Оказывается можно без проблем искать в аллспавне объекты для их последующего спавна с помощью функции alife():create(spawn_id). Здесь spawn_id - это порядковый номер секции в аллспавне. Секции эти тасуются при каждом изменении аллспавна, поэтому этот идентификатор меняется, и спавнить таким образом вроде как считалось нецелесообразным.Однако, как выясняется, этот номер можно определить. Для этого есть специальная метка, во многом схожая с использованием story_id, которая называется spawn_story_id. Это поле можно задать в секции в аллспавне совершенно точно также, как задаётся story_id, для номеров можно завести строковые обозначения, которые регистрируются в файле game_spawn_story_ids.ltx и соответственно попадают в таблицу spawn_story_ids. Нумерация там не пересекается со story_ids. В оригинале игры это всё вообще не используется.Теперь, если таким образом пометить какой-то объект в аллспавне, то его spawn_id можно найти с помощью alife():spawn_id(spawn_story_id). Т.е. задаём число - получаем число. Что важно, что объекта при этом может и не быть. Работает это таким образом, что при старте игры все помеченные таким образом объекты сохраняются в отдельной базе данных (точнее, сохраняются их spawn_id) и эта база затем в неизменном виде сохраняется в сейве.В итоге, можно организовать с малыми хлопотами следующий алгоритм. Допустим, нам нужен переход, который должен появиться по условию (или даже появляться и исчезать много раз по условию), и мы хотим этот переход сделать с помощью аллспавна. Поступаем так:1. Создаём переход в аллспавне как обычно.2. Метим его одновременно метками spawn_story_id и story_id. Пусть это будут story_ids.some_level_changer и spawn_story_ids.some_level_changer. Обращаю внимание. Я здесь дал меткам похожие имена, но это разные числа, никак друг с другом не связанные.3. При запуске игры объект удаляем (к примеру, если не хотим иметь его с самого начала игры). Для удаления нам нужен реальный серверный объект, ищем его такlocal lc = alife():story_object(story_ids.some_level_changer)и удаляем как обычноalife():release(lc, true)4. Далее, при наступлении какого-то условия, когда нужно создать этот переход обратно, поступаем так:local spawn_id = alife():spawn_id(spawn_story_ids.some_level_changer)alife():create(spawn_id) 4 5 5 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
*Shoker* 322 Опубликовано 14 Ноября 2013 Поделиться Опубликовано 14 Ноября 2013 (изменено) В дополнение к этому посту по поводу функции global_transform(), по крайнем мере в ЗП она рабочая, и при вызове возвращает матрицу, (class matrix) которая хранит координаты кости, а также направление этой кости (или нечто похожее, я как раз разбираюсь) local ph_shell = door:get_physics_shell() local ph_element = ph_shell:get_element_by_bone_name("door") if ph_element ~= nil then local m = ph_element:global_transform() end C.X = 355.5 C.Y = 56.6 C.Z = 763.6 I.X = 1 I.Y = -5.4984565167615e-007 I.Z = -2.3666775632591e-006 J.X = 5.4984121788948e-007 J.Y = 1 J.Z = -1.8957925931318e-006 K.X = 2.3666784727538e-006 K.Y = 1.8957912288897e-006 K.Z = 1 Направление кости в виде углов эйлера (которые в СДК используются) можно по идее получить матричной функцией getHPB(), но т.к у меня она вызывала вылет, я для этого использую функцию из Zones Editor - extract_euler_xzy(m) Плохо только то, что ph_shell:get_element_by_bone_name("door") работает не для всех костей (а судя по всему только для костей с типом joint), а сам ph_shell есть тока у неживых объектов (у живого сталкера он отсутствует) PS: На правах оффтопа, malandrinus - подскажи пож-ста по поводу функции extract_euler_xzy(m), она возвращает x z y, а если соотнести их с HPB (такие обозначения используются в сталкере), то что чему равно? B это наклон, H кажется горизонталь, P вертикаль. ******************************************************************************* По поводу вопроса разобрался:HPB идут в таком порядке. local p,b,h = extract_euler_xzy(m) Изменено 14 Ноября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
macron 1 823 Опубликовано 14 Ноября 2013 Поделиться Опубликовано 14 Ноября 2013 (изменено) Старый справочник (от 11.10.2004) по классам и т.п. http://rghost.ru/50179368 Изменено 14 Ноября 2013 пользователем macron 3 Ссылка на комментарий
Graff46 598 Опубликовано 19 Февраля 2014 Поделиться Опубликовано 19 Февраля 2014 [level_script] script= <имя модуля 1>,<имя модуля 2>,<имя модуля 3> имя модуля это имена скрипт файлов? Если да, то расширение *.script указывать? Ссылка на комментарий
Malandrinus 615 Опубликовано 21 Марта 2014 Автор Поделиться Опубликовано 21 Марта 2014 Дабы закрыть вопрос с [level_script]. Походу эта фишка больше не работает. Я как-то очень давно её тестировал, возможно на каком-то раннем патче. Уже и не помню, на каком именно, но скорее всего на четвёртом. Вот пример того, как это использовалось в билде 1946, где кабаны играют в футбол тушкой сталкера.Файл levels\script_test\level.ltx [level_scripts] script = futbol Файл futbol.script (с сокращениями) class "CPlayer" function CPlayer:__init(obj, bool) end function CPlayer:update() end function main() local command = {} local bool = get_level_object("bool") table.insert(command, CPlayer(get_level_object("boar1"), bool)) table.insert(command, CPlayer(get_level_object("boar2"), bool)) while(true) do for i = 1, table.getn(command) do command[i]:update() end wait() end end Т.е. мы видим, что в функции main, которая должна выполниться при загрузке уровня script_test, создаётся два объекта схем управления кабанами (класс приведён с сокращениями). Затем запускается бесконечный цикл, а в цикле эти схемы дёргают кабанов. Кому интересно, скачайте этот билд здесь и гляньте сами. Вкратце, там просто кабаны направляются скриптом к целевому объекту (тушке сталкера), а при расстоянии меньше заданного тушке наносится хит, чтобы отбросить. Мне не удалось вызвать выполнение функции main из аналогичным образом прописанного файла на шестом патче. Скорее всего это уже не работает, так что забудьте об этой фишке. Тем более, что её использование подразумевалось совместно с потоками Lua, что в целом лишено смысла в финальной версии игры. Кроме того, чтобы ни подразумевалось делать на этом механизме, можно сделать с тем, что есть и работает: биндеры, родная логика, скриптовые таймеры и т.п. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Карлан 1 049 Опубликовано 4 Июня 2014 Поделиться Опубликовано 4 Июня 2014 что тегов class может быть несколько Может то может, только юзатся будет всегда первый, другие будут игнорироваться, посему присваивать два и более класса одному specific_character бессмысленно. Ссылка на комментарий
Это популярное сообщение. proper70 74 Опубликовано 14 Сентября 2014 Это популярное сообщение. Поделиться Опубликовано 14 Сентября 2014 В дополнение к таблице _G: Если через кейлоггер или еще как-то вызвать команду _G[имя скрипта] = nil, то движок вновь перекомпилирует указанный скрипт при первом к нему обращении. Что это дает? Это дает то, что если вы отлаживаете какой-либо код, то нет необходимости делать сейв/лоад после каждой правки. Если мы, допустим, правим файл amk.script, то достаточно после сохранения правок через кейлоггер вызвать _G.amk = nil и все - движок перекомпилирует его по новой и все изменения тут же вступят в силу без очередного сейв/лоада. Жаль, что эту фичу я для себя открыл только сейчас. Сколько времени можно было бы сэкономить. Это работает для всех файлов кроме биндеров. Дело в том, что для каждого объекта биндер зачем-то компилируется отдельно, поэтому чтобы увидеть изменения, например в bind_monster.script, то нужно написать _G.bind_monster = nil и заспавнить нового монстра. И на новом объекте изменения уже будут применены. 1 7 Ссылка на комментарий
НаноБот 740 Опубликовано 15 Октября 2014 Поделиться Опубликовано 15 Октября 2014 (изменено) Народ! Я сейчас не плохое открытие сделал В общем про биндер, функция net_Relcase переводится как разрыв сети, и вызывается она когда объекты в онлайне удаляются, не забываем что движок основан на мультиплеере, т.е. разъединяются. function mybinder_binder:net_Relcase(obj) if obj then log("mashalat_binder:net_Relcase(objid-"..obj:id()..")name-("..obj:name()..")section-("..obj:section()..")time-("..time_global()..")") end return false end Как это может использоваться, да как уходно, например фейковые ножи, эта функция запускается, проверяем обж если это то, то спавним в ножевой слот ножик, и т.к. далее... В общем, можно добавить куда надо эту инфу, скриптерам пригодится. Ещё надо проверить парент удаляемых объектов, по поже отпишусь... PS Эта функция срабатывает так же и при уходе в оффлайн, парент равен нил, ну это и понятно, объекты то удаляются. Изменено 15 Октября 2014 пользователем НаноБот ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
Zander_driver 10 333 Опубликовано 1 Декабря 2014 Поделиться Опубликовано 1 Декабря 2014 function bone_position(string) const [скрыть] vector bone_position(string bone_name) const возвращает координаты кости. Принимает один аргумент - имя кости. Может быть применен к любому объекту, но модель объекта при этом должна иметь тип MT_SKELETON_ANIM или MT_SKELETON_RIGID, короче, иметь эти самые кости Допустим я прочитал из нет-пакета объекта его визуал, узнал что за модель. Чтобы применять этот метод - как мне узнать имена всех имеющихся в данной модели костей? Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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. Ссылка на комментарий
RayTwitty 492 Опубликовано 18 Января 2015 Поделиться Опубликовано 18 Января 2015 (изменено) Ещё по поводу метода bone_position - если видимость кости, для которой спрашиваем координаты, выключена, тогда координаты эти будут равны позиции спавна физ. объекта (т.е. тоже самое, что возвращает метод position). Достаточно легко это проверить на каком-нибудь светильнике, включая и выключая видимость кости через set_bone_visible (метод ХЕ). Изменено 18 Января 2015 пользователем Shadows Ссылка на комментарий
Zander_driver 10 333 Опубликовано 25 Января 2015 Поделиться Опубликовано 25 Января 2015 Собственно создает конфиг-файл. После чего, с ним можно работать как и с обычным конфигом: Я так понимаю, создает не на диске юзера, а в памяти движка, верно? Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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. Ссылка на комментарий
Карлан 1 049 Опубликовано 25 Января 2015 Поделиться Опубликовано 25 Января 2015 @Zander_driver, верно. У тебя так логика для сталкеров делается Ссылка на комментарий
Карлан 1 049 Опубликовано 26 Января 2015 Поделиться Опубликовано 26 Января 2015 Тут прикололся что в артикл колбек передается 4 параметр, а именно тип: function actor_binder:article_callback(npc, group, name, _type) Я себе так сделал. Короче это числовой параметр, возвращает цифру от 0 до 3, что означает: 0 - добавлено в энциклопедию 1 - добавлено в журнал 2 - добавлено в инфо -- не работает вроде (позже если выловлю - отпишусь) 3 - добавлено в задания -- не работает вроде Занавес. Ссылка на комментарий
Malandrinus 615 Опубликовано 26 Января 2015 Автор Поделиться Опубликовано 26 Января 2015 Может то может, только юзатся будет всегда первый, другие будут игнорироваться, посему присваивать два и более класса одному specific_character бессмысленно.Это не так. Читаются все. Могу показать фрагмент этого кода. как мне узнать имена всех имеющихся в данной модели костей?По-простому никак. Названия костей надо просто знать заранее. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Карлан 1 049 Опубликовано 26 Января 2015 Поделиться Опубликовано 26 Января 2015 Это не так. Читаются все. Могу показать фрагмент этого кода. Давай. Лично я сам присваивал несколько классов в один профиль, и читался только первый, возможно что-то не так делал, не отрицаю, давно было. Ссылка на комментарий
Malandrinus 615 Опубликовано 27 Января 2015 Автор Поделиться Опубликовано 27 Января 2015 @Карлан, два файла. В первом (specific_character.cpp) читаются все классы в массив m_Classes. void CSpecificCharacter::load_shared (LPCSTR) { //... data()->m_Classes.clear (); int classes_num = pXML->GetNodesNum (pXML->GetLocalRoot(), "class"); for(int i=0; i<classes_num; i++) { LPCSTR char_class = pXML->Read ("class", 0, ""); if(char_class) { char* buf_str = xr_strdup(char_class); xr_strlwr (buf_str); data()->m_Classes.push_back(buf_str); xr_free (buf_str); } } //... Второй фрагмент, где среди прочитанных классов ищется нужный. Файл xrServer_Objects_ALife_Monsters.cpp : shared_str CSE_ALifeTraderAbstract::specific_character() { //... bool class_found = false; // пока не нашли for(std::size_t j=0; j<spec_char.data()->m_Classes.size(); j++) // цикл по всем классам профайла { if(char_info.data()->m_Class == spec_char.data()->m_Classes[j]) { class_found = true; break; } } Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Карлан 1 049 Опубликовано 27 Января 2015 Поделиться Опубликовано 27 Января 2015 (изменено) @Malandrinus, вчера не точно видно выразился. В процитированном тобою посте точно. Читаются все, используется первый найденный, поэтому и указывать несколько классов на один профиль бессмысленно (они прочитаются, но не используются, используется только первый (сейчас еще раз проверил в игре)). Если у тебя есть готовый код для игры, где используются несколько классов одним профилем, то покажи, мне действительно интересно увидеть где я не прав. Пока остаюсь при своем. По коду движка я не спорю что ты прав, сам вижу: #ifdef XRGAME_EXPORTS if(m_CheckedCharacters.empty()) char_info.m_SpecificCharacterId = m_DefaultCharacters[Random.randI(m_DefaultCharacters.size())]; else char_info.m_SpecificCharacterId = m_CheckedCharacters[Random.randI(m_CheckedCharacters.size())]; #else char_info.m_SpecificCharacterId = m_DefaultCharacters[Random.randI(m_DefaultCharacters.size())]; #endif set_specific_character(char_info.m_SpecificCharacterId); return m_SpecificCharacter; Но как это применить в игре я не соображу, на практике у меня не работает. Изменено 27 Января 2015 пользователем Карлан Ссылка на комментарий
Malandrinus 615 Опубликовано 27 Января 2015 Автор Поделиться Опубликовано 27 Января 2015 Что-то я тебя не понимаю. Допустим, у меня есть specific_character с классами stalker1 и bandit1. Тогда я могу сослаться из двух разных профайлов на этот конкретный specific_character по этим разным классам. Из одного профайла будет искать по одному классу, из другого по другому, но в обоих случаях будет найден этот specific_character. Не вижу, что здесь может не работать. Где это использовать? Ну не знаю. Есть допустим некий уникальный непись со своим визуалом. Допустим, он может перейти по сюжету из одной группировки в другую. Я создаю для него два профайла с разными классами для разных группировок, и из обоих ссылаюсь на один и тот же specific_character, где прописаны оба класса. Хотя наверное это можно сделать и иначе, но просто как иллюстрация. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Карлан 1 049 Опубликовано 27 Января 2015 Поделиться Опубликовано 27 Января 2015 @Malandrinus, теперь понял. Спасибо. Не под тем углом смотрел на этот вопрос. Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти