Перейти к контенту

Справочник по функциям и классам


Рекомендуемые сообщения

Ну тогда уж так:

alife_simulator - класс для управления серверными объектами. В игре существует всего один экземпляр такого класса, и получить его можно с помощью вызова глобальной функции alife().

  Список методов (Показать)

 

В придачу про класс vector.

vector - вспомогательный класс, содержащий три координаты, и позволяющий выполнять с ними различные манипуляции. Объекты класса vector являются аргументами многих функций и возвращаются многими функциями. См. например выше про метод create класса alife_simulator.

Отдельный объект класса вектор создаётся вызовом глобальной функции vector(). При создании имеет координаты [0,0,0].

  Список методов класса vector (Показать)

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

В языке Lua нет классов. Их поддержка добавлена с помощью технологии Luabind. С одной стороны - это конечно имитация "настоящих классов", с другой - расширение выглядит настолько органичным, что практически воспринимается как часть синтаксиса языка.

 

  Создание своего класса (Показать)

 

  Наследование от экспортированных классов (Показать)

 

Изменено пользователем Kirgudu
  • Нравится 1
  • Полезно 1
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение
  RvP писал(а):
выносите продвижения в шапку плиз
Делать мегашапку пока рано, ещё даже одной страницы темы нет =)

  Monnoroch писал(а):
а не мог бы ты дополнительно рассмотреть пару примеров собственно из сталкера?

С такими же детальными пояснениями.

На очереди object_binder. Там и рассмотрю.

 

А пока вот:

  Функции времени (Показать)
Изменено пользователем malandrinus
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Добил object_binder. Получилось многовато, но короче никак. Кроме того, пришлось разбить на две части. Для начала - некоторое введение в ситуацию со скриптовой моделью вообще. В основном трёп всякий =)


  Несколько общих слов об архитектуре и скриптовой модели сталкера (Показать)


Данная статья посвящёна классу object_binder и, кроме того, является в каком-то смысле иллюстрацией к одной из предыдущих статей "Наследование от экспортированных классов".
  Описание класса object_binder (Показать)


На очереди net_packet. Простой, но весьма важный класс.
  Описание класса net_packet (Показать)


  Использование объектов класса net_packet (Показать)


  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Несколько уточнений:

  Kirag писал(а):
Этот класс отвечает за движение неписей по путям. Информацию о путях берет только из алл.спавна. Переопределить это нельзя без ковыряния в движке, откуда следует невозможность задавать пути извне алл.спавна. Для решения этой задачи надо как-то обойти класс patrol.
Файл all.spawn можно дописывать, добавляя туда дополнительные точки переходов. Вопреки распространённому мнению, новую игру при этом начинать не надо.

 

  Цитата
index(string) - нет ни примеров использования, ни предположений, что это могло бы значить.
Вроде как это метод, обратный name. Т.е. по имени точки возвращает её номер.

 

  Цитата
Как обрабатываются связи между точками, до конца не ясно, могу только предположить, что для этого служит одна из этих команд:

patrol...

Но которая, и что она возвращает, и что требует в качестве аргументов - непонятно.

Это такие же конструкторы, как и patrol с одним только именем пути. Просто у них ещё есть дополнительные аргументы.

 

И, как мне думается, за само движение отвечает класс entity_action, которому передаётся объект класса move, у которого patrol - это аргумент. Короче, копать и копать ещё, но начало неплохое. Там глядишь, и разберёмся, как свои скриптовые схемы ваять.

  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение
  Kolmogor писал(а):
Про новую игру при добавлении путей вроде никто и не говорил :unsure: Про новую игру говорят при добавлении новых объектов, изменении старых

Я добавил level_changer, доспавнил его функцией create(<номер>) и ничего мне за это не было =)

 

Если кому это надо, то добавлю вот что. Я делал тестовый объект на кордоне, и сначала попробовал добавить секцию в файл для кордона. Выяснил, сколько всего объектов, сделал секцию с номером, на один большим...

