Официальная документация GMDK: Скрипты Gothic

Материал из Gothic Library Wiki
Перейти к навигацииПерейти к поиску


Комментарии[править | править код]

В этом руководстве мы дадим общий обзор использованному в Gothic языку программирования с упором на создание модификаций. Вкратце мы рассмотрим основные функциональные возможности и особенности языка. Мы не сможем в одной теме охватить полный спектр и возможности скриптового языка, но дадим общие понятия по созданию сценариев и пару полезных советов. Множество мелочей, которые здесь не будут объяснены, вы сможете найти в опубликованных статьях и отчетах по Gothic-MOD Kit. Смотрите также документацию по синтаксису языка.

Для чего используется скриптовый язык?[править | править код]

Скрипты Gothic выполняют множество задач. Основными из них являются:

- Указание свойств объектов и NPC.

- Установка поведения NPC-AI. Реакция на действие игрока (выполняется по восприятию).

- Установка ежедневного расписания NPC.

- Cоздание диалогов с NPC.

- Настройка воздействия магии на персонажа.

- Поведение камеры в определенных ситуациях.

- Настройка свойств эффектов частиц.

- Настройка свойств звуковых эффектов.

- Настройка меню и т.д.


Отдельные файлы сценариев имеют расширение *.D. Это обычные текстовые файлы со скриптами, которые впоследствии будут компилированы в единый файл DAT и сохранены на жестком диске. Список скриптов, которые будут компилированы, хранится в файле *.src. Он также является обычным текстовым файлом, в котором перечислены все необходимые файлы скриптов. В SRC-файлах разрешено использование подкаталогов и масок. Следите за последовательностью указанных в нем файлов, так как некоторые скрипты должны быть определены раньше других. Первыми скриптами в списке должны быть сценарии классов и глобальных констант, так как большинство последующих скриптов будут на них ссылаться.

Создание сценариев[править | править код]

Скриптовый язык использует так называемые "классы", которые определяют, какие свойства объектов постоянные, а какие изменчивые.

Классы начинаются с ключевого слова CLASS и не могут быть изменены. Они создают интерфейс между сценариями и, собственно, самой программой (Gothic), поэтому они должны в точности совпадать. Если же типы переменных или их порядок изменятся, то поведение Gothic станет непредсказуемым и в худшем случае произойдет сбой, так как Gothic будет прописывать необходимые значения в неправильное место.

Отдельные классы содержатся в папке "content\_intern" в файле "classes.d". В нем вы найдете краткое описание некоторых используемых переменных.

Важными классами являются:


C_NPC - качества и параметры NPC, которые могут быть изменены в скриптах.

C_ITEM - качества и параметры объектов, которые могут быть изменены в скриптах.

C_INFO - параметры информации, которая будет выдаваться во время диалога.


Классы бесполезны без инстанций соответствующих классов. Инстанции создают в игре объекты нужного класса, например, NPC является инстанцией класса "C_NPC". Инстанции обозначаются ключевым словом Instance. После этого свойства объекта инициализируются согласно определенным в классе значениям. Каждый D-скрипт в папке "story/npc/" инициализирует таким образом отдельного NPC.

Ограничение языка[править | править код]

Язык скриптов Gothic имеет некоторые ограничения и особенности, которые могут представлять интерес для более опытных программистов:

- Нет циклов For... While...

- Приоритет операторов аналогичен C++.

- Отсутствует несколько операторов присваивания целочисленных типов (+=, -=, ...).

- При доступе к элементам массива можно использовать в качестве индекса только постоянные величины. Например, массив ArrayName[10]=1234 разрешен, тогда как ArrayNane[varName]=1234 выдаст ошибку, так как в качестве индекса используется переменная величина.

- Массивы нельзя передавать в качестве параметров функции.

- Для чисел с плавающей точкой существует только оператор присваивания (величины Float не вычисляются).

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

- Локальные переменные в функциях рассматриваются как глобальные и сохраняют свое значение при выходе из функции. Таким образом, они создаются на время и затем снова удаляются, как в C++.


Внешние расширения языка[править | править код]

"Externals", иначе именуемый "BuildIn", обеспечивает функциональные возможности, которые трудно было бы реализовать с помощью сценариев. Здесь Gothic представляет набор внешних функций, которые можно вызвать через скрипты. Список этих функций с кратким описанием можно найти в файле \AI\AI_intern\externals.d.

Как с помощью скриптов определить поведение NPC?[править | править код]

Большинство NPC в игре управляются сценариями. Поведение и состояние NPC также определяются с помощью скриптов. При написании сценариев состояния персонажей необходимо строго соблюдать определенные правила.

Описание состояния персонажей состоит, как правило, из трех скриптовых функций, описывающих состояние персонажа в трех фазах. Первая фаза - "Begin" фаза. В ней даются все подготовительные команды для действий NPC. Например, NPC подходит к нужной точке, в которой будет выполнять все дальнейшие действия.

