Доп. опции SN:   A B C D E F G H I K L M O Q R T V W X
При помощи расширения стандартного ресивера !!SN были введены основные новые команды для ERA.
См. описание стандартных команд !!SN

Ресивер SN: новые команды


Все команды ERA могут работать со следующими элементами ERM:

Также, стоит отметить, что в отличии от стандартных z-переменных (длиной до 511 символов) строковые литералы ERA (^…^ или ^%S(…)^) могут иметь длину до 1млн. символов.

Более того, для всех команд новых ресиверов ERA (SN/MP/RD) реализована поддержка:

Примеры (показать)
На экране мы увидим:Сегодня мы напоролись на чужаков... Это были орки!

Ядро ERA передаёт командам набор целых чисел (4 байта каждое). В случае строк или синтаксиса получения значения, эти числа представляют собой адреса переменных. Адрес переменной – числовое значение, описывающее местоположение данных в оперативной памяти.
Максимальное количество параметров команды: 64.
Пример (показать)


SN:L
Подгрузка динамической библиотеки (DLL)

L путь к библиотеке /? описатель загруженной библиотеки

Пример:


SN:A
Получить адрес машинной функции из библиотеки

A описатель загруженной библиотеки / название функции /? адрес функции

Пример:


SN:E
Выполнить машинную функцию

Соглашение о вызове:
   0  (PASCAL)
   1  (CDECL или STDCALL)
   2  (THISCALL)
   3  (FASTCALL)

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

E адрес функции / соглашение о вызове /аргументы…

Примеры: Получить ID текущего игрового диалога: Вычисление корня квадратного на примере стороннего модуля:


SN:F
Выполнить функцию с указанными аргументами для её выполнения из библиотеки era.dll или kernel32.dll (ERA сама выберет нужную библиотеку для функции и закэширует её адрес по имени).
Нет необходимости, в большинстве случаев, использовать последовательность команд SN:L→SN:A→SN:E.

Используется соглашение STDCALL.

F название функции / аргументы ф-ции…

Примеры:


SN:D
Перерисовать (обновить) экран героя, города, встречи двух героев, карты приключений.
Комментарий: команда более безопасна, чем аналогичная ей UN:R.
Команду следует использовать, непосредственно, в указанных выше игровых окнах, т.к. каждому игровому окну соответствует своя функция обновления и только для него.
Пример:


SN:G[имя]
Переход на определённую команду текущего триггера.

На сегодня команда SN:G считается устаревшей и её использование в скриптах крайне не рекомендуется!
Изначально команда создавалась как промежуточный вариант выполнения быстрых циклов. Сейчас предпочтительнее для этих целей использовать связку !!if / !!re.

Для выполнения переходов реализованы командные «ярлыки» (метки), которые заменяются на порядковый номер ресивера внутри текущего триггера, перед которым они стоят (отсчёт начинается с 0). В «счётчик» команд попадают все !!XX-подобные ресиверы. Самим меткам порядковый номер, как команде внутри триггера, не присваивается.
Синтаксис использования следующий:

[имя_метки] – использование метки (будет заменено номером ресивера, для которого метка объявлена)
[:имя_метки] – объявление метки (текущий номер ресивера запоминается и связывается с именем метки)

В качестве имени метки допускается любой произвольный текст. Использовать метки можно как до, так и после их объявления.
Метки используются только с командой SN:G для выполнения циклов и условий.
Пример: ВАЖНО: не разрешается использовать SN:G для "прыжков" как из структурных блоков, так и в структурные блоки.
Пример:
Для прерывания цикла есть команда !!br. Эмулировать SN:G можно так:

Старый синтаксис:
SN:G# - переход на команду # (0…) текущего триггера.
Пример (показать)


SN:H^xxx^…
Команда позволяет работать с названиями/подсказками/описаниями без необходимости хранить текст в выделенных для этого z-переменных.
На данный момент реализованы следующие типы команд SN:H:

Режим получения текста работает со всеми этими типами команд, давая возможность получать актуальный текст/описание в z-переменные для последующего вывода: Для удаления (актуальных значений или установленных ранее через SN:H) или восстановления (стандартный текст) подсказок/описания используйте синтаксис ^-xxx^
Пример:


H^monname^/#1/#2/^текст^
H^monname^/#1/#2/?z#
Изменение имени существ, их описания.

        #1 – номер монстра
        #2 – тип текста:
	0 – имя монстра в ед.ч.
	1 – имя монстра во мн.ч.
	2 – специальный текст (описание)
Комментарий: команда отличается от аналогичной ей UN:G1 тем, что не требует использования z-переменныx.

Пример:


H^object^/X/Y/L/^текст^
Установить подсказку для объекта на карте в координатах X Y L.
H^object^/#1/#2/^текст^
Установить подсказку для объекта определённого типа/подтипа.

        #1 – тип (-1 = пропустить) 
        #2 – подтип (-1 = пропустить)