У меня заспавнился не тот. Начал выяснять, откуда он взялся, и понял, что это последний объект из последнего уровня (ящик какой-то). Тогда я просто добавил новый объект в конец последнего уровня, и все получилось.

Мораль, номер объекта из all.spawn - это просто его номер в порядке компиляции. Зачем acdc разбирает объекты по уровням, не знаю. Но на мой взгляд, после этого они перетасованы. Если каждый раз начинать игру заново, то это и без разницы. Но если мы хотим использовать пересобранный all.spawn не начиная игру заново, то видимо acdc не годится.

Изменено пользователем malandrinus
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

В качестве разминки разберём класс render_device. Один из тех классов, про который должен знать каждый модостроитель, а между тем практически незамеченный.

 

  Описание класса render_device (Показать)

 

 

Подправил описание render_device. Неизвестных методов и свойств практически не осталось. В дополнение привожу пример практического использования - функцию, которая проецирует произвольную точку в пространстве на экран.

 

  Функция проекции точки на экран (Показать)

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

На очереди класс FS. Если кому интересно, то внутри самого движка он имеет имя CLocatorAPI. Это класс для работы с файловой системой и файлами.

  Описание класса FS (Показать)

 

Ещё один класс, имеющий отношение к файловой системе - это CSavedGameWrapper. С помощью этого класса можно получить информацию о сохранённой игре

  Описание класса CSavedGameWrapper (Показать)

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Попробуем приступить к game_object. Это класс для доступа к онлайновым (клиентским) объектам. Причём один класс является интерфейсом для совершенно разных объектов. Разработчики не придумали ничего лучше, как взять и объединить в одном классе все интерфейсы всех клиентских объектов: актора, сталкеров, монстров, физических объектов, автомобилей и лампочек, вообще всех. Более странного и вообще говоря уродливого объектно-ориентированного дизайна я ещё не видел. Во-первых, класс вышел совершенно необозримым - три сотни методов! Во-вторых, вызов не подходящего метода для произвольно взятого объекта приводит к совершенно непредсказуемым результатам. В лучшем случае не будет ничего, а чаще всего - будет вылет, причём обычно без лога. Наконец, описание этого класса в lua_help совершенно невнятное (как впрочем и всех остальных классов): типы возвращаемых значений опущены, типы входных аргументов указаны не всегда, а о назначении большинства методов можно только гадать. Предлагаю несколько более внятное описание. Источником информации служил в первую очередь документ из билда 1935, где описаны (весьма лаконично) многие методы этого класса. Во вторую очередь использована отладочная информация из мультиплеерных билдов, что позволило довольно точно восстановить типы аргументов и возвращаемых значений. Для некоторых функций имеются описания, полученные либо мной лично либо подсмотренные на форумах. Так что предлагаю рассматривать всё это как плод коллективного творчества.

Пара замечаний:

1. Информация по-любому неполная. Многие (скорее даже большинство) методы не описаны, хотя типы аргументов и возвращаемых значений имеются полностью.

2. Вследствие большого объёма причёсывать сил не осталось, так что выкладываю как есть. В некоторых местах осталась информация стороннего характера - сравнение с ранними билдами, внутренние названия функций и некоторые мои собственные домыслы.

3. Я перетасовал список методов с целью их осмысленной группировки "по родству". Очевидно, что мог и заблуждаться насчёт "родства" методов, так что смотрите в оба.

4. Поскольку описание не закончено, то предлагаю всем поучаствовать в завершении этого этапа.

 

  Описание класса game_object: (Показать)
Изменено пользователем malandrinus
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение
  Регистрация скриптовых классов с помощью object_factory (Показать)

 

Изменено пользователем Kirgudu
  • Нравится 1
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Небольшой апдейт. Сегодня разберём глобальные функции или иначе функции из пространств имён. Такая функция в любом месте вызывается следующим образом:

<пространство имён>.<имя функции>(<список аргументов>)

Пространства имён - это всего лишь способ сгруппировать функции по некоторому признаку. Хотя надо заметить, что логика группировки функций в сталкере иной раз не поддаётся объяснению.