Вторая фаза - "Loop" фаза. До тех пор, пока NPC находится в этом состоянии, скриптовая функция повторяется снова и снова, выполняя запрограммированные действия, и переходит в следующую фазу в случае окончания или прерывания функции. Эта фаза также может возвращать значение, определяющее условие, должно ли текущее состояние персонажа пройти полный цикл, прежде чем прерваться или закончиться. Если возвращается значение больше нуля, то состояние персонажа заканчивается и запускается фаза "End". Фаза "End" является заключительным этапом. Здесь вводятся команды, позволяющие закончить выход персонажа из текущего состояния. Например, подъем NPC со скамейки, после того как он сидел на ней.

Имена трех функций скриптов, отвечающих за фазы состояния, всегда должны начинаться с приставки "ZS_". Для соответствующих фаз состояний также добавляются определенные окончания к имени функции. Три функции сценария должны выглядеть примерно следующим образом:

 FUNC VOID ZS_[ИмяСостояния] ()

{

   // Начало фазы "Begin-фаза"
   // Данная функция запускается только один раз при входе в состояние

};

 FUNC VOID ZS_[ИмяСостояния]_LOOP ()

{

   // Повторяющаяся фаза или "Loop-фаза".
   // Фаза будет повторятся до тех пор пока
   // не будет прервана 
   // или пока не закончится.

};

 FUNC VOID ZS_[ИмяСостояния]_END () 

{

   // Завершающая фаза или "End-фаза".
   // Позволяет NPC выйти из текущего состояния.

};


Ознакомиться с простым сценарием состояния можно в скрипте content/story/zs/zs_guard.d".

Как назначить состояние NPC?[править | править код]

Многие NPC имеют свой скриптовый распорядок дня, в котором определяется, в какое время и какие действия должен выполнять персонаж. Пример описания распорядка дня можно найти в файле content\story\npc\bau_904_bauer.d. В скрипте функция распорядка дня NPC определяется строкой "Rtn_start_904". Дальше перечисляются состояния персонажа в определенное время. Состояния записываются через приставку "TA_" и передаются на выполнение Gothic через Build-In функцию. Таким образом, настраивается распорядок дня NPC.

Распорядок дня монстров также управляется скриптами, однако, этот сценарий намного сложней и должен быть предварительно просчитан Gothic. При желании можете заглянуть в скрипты монстров. При запуске игры NPC и монстры входят в состояние, соответствующие их распорядку дня.

NPC может выйти из своего состояния при срабатывании восприятия на внешний раздражитель. Например, когда NPC обнаруживает игрока за кражей, видит монстра или драку. Восприятия влекут за собой изменение состояние персонажа. На какие раздражители NPC должен реагировать, описывается в Begin-фазе состояния. При срабатывании восприятия передается Build-In команда Npc_PercEnable, которая активирует нужное состояние персонажа. Если NPC реагирует на восприятие, то персонаж переходит в новое состояние. Конечно, можно изменить состояние вручную. Это реализуется с помощью встроенной функции AI_StartState.

Как с помощью скриптов давать команды NPC?[править | править код]

Для этих целей существуют встроенные функции, которые начинаются с приставки "ai_". Более сложные действия ,которые должны длиться на протяжении долгого времени, описаны в файле "externals.d". К таким действиям можно отнести, например, движение к определенной цели, сидение на скамье и т.д. AI команды выполняются одна за другой, если NPC не прерывает их выполнение.

В игре есть несколько глобальных переменных NPC, с помощью которых можно решить множество важных вещей. В состояниях используется переменная "self", которая является ссылкой на актуального NPC, находящегося в этом состоянии. Такие переменные Gothic инициализирует автоматически.

Для написания сценариев используется и другие виды переменных, которые можно использовать также при описании реакции на восприятие:

- C_NPC hero: Данная переменная ссылается на текущего игрока. - C_NPC self: NPC, который входит в текущее состояние. - C_NPC other: NPC - раздражитель (например, игрок в диалогах, правонарушитель). - C_NPC victim: Жертва определенных действий (К примеру, некий третий персонаж напал на NPC). - C_ITEM item: Воспринимаемый предмет.

Проверку на инициализацию подобных величин в Gothic можно произвести с помощью Build-In методов Hlp_IsValidNpc или Hlp_IsValidItem. Все глобальные переменные расположены в файле content\_intern\classes.d и не могут быть изменены.


Как разместить NPC в мире?[править | править код]

В мир NPC вставляются также с помощью скриптов. NPC создаются при запуске новой игры или при переходе на новый игровой уровень. В скриптах описывается метод вставки NPC.

Основной функцией при вставке NPC является Startup-функция. Функция выполняется один раз при запуске игры или нового игрового уровня. Здесь прописываются NPC и точки Waypoint, в которые персонажи должны будут вставляться. Если у NPC есть свой распорядок дня и при этом сменяется его Waypoint, то Gothic вставит персонажа в другое место с учетом этого распорядка.

Название функции сценария состоит из приставки "STARTUP_" и имени ZEN-файла. Также есть функция Init (Записывается Init_[ZEN-имя файла]. Функцию необходимо повторять после каждой STARTUP-функции. Init-функция не предназначена для записи команд вставки NPC, так как NPC начнут дублироваться при повторной загрузке уровня. Чтобы вставить NPC, используется Build-In метод Wld_InsertNpc. В методе указывается имя инстанции NPC и Waypoint, где будет вставлен NPC. Пример вы сможете посмотреть в файле content\story\startup.d.