# Пользовательские дополнения

На главную

## Оригинальные интерфейсы и пользовательские дополнения

Пользовательские дополнения совершенно независимы от оригинальных. Они не могут пользоваться никакими ресурсами оригинальной игры (кроме специально оговоренных) и должны содержать полностью все данные и функциональность. Все пользовательские дополнения должны быть созданы либо "с нуля", либо на основе других пользовательских дополнений и/или отдельных элементов (данных и скриптов). Изменять функциональность и внешний вид оригинальных интерфейсов из пользовательских дополнений нельзя.

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

## Структура пользовательских данных

Все пользовательские дополнения и отдельные элементы, распознаваемые игрой, должны устанавливаться в папку data\Mods.

Собственно дополнения должны находиться в папке data\Mods\Addons. Каждое дополнение - в отдельной папке. Например:

-     data\Mods\Addons\Addon01

-     data\Mods\Addons\Addon02

-     data\Mods\Addons\AddonManager

Папка data\Mods, помимо собственно дополнений, может также содержать общие элементы, не входящие непосредственно ни в какое дополнение. Например, можно выделить отдельные папки для общеупотребительных скриптов и элементы для конструирования диалогов:

-     data\Mods\CommonScriptParts

-     data\Mods\DialogParts

### Структура пользовательского дополнения

Каждое пользовательское дополнение, чтобы распознаваться игрой, должно в обязательном порядке содержать файл-описатель AddonDesc.(UIAddon).xdb.

Например:

-     data\Mods\Addons\Addon01\AddonDesc.(UIAddon).xdb

-     data\Mods\Addons\Addon02\AddonDesc.(UIAddon).xdb

-     data\Mods\Addons\AddonManager\AddonDesc.(UIAddon).xdb

Файл-описатель должен содержать следующие ключевые поля:

Автоматический запуск дополнения после старта игры:

    <AutoStart>true</AutoStart>

Список исполняемых Lua-скриптов:

    <ScriptFileRefs>

    	<Item href="ScriptAddonTest1.lua" />

    </ScriptFileRefs>

Идентификатор главной формы:

    <MainFormId>Main</MainFormId>

Список форм:

    <Forms>

    	<Item>

    		<Id>Main</Id>

    		<Form href="MainForm.(WidgetForm).xdb#xpointer(/WidgetForm)" />

    	</Item>

    </Forms>

### Типы файлов

Основные ресурсы игры:

- *.xdb - описатели данных, XML-файлы в кодировке UTF-8
- *.lua - Lua-скрипты
- *.luac - скомпилированные в байткод Lua-скрипты
- *.txt - локализуемые тексты в кодировке UTF-16LE
- *.bin - ресурсы игры во внутреннем формате (получаются после экспорта)

Исходные данные:

- *.tga - исходные файлы для экспорта рисунков

### Отладка

Для вывода отладочной информации используется файл Personal\Logs\mods.txt.

### Lua-скрипты

Игра использует LuaJIT версии 2.0.3.

Подключены стандартные библиотеки: base, table, string, math.

Запрещено неявное объявление глобальных переменных, необходимо использовать функцию Global( name, value ).

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

Взаимодействие скрипта с клиентом игры происходит через механизм обработки событий. Первый раз скрипт получает управление при старте дополнения. Все скрипты, используемые дополнением, описаны в файле AddonDesc.(UIAddon).xdb. Скрипты инициализируются в том порядке, в котором они перечислены в списке (поле ScriptFileRefs).

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

Пример инициализации показан в дополнении SampleInit.

В дальнейшем управление передается скрипту только на время обработки событий, инициируемых движком игры. Скрипт обязан провести необходимую обработку и вернуть управление игре. Есть два основных класса событий: игровые события и реакции системы Widgets - нажатие кнопок, ввод с клавиатуры и т.д. Скрипт сам определяет (регистрирует) те события и реакции, которые он хочет обрабатывать.

События игры и реакции содержат один параметр - таблицу. Содержимое таблицы зависит от конкретного события или реакции. Регистрация событий производится функцией common.RegisterEventHandler. Регистрация реакций - функцией common.RegisterReactionHandler. Первый параметр - функция-обработчик, второй - название события или реакции. Функции-обработчики должны иметь один параметр - это таблица, содержащая информацию о событии или реакции. Аддон может регистрировать только одну функцию-обработчик для события или реакции.

Пример регистрации скрипта на обработку событий показан в дополнении SampleEventRegistration.

Пример регистрации обработчика реакций показан в дополнении SampleReactionHandler.

Загрузкой/выгрузкой дополнений (включая оригинальные) также можно управлять из пользовательских скриптов.

Пример отключения оригинального интерфейса игры показан в дополнении SampleZoneAnnounce.

### Компиляция Lua-скриптов в байткод