Если используется несколько вариантов установки подсказок для одного объекта, то приоритет поиска подсказки таков:

  1. объект с точными координатами
  2. объект с указанными типом/подтипом
  3. объект с указанным типом и подтипом -1
  4. объект с типом -1 и указанным подтипом
  5. объект c типом/подтипом как -1
Комментарий: команда отличается от схожих с ней команды OB:H и ресивера HT тем, что не требует использования z-переменныx.

Пример:


H^secskill^/#1/#2/^текст^
H^secskill^/#1/#2/?z#
Возможность установки текста вторичных навыков:

        #1 – вторич.навык (0..27)
        #2 – тип текста:
	0 – имя навыка
	1 – базовый уровень (описание)
	2 – продвинутый уровень (описание)
	3 – экспертный уровень (описание)
Комментарий: команда отличается от аналогичной ей UN:G0 тем, что не требует использования z-переменныx.

Пример: Вы получите два разных сообщения:тест и Обучение


H^spec^/#1/#2/^текст^
H^spec^/#1/#2/?z#
Настроить свой текст для специализации героя

        #1 – герой
        #2 – тип текста для специализации:
	0 – название (не используется в игре)
	1 – краткое описание (не используется в игре)
	2 – полное описание
Комментарий: команда отличается от аналогичной ей UN:G2 тем, что не требует использования z-переменныx.

Пример:


SN:I
Динамическая интерполяция строковых переменных.
Команда может использоваться для интерполяции строковых переменных, получамых из внешних источников, таких как ini-файлы и команда SN:T (хотя её использование рекомендуется только для отладки и портирования).

I строковая переменная /? z#

Пример:
Допустим, в переменной z2 хранится следующее: %Y5 %V996 текст %Z5
Нам надо увидеть, какие значения каждая переменная содержит на данный момент.
Для этого мы используем следующее: Теперь z3 содержит всю информацию из z2, включая все значения интерполированных переменных.


SN:O?X/?Y/?L
Получить координаты входа объекта на карте.
Команде передаются три числовые переменные с координатами объекта, в которые и будут записаны координаты входа объекта.
Комментарии (показать)

Пример:
Давайте узнаем координаты входа объекта, кликнув на другой части объекта…


SN:Q
Прервать обработку текущего события
Комментарий: команда отличается от FU:E тем, что прерывает всю цепочку однотипных триггеров.

Пример:


SN:R
Подменяет в игре "на лету" имена ресурсов.

Используется соглашение STDCALL.

R ^старое имя файла^ / ^новое имя файла^

Для сброса подмены файла укажите пустое значение вместо параметра "новое имя".
Комментарии (показать)

Команда представляет собой обёртку над экпортируемой функцией RedirectFile из era.dll. Если более детально, то SN:R ни что иное как: Все подмены файлов локальны, запоминаются в сохранениях игры и отменяются при выходе из игрового сценария (карты).
Игра выгружает неиспользуемые ресурсы, поэтому большинство ресурсов могут динамически подменяться, пока вы играете.
Если ресурс используется в Окне героя, выполняйте подмену перед тем, как откроется это окно (т.е. до кэширования ресурсов).
Пользовательские игровые фоны могут так же быть внедрены, давая возможность игроку переключать темы прямо во время игры (необходимо загрузить сохранение игры для визуального обновления).
Указав шаблон *.mp3 для параметра "старое имя" подмена произойдёт для всех mp3-файлов сразу.

Примеры:


SN:T^имя^/?z#/#1/?$1.../#7/?$7
Позволяет получать переводы строк по ключам (произвольным уникальным строковым идентификаторам).
В json-файлах хранятся пары вида «Ключ - Значение», где значением является текст перевода с опциональными параметрами.

	(имя) – имя ключа
	z# – z-переменная для получения результата
	#1 – наименование параметра 1
	$1 – значение параметра 1
	…
	…
	#7 – наименование параметра 7
	$7 – значение параметра 7
Пример (показать)
Мой test.json:
{
  "test.gold_amount_report": "У вас осталось @gold@ золотых. Неплохо!"
}

См. также: Выдержка из истории изменений ERA по json-файлам


SN:X
Доступ к параметрам новых событий

X до 16 параметров

Новые события ERA и добавляемые модулями события нуждаются в возможности обмениваться данными со скриптами. Эту возможность обеспечивает команда , выступающая в качестве хранилища значений. Тип значений определяется способом работы с ними. Так, можно установить в слот 0 значение 5, а потом получить его в вещественную e-переменную. Поскольку работа происходит на машинном уровне, то в e-переменной окажется вовсе не 5, а неопределённый мусор. В случае получения строковой переменной (текста), команда трактует значение в слоте как адрес. Поэтому, !!SN:X0; !!SN:X?z1; приведёт к вылету, т.к. по адресу 0 нет никакой строки.
Пример: Т.к. в ERA переменные x1..x16 доступны для любых триггеров, SN:X параметры и есть x1..x16.
Замечание: на данный момент команда SN:X устарела, т.к. параметры событий можно читать/писать, обращаясь напрямую к x1..x16.
Пример: Команду X целесообразно использовать только для редко требуемых операций по низкоуровневому преобразованию типов или получению адресов…