Всего есть несколько пространств имён: безымянное (т.е. функции их него вызываются просто по именам как обычные глобальные функции), game, level, relation_registry, actor_stats. В ЧН (и ЗП) появилось пространство имён main_menu, кроме того есть незначительные изменения в остальных: некоторые функции исчезли, некоторые добавлены. Изменения однако незначительны.

Сейчас рассматриваем только три основных пространства имён (безымянное, game, level) и только для ТЧ.

 

  Безымянное пространство имён (Показать)

 

  Пространство имён game (Показать)

 

  Пространство имён level (Показать)

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Чуть дополнил описание game_object (см. пост ранее). Продублирую изменения в этом посте.

 

  дополнения к описанию game_object (Показать)

 

 

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Сначала в двух словах, как пользоваться механизмом выдачи заданий.
Для выдачи задания есть метод класса game_object (естественно, это должен быть актор)

void give_task(
    CGameTask* <задание>, -- подготовленный объект задания, см. далее
    int <время до истечения>, -- время от начального момента до истечения срока задания в ms
    boolean <проверять на наличие такого>) -- если true и задание с таким идентификатором уже есть, то не будет добавлено

Комментарии:


1. Нетрудно посчитать, что в 32-х разрядное целое влазит миллисекунд примерно на месяц. Соответственно - это и будет максимально возможным временем для задания.
2. Третий параметр вероятно имеет смысл использовать для разных категорий заданий. Одноразовые квестовые должны иметь параметр true, а повторяющиеся однотипные - false

Выдаём задания так:
1. Сначала надо подготовить объект типа CGameTask. Самый простой способ - воспользоваться уже готовыми заданиями, описанными в xml файлах. Для этого у класса CGameTask есть метод load
local new_task = CGameTask()
new_task:load("gar_car_graveyard_quest") -- задание "Предложить помощь Бесу"
2. Собственно выдаём задание
db.actor:give_task(new_task, 3600*1000, true) -- срок выполнения 1 час, если уже выдано, то второй раз не получим

Для получения статуса отдельной подзадачи задания есть метод класса get_task_state.
enum ETaskState get_task_state(string <идентификатор задания>, int <номер подзадачи>)
перечисление ETaskState экспортировано в виде класса task (см. далее)
Пример использования
local task_status = db.actor:get_task_state("gar_car_graveyard_quest", 0)

Для установки статуса отдельной подзадачи есть метод set_task_state:
void set_task_state(enum ETaskState <статус>, string <идентификатор задания>, int <номер подзадачи>) -- если такого задания у актера нет, то выдаст ошибку

Это всё было для уже готовых заданий. Если надо лепить задания скриптами, то необходимо использовать все возможности класса CGameTask. Далее я привожу описание классов CGameTask, вспомогательного класса SGameTaskObjective и task. Если кому это на самом деле надо, этого описания должно быть достаточно.


  Описание класса CGameTask (Показать)

  Описание класса SGameTaskObjective (Показать)

  Вспомогательный класс task с константами статуса (Показать)

Начиная с ЧН система заданий несколько изменилась. Исчезли подзадачи и соответственно перестал быть нужным класс SGameTaskObjective. Его методы по сути просто перешли в состав класса CGameTask. На мой взгляд всё стало проще, и если Вы поняли, как это работает в ТЧ, то экстраполировать это на ЧН и ЗП труда не составит.

Изменено пользователем Kirgudu
  • Спасибо 1
  • Полезно 1
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

lekzd,

можно попытаться по разнице между position и center. Это типа по наклону туловища =) Но там тоже нестабильные значения.

Вообще-то по скорости не так уж и плохо работает. Если учесть, что апдейты идут нерегулярно и вычислять скорость по настоящему, т.е. учитывая параметр delta, то точность повышается. Также вроде как лучше вычислять скорость только с учётом координат xz, т.е. игнорировать вертикальную компоненту. Кроме того, можно ввести фильтрацию шума - усреднение по нескольким точкам. У меня усреднение по трём дало достаточно различимую картину: стоит, идёт, бежит. Но иногда таки бывают выбросы. По пяти точкам - различие практически идеальное. Хотя и появляется некоторая микроскопическая задержка, связанная с размазыванием переходов.