Для создания байткода из исходного Lua-скрипта нужно использовать исполняемый(exe) фаил, собранный из исходных кодов библиотеки LuaJIT.
Байткод сгенерированный компилятором библиотеки Lua не совместим с LuaJIT!

Собранный исполняемый файл библиотеки LuaJIT 2.0.3 приложен к данной документации в папке LuaCompiler.
Для самостоятельной сборки исполняемого файла LuaJIT нужно скачать исходный код библиотеки на официальном сайте проекта LuaJIT и следовать инструкциям по сборке.

Генерация байткода запускается вызывом из консоли исполняемого файла LuaJIT с параметром -b и указанием исходного и целевого файла(со скриптом).
>luajit-2.0.3.exe -b source.lua destination.luac

### Экспорт текстур

Исходные текстуры для интерфейсов должны быть в формате *.tga. Чтобы использовать текстуры в дополнениях их необходимо предварительно перевести во внутренний формат игры. Экспорт осуществляется утилитой Mods\UITextureConvertEditor.exe (рабочим каталогом при запуске должна быть папка Mods). Окно экспортера имеет следующий вид:

Для экспорта необходимо выбрать из выпадающего списка желаемый тип текстуры, а также задать сами текстуры. Текстуры можно добавлять как через диалог (кнопка "Добавить..."), так и перетаскивая мышью файлы с исходными текстурами на окно экспортера. Результаты (в случае успешного экспорта) будут находиться в той же папке, что и исходная текстура.

ВНИМАНИЕ! Исходные текстуры обязательно должны находиться внутри папки data\Mods\Addons.

Типы текстур:

- WidgetLayerSimpleTexture - основной тип экспорта. Используется для большинства текстур, из которых составляются интерфейсы. Текстура экспортируется как тип UITextureElement. Помимо этого создается слой, необходимый для использования текстуры в элементах UI.
- WidgetLayerTiledTexture - используется для экспорта текстур, предназначенных для использования в элементах UI по "черепичному" принципу. Текстура экспортируется как тип UISingleTexture. Помимо этого создается слой, необходимый для использования этой текстуры в элементах UI.
- UISingleTexture - основной тип экспорта для работы с "индивидуальными" текстурами. Чаще всего это иконки и текстуры, предназначенные для использования в качестве "черепицы". Рекомендуется использовать текстуры с размерами, кратными степени 2.
- UITextureElement - экспорт текстуры, предназначенной для использования в качестве одной из составляющих того или иного интерфейса.

Дополнительные настройки:

- "Использовать формат DXT3 вместо DXT5" - использовать другой формат сжатия для текстур с несколькими градациями прозрачности:

- DXT3 - более четкие контуры, но меньше градаций самой прозрачности
- DXT5 - лучше передает плавные переходы уровня прозрачности за счет менее четких контуров последней

- "Принудительный экспорт" - заново экспортировать текстуру независимо от того, менялась она со времени последнего конвертирования или нет.

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

- Кнопка "Сконвертировать" запускает экспорт всех вновь добавленных файлов (со статусом "added") с текущими настройками, процесс может занять некоторое время. После окончания экспорта для каждого файла будет показан результат конвертирования: "converted" - успех или "failed" - провал. Повторный экспорт текстуры (например, с другими настройками) невозможен (независимо от успеха или неуспеха). Для повтора (например, для экспорта текстур с другими настройками) необходимо закрыть утилиту и выполнить процедуру заново.

### Упакованные пользовательские дополнения

Более удобным способом распространения пользовательских дополнений являются архивы. Архив представляет собой zip-архив и должен иметь расширение *.pak, zip-архив должен иметь стандартное (нормальное) сжатие. Его нужно помещать в ту же папку, что и "развернутые" дополнения - data\Mods\Addons. Например:

data\Mods\Addons\UserAddon01.pak
data\Mods\Addons\UserAddon02.pak

Путь до файлов внутри архива должен совпадать с путем до оригинальных файлов. Например, для дополнения UserAddon01, лежащего в каталоге Mods\Addons и содержащего файлы:

AddonDesc.(UIAddon).xdb
MainForm.(WidgetForm).xdb
ScriptUserAddon01.lua

версия в виде архива UserAddon01.pak должна содержать следующие файлы:

Mods\Addons\UserAddon01\AddonDesc.(UIAddon).xdb
Mods\Addons\UserAddon01\MainForm.(WidgetForm).xdb
Mods\Addons\UserAddon01\ScriptUserAddon01.lua

### Локализация

Для локализации пользовательских дополнений на другие языки можно использовать механизм языковых архивов. Языковой архив представляет собой zip-архив (со стандартным, нормальным сжатием), содержащий текстовые файлы с локализацией на тот или иной язык. Архивы с локализацией нужно помещать в ту же папку, что и "развернутые" дополнения - data\Mods\Addons. Например:

data\Packs\UserAddon01.eng
data\Packs\UserAddon02.eng