Работа с дополнительной памятью

SN:M…

ERM переменные статичны и ограничены в количестве. Статичность приводит к невозможности организовывать динамические структуры данных (например, списки), для которых нужны функции выделения и освобождения памяти, а ограниченное количество ведёт к необходимости строгого учёта индексов без возможности выйти за их пределы. Более того, ERM строки в виде z-переменных занимают ровно 512 байт каждая в независимости от размера их содержимого. ERA предоставляет программисту до 2 млрд. слотов под массивы новых переменных (числовых или строковых). Размер массивов может изменяться средствами ERM. Поскольку работа с динамическими структурами предполагает автоматическое выделение номеров слотов, то такая возможность присутствует. Слоты с положительными индексами принадлежат пользователю, а с отрицательными используются при автовыделении памяти.
Замечание: команды SN:M не поддерживают работу переменных с косвенными ссылками…


M#
Удаление слота памяти

M номер слота, начиная с 0

Пример:


M#1/$2
Установка/получение размера слота
(Размер слота – это количество элементов в массиве)

        #1 – номер слота
        $2 – кол-во элементов

Команда возвращает -1, если слот не существует.
Пример:


M#1/#2/$3
Работа со значениями элементов слотов

        #1 – номер слота
        #2 – номер элемента, начиная с 0
        $3 – значение
Пример:


M#1/?#2/#3
Получение адреса элемента слота

        #1 - номер слота
        #2 - адрес элемента (только получение)
        #3 - номер элемента

Комментари: при удалении слота или изменении его размера – адрес станет недействительным!
Примеры (показать)

А вот другой пример, когда требуется скопировать строковое значение из массива в массив напрямую.
Как уже было сказано ранее, все команды ERA получают параметры в виде 4-байтовых чисел. Для строк это обычно адрес первого символа. Когда мы пишем z1, команда получает адрес этой переменной. Когда строковое значение ^текст^ – строка сперва сохраняется во временном буфере, затем команде передаётся её адрес, после чего буфер освобождается.. Таким образом, длинные строки (>512 байт) можно копировать между собой и использовать как буфер для накопления:


M#1/#2/#3/#4
Создание нового слота

        #1 – номер слота: "-1" для автовыделения свободного номера и помещения его в v1
        #2 – кол-во элементов в слоте
        #3 – тип элементов: 0 (число) и 1 (строка)
        #4 – запоминать ли значения в сохранёнках:
	= 0 (нет, при загрузке игры содержимое элементов будет представлять собой случайный мусор)
	= 1 (да, содержимое нужно сохранять как есть)

Комментарий: старое содержимое слота (если оно было), уничтожается.
Если значения в сохранениях не запоминать (#4=0), то экономится место в файле и возрастает скорость сохранения.
Пример:


SN:K…
Команды SN:K работают как со строками (текстовыми переменными), так и с их адресами в памяти. Это делает SN:K более низкоуровневой и функциональной, чем схожие с ней по некоторым действиям команды VR:M#.

K#1/?#2
Получение размера строки (включая пробелы)

K строка или её адрес /? размер строки

Пример:


K#1/#2/$3
Работа с символами строки

K строка или её адрес / номер символа, начиная с 0 /[?] значение символа

Пример: Замечание: синтаксис получения символа в $3 параметр работает некорректно.


K#1/#2/#3/#4
Копирование блока памяти

K кол-во байт / адрес источника / адрес приёмника / произвольное значение

Комментарий: поддерживаются числовые и строковые переменные.

Пример:


Работа с ассоциативной памятью

SN:W[…]

Очень часто бывает нужно завести переменные для конкретных героев, конкретных клеток карты или объектов по запросам игрока.
Выделение статической памяти для всех героев, всех объектов или всех клеток обладает существенными недостатками: чрезмерное потребление памяти, замедление процесса сохранения игры, ограниченность размеров.
Все эти проблемы решаются при работе с глобальным хранилищем пар типа «Ключ - Значение», напоминающем ini-файлы.
Каждому ключу может соответствовать 1 числовое и 1 строковое значение.
Значения 0/пусто не записываются в сохранения, что позволяет экономить место.
При запросе несуществующего ключа будет возвращено 0/пусто, в зависимости от типа приёмника.
Пример:
Давайте создадим ключ и запишем в него значения разных типов, при этом они пересекаться не будут:


W
Полная очистка ассоциативной памяти

W^имя^/$
Работа с переменной

W имя переменной /[?] значение переменной

Пример:
Пусть щелчок правой кнопкой мыши на карте приключений приводит к отображению количества щелчков по данной клетке.
Фактически, это аналог команды !!PO по требованию. Замечание: внутри %I() нельзя использовать символ процентов (%).

W^имя^
Удаление переменной