Вопрос ещё, для чего это надо. Если скажем надо просто отобразить состояние бега на худе, то и так вполне сойдёт.

  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Введение

  Показать


Итак. Все игровые сущности (сталкеры, монстры, предметы и пр.) в общем случае существуют одновременно на двух сторонах - на сервере и на клиенте. На каждой стороне для этого есть соответствующие классы. На серверной - это классы, имя которых начинается на "cse". С некоторыми поправками можно считать, что все серверные классы происходят от cse_abstract. На клиентской стороне есть соответствующая иерархия классов. Можно считать, что все они происходят от CGameObject. На клиентской стороне есть ещё и game_object, который также является интерфейсом к клиентским объектам, причём основным интерфейсом. Его описание уже начато, но оно далеко от завершения.

Классы как серверные, так и клиентские образуют иерархию наследования классов. На самом примитивном уровне можно считать, что наследование означает включение всех членов базового класса (т.е. свойств и методов) в производный класс. В свою очередь это означает, что нет необходимости описывать унаследованные члены для всех производных классов, достаточно это сделать один раз для базового. Кроме того я ввожу важное соглашение для описания классов: я не буду приводить полный список членов класса для каждого из них, а только список методов и свойств, которые добавляет конкретный класс сверх унаследованных. Поэтому, если по описанию в классе нет ничего, то смотрите на классы от которых он унаследован и смотрите список их методов и список методов их базовых классов и т.д. Я вынужден так сделать во-первых в силу ограничения форума, во вторых для убирания избыточности при описании. Я также буду пользоваться спойлерами: после описания класса будет идти спойлер с его производными классами, в них спойлеры с их производными и т.д. (наподобие матрёшки =)

Начнём с серверных.
Можно обратить внимание, что имеется некоторое количество базовых классов и интерфейсов, которые вообще не содержат никаких методов или свойств. Наследование от них не даёт конкретной информации о свойствах серверного класса, но парадоксальным образом может дать некоторые догадки о применимости методов game_object. Вот список этих базовых интерфейсов:

Базовые интерфейсы

  Показать

 

Несколько предваряющих комментариев к дальнейшему материалу. 

  Показать


Вся иерархия серверных классов

  Показать

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Полагаю, красивая картинка никому не помешает. Вот вам диаграмма серверных классов с высоты птичьего полёта =) Обращаю внимание на нотацию записи: большая пустая стрелка означает отношение обобщения (или наследования иными словами) и направлена от унаследованного класса к базовому. Включение абстрактного интерфейса обозначается стрелкой с кружочком и указанием, какой интерфейс наследуется. Это сокращённая форма записи, позволяющая избавиться от нагромождения линий и лучше понять основную линию наследования.

  Генеалогия серверных классов (Показать)
Изменено пользователем malandrinus
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

7.9,

всё верно, только не 40 млн., а 4 мрд., точнее максимальное 32-х разрядное беззнаковое целое:

4294967295 что в миллисекундах составляет примерно 1193 часа, т.е. 49 дней.

Это известная проблема: после примерно месяца игрового времени часть функций, связанных с использованием этого счётчика, начинают работать неправильно. Вроде как это даже лечили. Хотя если этот счётчик используется не только скриптами, но и движком, то всё не вылечить.

Изменено пользователем malandrinus
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

Разбираем систему клиентских классов.

Сначала немного лирики.

  Показать


Довольно лирики. Далее представлена система клиентских классов. Используются те-же соглашения, что и раньше: конструктор не показан, если класс не добавляет своих методов, то показан одной строкой.

 

Иерархия клиентских классов

Сперва базовые интерфейсы. Их не так много, как у серверных. 

  Показать

 

Все остальные классы имеют своим предком CGameObject

Классы, производные от CGameObject

  Показать