Расширение языкового пакета должно соответствовать языку локализации. Например:

UserAddon01.rus
UserAddon01.eng
UserAddon01.fra
UserAddon01.ger
UserAddon01.spa

Путь до файла с локализацией внутри архива должен совпадать с путем до оригинального текстового файла. Например, для дополнения UserAddon01, лежащего в каталоге Mods\Addons и содержащего текстовые файлы:

Header.txt
LocalizedTexts\Text01.txt
LocalizedTexts\Text02.txt
NotLocalizedTexts\Text01.txt
NotLocalizedTexts\Text02.txt

архив с локализацией на английский язык UserAddon01.eng может содержать следующие файлы:

Mods\Addons\UserAddon01\Header.txt
Mods\Addons\UserAddon01\Texts\Text01.txt
Mods\Addons\UserAddon01\Texts\Text02.txt

В этом случае при запуске клиента с выбранным английским языком оригинальные тексты Header.txt, LocalizedTexts\Text01.txt, LocalizedTexts\Text02.txt будут заменены на тексты из архива. А тексты из каталога NotLocalizedTexts\ останутся не переведенными.

### Примеры дополнений

Для использования дополнений их необходимо перенести или скопировать в папку data\Mods\Addons.

#### SampleInit

Дополнение data\Mods\SampleAddons\SampleInit. Пример инициализации скрипта.

Дополнение регистрирует два скрипта. Первый, Mods\SampleCommon\SampleAddonBase.lua, - общий для нескольких аддонов, содержит вспомогательные функции. Из него используется LogInfo - скриптовая обертка для функции клиента, выводящей отладочную информацию (в файл Personal\Logs\mods.txt). Второй, ScriptSampleInit.lua, - собственный скрипт аддона, выводящий во время инициализации скрипта отладочное текстовое сообщение.

#### SampleEventRegistration

Дополнение data\Mods\SampleAddons\SampleEventRegistration. Пример регистрации скрипта на обработку событий.
Скрипт регистрирует глобальную переменную - счетчик времени и ловит событие, приходящее раз в секунду. На каждый приход события выводится отладочное текстовое сообщение.

#### SampleReactionHandler

Дополнение data\Mods\SampleAddons\SampleReactionHandler. Пример регистрации обработчика реакций.

Скрипт ловит реакцию от кнопки и перемещает диалоговое окно по экрану.

#### SampleZoneAnnounce

Дополнение data\Mods\SampleAddons\SampleZoneAnnounce. Пример, выводящий уведомление о переходе игрока в другую зону. Показывает возможность отключения оригинального интерфейса игры с аналогичной функциональностью.

#### SampleLocalization

Дополнение data\Mods\SampleAddons\SampleLocalization. Пример локализации на несколько языков.

### Client-Lua API

Интерфейс, предоставляемый Lua-скриптам клиентом игры.

Полный список: функции и события Lua API.

Замечание: дополнительные описания (в частности, возможностей, использование которых по каким-либо причинам для создания пользовательских дополнений недоступно) не предоставляются. Ссылки на дополнительные описания неактивны и помечены как "закрытая ссылка".

Можно выделить следующие основные подсистемы клиента:

- GameState - логика игры без визуальной части.
- UIState (система UI в целом) - вся визуальная составляющая.

- Система Widgets - часть UIState, реализующая элементы пользовательского интерфейса: панели, кнопки, текстовые элементы, контейнеры и др.

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

Отдельно можно выделить: глобальные целочисленные константы (определенные в клиенте игры).

Помимо целочисленных констант широко используются "строковые". Главным образом - для вывода локализуемых сообщений и т.п. Для "текстовых" констант принята запись "ENUM_...", для целочисленных констант префикс "ENUM_" не используется.

### Ресурсы игры

Основной формат ресурсов игры - *.xdb-файлы. Это xml-файлы в кодировке UTF-8, которые непосредственно описывают ресурсы игры, а также содержат ссылки на другие ресурсы. Ими могут быть как другие описатели, так и файлы прочих типов (локализуемые тексты, скрипты, бинарные данные). Создавать и редактировать *.xdb-описатели можно как в стандартном "Блокноте", так и в других редакторах. (Описатели для текстур создаются во время их конвертации утилитой экспорта).

Основные типы ресурсов, используемые при создании пользовательских интерфейсов, включают в себя элементы системы Widgets и наиболее важные элементы системы UI в целом. Значения полей по умолчанию для них можно найти в папке ResourceSystem. Файлы вида SampleDefault.(имя_типа).xdb содержат значения полей по умолчанию. Файлы вида SampleDefaultExt.(имя_типа).xdb дополнительно содержат значения полей по умолчанию для элементов списков (массивов).

Описание полей ресурсов виджетов: Widget.

Пример универсального слота для отображения предметов или заклинаний: UniSlot.

На главную