Рисовать картинку с иерархией наследования смысла нет, поскольку и так всё довольно очевидно. За исключением малого числа классов остальные к CGameObject ничего не добавляют. Соответственно и описывать нечего. Названия классов более или менее говорят о том, для каких объектов они предназначены. Где мог, указал точные сигнатуры функций (CCar, CHelicopter и hanging_lamp). Для новых классов и методов по сравнению с ТЧ такой информации к сожалению нет.

Несколько рассуждений на тему взаимодействия серверного и клиентского объектов. Попробуем рассуждать логически. Есть сервер, есть клиент. Это в общем случае разные компьютеры. Каким может быть взаимодействие объектов, находящихся по разную сторону сети? Могут ли они, к примеру, вызывать методы друг друга, или непосредственно читать данные своего "напарника"? Очевидно нет. Моё мнение такое, что их взаимодействие сводится в основном к посылке данных друг другу. При этом, данные посылаются "пачкой", т.е. обо всём состоянии сразу. То, что я наблюдал, выглядит так: при переходе в онлайн создаётся клиентский объект, серверный его инициализирует, посылая ему при создании нетпакет. Этот момент можно отловить в биндере клиентского класса. Все дальнейшие движения происходят от клиентского объекта к серверному. Это означает, что периодически клиентский затирает данные серверного. Точные моменты, когда это происходит, периодичность, а также механизм передачи данных мне лично понять пока не удалось. По крайней мере на серверной стороне ничего не видно, просто тихо меняются данные, и понять, когда это происходит, крайне непросто.
Однако некоторые выводы таки можно сделать. Если взаимодействие классов примерно такое, как я здесь предположил, то совместимость классов определяется совместимостью бинарных данных, которые они друг другу посылают. Ну в общем классы должны друг другу соответствовать, хотя, как далее будет видно, это правило на практике (очень редко) нарушается. Если не забыли ещё, то зарегистрированные пары классов задаются идентификаторами класса. В файлах конфигурации (в секциях объектов) этим идентификаторам соответствует параметр class. В скриптах - это один из членов clsid. В движке уже зарегистрированы соответствующие пары классов, и вы можете добавлять свои пары с помощью класса object_factory. Я это всё описывал 
здесь.

Далее я привожу таблицу соответствия классов. Для полноты картины в ней указаны классы, которые не экспортированы в Lua. Если класс не экспортирован, то это означает, что вам не удастся зарегистрировать на его основе свою пару классов. Однако это не мешает (теоретически) создавать объекты этого класса при условии, что имеется и известен его идентификатор.
Приведённая таблица собрана из разных источников, в том числе основана на примерах регистрации классов из игры. Видно, что иногда клиентский класс использует в качестве "напарника" серверный, который является базовым для своего "родного" серверного. Видимо, это технически в норме вещей и так можно поступать и нам. Из этого ряда выбивается CZombie, для которого вроде бы родным должен быть серверный класс cse_alife_monster_zombie, а регистрируют его с cse_alife_monster_base. Это вроде как нарушает вышеописанную логику, поскольку cse_alife_monster_base не является базовым для cse_alife_monster_zombie. С другой стороны, он так зарегистрирован в самом движке. Возможно cse_alife_monster_zombie попросту не задействован и никакого отношения к CZombie на самом деле не имеет. 


Таблица соответствия серверных и клиентских классов

  Показать
Изменено пользователем Murarius
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение

dimos,

Это «Отбойник» - автоматический дробовик из ЗП. Секция wpn_protecta в файле configs\weapons\w_protecta.ltx.

Я думаю, что не получится сделать оружие, стреляющее двумя типами патронов. При выстреле из подствольника спавнится граната, обрабатывается её физика и т.д. Это не превратить в выстрел из дробовика. Ну по крайней мере я не знаю, как это сделать.

W_GLAUNC - это вообще никак не поможет, поскольку это объект подствольника, а все аддоны - это просто инвентарные предметы. Они не стреляют, стреляют стволы. При надевании аддона сам объект аддона исчезает, а у ствола просто устанавливается соответствующий флажок.

Изменено пользователем malandrinus
  Полезный утиль (Показать)

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
  • Куратор(ы) темы:

×
×
  • Создать...