Версия 3.3.0 (11/2020) ------------------------ [-] Удалена опция ini " Debug.Трекерм.IgnoreRealTimeTimers". ERA все равно не отслеживает триггеры без обработчиков. [- ] Исправлена ошибка в Array_CustomSort, приводящая к неправильному окончательному упорядочению элементов списка. [ + ] Добавлена новая команда ERM SN:B для работы с двоичными буферами на низком уровне. Это позволяет: - получить адрес локальной или статической глобальной переменной ERM; - чтение / запись целого числа / строки из / в определенный адрес. !!SN:B (intAddress) или ?(intVar) или (strVar) или ?(strVar) [ / ?(addressValue) или (dummy)/$valueAtAddress] Первый аргумент определяет переменный адрес для работы. Для строк это всегда адрес первого строкового символа, независимо от синтаксиса GET / SET. Для floats / ints установите синтаксическое среднее значение переменной в качестве адреса. Синтаксис GET означает адрес указанной переменной. !!VR (тест: y): S8943200; !!SN:B (тест); означает использование 8943200 в качестве адреса !!СН: Б?(test); означает использование адреса (test) y-переменной. !!VR (текст: z): S^hello world^; !!SN:B (текст); означает использование адреса первого символа (текста) !!СН: Б?(текст); означает также использовать адрес первого символа (текста). Пример: Объявим целочисленную y-переменную и определим ее адрес для использования с внешней функцией API. !!VR(fileHandle:y): S(INVALID_HANDLE_VALUE); !!СН: Б?(файловая ручка)/?(fileHandleAddr: y); (fileHandlerAddr) теперь является адресом переменной (fileHandle). Давайте прочитаем последнее имя savegame из статического буфера H3 !!SN:B (ADDR_MARKED_SAVEGAME_NAME)/d/?(lastSavegameName:z); !!IF: M^You last savegame name was %(lastSavegameName)^; [ + ] Добавлен каталог "Runtime" в каталог Heroes 3. Моды должны читать / записывать данные, созданные или измененные во время выполнения там. Если вам нужна конфигурация, которую игрок сможет изменить с помощью графического интерфейса, считайте данные из "Runtime\you mod.ini", fallbacking к значениям конфигурации json из каталога Lang. Таким образом, очистка каталога "Runtime" будет иметь тот же эффект, что и переустановка всех модов с нуля. [ + ] Добавлена функция экспорта GetProcessGuid, позволяющая получить уникальный 32-символьный идентификатор запуска игрового процесса. Каждый запуск игрового процесса будет генерировать различное значение. Моддеры могут использовать это значение для проверки того, является ли игрок перезапустил игровой процесс или нет. процедура GetProcessGuid (Buf: pchar); stdcall; Использование: !!SN:F^GetProcessGuid^/?(processGuid:z); !!Если: M^%(processGuid)^; [+] Добавлены следующие функции в мод " Era Erm Framework: !?FU(GetTimeMsec); ; Возвращает текущее время в миллисекундах (время от запуска компьютера, переполнение каждые 49.71 дней) !#VA (результат: x); !?Фу (PackUnion); ; Безопасно упаковывает поля объединения в одно 32-битное целое число, позволяя хранить несколько значений в одной переменной. ; Аргументы представляют собой пары (значение поля, размер поля в битах). Первое поле записывается в бит 0-й позиции. ; Последний аргумент-результат. ; Пример: P (x)/ 8/(y)/ 8/(z)/ 8/(heroId)/ 8/?(результат: y); !?FU(UnpackUnion); ; Безопасно распаковывает одно 32-битное целое значение в несколько значений полей. ; Первый аргумент-упакованное значение. ; Другие аргументы являются парами (?значение поля, размер поля в битах). Первое поле считывается в бит 0-й позиции. ; Пример: P45683/ ?(x: y) / 8/ ?(y:y) / 8/ ?(z:y)/ 8/?(героид:y) / 8; !?FU(Array_Shuffle); ; Случайным образом перетасовывает все элементы в списке. !#VA (список: x); идентификатор массива. !?FU(Array_Merge); ; Заданный целевой массив и произвольное число исходных массивов. Добавляет все элементы из всех исходных массивов ; к целевому массиву. ; Пример. Дано listA = [100, 200, 300], listB = [500, 600]. P (listA)/(listB) => [100, 200, 300, 500, 600] !#VA (dstArray:x); целевой массив для добавления новых элементов. !#VA(firstArrayToMerge:x);... Массивы для слияния с первым Примеры: !!Фу (NewStrArray): П?(listA: y); !!FU (Array_Push):P (listA)/^one^ / ^two^ / ^three^; !!Фу (NewStrArray): П?(listB:y); !!FU (Array_Push):P (listB) / ^wog^ / ^era^; !!FU (Array_Merge):P (listA)/(listB)/(listB); !!FU (Array_Join):P (listA)/?(текст:z) / ^ ^; !!IF: M^%(текст)^; " one two three wog era WOG era" !?FU(Array_Slice); ; Возвращает часть исходного массива в качестве нового триггера-локального массива. !#VA (list:x); массив для получения среза. !#VA (start:x); начальный индекс, начинающийся с нуля. Отрицательное смещение означает "с конца". !#VA (count:x); количество элементов для копирования. Отрицательное значение означает "пропуск" этого количества элементов из конца списка. !#VA (result:x); результирующий массив. !#VA(arrayStorageType:x); OPT. Специальный тип хранения для результата типа M_STORED. По умолчанию: M_TRIGGER_LOCAL. Примеры: !!Фу (NewStrArray): П?(listA: y); !!FU (Array_Push):P (listA)/^one^ / ^two^ / ^three^ / ^four^ / ^five^; !!FU (Array_Slice):P (listA)/-4/-1/-что?(listB:y); !!FU (Array_Join):P (listB)/?(текст:z) / ^ ^; !!Если: M^%(текст)^; " два три четыре" !?FU(Substr); ; Возвращает подстроку из существующей строки. !#VA (strPtr:x); исходная строка. !#VA (start:x); начальное смещение, начиная с нуля. Отрицательное смещение означает "с конца". !#VA(count:x); OPT. Количество символов для копирования. Отрицательное значение означает "пропуск" этого количества символов из конца строки. !#VA (result:x); результирующая подстрока. Примеры: !!VRs ^ message^: S^хорошего дня, дорогой Перри^; !!FU (Substr): Ps^message^ / -5/(INT_MAX)/?s^submessage^; копирование до 5 символов с конца !!IF: M^%s (submessage)^; " Perry" !!VRs ^ message^: S^хорошего дня, дорогой Перри^; !!FU (Substr): Ps^message^ / 5/(INT_MAX)/?s^submessage^; copy, пропуская первые 5 символов !!IF: M^%s (submessage)^; "хорошего дня, дорогой Перри" !!VRs ^ message^: S^хорошего дня, дорогой Перри^; !!FU (Substr): Ps^сообщение^/5/-6/-что?s^submessage^; копирование с 6-го символа до конца, не включая последние 6 символов !!Если: M^%s (submessage)^; " хороший день дорогой" !?Фу (Скандир); ; Читает содержимое каталога, заполняя указанный список именами файлов. ; Пример: P^Np3^/(fileList)/(SCAN_FILES_ONLY); !#VA (dirPathPtr:x); абсолютный или относительный путь к каталогу для сканирования. !#VA (fileList:x); идентификатор массива для хранения имен файлов. !#VA(itemsType: x); OPT. Тип собираемых элементов: файлы, каталоги или то и другое вместе. Одна из констант SCAN_XXX. По умолчанию: SCAN_FILES_AND_DIRS. !#VA (fullPaths:x); OPT boolean. Если true, то результирующие элементы будут иметь предустановленный dirPath. По умолчанию: false. !?Фу (Савейни); ; Сохраняет ini-файл, если он ранее был кэширован в памяти (была выполнена любая операция чтения/записи). !#VA(filePathPtr: x); абсолютный или относительный путь к ini-файлу !?FU (WriteIniInts); ; Записывает несколько целочисленных значений в ini-файл в памяти, но откладывает сохранение данных на диск. Вызовите "SaveIni", чтобы очистить кэшированные данные. ; Пример: P^Runtime/my mod.ini^ / ^уровни героев^ / (HERO_ORRIN) / 13/(HERO_XERON) / 41; !#VA(filePathPtr: x); абсолютный или относительный путь к ini-файлу !#VA (sectionNamePtr:x); имя раздела в ini-файле. !#VA(firstKeyPtr:x); ... До 7 Ключей, пар значений для записи. !#VA(firstValue:x); !?FU(WriteIniStrings); ; Записывает несколько строковых значений в ini-файл в памяти, но откладывает сохранение данных на диск. Вызовите "SaveIni", чтобы очистить кэшированные данные. ; Пример: P^Runtime / my mod.ini^ / ^пользовательские имена героев^ / ^ %(HERO_ORRIN)^ / ^Perrin R^/ ^ %(HERO_XERON)^ / ^Berson^; !#VA(filePathPtr: x); абсолютный или относительный путь к файлу ini !#VA (sectionNamePtr:x); имя раздела в ini-файле. !#VA(firstKeyPtr:x); ... До 7 пар ключей и значений для записи. !#VA(firstValue:x); !?FU(ReadIniStrings); ; Считывает несколько строковых значений из ini-файла или из памяти, если ini-файл был прочитан / записан ранее. ; Пример: P (filePath)/(sectionName)/^%(HERO_ORRIN)^/?(orrinName:z)/^Orrin^ / ^%(HERO_XERON)^/?(xeronName:z) / ^Xeron^; !#VA(filePathPtr: x); абсолютный или относительный путь к ini-файлу !#VA (sectionNamePtr:x); имя раздела в ini-файле. !#VA(firstKeyPtr:x);... До 4 (ключ,?value, defaultValue) отключается для чтения. !#VA(firstValue:x); !#VA(firstValueDefault:x); !?Фу(ReadIniInts); ; Считывает несколько целочисленных значений из ini-файла или из памяти, если ini-файл был прочитан / записан ранее. ; Пример: P (filePath)/^hero levels^ / ^%(HERO_ORRIN)^/?(orrinLevel:y)/1 / ^%(HERO_XERON)^/?(xeronLevel:y) / 1; !#VA(filePathPtr: x); абсолютный или относительный путь к ini-файлу !#VA (sectionNamePtr:x); имя раздела в ini-файле. !#VA(firstKeyPtr:x);... До 4 (ключ,?value, defaultValue) отключается для чтения. !#VA(firstValue:x); !#VA(firstValueDefault:x); !?FU (GetMaxMonsterId); ; Возвращает идентификатор последнего поддерживаемого монстра в игре. !#VA (результат: x); !?Фу (GetUpgradedMonster); ; Возвращает идентификатор обновленного монстра или NO_MON, если обновление не существует. !#VA (monId:x); идентификатор монстра, для которого нужно получить обновление. !#VA (результат: x); OUT. Идентификатор обновленного монстра или -1. !?FU (GetDegradedMonCandidates); ; Возвращает временный список всех монстров, которые могут быть обновлены до указанного монстра. ; Там может существовать несколько монстров, обновляющихся до одного и того же типа. Производительность функции низкая. !#VA (monId:x); обновленный идентификатор монстра. !#VA (degradesList:x); идентификатор временного массива SN:M с деградированными кандидатами-монстрами. !?Фу(BattleStack_Shoot); ; Заставляет один стек стрелять в другой. !#VA(attackerStackId:x) (defenderStackId:x); !!BM (attackerStackId): Z?(attackerStackStruct:y); !!BM (defenderStackId): Z?(defenderStackStruct:y); !!SN:E4453920/(CALLCONV_THISCALL)/(attackerStackStruct)/(defenderStackStruct); !?FU (LoadIntGlobalsFromJson); ; Загружает глобальные настройки mod/script из конфигурации json прямо в глобальные переменные с префиксами имен. ; Поддерживает использование любого имени константы вместо чисел в JSON. Например, вы хотите загрузить ; значения json "umt.randomizationIntervalDays " и " umt.playAltThemesSequently " к глобальным переменным ; я^umt_randomizationIntervalDays^ и я^umt_playAltThemesSequently^ и хочу иметь возможность писать в json: ; "УМТ.playAltThemesSequently": "правда". ; ; Пример: P^umt.^ / ^umt_^ / ^randomizationIntervalDays^ / ^playAltThemesSequently^; !#VA (jsonKeysPrefixPtr:x); имя префикса ключей json типа ^mix.глобальный.^ for {"mix": {"globals": { ... }}} !#VA (globalVarsPrefixPtr:x); имя префикса глобальных переменных. Обычно мод префикс типа " mix_ "или"umt_". !#VA(firstKeyNamePtr:x);... До 14 имен ключей json для чтения и преобразования в глобальные переменные !?Фу (SaveGame); !#VA (fileNamePtr:x); имя файла без расширения для сохранения игры. !#VA (appendExtension:x); OPT boolean. Если значение true, то к имени файла будет добавлено автоматическое расширение. По умолчанию: TRUE. !#VA (compressFile:x); OPT boolean. Если true, сохраненный файл будет gzipped. В противном случае файл записывается без сжатия. По умолчанию: TRUE. !#VA (saveToData:x); OPT boolean. Если true, то сохранение выполняется в каталог Data, а не в каталог" игры". По умолчанию: FALSE. !#VA (markInList:x); OPT boolean. Если значение true, сохраненная игра будет отмечена в диалогах сохранения/загрузки как выбранная. По умолчанию: TRUE. [+] Добавлены новые события в мод "Era Erm Framework" : - "OnStartOrLoad": происходит после запуска карты или загрузки savegame. Безопасная альтернатива "OnGameStart", которая запускается перед отображением карты приключений. [ + ] Добавлены новые константы в мод "Era Erm Framework" для битов, битовых масок, адресов игровых менеджеров и т. д. [!] Он: команда L была переписана для поддержки #/^...^ Синтаксис эпохи 3. Автоматическая перерисовка карты приключений была удалена. Отныне команда поддерживает любую строку ERM. Он:L3 не нуждается во втором аргументе. [- ] Исправлена ошибка un44.специальная рамка def dragon. Версия 3.2.0 (11/2020) ------------------------ [ @ ] Особая благодарность Andarium за поддержку проекта. [ + ] Обновлен плагин "WOG native dialogs". Добавлена поддержка переопределения любого zsetup00.txt-часть с использованием конфигурационных файлов json. Смотрите пример полной замены вкладок/страниц WOG Options в Mods/WoG/Lang / WOG options.формат JSON.пример. Добавлена поддержка управления, какие изображения могут быть выбраны в диалогах IF:N-like. Исправлены возможные сбои, связанные с использованием освобожденных языковых буферов данных. Кредиты: Игрик. [ + ] Обновлено " расширены исправления игровых ошибок.dll " плагин от igrik. Исправлена ошибка способности к повреждению стековых блоков и ошибка клонирования существ WoG experience. [ + ] Обновленные файлы автозаполнения событий и констант в редакторе Sublime Text Erm. [ + ] Включен переработанный un44.def file by Bes. [ + ] Добавлена поддержка D-синтаксиса в параметрах функции. !!FU (edu_Test):Pd-200; пройдет -200, ранее 200 [ + ] Добавлены настройки локали для Lang/era.формат JSON: "эра.место действия.decimal_separator " - разделитель дробной части в числах (например, точка в 3.14 для английского языка) "эра.место действия.thousand_separator " - разделитель каждой группы из 3 цифр в украшенных числах. Для этого рекомендуется использовать универсальное пространство. Пример: "19 841". "эра.место действия.non_breaking_space " - символ пробела, который рассматривается как часть слова и не завернут в слово. "эра.место действия.metric_suffixes.0" - количественный метрический суффикс для тысяч, таких как "K". Примерный номер: "15.3 K" для "15 300". "эра.место действия.metric_suffixes.1 " - количественный метрический суффикс для миллионов, например "М". Примерный номер: "1.2 м" для "1 200 000". "эра.место действия.metric_suffixes.2 "- количественный метрический суффикс для миллиардов, таких как"G". Примерный номер: "1.06 G" для "1 060 000 000". [ + ] Улучшена поддержка сложных диалогов Heroes 3. Титры: Берсерк, Игрик. IF: N (msgType)/^text^[/?результат/(textAlignment)/(preselectedPicId) / (selectablePicsMask)]. selectablePicsMask-битовая маска изображений, разрешенная для выбора. Значение по умолчанию -1 (все картинки). Чтобы сделать первый и четвертый снимки выбираемыми только укажите маску 1 ^ 0 + 1 ^ 3 = 1 + 8 = 9. Эта настройка позволяет некоторым изображениям выступать только в качестве украшения,а другим-в качестве выбираемых элементов. Пример: - Давайте выведем выделение двух типов армий в центре и двух ресурсных затрат по краям. ; Изображения монстров будут выбираться, изображения ресурсов не будут выбираться. !!FU (ConstructBitMask): P (DLG_RESULT_PIC_2)/(DLG_RESULT_PIC_3)/?(selectablePicsMask:y); !!IF:N(PIC_TYPE_RES_CRYSTAL)/100/(PIC_TYPE_MONSTER)/(MON_CYCLOPS)/(PIC_TYPE_MONSTER)/(MON_EFREETI)/(PIC_TYPE_RES_SULFUR)/100; !!Если: N (MSG_TYPE_CHOOSE_PIC)/^какую армию вы хотите призвать?^/?(выбор: y)/(TEXT_ALIGN_CENTER)/(DLG_NO_SELECTION)/(selectablePicsMask); [ + ] Добавлены новые события "OnBeforeBattleReplay" и "OnAfterBattleReplay", в зависимости от сторонних плагинов, таких как "BattleReplay" от igrik. Движок теперь обрабатывает "OnBeforeBattleReplay", чтобы исправить проблемы с генерацией препятствий battlefield. [ + ] Отныне допускаются повторяющиеся объявления констант с одинаковым значением. !#DC (TRUE) = 1; !#DC (TRUE) = 1; не дает ошибки !#DC (TRUE) = 3; ошибка: константа TRUE уже определена со значением 1 [+] Добавлена новая команда ERM VR:F в виде !!VR (numericVar): F(minValue)/(maxValue). Он используется для принудительного значения в определенном диапазоне и может использоваться вместо математических функций ToRange, Min и Max. Все аргументы должны быть одного типа. (numericVar) - любая целочисленная или плавающая переменная. (minValue) - минимальное значение диапазона (целое или плавающее). (maxValue) - максимальное значение диапазона (целое или плавающее). Если диапазон недопустим (minValue) > (maxValue), то результатом будет (minValue). Примеры: !!VR (значение: y): S77 F10/100; заставить 77 быть в 10..100 диапазон !!IF: M^%(value)^; отображает 77 !!VR(значение: y): S444 F10/100; заставить 444 быть в 10..100 диапазон !!IF: M^%(value)^; отображает "100" (максимально возможное значение) !!VR (значение: y): S-7 F10/100; сила -7 должна быть в 10..100 диапазон !!IF: M^%(value)^; отображает "10" (минимально возможное значение) !!VR(значение: y): S4 F6/2; заставить 4 быть в недопустимом 6..2 Диапазон !!IF: M^%(value)^; отображает "6" (начальное значение диапазона используется в случае недопустимого диапазона) !!VR(value1:y): S93; !!VR(value2:y):S50; !!VR(value1):F (INT_MIN)/(value2); value1 = минимум (value1, value2) !!IF: M^%(value)^; отображает "50" (наименьшее из 2 значений) !!VR(value1:y): S93; !!VR(value2:y):S50; !!VR (value1):F (value2)/(INT_MAX); value1 = максимум (value1, value2) !!IF: M^%(value)^; отображает "93" (самое большое из 2 значений) [+] Добавлена возможность вызова функций, возвращающих значения float с помощью SN: F. просто добавьте точку (".") перед именем функции. [+] Добавлена возможность возвращать строки из функций с помощью P?(someStr) синтаксис. Если (someStr) является строковой переменной, то соответствующий X-аргумент устанавливается равным 0 Перед выполнением функции. Ожидается, что функция присвоит Z-строковый индекс результата X-аргументу. Это может быть локальная строка, глобальная строка, локальная строка триггера, строка ERT. Значение этой строки будет присвоено переменной (someStr) на выходе из функции. Пример: !?FU(test_AppendHeroName); !#VA(introTextPtr: x); текст для добавления имени героя к !#VA(resultPtr: x); строка результата !!VR (результат:z):Sz (introTextPtr) +^Corwin^; !!VR (resultPtr): Z (result); создайте локальную переменную триггера с результатом и назначьте ее индекс аргументу resultPtr !?FU(OnAfterErmInstructions); !!VR(greetingBeginning:z): S^Привет, ^; !!FU (test_AppendHeroName): P (greetingBeginning)/?(приветствие: z); !!IF: M^%(приветствие)^; display "Hello, Corwin" [ + ] Реализовано сохранение и загрузка глобальных констант в savegames. [+] Добавлена новая команда ERM SN:C(constantName)/?(постоянное значение) [ / ?(константинисты)] Это позволяет получить постоянное значение по имени во время выполнения. Например, можно использовать константы в конфигурациях json. Короткий пример: !!SN:C^OBJ_MONSTER^/?(constValue: y)/?(константы:y); !!IF: M^OBJ_MONSTER = %(constValue). Константа существует: %(constExists)^; OBJ_MONSTER = 54. Константа существует: 1 Давайте разрешим использовать константы в конфигурационном файле json для key ' edu.banned_obj_type'. !!VR (ключ:z): S^edu.banned_obj_type^; подготовить ключ для загрузки из json !!SN:T (ключ)/?(valueStr: z); загрузить перевод для данного ключа в виде строки !!SN:C (valueStr)/?(значение: y)/?(constExists: y); попробуйте найти константу с тем же именем, что и значение !!VR (value)&(constExists)=(FALSE): V (valueStr); если константа не найдена, преобразуйте строковое значение в целое число !!Если:M^edu.banned_obj_type = %(value)^; отображение загруженного значения конфигурации [+] Добавлены новые константы в мод "Era Erm Framework" : - ARG_SYNTAX_GET, ARG_SYNTAX_SET, ARG_SYNTAX_ADD для типов синтаксиса аргументов FU: S. - Множество других новых констант. [+] Добавлены новые события в мод "Era Erm Framework" : - "OnAfterBattleSetup", происходящий сразу после событий" OnBeforeBattle "и" OnBeforeBattleUniversal". Новое событие позволяет быть уверенным, что основные параметры боя (герои, быстрый бой, координаты) настроены. [+] В моде "Era Erm Framework" были введены следующие улучшения: - События" OnBeforeBattle" и "OnBeforeBattleUniversal" были улучшены, сохраняя большинство параметров prebattle в глобальных переменных. i^battle_isQuick^: (TRUE) если включен быстрый бой, (FALSE) в противном случае i^battle_x^: боевая координата x i^battle_y^: Битва y-координата i^battle_z^: боевая Z-координата i^battle_owner_0^: владелец левой стороны или (NO_OWNER) i^battle_owner_1^: владелец правой стороны или (NO_OWNER) i^battle_hero_0^: левый боковой герой или (NO_HERO) i ^ battle_hero_1^: правый боковой герой или (NO_HERO). Любое отрицательное значение нормализуется в (NO_HERO) i ^ battle_ai_0^: (TRUE) если левая сторона управляется искусственным интеллектом, то (FALSE) в противном случае. i ^ battle_ai_1^: (TRUE) если правая сторона управляется искусственным интеллектом, то (FALSE) в противном случае. i ^ battle_human_0^: (TRUE) если левая сторона контролируется человеком, то (FALSE) в противном случае. i ^ battle_human_1^: (TRUE) если правая сторона контролируется человеком, то (FALSE) в противном случае. i ^ battle_remote_0^: (TRUE) если левая сторона управляется дистанционным человеком, то (FALSE) в противном случае. i^battle_remote_1^: (TRUE) если правая сторона управляется удаленным человеком, (FALSE) в противном случае. i^battle_local_0^: (TRUE) если левая сторона контролируется местным человеком или ИИ, (FALSE) в противном случае. i^battle_local_1^: (TRUE) если правая сторона контролируется местным человеком или ИИ, (FALSE) в противном случае. i^battle_localHuman_0^: (TRUE) если левая сторона контролируется локальным человеком, (FALSE) в противном случае. i^battle_localHuman_1^: (TRUE) если правая сторона контролируется локальным человеком, (FALSE) в противном случае. i^battle_hasHuman^: (TRUE) если хотя бы одна сторона контролируется человеком, (FALSE) в противном случае. I ^ battle_humanOnly^: (TRUE) если все стороны контролируются людьми, (FALSE) в противном случае. i ^ battle_ aionly^: (TRUE) если все стороны контролируются искусственным интеллектом, (FALSE) в противном случае. i^battle_isVisible^: (TRUE) если хотя бы одна сторона является человеком и быстрая битва выключена, (FALSE) в противном случае. i ^ battle_isNetwork^: (TRUE) если это сетевая битва человек против человека, то (FALSE) в противном случае. i^battle_type^: бит-Маска типа Битвы: набор констант BATTLE_TYPE_FLAG_XXX. i^battle_current_side^: текущая / активная боевая сторона стека (BATTLE_LEFT = 0 или BATTLE_RIGHT = 1). Изменения в событиях" OnBeforeBattleStackTurn" и "OnBattleStackObtainsTurn". i^battle_current_stack^: текущий / активный идентификатор стека. Изменения в событиях" OnBeforeBattleStackTurn" и "OnBattleStackObtainsTurn". i^battle_acting_stack^: идентификатор стека, выполняющего действие. Он установлен только в "OnBeforeBattleAction". i^battle_acting_side^: сторона (BATTLE_LEFT = 0 или BATTLE_RIGHT = 1) стека, выполняющая действие. Он установлен только в "OnBeforeBattleAction". - i^battle_round^ сохраняет текущий действительный раунд и может использоваться на протяжении всего боя триггеров и в OnBattleRound состоянии как !?FU (OnBattleRound)&i^battle_round^=0 вместо v997. [+] Добавлены следующие функции в мод " Era Erm Framework: !?Фу(NewIntArray); ; Создает и возвращает триггер локального массива целых чисел. ; Альтернативные аргументы функции: ; (?result) результирующий массив будет содержать 0 элементов. ; (размер)/(?result) результирующий массив будет содержать элементы (size) со значением 0. ; (размер)/(fillValue)/(?result) результирующий массив будет иметь (size) items will (fillValue) value ; Вы можете дополнительно указать параметр (storageType) после (?результат) аргумент со значением типа M_STORED или M_TEMP. !?Фу (NewStrArray); ; Создает и возвращает триггер локального массива строк. ; Альтернативные аргументы функции: ; (?result) результирующий массив будет содержать 0 элементов. ; (размер)/(?result) результирующий массив будет иметь элементы (size)со значением^^. ; (размер)/(fillValue)/(?result) результирующий массив будет иметь (size) items will (fillValue) value ; Вы можете дополнительно указать параметр (storageType) после (?результат) аргумент со значением типа M_STORED или M_TEMP. !?FU(Array_Push); ; Добавляет новые элементы в конец массива, автоматически изменяя его размер. !#VA(list: x); идентификатор массива для отправки элементов в !#VA(firstItem:x);... До 15 аргументов для добавления в список !?FU(Array_Pop); ; Удаляет элементы из конца массива один за другим, возвращая их значения и автоматически изменяя размер массива. ; По крайней мере один элемент удаляется из массива, если это возможно. ; Пример: P{list}/?{lastItem}/?{beforeLastItem}. !#VA (list:x); идентификатор массива для извлечения элементов из него. !#VA (firstItem:x); OUT параметры... До 15 аргументов, чтобы выскочить из списка. Если элемент не может быть извлечен, ему будет присвоено нулевое значение или пустая строка. -------- ПРИМЕРЫ --------- !!Фу (NewStrArray): П?(list:y); create trigger-локальный строковый массив !!FU (Array_Push): P (list)/^igrik^ / ^PerryR^ / ^Panda^; заполните его 3 значениями !#VA(items[4]: z); объявить массив из 4 локальных z-строк !!FU (Array_Pop):P (список)/?(пункты[0])/?(пункты[1])/?(пункты[2])/?(элементы[3]); pop элементы из массива один за другим !!IF: M^%(items[0]) %(items[1]) %(items[2]) %(items[3])^; отображает "Panda PerryR igrik " ; теперь (список) не содержит никаких элементов ------ КОНЕЧНЫЕ ПРИМЕРЫ ------- !?FU(H3Dlg_StopAnimation); ; Останавливает анимацию текущих диалогов !?FU(H3Dlg_ResumeAnimation); ; Возобновляет анимацию остановленных диалогов !?FU(H3Dlg_ShowPopup); ; Показывает диалог H3 как всплывающее окно RMB. !#VA(h3Dlg:x); адрес диалогового объекта H3 !?FU(H3Dlg_Coords); ; Позволяет получить доступ к координатам отображения диалогового окна H3. Автоматически исправлены неверные координаты. !#VA (h3Dlg:x); адрес диалогового объекта H3. !#VA(x:x); X-координата, поддерживает синтаксис GET / SET / ADD !#VA(y:x); y-координата, поддерживает синтаксис GET / SET / ADD !?FU(DL_FindById); ; Возвращает адрес объекта диалогового окна DL по идентификатору DL или (NULL). !#VA(dlgId:x); !#VA (результат: x); !?Фу (DL_Destroy); ; Уничтожает объект диалога DL. !#VA(dlgObj:x); !?FU(DL_ShowPopup); ; Показывает диалоговое окно DL как всплывающее окно RMB. ; Диалог будет уничтожен после показа. Вызовите DL: N еще раз, чтобы воссоздать его. ; © GrayFace !#VA (dlgId:x); DL dialog ID. Пример: !?FU(OnAdventureMapRightMouseClick); !!CM:R (FALSE); отключить реакцию по умолчанию !!DL89: N^cmenu.txt^; загрузить пользовательский диалог DL !!FU (DL_ShowPopup): P89; отображение диалогового окна DL при удержании правой кнопки мыши !?FU(DL_Coords); ; Позволяет получить доступ к DL-диалоговое окно отображения координат. Вызовите DL:N, прежде чем пытаться получить доступ к координатам. ; © igrik !#VA (dlgId:x); DL dialog ID !#VA(x:x); X-координата, поддерживает GET/SET / ADD синтаксис !#VA(y:x); y-координата, поддерживает синтаксис GET / SET / ADD !?FU(DL_GetSize); ; Возвращает ширину и высоту диалогового окна DL-dialog. !#VA(dlgId:x); DL dialog ID !#VA (ширина: x); OUT. Ширина диалогового окна !#VA (Высота: x); OUT. Высота диалогового окна !?FU(DL_AlignDlg); ; Выравнивает положение отображения диалогового окна. Вызовите DL: N перед попыткой использовать эту функцию. !#VA(dlgId:x); DL dialog ID !#VA (alignment:x); битовая маска констант TEXT_ALIGN_XXX. !?Фу (DecorateInt); ; Преобразует целое число в строку, разделяя каждую трехзначную группу на "эру".место действия.thousand_separator " character. ; Пример: P74276689 = > " 74 276 689" !#VA (значение:x); номер для украшения. !#VA(resultPtr: x); OUT. Строка результата. !#VA (ignoreSmallNumbers:x); необязательное логическое значение. Если установлено значение DONT_DECORATE_SMALL_INTS, значения По умолчанию: false. !?FU (FormatQuantity); ; Форматирует заданное положительное или отрицательное количество в удобочитаемую строку с желаемыми ограничениями по длине и максимальному количеству цифр. ; Использует настройки локали игры и метрические суффиксы, такие как "K", "M" и "G". ; Пример: P-1234567890/6/4 => "-1.23 G" !#VA (значение:x); количество для форматирования. !#VA(resultPtr: x); OUT. Строка результата. !#VA(maxLen:x); необязательно. Максимальная желаемая длина строки в логических символах. По умолчанию: 5. !#VA (maxDigits:x); необязательно. Максимальное количество цифр для использования в результате (чем больше цифр для отображения, тем медленнее число считывается человеком). По умолчанию: 4. [+] Изменены следующие функции в моде "Era Erm Framework" : !?FU(Array_Join); ; Объединяет элементы массива в единую строку, используя переданную строку клея. Работает как с числовыми, так и со строковыми массивами. Пример: ["один", "два", "три"] с клеем "- - - "станьте" один --- два --- три". !#VA (список:x); идентификатор массива. !#VA(resultPtr: x); OUT. Строка результата !#VA(gluePtr:x); опционально. Клеевой шнур. По умолчанию: ''. !?Фу (GetStrAtAddr); ; Считывает нулевую завершенную строку по указанному адресу в переменную s^result^. ; Нулевой адрес (0) приводит к пустой строке. !#VA (strAddr:x); адрес строки с нулевым окончанием в памяти или 0. !#VA (resultPtr:x); строковая переменная, в которую копируется содержимое строки. !?Фу (StrToUpper); ; Преобразует заданную строку в верхний регистр. !#VA (strPtr:x); исходная строка. !#VA(resultPtr: x); OUT. Строка результата. !?Фу (StrToLower); ; Преобразует заданную строку в нижний регистр. !#VA (strPtr:x); исходная строка. !#VA(resultPtr: x); OUT. Строка результата. !?FU (MonCountToFuzzyText); ; Преобразует количество монстров в строковый диапазон значений, например " 50-99 "или" 2K+ " с максимальным ограничением длины. ; Пример P777/?{result}/(MON_FUZZY_COUNT_SHORT) = > "500-999". !#VA (monNum:x); количество монстров для преобразования в текст. !#VA(resultPtr: x); OUT. Строка результата !#VA(maxTextLength:x); необязательно. Ограничение длины результата в виде константы MON_FUZZY_COUNT_XXX. По умолчанию: MON_FUZZY_COUNT_SHORT [+] Добавлена экспортированная функция "ToStaticStr" ({n} Str: pchar): {n} pchar; Он принимает указатель на строку с нулевым окончанием или null. Возвращает null для аргумента null. В противном случае возвращает постоянный статический строковый адрес для заданного строкового содержимого. Результат всегда один и тот же для одного и того же содержимого строки. Результат доступен только для чтения и никогда не будет освобожден. Эта функция служит двум целям: - Преобразование строки из временного буфера в статический буфер с бесконечным сроком службы без потери памяти для несколько вызовов для одного и того же содержимого строки. - Результат может быть обработан как уникальная строка hash / ID. Таким образом, сравнивая два результата "ToStaticStr" можно выполняется только с помощью указателей. Например, вы пишете плагин, где вам нужны статические строковые адреса для диалоговых элементов, подсказок, внутриигровых структур. Вы получаете эти строки из языкового файла json и хотите поддерживать ключ перезагрузки F12. Просто используйте ToStaticStr(tr(...)). Если перевод не будет изменен во время игры, ToStaticStr вернет тот же буфер адреса для одного и того же содержимого строки. В противном случае потребление памяти будет расти, но клавиша F12 будет работать хорошо. Никаких аварий, никаких болтающихся указателей. [+] Добавлена экспортируемая функция "DecorateInt", которая преобразует целое число в строку, разделяя каждую трехзначную группу на "era".место действия.символ thousand_separator". функция DecorateInt (Value: integer; Buf: pchar; IgnoreSmallNumbers: integer): integer; stdcall; Возвращает конечную длину строки в байтах. Укажите IgnoreSmallNumbers, чтобы оставить значения Использует настройки локали игры. Пример: 2138945 => "2 138 945" [+] Добавлена экспортируемая функция "FormatQuantity", которая форматирует заданное положительное или отрицательное количество в удобочитаемую строку с желаемыми ограничениями по длине и максимальное количество цифр. Использует настройки локали игры и метрические суффиксы, такие как "K", "M" и "G". функция FormatQuantity (Value: integer; Buf: pchar; BufSize: integer; MaxLen, MaxDigits: integer): integer; Возвращает конечную длину строки в байтах; MaxLen-максимальная желаемая длина строки в логических символах. MaxDigits-максимальное количество цифр, используемых в результате (чем больше цифр отображается, тем медленнее число считывается человеком). Оптимальными настройками, например, для количества повреждений или нейтралов, будут MaxLen = 5, MaxDigits = 4. Примеры: FormatQuantity(1234567890, 10, 10) = '1234567890' FormatQuantity(-1234567890, 6, 4) = '-1.23 Г' FormatQuantity(123, 2, 4) = '0K' FormatQuantity(1234567890, 6, 2) = '1G' FormatQuantity(1234567890, 1, 2) = '9' FormatQuantity(1234567890, 1, 0)= " [ * ] Восстановлена старая функция IF: Q для типов сообщений MSG_TYPE_CHOOSE_PIC и MSG_TYPE_CHOOSE_PIC_OR_CANCEL: третья картинка не может быть выбрана. [ * ] Триггер-локальные строки и время жизни массива были увеличены. Такие элементы утилизируются только после обработки всей цепочки одинаковых триггерных обработчиков. [ * ] Изменен zcrtrait.txt: значение боя Санты гремлина и значение ИИ изменились с 500 до 300. Убрал "Can gift" из описания. [ * ] Полностью отключено поведение событий старого багги "OnBattleRound". Отныне "OnBattleRound" - это псевдоним"OnCombatRound". v997 содержит действительный боевой раунд на протяжении всего сражения. Не используйте "OnCombatRound" в плагинах, это псевдоним для Только ЭМ. Вместо этого используйте "OnBattleRound". [ * ] (TRUE) и (FALSE) ERM-константы теперь предопределены заранее. [- ] Исправлено re / FU / DO/OB/...десятки команд... не поддерживал глобальные именованные переменные в параметрах приемника. Примеры: !!FUi^edu_someFunc^: P; !!OBi^edu_x^ / i^edu_y^/i^edu_z^: T?(objType:y); [- ] Исправлена ошибка: FU: S используется для возврата поврежденных значений. [- ] Исправлена ошибка в HookCode: зацепление коротких прыжков приводило к повреждению памяти. [- ] Исправлено, если: Q с типом сообщения 7 (MSG_TYPE_CHOOSE_PIC): результат теперь действителен флаг 1/0, а не значение 1/2, как это было раньше. [- ] Исправлено имя артефакта "Рог Изобилия" в artevent.формат txt. Вратари: Валерий (Саламандра). Версия 3.1.2 (10/2020) ------------------------ [ * ] Исправлена библиотека Json для разрешения последовательных строк комментариев. Пример: { "смесь": { // строка комментария 1 // строка комментария 2 "глобальный": { "тест": "лучший" } } } Версия 3.1.1 (10/2020) ------------------------ [+] Включен обновленный плагин" game bug fixes extended " со многими исправлениями сбоев / переполнений / ошибок. Стабильность игры повысилась. Титры: Бен, Игрик, Розекавалье и другие. Старый плагин" game bug fixes " от RoseKavalier был удален. [ + ] Добавлено "никаких тюрем на случайных картах.bin.off " и " one slot combo arts.bin.off " патчи от igrik. Первый отключает генерацию тюрем на случайных картах. Второй позволяет комбинированным артефактам занимать один слот без возможности дальнейшей разборки. [ + ] Санта-Гремлины теперь становятся обычным подразделением с нормальным недельным ростом (16 в неделю), без подарков и со следующей ледяной смелой силой заклинания: (Количество Сант - 1) / 2 + случайный(0, 1), если количество Сант четное. Таблица количества Санта гремлина и окончательного урона: 1 - 10 2-10 или 30 3 - 30 4-30 или 50 5 - 50 6-50 или 70 и т.д. [ + ] Заменил генератор псевдослучайных чисел Heroes 3 высококачественным генератором Mersenne Twister. Родной генератор по-прежнему используется для генерации боевых препятствий и в многопользовательских сражениях, исключая Hot Seat. [+] Добавлены новые функции в мод "Era Erm Framework" : !?FU(Array_Copy); ; Изменяет размер целевого массива в соответствии с размером исходного массива и копирует все исходные элементы в целевой массив. ; Оба массива должны иметь один и тот же тип элементов. !#VA (srcArray:x); идентификатор массива для копирования элементов из (источника). !#VA (dstArray:x); идентификатор массива для копирования элементов в (пункт назначения). !?FU(Array_Clone); ; Создает триггер локальной копии массива. !#VA (srcArray:x); идентификатор массива для клонирования. !#VA (result:x); идентификатор локального массива триггера результата. !?FU(Tm32Encode); ; Быстрое и обратимое хеширование int32. Ссылка: https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key !#VA(значение: x) (результат: x); !?FU(Tm32Decode); !#VA(значение: x) (результат: x); [ + ] Обновлены следующие функции мода" Era Erm Framework": !?FU (MonCountToFuzzyText); ; Преобразует количество монстров в строковый диапазон значений, например "50-99" или "2K+" максимальной длиной 7 символов. ; Возвращает результат в s^result^ !#VA(monNum:x); !#VA(withDescription:x);?логический. Если true, то результатом будет родной текст H3, такой как"a pack (10-19) of". По умолчанию: false. !?FU (DeconstructBitMask); ; Деконструирует битовую маску в список битовых / флаговых позиций (каждая с 0..31 значение). ; Например, P137 / (list) заполнит список значениями [0, 3, 7], поскольку ; 2 ^ 0 + 2 ^ 3 + 2 ^ 7 = 1 + 8 + 128 = 137. Это означает, что установлены биты 0, 3 и 7. !#VA (mask:x); битовая маска. !#VA (результат:x); будет содержать новый идентификатор локального массива триггера с позициями бит/флаг. [ * ] Удалена проверка типов из SN: M(array)/(itemIndex)/(value), позволяющая использовать целочисленные адреса для установки значений строковых элементов. [- ] Исправлен сбой в плагине" quest log " от igrik. Версия 3.1.0 (10/2020) ------------------------ [ + ] Обновлен плагин "WOG native dialogs". Добавлена поддержка диалогов IF:B/P и расширенных диалогов IF:Q/IF:N. Реализован расширенный диалог журнала боевых действий. Чтобы открыть его, нажмите "H" или нажмите LMB на панели журнала в бою. Улучшена совместимость с плагинами majaczek. Кредиты: Игрик. [ + ] Обновлен плагин "quest dialog". Обеспечена совместимость с улучшенными диалогами Heroes 3. Кредиты: Игрик. [ + ] Реализована поддержка IF: Q с типом сообщения 7 (MSG_TYPE_CHOOSE_PIC) и выбором 3-х изображений. Результат-1, 2, 3 или 0 для отмены. Вместо этого предпочитайте использовать IF:N для лучшего управления диалогом. [ + ] Реализована расширенная поддержка сложных диалогов в ERM. Титры: Игрик, Берсерк. IF: N (msgType)/^text^[/?результат / (textAlignment)/(preselectedPicId)]. Отображение диалогового окна с возможностью выбора до 8 изображений. msgType - это одна из констант MSG_TYPE_XXX (сообщение, вопрос, всплывающее окно, выбор изображения с дополнительной кнопкой отмены). textAlignment - это битовая маска флагов TEXT_ALIGN_XXX. Поддерживается как вертикальное, так и горизонтальное выравнивание. -1 означает "использовать значение по умолчанию". preselectedPicId - это предварительно выбранный индекс изображения: 0-7 или -1 для none результат будет содержать -1 в большинстве случаев (TRUE) или (FALSE) для вопросов, 0-7 (индекс изображения) для выбора изображения и -1 для отмененного выбора. Пример: !?FU(OnAfterErmInstructions); !!ЕСЛИ: N (PIC_TYPE_SPELL)/(SPELL_TOWN_PORTAL)/(PIC_TYPE_RES_GOLD)/300/ (PIC_TYPE_RES_WOOD) / 5/(PIC_TYPE_RES_MERCURY) / 10/(PIC_TYPE_RES_ORE) / 15/ (PIC_TYPE_RES_SULFUR) / 20/(PIC_TYPE_RES_CRYSTAL) / 25/(PIC_TYPE_MONEY) / 5000; !!Если: N (MSG_TYPE_CHOOSE_PIC_OR_CANCEL) / ^бери все, что тебе нужно, братан!^/?(chosenItem:y)/(TEXT_ALIGN_LEFT); !!Если:M^%(chosenItem)^; [ + ] Диалоги IF:N и IF:Q с картинками теперь поддерживают специальный флаг типа изображения: (PIC_TYPE_FLAG_DISPLAY_ZEROS). Если он установлен, нулевые количества (ресурсы, монстры, опыт и т. д.) будут отображаться как "0 Архангелов" вместо "Архангелов" или пустой подписи. Пример: !!VR(picType:y): S(PIC_TYPE_EXPERIENCE) |(PIC_TYPE_FLAG_DISPLAY_ZEROS); !!VR(picSubtype:y):S0; !!Если: Q2/(picType)/(picSubtype)/(MSG_TYPE_QUESTION) / ^ничего не хотите?^; [ + ] Обновленные константы модов" Era Erm Framework": типы данных, флаги и опции wog, константы городов, лимиты игр, магические уровни, боевые действия, слоты артефактов героев, идентификаторы диалогов, типы изображений, выравнивание текста и многое другое. [ + ] Добавлен файл " 9999 era-key codes.erm "до" Era Erm Framework " с более чем 150 ключевыми кодами констант. [+] Добавлено событие" OnAfterErmInited " в "Era Erm Framework", происходящее прямо в конце !?Pi / событие "OnAfterErmInstructions". Событие позволяет выполнять действия после того, как большинство скриптов инициализировали свои переменные и выполнили базовую конфигурацию карты/памяти. [+] Добавлены новые события в "Era Erm Framework": "OnKeyPressed_AdvMap", "OnKeyPressed_Battle", " OnKeyPressed_HeroScreen", "OnKeyPressed_HeroMeetingScreen", "OnKeyPressed_Town", происходящие сразу после событий "OnKeyPressed" и принимающие два аргумента: x1-код ключа x2-предотвращение реакции по умолчанию (0 - Нет, 1 - да). Пример: !?FU(OnKeyPressed_Battle)&x1=(KEY_F1):; !#VA (ключ:x) (preventDefault:x); !!VR(preventDefault):S (TRUE); !!Если: M^нажал F1 в бою!^; [+] SN: F теперь поддерживает 'user32.функции dll. [ + ] Добавлены новые функции в "Era Erm Framework". !?FU(Array_SortedUnique); ; Оставляет в массиве только уникальные отсортированные целочисленные элементы. ; Призывая к [15, 4, 3, 3, 1, 20, 15] список будет переставлять и усекать список следующим образом: ; [1, 3, 4, 15, 20] !#VA (список: x); идентификатор массива !?FU(Array_EnsureMinSize); ; Проверяет, имеет ли массив хотя бы заданный минимальный размер, и увеличивает размер, если нет, заполняя его новыми элементами ; с необязательным значением по умолчанию. !#VA (список: x); идентификатор массива. !#VA (minSize:x); минимальный желаемый размер массива. !#VA (fillValue:x); необязательно. Заполните значение для новых элементов. По умолчанию: ^^ или 0. !?Фу (конструктивная Маска); ; Принимает до 15 битных/флаговых позиций (0..31). Возвращает маску с соответствующими битовыми флагами. ; На самом деле, учитывая аргументы Xi, возвращает Sum(2 ^ xi). ; Например, P0/3/7/- что?(маска: y) даст 2 ^ 0 + 2 ^ 3 + 2 ^ 7 = 1 + 8 + 128 = 137. !#VA(args:x);... До 15 позиций бит/флаг. !#VA (result:x); последний аргумент будет содержать маску результата. !?FU (DeconstructBitMask); ; Деконструирует битовую маску в список позиций бита / флага (каждая с 0..31 значение). ; Например, P137/(list) заполнит список значениями [0, 3, 7], потому что ; 2 ^ 0 + 2 ^ 3 + 2 ^ 7 = 1 + 8 + 128 = 137. Это означает, что установлены биты 0, 3 и 7. !#VA (mask:x); битовая маска. !#VA (list:x); идентификатор массива для заполнения позициями битов/флагов. !?FU (MonCountToFuzzyText); ; Преобразует количество монстров в читаемый человеком диапазон значений, например "50-99" или "2K+". ; Возвращает результат в s^result^ !#VA(monNum:x); !?FU(DisableErrors); ; Отключает сообщения об ошибках ERM и сбрасывает опцию error. !?FU(EnableErrors); ; Включает сообщения об ошибках ERM и возвращает последний флаг ошибки (TRUE или FALSE). !#VA (результат: x); !?Фу (StrToUpper); ; Преобразует заданную строку в верхний регистр. Результат возвращается в формате s^result^. !#VA(strPtr:x); !?Фу (StrToLower); ; Преобразует заданную строку в нижний регистр. Результат возвращается в формате s^result^. !#VA(strPtr:x); !?Фу (GetStrAtAddr); ; Считывает нулевую завершенную строку по указанному адресу в переменную s^result^. ; Нулевой адрес (0) приводит к пустой строке. !#VA(strAddr:x); [ + ] Добавлена экспортированная функция Era ShowErmError (Error: pchar); stdcall; Эта функция показывает обычный диалог ERM error и может использоваться для отчетов об ошибках ERM-скриптов и отладки. Пример: !!if|(baseFaction)<(NO_TOWN)/(baseFaction)>(MIX_MAX_POSSIBLE_FACTION_ID):; !!SN:F^ShowErmError^ / ^недопустимый аргумент "baseFaction": %(baseFaction)^; !!FU:E; !!en; [ + ] Добавлена возможность продления срока службы триггерного локального массива SN:M до родительской области. Теперь можно вернуться триггер-локальные массивы для вызывающей функции без необходимости освобождать этот массив впоследствии. Таким образом, автоматическая память управление сохранено. Пример: ; Функция глубокого уровня возвращает триггер-локальный массив из 3 строк другой функции, которая в своем случае возвращает тот же массив ; к триггеру" OnAfterErmInstructions". Массив будет освобожден после завершения блока выполнения "OnAfterErmInstructions". !?FU(FuncB); !#VA (результат: x); !!SN:M(M_AUTO_ID) / 3/(M_STR)/(M_TRIGGER_LOCAL)/?(результат); !!SN:V (результат)/0 / ^один^ / ^два^ / ^три^; !!SN:F^ExtendArrayLifetime^/(результат); !?Фу (Функа); !#VA (результат: x); !!FU (FuncB):P?(результат); !!SN:F^ExtendArrayLifetime^/(результат); !?(OnAfterErmInstructions); !!Фу (Функа): П?(arr:y); !!FU (Array_Join):P (arr) / ^ ^; !!IF: M^%s (результат)^; Display " one two three" !?(OnAfterErmInstructions); ; здесь массив (arr) уже удален [ + ] Добавлена поддержка локальных z-строк в качестве параметров функции. Они будут преобразованы во временные индексы z-переменных, доступные только для чтения. Пример: !!VR(str:z): S^хорошего вам дня!^; !!FU (StrToUpper): P (str); здесь z-1 будет преобразован во что-то вроде "10000002", что является индексом z10000002 !!IF: M^%s (result)^; Display "HAVE a NICE DAY!" [+] Добавлена возможность определения постоянных псевдонимов ERM 2. Пример: !#DC(PIC_TYPE_RES_FIRST) = (PIC_TYPE_RES_WOOD); !#DC(PIC_TYPE_RES_LAST) = (PIC_TYPE_RES_MITHRIL); Теперь (PIC_TYPE_RES_FIRST) будет иметь то же значение, что и константа (PIC_TYPE_RES_WOOD). [ + ] Добавлена возможность использовать константы в объявлениях локальных массивов. Ранее размер массива мог быть только числом. Теперь можно указать имя константы вместо числа без скобок. Пример: !#DC (MAX_DWELLING_ALT_CREATURES) = 4; !#VA(dwellingMonTypes[MAX_DWELLING_ALT_CREATURES]: y); определить массив из 4 элементов для хранения типов жилых монстров [+] Добавлена поддержка электронных переменных в VR: C. !!VR(поплавки[3]: e): C0 / 0 / 0; Не забывайте, что в VR:C преобразование integer-float не выполняется, все значения копируются как есть. Единственная безопасная константа для e-переменных - 0. [ + ] Улучшено TR:T, чтобы разрешить любое количество аргументов. [ + ] Улучшена команда UN: U. Он не вызывает ошибки, если больше не найдено никаких объектов, но вместо этого устанавливает координату x в значение -1. Таким образом нет преждевременных требуется подсчет объектов. Был добавлен новый синтаксис с 6 параметрами, позволяющий использовать произвольные целочисленные переменные вместо v-переменных. !!UN: U(objectType)/(objectSubtype)/(направление типа -1/-2 или индекс объекта)/(x)/(y)/(z). Пример: ; Давайте пройдем через всех монстров карты, удваивая их количество !#VA(x:y) (y:y) (z: y); определение переменных для хранения координат объекта !!VR (x):S-1; Установка координаты x на -1 заставит начать поиск с нуля !!re i; бесконечный цикл !!UN:U (OBJ_MONSTER)/(ANY_OBJ)/-1/(x) / (y)/(z); найти следующего монстра, (x) = -1 при сбое !!br&(x) !!MO (x)/(y)/(z): Gd*2; двойное количество монстров !!en:; [ + ] Улучшена функция Heroes 3 "DisplayComplexDialog" (4F7D20). Последний аргумент "closeTimeoutMsec "был перегружен на"Opts". ОПТС это: 16 бит для closeTimeoutMsec, 4 бита для msgType (1-ok, 2 - question, 4 - popup и т. д.), // 0 обрабатывается как 1. 4 бита для выравнивания текста битовая маска (0..15), 8 бит для внутреннего использования H3, обычно 0 Таким образом, стало возможным отображать диалоги до 8 изображений и любого типа (сообщение, вопрос, всплывающее окно, выбор изображения). [+] Добавлена экспортированная функция FindNextObject (ObjType, ObjSubtype: integer; var x, y, z: integer; Direction: integer): integer; stdcall; Он работает так же, как UN:U с синтаксисом быстрого поиска, но не вызывает ошибки при отсутствии других объектов, возвращает флаг успеха и позволяет использовать переменные, отличные от v, для хранения координат. Вам больше не нужно будет считать предметы, прежде чем искать их. Направление -1 для прямого и -2 для обратного. Пример: - Давайте пройдем через всех картографических монстров, удвоив их количество !#VA(x: y) (y:y) (z:y); определение переменных для хранения координат объекта !!VR(x): S-1; Установка X-координаты на -1 заставит начать поиск с нуля !!re i; бесконечный цикл !!SN: F^FindNextObject^ / (OBJ_MONSTER)/(ANY_OBJ)/?(x)/?(y)/?(z)/-1; найти следующего монстра, v1 (TRUE) на успехе !!br&v1=(FALSE):; завершите цикл, если ничего не найдено !!MO (x) / (y)/(z): Gd*2; двойное количество монстров !!en:; [ * ] Локальные именованные e-переменные выделяются из индекса 2, чтобы сохранить e1 для результата функций. [ * ] теперь x16 можно выделить как локальную именованную переменную. Ранее следующий код приводил бы к ошибке: !!VA(args[16]: x); [ * ] SN:G устарел и может быть удален в будущих версиях. [- ] Исправлено SN: O. больше не прячется лодка/герой. [- ] Исправлен приемник HE для поддержки любой переменной ERM, как !!HEi^heroId^. [- ] Исправлена проверка индексов VR:C, позволяющая переопределять защищенную память командами типа VRy-99:C1 / 2 / 3; [- ] Исправлена часть компилятора ERM 2, ответственная за распределение локальных индексов z-массивов. Ранее !#VA (имена[3]:z) используется для выделения массива [z-3, z-4, z-5] (убывающие индексы). Теперь соответствующий массив будет иметь вид [z-5, z-4, z-3] (Увеличение индексов). Таким образом, можно использовать безопасно индексировать арифметику, как: !#VA (имена[3]: z); !!VR(имена[2]): S^хорошего дня!^; !!VRi:S2; i-логический индекс элемента массива !!VR (itemPtr:y): S (@array) +i; itemPtr содержит реальный Z-индекс элемента массива !!IF: M^%z (itemPtr)^; отображение I-го значения элемента [- ] Исправлено UN: C. Он не принимал аргумент отрицательного размера, в то время как -1, -2 и -4 являются допустимыми размерами. Предпочитайте использовать константы (UNC_XXX) для указания допустимого типа данных. [- ] Исправлено переполнение опыта существ после битвы. Кредиты: Игрик. [- ] Исправлена проверка мультиплеера в диалоге выбора типа атаки, приводящая к ошибкам "Эта функция не работает в сообщении Human vs Human network baced battle". [-] Удалены остальные файлы из мода" анимированные деревья". Кредиты: Archer30. [!] Обратите внимание, что SN:O не работает с глобальными именованными переменными. [!] Обратите внимание, что v1 не должен использоваться для хранения чего-либо вневременного, потому что из эпохи 2.X он меняется при каждом вызове SN:E/SN: F. Это грязная переменная для быстрого возврата результата. Вместо этого используйте v2/v3/v4. Версия 3.0.5 (09/2020) ------------------------ [ + ] Обновлен плагин "WOG native dialogs". Все локализованные строки были перемещены в файл json. Добавлена возможность настройки шрифтов, используемых в различных диалогах. Кредиты: Игрик. [ + ] Обновлено " исправление скелета трансформатора.бин " патч. Адская Гидра превращается в костяного Дракона. Возвращена оригинальная трансформация для мумий. Кредиты: Бес. [+] SN: V теперь поддерживает отрицательные индексы, то есть n-й от конца, такой же, как SN: M. [+] Добавлена возможность запроса информации о массивах SN:M. !!SN:M#1/(?)$2/(?)$3/?($4)[/?$5]; #1-идентификатор массива $2-количество предметов $3 - Тип элементов (0-целые числа, 1-строки) $4-тип хранения элементов (-1-триггер локальный, 0-временный, 1 - с сохраненным содержимым savegame) $5-небезопасный временный адрес первого элемента массива в памяти По крайней мере, сингл № 2..# 4 параметр должен использовать синтаксис GET. В этом случае параметры SET-синтаксиса игнорируются. Пример: !!SN:M (массив)/d/?(itemsType: y) / d; проверьте, является ли это массивом целых чисел или строк !!if&(itemsType)=(M_INT):;... [+] Добавлены новые константы в мод "Era Erm Framework" : - Константы TOWN_XXX для каждого типа города в игре. - Константы CALLCONV_XXX для возможных соглашений о вызовах SN:E. - Константы BATTLE_XXX для боевых сторон и ограничений стека. - FLOAT_INF и FLOAT_NEG_INF, представляющие значения бесконечности для чисел с плавающей запятой. Использование: !!VR(inf:e):C (FLOAT_INF); назначить положительную бесконечность переменной (inf) без преобразования типа !!Если&(someValue)=(inf): значение M^Слишком большое^; Проверьте некоторый e-var на положительную бесконечность [ + ] Расширенный oneveryday триггер в моде "Era Erm Framework". Автоматически устанавливаются следующие глобальные переменные: - I^timerDay^: 1..+бесконечность - I^timerWeekDay^: 1..7 - i^timerMonthDay^: 1..28 - i ^ timerWeek^: 1..+бесконечность - i^timermontweek^: 1..4 - я ^ тимермонт^: 1..+бесконечность - я ^ timerOnce^: 0..1 - i ^ timerOwner^: 0..7 - я ^ тимерисай^: 0..1 - я ^ тимеришуман^: 0..1 [ + ] Добавлены математические функции в мод "Era Erm Framework". !?Фу(Пау); ; Повышает значение до заданной мощности. Все аргументы и результат являются поплавками. ; Пример: 2^3 = 8, т. е. 2 * 2 * 2 = 8 !#VA(база: x) (мощность:x) (результат:x); !?Фу (Sqrt); ; Возвращает значение квадратного корня. Все аргументы и результат являются поплавками. !#VA(значение: x) (результат: x); !?FU(IntLog2); ; Возвращает Ceil(Log2 (N)) или 0 для недопустимых значений ( Примеры: !!FU (IntLog2):P100/?(res: y); !!IF: M^%(res)^; отображает 7, потому что 2^7 = 128 и 2^6 = 64 Это означает, что для хранения данных со 100 возможными значениями необходимо 7 бит. ; Это также означает, что если одно значение в 100 раз больше другого, то ; потребовалось бы 7 умножений на 2, прежде чем второе значение стало бы >= первым. !!VR(база: e): S123: 10; база = 12,3 !!VR (мощность: e): S35: 10; мощность = 3,5 !!FU (Pow):P (база)/(мощность)/?(поплавок: e); !!IF: M^%(float)^; 12.3 ^ 3.5 = 6526.31287 !!VR (значение: e): S123 :10; !!FU (Sqrt): P (value)/?(поплавок: e); !!Если: M^%(float)^; 12.3 ^ 0.5 = 3.507. То есть 3,507 * 3,507 = 12,3 [+] Добавлены функции для обработки массивов SN: M в моде" Era Erm Framework". !?FU(Array_Join); ; Объединяет элементы массива в единую строку, используя переданную строку клея. Работает как с числовыми, так и со строковыми массивами. Пример: ["один", "два", "три"] с клеем "- - - "станьте" один --- два --- три". ; Возвращает s^result^ ; Использует s^ _ ^ !#VA (список:x); идентификатор массива. !#VA(gluePtr:x); опционально. Клеевой шнур. По умолчанию: ''. Пример: ; Создать список с именами первых 10 героев !!SN:M(M_AUTO_ID) / 10/(M_STR)/(M_TRIGGER_LOCAL)/?(имена: y); !!ре я/0/10/1/-1:; !!Вуз:B0/?(heroName: z); !!SN:V (имена) / i/(heroName); !!en:; ; Отображение присоединенных элементов списка !!FU (Join):P (имена) / ^ ^; !!VR (textPtr:y): Zs^результат^; !!IF: M^%z (textPtr)^; !?FU(Array_Sort); ; Сортирует элементы массива в порядке возрастания. Позволяет сортировать определенный поддиапазон массива. !#VA (список:x); идентификатор массива. !#VA (startInd:x); необязательный начальный индекс поддиапазона массива для сортировки. По умолчанию: 0. !#VA (endInd:x); необязательный конечный индекс поддиапазона массива для сортировки. По умолчанию: numItems-1. Пример: ; Пусть переменная (names) содержит идентификатор массива SN:M с именами героев (см. пример с функцией Join) !!FU (Array_Sort): P (имена); будет сортировать его !?FU(Array_CustomSort); ; Сортирует элементы массива в порядке возрастания пользовательская функция компаратора. Позволяет сортировать определенный поддиапазон массива. ; С помощью этого метода можно выполнить любую сложную сортировку в любом направлении и по неограниченному количеству критериев. Это стабильный метод сортировки, то есть элементы, о которых мы сообщим как о равных, сохранят свое относительное положение друг относительно друга. Например, если отсортировать "Энн", "Дэвид" и " Кен "по длине имени, то результатом будет "Энн", "Кен", "Дэвид", а не "Кен", "Энн", "Дэвид". ; При сортировке массива строк функция компаратора будет получать z-индексы строк в качестве аргументов. !#VA (список:x); идентификатор массива. !#VA (compareFunc:x); идентификатор функции сравнения ERM. Он будет вызван несколько раз со следующими аргументами: ; (value1, value2, state), где 'state' - это любое пользовательское значение, которое вы указываете при вызове Array_CustomSort. ; Обычно состояние - это некоторый идентификатор массива или адрес внешней структуры, который клиент использует для сравнения элементов. ; ; Функция должна возвращать значение: ; ; > 0, если value1-item должен быть помещен после value2-item ; 0 если заказ между двумя пунктами должен быть оставлен как есть. !#VA(состояние: x); необязательно. Пользовательское значение, которое всегда передается функции сравнения в качестве третьего аргумента. По умолчанию: 0. !#VA (startInd:x); необязательно. Запустите индекс поддиапазона массива для сортировки. По умолчанию: 0. !#VA(endInd:x); необязательно. Конечный индекс поддиапазона массива для сортировки. По умолчанию: numItems-1. Пример 1. Сортировка массива идентификаторов монстров ПО HP каждого монстра !!SN:M(M_AUTO_ID) / 10/(M_INT)/(M_TRIGGER_LOCAL)/?(Монс:y); !!SN:V(Монс)/0/39/12/20/92/78/17/13/43/6/32; !!FU(Array_CustomSort):P (mons)/(tst_CompareByMonHp); !!FU (Array_Join):P (mons) / ^ ^; !!IF: M^Monster IDs: %s (результат)^; !?FU(tst_CompareByMonHp); !#VA(mon1:x) (mon2:x) (состояние:x) (результат:x); !!VR (результат): S0; !!MA:P (mon1)/?(hp1:y); !!MA:P (mon2)/?(hp2: y); !!если&(hp1)>(hp2):; !!VR (результат): S1; !!el&(hp1)):; !!ВР (результат): с-1; !!en; Пример 2. Сортировка имен посетителей по длине имени !!SN:M (M_AUTO_ID) / 4/(M_STR)/(M_TRIGGER_LOCAL)/?(посетители: y); !!SN:V (посетители) / 0/^Лаура^/^Ден^/^Агриэль^/^Кен^; !!FU (Array_CustomSort): P (посетители)/(tst_CompareByStrLen); !!FU (Array_Join):P (посетители) / ^ ^; !!Если: M^посетители: %s (результат)^; !?Фу(tst_CompareByStrLen); !#VA (str1Ptr:x) (str2Ptr:x) (состояние: x) (результат:x); !!VRz (str1Ptr): M4/?(str1Len:y); !!VRz (str2Ptr): M4/?(str2Len:y); !!VR(result):S(str1Len) -(str2Len); !?FU(Array_Revert); ; Изменяет порядок ИТМ в массиве. Позволяет только изменить порядок конкретного поддиапазона массива. !#VA (список: x); идентификатор массива. !#VA (startInd:x); необязательный начальный индекс поддиапазона массива. По умолчанию: 0. !#VA (endInd:x); необязательный конечный индекс поддиапазона массива. По умолчанию: numItems-1. Пример: ; Пусть переменная (names) содержит идентификатор массива SN:M с именами героев (см. пример с функцией Join) !!FU (Array_Revert): P (имена); вернет порядок элементов !?FU(Array_Fill); ; Заполняет массив или поддиапазон массивов с увеличением / уменьшением значений. ; Пример: FU (Array_Fill): P(array)/100/2; заполнит элементы 100, 102, 104, 106... !#VA (список:x); идентификатор массива. !#VA (startValue:x); начальное значение для заполнения. !#VA (шаг:x); значение, которое нужно добавить, чтобы увеличить наполнитель на каждом шаге. По умолчанию: 0. !#VA (startInd:x); необязательно. Начальный индекс поддиапазона массива. По умолчанию: 0. !#VA(endInd:x); необязательно. Конечный индекс поддиапазона массива. По умолчанию: numItems-1. Пример: ; Let (array) - это некоторый массив целых чисел. Давайте наполним его 100, 98, 96... !!FU(Array_Fill):P (array) / 100 / -2; [ * ] Создание массива с использованием SN:M с 5 параметрами больше не изменяет v1. [ * ] Извлек все поставляемые Era ERM скрипты в мод" Era Erm Framework". [ * ] Извлечен код тестирования ERM в отдельный мод "Era Erm Tests". [ * ] Обновлены фрагменты редактора ERM и файлы автозаполнения. Добавлены быстрые фрагменты "ifm", " ifl " и "snm". [-] Примененные исправления к константам ERM (Era Erm Framework mod): Исправлено постоянное имя: MON_SUPREMEARCHANGEL => MON_SUPREME_ARCHANGEL. Исправлена константа MON_LAST_WOG => 196 вместо 197. Кредиты: Игрик. Исправлены константы первичных навыков. Кредиты: Алгор. [- ] Исправлена ошибка включения !Использование синтаксиса #VA (- varName). [- ] Исправлена генерация дампа памяти ERM: отчеты о слотах используются для хранения информации о зарезервированных элементах. [- ] Исправлена отчетность по x-переменным в модуле отслеживания ERM. Ранее значение мусора x0 выводилось как первое. [- ] Исправлено имя портрета Нагаша в исполняемых файлах редактора игр и карт. Больше никаких " пропавших без вести hpsz001.pcx " ошибка. Версия 3.0.4 (09/2020) ------------------------ [+] Расширенные лимиты доходов города с -32768..От 32767 до -2147483648..+2147483648 и добавлено новое событие OnCalculateTownIncome с тремя параметрами: идентификатор города, доход (сумма золота), бункер ресурсов счета? (0 или 1). [ + ] Введено расширено !!re синтаксис: !!re counter/start/stop/step/stop_modifier, где stop_modifier - это любое целое значение, это будет добавлено к значению остановки. Новый синтаксис позволяет выражать такие циклы, как, например, от 0 до SOME_VAR - 1. Пример: !!re i/0/(numStacks)/1/-1:; ... !!en:; [+] !!re теперь позволяет использовать любые переменные, включая глобальные именованные переменные s/I. [ + ] Улучшена стабильность ERM. Теперь все неуказанные параметры обрабатываются как 0 в синтаксисе X# и игнорируются в синтаксисе X$. В результате, !!Дл:а без 4-го параметра больше не будет случайных сбоев и !!TR может использоваться с любым количеством параметров, в то время как ранее требовалось ровно 8. Обратите внимание, что многие команды ERM все еще требуют точного количества обязательных параметров. [+] !!DL: A был улучшен, принимая любую строку, включая строковый литерал, в качестве 3-d параметра. [ + ] Включен обновленный плагин "WOG native dialogs" от igrik. Отныне Плагины экспортируют функцию _ _ cdecl int UseWin32InputControl (int newState). Функция позволяет переключаться между Heroes 3 native input control и Windows input control. Последний позволяет вводить азиатские и ' { ' ,'} ' символы. Режим можно переключить в любое время даже используя ERM. UseWin32InputControl возвращает предыдущее состояние. [ * ] Полностью восстановлены оригинальные портреты Нагаша и Джеддитов, описания и специальности. [*] Изменена генерация отчета об ошибках ERM: создается не только дамп памяти ERM, но и сохраняется вся отладочная информация, например если нажать клавишу F11 вручную. [- ] Исправлена ошибка WoG, запрещающая дважды устанавливать диалоговые подсказки с помощью команды DL: H. Кредиты: gamecreator. [-] Исправлена ошибка в движке кэширования ERM: GET-синтаксис мог выдавать мусорные значения при попадании в кэш. [-] Исправлена ошибка в движке ERM, приводившая к сбоям в работе !!UR: S и еще несколько возможных команд. [-] Исправлена ошибка: IF: N$ использовался для создания ошибок ERM и сбоев. Титры: хельгтла. [- ] Исправлена ошибка: HE: P возвращал unsigned 65535 вместо signed -1. [- ] Исправлена ошибка: компилятор ERM не обрабатывал пост-триггеры. [- ] Исправлена ошибка, из-за которой многие команды Era возвращали мусор после допустимого содержимого строки. Кредиты: Перрир. [- ] Исправлен редактор карт = > WOG tools меню ярлыков для реальных программ. Кредиты: Archer30. Версия 3.0.3 (07/2020) ------------------------ [ + ] Добавлена команда SN:H^art^ / art ID / 0 (name) или 1 (description)/$text позволяет получить / задать любое имя/описание артефакта без зависимости от z-переменных. [ + ] Парсер ERS-файлов был переписан заново. Нет больше ошибок H3, вызванных ограничением длины пути 12 символов. Любое имя файла ers, например " какой-нибудь скрипт loooooong.Эрс " поддерживается. [+] Добавлено событие OnBeforeBattleStackTurn. Это происходит прямо перед событием OnBattleRegenerationPhase. Параметры: идентификатор стека (0..41). Измените первый параметр, чтобы дать очередь другому стеку. Обратите внимание, что подобное событие OnBattleStackObtainsTurn происходит, когда стек становится активным и вообще не связано с фазой регенерации. Обычно OnBattleStackObtainsTurn возникает после OnBattleRegenerationPhase но также может быть вызван вручную вызовом 464F10 (THISCALL, ecx = CombatManager, сторона 0..1, StackInd 0..20). [-] HE:P без 4-го параметра теперь работает как в WoG 3.58 f по соображениям совместимости. Если герой принадлежит текущему игроку, воспроизводится звук телепорта и перерисовывается экран. В противном случае телепортация проходит бесшумно без визуального обновления. [- ] Исправлена ошибка: каждая перезагрузка уменьшала длину строк ERT на единицу. Титры: Арнованклер. [-] В том числе отсутствует ztower1.def в hmm35wog.Пак. Титры: Арнованклер. [- ] Исправлено недопустимое значение боя волшебницы в zcrtraits.формат txt. Кредиты: Archer30. [-] ztport01.def monolith больше не будет использоваться на случайных картах (удалено из zaobjts.формат txt). [*] Если: N исправление было улучшено. Кредиты: Игрик. [ * ] Экспортированные Era функции с логическими результатами теперь возвращают int32 0 или 1 (ранее 0 или -1). Версия 3.0.2 (06/2020) ------------------------ [+] Добавлено новое событие ERM 'OnAdvMapTileHint', позволяющее получить / установить подсказку для любой плитки, мышь в данный момент закончена. Параметры: x, y, z, тип объекта, подтип объекта. Пример: !?FU (OnAdvMapTileHint); отображение координат плитки и исходной подсказки !#VA(x:x) (y:x) (z: x) (objType: x) (objSubtype:x); !!ММ: М?(existingHint:z); !!MM: M^%(x) %(y) %(z) %(objType) %(objSubtype): %(existingHint)^; [+] Добавлена поддержка %Vf..синтаксис t в интерполированных строках, который присутствовал в WoG 3.58. [ + ] Восстановлено коротко !!Поддержка синтаксиса HE: X6 и исправлена ошибка ERM HE: X7: короткий синтаксис работал как X7 / a/d/0/0/0/0 вместо X7 / 0 / a / d/0/0/0-да. [ + ] Обновлено VFS.dll до версии 1.0.5. [- ] Исправлена ошибка в "era-testlib.ЭМ": !?FU (et_expectror) не восстановил опцию подавления ошибок. Версия 3.0.1 (06/2020) ------------------------ [ + ] Добавлены первые тесты ERA ERM. Библиотека тестов в "Tests / 1000 era-testlib.ЭМ" и тесты, покрывающие найденное баги и часть нового функционала в "тестах / era-тестах.э". [ + ] Добавлены новые 3 магические константы. Все они безопасны для использования внутри строк и в качестве параметров: (Файл) расширяется до текущего имени файла скрипта. (Строка) расширяется до текущего номера строки в файле скрипта. (Код) расширяется до фрагмента исходного кода экранированной текущей строки. Эти константы особенно полезны для отладки, сообщения об ошибках и автоматизированных тестов. Видеть - Тесты / эра-тесты.ЭМ " для примера. [+] Добавлены новые константы: TRUE, FALSE, SN_M_* (для параметров SN:M). [+] Добавлены новые escape-последовательности для строковых литералов (^...^): '% \ : 'расширяется в'; '(обычно запрещенный символ для литералов, маркирующий приемный конец). '%\"'расширяется в' ^ ' (обычно запрещенный символ для литералов, отмечающий конец литерала). '%%'расширяется до' % ' (используется для предотвращения возможной интерполяции переменной, %%y5 => %y5, а не значение y5). [+] !!Приемники FU / DO теперь действительно могут быть вызваны без аргументов. Для всех приемников WoG 3.58 ERM кроме SN / MP вызывающей подкоманды без параметров фактически проходит один параметр со значением 0. Пример: !!См:R; это то же самое, что !!См:R0; Это не подходит для функций, которые могут полагаться на подсчет аргументов для реализации значений параметров по умолчанию и опционные параметры. С этого момента !!FU: P; не передает никаких параметров и !!FU:P6; передает один параметр. [!] Макросы ERM старого стиля ($...$ ) устарели, хотя и улучшены и полностью работают. Обратите внимание, что имена макросов не очищаются до тех пор, пока игровой процесс не будет перезапущен, поэтому предпочитайте не использовать их вообще. [*] !!SN: U был переименован в !!SN:V (вектор). [+] !!СН: м был значительно улучшен. Отрицательные индексы позволяют получить доступ к элементам из конца массива. -1-последний элемент -2-предпоследний и т. д. Это стало легко получить доступ к списку хвоста, как !!SN:M (arrayId)/-1 / ^новое значение^; SN: M изменение размера массивов было улучшено таким образом, что теперь они могут использоваться в качестве списков без снижения производительности. Память распределяется блоками, растущими экспоненциально, поэтому большую часть времени выделение действительно не выполняется, просто вспоминая новое количество предметов. Примеры: ; Создайте новый список из 3 элементов, хранящихся в сохраненных играх. Поместите его идентификатор в глобальную переменную i^heroNames^. !!SN:M (SN_M_AUTO_ID) / 3/(SN_M_STR)/(SN_M_STORED)/?i^heroNames^; ; Установите значения всех элементов сразу !!SN: Vi^heroNames^ / 0 / ^Corwin^ / ^Deo^ / ^Bers^; - Погоди, забыл про "саламандру", добавь и его тоже !!SN: Mi^heroNames^ / d1; увеличен размер списка на 1 !!SN: Mi^heroNames^ / -1 / ^Salamandre^; и написан новый пункт до конца [ + ] Обновлен редактор ERM, основанный на Sublime Text. [!] !!FU: C устарел и больше не поддерживается. Он может быть использован повторно в будущем. [ * ] ErmLegacySupport по умолчанию установлен в 0 в heroes3.ini. Он был введен для старых сценариев, опираясь на отрицательные y-Вары автоматически обнуляются. [ + ] Все X-параметры функции, которые не были переданы, теперь инициализируются нулями. Это поведение подходит для необязательный аргумент. Просто не передавайте странные аргументы !!ФУ:П/!!DO: P / etc, и они будут иметь значение 0. [ + ] Добавлен новый синтаксис !!Фу: приказ. Установите значения по умолчанию для параметров. !!FU: A#1 / [#2.../#3...]; #1-значение по умолчанию для первого параметра (x1) #2-значение по умолчанию для второго параметра... Команда изменяет значения только в том случае, если они не указаны во время вызова функции. Пример: ; Найти объект с заданным типом и подтипом !?FU(acl_FindObj); ; Объявить два необязательных параметра !#VA / (objType:x) (objSubtype:x); ; Укажите значение по умолчанию -1 для обоих параметров !!FU:A (NO_OBJ)/(NO_OBJ); ... Еще один пример со строковыми параметрами. "Ptr" означает "указатель", индекс z-переменной. !?FU(acl_ShowMessage); !#VA / (messagePtr); !!FU:A?(numArgs:y); получить количество переданных аргументов !!VR (message: z): S^OK^; настройка текста сообщения по умолчанию !!VR (message)&(numArgs)>=(@messagePtr): Sz (messagePtr); переопределить текст сообщения с предоставленным значением, если оно передано !!IF: M^%(message)^; отображение сообщения Последняя строка работает, потому что @messagePtr для первого аргумента (x1) вернет 1. Это удобный способ проверить, был ли передан тот или иной параметр. [ + ] Предлагается оформлять объявления функций в следующих вариантах: ; Bried описание функции, как: ; Скрывает прямоугольную область на карте. !?FU(es_HideMapSquare); !#VA(x1:x) (y1:x) (x2:x) (y2: x) (level: x); быстрое объявление всех параметров без описания ; Альтернативная декларация с объясненными аргументами: !?FU(es_HideMapSquare); !#VA(x1:x); верхняя левая координата x !#VA(y1:x); верхняя левая координата y !#VA(x2:x); нижняя правая координата x !#VA(y2:x); нижняя правая координата y Помните, что все в порядке !#VA перед закрытием '; ' и кроме (variableName) просто удаляется из скомпилированного кода. Для функций с необязательными аргументами предлагается отделять необязательные аргументы от обязательных с помощью'/'. ; Добавляет стек монстров в армию героев. Количество по умолчанию - 1. !?FU(es_AddMonster); !#VA (hero:x) (monType:x) / (monNum:x); !!FU:A0 / 0 / 1; укажите значения аргументов по умолчанию !!Он (герой): C2 / (monType)/(monNum) / 1; Альтернативно, опциональность аргумента может быть указана в его описании. !?FU(es_AddMonster); !#VA (hero:x); идентификатор героя !#VA (monType:x); тип монстра !#VA (monNum:x); необязательно. По умолчанию: 1 [-] Добавлено недостающее 1000 era-const.erm и 1000 era-stdlib.файлы erm для WOG mod. [- ] Исправлена ошибка: z-переменные с недопустимыми отрицательными индексами считались изменчивыми. Кредиты: gamemaster. [- ] Неизвестные имена макросов $...$ теперь сообщаются как ошибки, как это было в эпоху 2.икс. [- ] Исправлена ошибка: ERM должен перестать оценивать параметры кэшированного приемника после первой ошибки. Версия 3.0.0 (06/2020) ------------------------ [ + ] Введен расширенный режим предварительной компиляции ERM, называемый ERM 2.0 и активируемый через сигнатуру первой строки "ZVSE2". Основные признаки: - Именованные локальные переменные для написания удобочитаемого кода вместо зашифрованного. Пример: !!Он-1:C0 / 0/?(monType:y)/?(monNum: y) вместо того, чтобы !!Он-1:C0 / 0/?y23/?y24; - Глобальные именованные константы вместо магических чисел для написания самоописывающегося кода: Пример: !?FU(OnKeyPressed)&x1=(KEY_1) вместо !?FU (OnKeyPressed)&x1=49; Что такое 49??? - Строгое различительное именование функций, локальных переменных и констант. Тут уж ничего не перепутаешь. Пример: thisIsVariable, THIS_IS_CONSTANT, ThisIsFunction и era_ThisIsFunctionAgain. = = = = Названные глобальные константы ==== Константой называется значение, которое определяется один раз и никогда не изменяется. Например, 13 (Тип Архангельского монстра). Константу можно использовать везде, где можно использовать числа. В настоящее время Era поддерживает только целочисленные числа константы, записанные во всех заглавных буквах: (MON_ARCHANGEL), (OBJ_MINE), (PLAYER_RED). Допустимые символы: [A-Z0-9_]. Для определения константы используйте следующую инструкцию !#DC(CONSTANT_NAME) = 777; где 777-произвольное число. Примеры: !#DC (PLAYER_BLUE) = 1; !#DC (SKILL_FIRST_AID) = 27; Чтобы использовать константу, просто напишите ее имя в скобках: !!OW: R (CURRENT_PLAYER) / (RES_GOLD)/d1000; дайте 1000 золотых текущему игроку будет скомпилирован на !!OW: R-1/6/d1000; дайте 1000 золотых текущему игроку --- Называющий --- Авторы сценариев должны использовать уникальный префикс перед постоянными именами, чтобы предотвратить конфликты имен. Любые константы без префикса может быть добавлен в ERA в будущем и сломать ваш скрипт. Пример: ; для mod Battle Heroes давайте использовать префикс "BH_" !#DC (BH_ART_RING_OF_POWER) = 160; !#DC (BH_CLASS_WARRIOR) = 1; !#DC(BH_CLASS_MAGE) = 2; !#DC (BH_CLASS_RANGER) = 3; --- Глобальность --- Константы глобальны. Это означает, что один скрипт может использовать константы другого скрипта. Чтобы убедиться, что ваши константы всегда загружаются раньше других скриптов, размещайте их в скрипте с высоким приоритетом (напр. "1000-Феникс констс.э"). --- Стандартные константы --- ERA предоставляет файл " 1000-era const.erm" со многими предопределенными константами, охватывающими большинство значений, упомянутых в справке ERM. Просмотрите его, прежде чем определить свою собственную константу для вторичного навыка, монстра или цвета игрока. = = = = Именованные локальные переменные ==== Каждый триггер ERM (!?XX перед следующим !?XX) теперь можно объявлять и использовать собственные именованные локальные переменные, выделенные из Х1..x16, y1..y100, z-1..z-10, e1..наборы Е100. Именованные переменные заменяются обычными переменными во время компиляции скриптов и вообще не влияют на производительность. Пример: (день) может быть скомпилирован в y5; --- Называющий --- Имена переменных должны находиться в так называемом" camelCase " и содержать только символы [a-zA-Z0-9]. Они должны быть завернуты в парантезах то же самое, как имена функций обернуты. Пример допустимых переменных: (hero), (monNum), (isAutocombatMode), (specialObject7). --- Декларация --- Переменные должны быть объявлены при первом использовании: т. е. их тип (x, y, z, e, v) и длина массива (для массивов) должны быть указаны. Если вы пишете '[некоторое число]' после имени переменной, переменная станет массивом (последовательностью переменных) с заданной длиной. Если вы пишете ':e ' после имени переменной или длины массива, это будет означать, что тип переменной - "e" (числа с плавающей запятой). Примеры: !!ОН-1: N?(hero:y); дайте некоторое y-переменное имя "hero" и запишите в него текущий идентификатор героя !#VA (arts[4]: y); выделите 4 y-переменные с последовательными индексами и назовите массив " arts" !Инструкция #VA-это псевдокоманда, которая отбрасывается из окончательного скомпилированного кода и может использоваться для хранения объявлений переменных. Пример: !?FU(acm_Sum); ; Функция вычисляет сумму двух чисел !#VA(first: x) (second:x) (result:x); [привязать "first" к x1, "second" к x2, "result" к x3] !!VR (результат): S (первый) +(второй); [вычислить результат] --- Использование --- Допускается указывать один и тот же тип и длину массива для переменных в каждом месте использования переменных, но это не обязательно. После того как вы объявили переменную, больше нет необходимости писать ее тип/длину. Пример: !!ОН-1: N?(герой: y); !!HE (hero): K1; убить героя с идентификатором в переменной (hero). будет скомпилировано примерно так: !!ОН-1: N?y5; !!HEy5:K1; --- Массивы --- Если вам нужна не одна переменная, а последовательность переменных, например для хранения координат объектов [x, y, l] , тогда вам нужен массив. Укажите длину массива в квадратных скобках сразу после имени переменной при объявлении. !#VA(coords[3]: y); выделите 3 y-переменные с именем 'coords' Элементы или элементы массивов имеют нулевую индексацию и могут быть доступны с помощью прямого индекса. Для массива из 3 элементов возможными индексами являются 0, 1, 2. Пример: !!СМ:П?(coords[0])/?(coords[1])/?(coords[2]); будет скомпилировано примерно так: !!СМ:П?y50/?y51/?y52; Если вы не укажете индекс массива, то будет использован первый элемент массива. Это значит, что (тест) и (тест[0]) имеют один и тот же смысл. Регулярными переменными считаются массивы длиной 1. --- Отрицательные индексы массива --- Отрицательный индекс массива означает n-й элемент с конца. -1 будет указывать на последний элемент, -2-на тот, который предшествует последнему, и так далее. Пример: ; выделить массив из 10 y-переменных и присвоить последней значение 2000 !#VA (массив[10]: y); !!VR (массив[-1]): S2000; будет скомпилировано примерно так: ; выделите y1..y10 !!VRy10:S2000; --- Освобождение локальных переменных --- Если вам больше не нужен большой массив переменных, но вы хотите объявить еще один большой массив, то освободите предыдущий. Синтаксис: !#VA (- variableName); забудет об указанном variableName, что позволит повторно использовать индексы, выделенные для этой переменной. Пример: !#VA(myArts[100]: y); выделите y1..y100 для хранения идентификаторов артефактов ...; использовать их !#VA (- myArts); отпустите имя 'myArts' и y1..индексы y100. !#VA(coords[3]: y); выделите y1..y3 как переменная' coords' --- Получение адреса переменной (реальный индекс) --- Часто бывает необходимо получить реальный индекс переменной или даже элемента массива. Если вы хотите вывести "2" вместо y2, используйте оператор адреса'@'. Пример: ; Инициализировать массив с помощью 3 артефактов !#VA (arts[3]: y); !!VR (arts):C (ART_SKULL_HELMET)/(ART_HELM_OF_CHAOS)/(ART_DEAD_MANS_BOOTS); ; Выберите один артефакт случайным образом ; то же самое, что и R0/0/2, генерирует случайное число в 0..2 диапазон и присваивает его переменной artPtr. !!VR (artPtr:y): R0 / (@arts)/(@arts[-1]); ; Дайте артефакт герою !!Он-1:Ай(артптр); будет составлено что-то вроде этого: !!VRy1:C20 / 21 / 56; !!VRy4:R0 / 0 / 2; !!HE-1: Ayy4; Адресный оператор " @ " компилируется в реальный (конечный) индекс переменной. Например, для массива "test[10]: y" сопоставляется с y50..y59 (@test[1]) будет компилироваться до "51". Пример объявления массива из 10 y-переменных и инициализации всех их с помощью параметра -1. !#VA(monTypes[10]: y); !!re i/(@monTypes)/(@monTypes[-1]):; повторите от I = первый индекс массива к i = последний индекс массива !!VRyi:S-1; set -1 для текущего элемента массива !!en:; В других языках программирования переменные, содержащие другие переменные адреса / индексы, обычно называются " указателями" и сокращенно "ptr"или " Ptr". Мы перепишем предыдущий пример с именованной переменной вместо быстрого" i " var просто в учебных целях. !!re (monTypePtr: y)/(@monTypes)/(@monTypes[-1]):; repeat from (monTypePtr) = first array index to (monTypePtr) = last array index !!VRy (monTypePtr): S-1; set -1 для текущего элемента массива !!en:; --- Именование аргументов функции --- Индексы для именованных локальных переменных распределяются, начиная с наименьшего возможного значения. Это означает, что мы можем назвать даже аргументы функции, если объявим их в том же порядке, в каком будут передаваться аргументы. Пример: !?Фу (BH_GetHeroSecSkill); !#VA (hero: x) (skill:x) (result:x); теперь hero = x1, skill = x2, result = x3 !!Он (герой): S (навык)/?(результат); !?FU(...); некоторое событие !!Фу (BH_GetHeroSecSkill)/(HERO_XERON)/(SKILL_FIRST_AID)/?(xeronFirstAidLevel: y); так каков же уровень навыка первой помощи, которым обладает Xeron? ) --- Повторное объявление --- Если вам нужно объявить переменную в обеих ветвях блока if-then, укажите тип/длину в обеих ветвях блока if-then. !!если&(день)>90:; !!VR (цена: y): S (день) *100; ... !!el:; !!VR (цена: y): S (день) *(уровень сложности) +300; ... !!en:; --- Повторное использование того же имени в другом триггере --- Имена переменных являются локальными только для ближайшего триггера. Новый триггер запускается без каких-либо объявленных переменных. Пример: !?FU(OnHeroScreenMouseClick); !!СМ: F?(флаги:y); флаги = y1 !?FU (OnHeroScreenMouseClick); !#VA(flags[23]: e); flags-это массив, привязанный к e1..Е23 --- Интерполяция --- Для замены локальных переменных в строковых литералах используйте синтаксис %(varName). Пример: !!VR (цена: y): S600; !!VR(heroName:z): S^Робин Гуд^; !!Если:Q2 / ^хотели бы вы нанять %(heroName) только за золото %(price)?^; синтаксис %y (varName) также поддерживается и компилируется в нечто вроде %yy5. = = = = Именованные функции ==== Имена функций должны состоять только из символов [A-Za-z0-9_], начинаться с буквы и содержать не менее одна строчная буква (a-z). Существует два разрешенных метода именования: 1) Начните функцию с заглавной буквы. (CalcHeroArmyPower), (ShowUpgradeDialog). ERA оставляет за собой право объявлять функции без префиксов, начиная с "On" для событий. Этот метод не является рекомендуется, из-за возможных коллизий имен в разных модах. Два мода могут объявлять функции будут одни и те же названия и тем самым производить трудные для отладки баги. 2) Запустите функцию с любым уникальным префиксом case с символом'_'. Префикс обычно является аббревиатурой mod. Например, для мод" жилища расширенные " используются следующие функции: !?FU(dex_SetDwellingSlotByTownType); !?FU(dex_dwellingp население); ... --- Генерация новых событий --- Вы можете вызвать функцию, даже если у нее нет обработчиков. Например, в Upgrade All Creatures mod вы хотите, чтобы другие скрипты могли уведомлять, какой монстр может быть обновлен в конкретном городе. Просто вызовите несуществующую функцию like !!FU(auc_OnDetermineMonsterUpgrade): P... в вашем сценарии со всеми необходимые параметры и другие скрипты смогут писать новые обработчики событий, такие как: !?FU(auc_OnDetermineMonsterUpgrade); ... --- Передача функции в качестве обработчиков или обратных вызовов --- Вы можете использовать функцию как обычную константу, скомпилированную в число. Вы можете присвоить его переменной или передать в другая функция. !!VR(spellHandler:y): S (newmagic_DesintegrationSpellHandler); !!Фу (заклинатель): П; будет компилироваться до чего-то подобного !!VRy20:S95003; !!FUy20:P; [ + ] Добавлена 1000 era - stdlib.erm скрипт, который будет содержать безопасный для всех дополнительных функций ERM. В настоящее время !?Fu (OnEvenyDay) событие усиливается. Его обработчики получат 5 параметров: !?Фу (OnEveryDay); !#VA (day:x1) (weekDay:x) (once:x) (owner: x) (isAi:x); !!Если: M^%(день) %(будний день) %(один раз) %(владелец) %(isAi)^; [ + ] Добавлено 1000 era - conts.сценарий erm с большим количеством констант, которые будут использоваться в сценариях ERM 2.0. Редактор ERM, основанный на Sublime Text, поддерживает автозавершение констант. Помните, что константы без префикса имени mod зарезервированы для ERA. Предпочтите BH_GOLD_PER_VICTORY к GOLD_PER_VICTORY для Battle Heroes mod, например. [ + ] Переменные с плавающей запятой (e-переменные) передаются командам ERM как необработанное значение 4 байта, обрабатывается большинством команд как целое число, что может вызвать множество ошибок, если вы не знаете, что делаете. Исключение составляет !!VR: s команда, позволяющая прозрачное преобразование целое число-float. Чтобы скопировать плавающее значение, хранится в формате raw в целочисленной переменной для e-переменной и наоборот использовать !!VR: команда C. Он действует так же как VR:S, но без преобразования данных. [+] Новая команда !!VR$1:S#2 / #3. Преобразуйте float в целое число с помощью специального режима округления. $1-целочисленная переменная. #2-плавающая переменная #3-режим округления: < 0 для работы пол (округляет в сторону отрицательной бесконечности), 0 для нормального раунда (половина раунда далеко от нуля), > 0 для работы ceil (округление в сторону положительной бесконечности). [+] !!VR: +/-/*/:/% преобразуйте оба аргумента в float если таковой имеется float перед вычислением и конвертируйте обратно чтобы основать тип var на возврате. Таким образом !!VR(koef:e):S25 :10; koef = 2.5 !!VR(gold:y): S2 *koef; gold = 5, а не 4 [+] Новая команда !!VR$1:~#2 Сбрасывает биты #2 в целочисленной переменной $1. Пример: !!VR (flags):~17; unset bits/flags 1 + 16 от переменной (flags). [+] Новая команда !!VR$1: Z#2. Создает локальную временную z-переменную триггера с заданным содержимым и присваивает ее индекс целочисленной переменной. $1-целочисленная переменная. #2-любая строка. Команда может быть использована для создания временных z-переменных для изменения, например, описания артефакта, показать сообщение и восстановить описание. [+] ^....^ литерал в любой команде ERM интерполируется и заменяется временным индексом z-переменной перед приемником исполнение. Эта z-переменная освобождается сразу после выполнения receiver. Не используйте строковые литералы в командах настройки подсказок/описаний WoG 3.58, так как такие описания имеют короткий срок службы. Теперь можно передавать строки в функции. !?FU(ES_Ask); ; Показывает диалог вопросов с подписью. Возвращает логическое значение (1 при успешном выполнении и 0 при неудаче). !#VA (captionPtr:x) (questionPtr:x) (результат:x); !!IF: Q1 / ^{%z(captionPtr)} %z (questionPtr)^; !!VR (результат): S0; !!VR (результат)&1:S1; !?OB (OBJ_TOWN)/(ANY_OBJ); !!Фу (ES_Ask):П^Сфинкс спрашивает тебя:^/^ты действительно хочешь умереть, сражаясь с моими охранниками?^/?(ответ: y); !!HE (CURRENT_HERO)&(answer)=1:K1; пусть он умрет ))) [ + ] Только регулярные переменные ERT интерполируются автоматически. Регулярные z-переменные и временные ert-переменные не интерполируются в приемниках. Это значит, что !!VRz2:S^%%y5^; z2 теперь действительно "%y5" Ранее интерполяция выполнялась бы снова и снова рекурсивно, Преобразуя %y5 в значение y5, подобное 0. и даже позже использование z2 в любой команде снова запустило бы интерполяцию. !!Если: M1/z2; будет отображаться "%y5", а не значение y5. [ + ] Новый синтаксис VR$1:R/T: 0/min/max - генерирует случайное значение в заданном диапазоне и присваивает его целочисленной переменной $1. [+] VR: R/T теперь оба поддерживают синтаксисы с аргументами 1/2/3. [+] VR:T использует генератор Mersenne Twister qualitive, но он не синхронизирован в мультиплеере. [ + ] VR:M1. -1 как длина означает "до конца строки". [ + ] VR:M2 больше не хранит индекс маркера в глобальной переменной. Индекс токенов, который ранее игнорировался, теперь работает так, как и ожидалось. Разделителями токенов являются [#1..#31, ' ', ',', '.']. Не используйте для огромного текста, потому что производительность равна O (n^2), где n-число токенов. [+] VR:M3 Base/radix принудительно находится в 2..16 диапазон. [ + ] Интерполяция ERM (расширение переменных, начинающихся с % в строковых литералах ^...^ и ERT strings) был полностью переписан. Регистр верхнего регистра для старых переменных ERM поддерживается, но устарел. %X1-это хорошо, но %x1-лучше. Все новые s^...^, я^...^ и именованные локальные переменные поддерживаются. Поддерживаются косвенные ссылки. %s (именованная глобальная переменная) %i (именованная глобальная переменная) %xy7 %zi^именованная глобальная переменная^ %z(namedLocalVar) %(namedLocalVar) Поддерживаются быстрые Вары: %i %g %k Интерполяция %Vf...t - это то же самое, что и в WoG 3.58, но %vf...t означает реальную V-индексацию %vi означает v-var с I-индексом. %f означает быстрый' f ' var. %i означает быстрое "i" var. %F5 означает флаг 5 %Fx16 означает флаг с индексом x16 Идентификаторы функций и константы могут быть интерполированы таким же образом, как и именованные локальные переменные: %(CONST_NAME), %(era_FuncName), %(money), %y(moneyPtr) [+] IF:M# теперь работает с любой строкой [+] IF: N1 / # теперь работает с любой строкой, а не только с z1. [+] IF: N# теперь работает с любой строкой. [ + ] BA:B теперь может работать с любой строкой и целым числом. [ + ] Вызовите SN: F^GenerateDebugInfo^ для генерации содержимого каталога отладки точно так же, как это делает F11. [ + ] Экспортированная функция "NameTrigger" (void NameTrigger(int TriggerId, const char* Name)), позволяющая плагинам дайте имя любому триггеру ERM, который может быть использован в ERM like !?Фу (OnYourNewEvent). [ + ] Обновлен плагин" WOG native dialogs " от igrik. Теперь можно выбрать элемент в диалогах сообщений с помощью мыши дважды щелкните мышью. [+] с^...^, ^...^, я^...^ теперь можно свободно использовать в условиях. [ + ] Новые D-модификаторы (d~, d%, d|, d&, d<<, d><, d>>) работают со всеми приемниками. [+] Переписанная реализация хранения ert-строк. Убран лимит на 50000 строк. Увеличенные операции добавления / удаления производительность (от линейного поиска до поиска бинарного дерева). Формат Savegames был изменен. [ + ] Добавлена альтернатива VR:C для массивов SN:M. Новая команда !!SN: V#1/#2/$3...до $21 позволяет установить / проверить / получить / изменить множество элементов динамического массива (работа с вектором). #1-SN: M идентификатор массива. #2-стартовый индекс $3... - элементы с начальным индексом, начальным индексом + 1, начальным индексом + 2 и т. д. [+] Добавлена новая команда !!VR:R0 / #min/#max, генерируя случайное значение в заданном диапазоне и присваивая его переменной. Пример: !!VRy1:R0 / 100 / 300; установите y1 на случайное значение в 100..Диапазон 300 [ * ] Следующие экспортированные функции теперь возвращают 4-байтовое значение LONGBOOL, 0 для false, -1 (0xFFFFFFFF) для true. "ReadStrFromIni", "WriteStrToIni", "SaveIni", "PatchExists", "PluginExists", "Ask". [ + ] Добавлено " 1000-era const.erm " скрипт для WOG mod со стандартными константами эпохи, включая игроков, биты игроков, герои, ресурсы, предметы, монстры, артефакты, заклинания. Содержимое файла может быть исправлено и расширился в будущем. Все константы были зарегистрированы в Редакторе Erm, основанном на Sublime Text. [ + ] Добавлен " 1000-era stdlib.ERM " скрипт с универсальными функциями ERM и событиями. В Настоящее Время "OnEveryDay" событие усиливается следующими аргументами x: day, week day, once (0..1), владелец (цвет), Исай (0..1). [ * ] Исправлена ошибка WoG с обнаружением тактики в самом первом раунде. Не используйте BU:R in !?БР или !?FU (OnCombatRound) для нулевого раунда, потому что несколько структур не инициализируются в этот момент и может произойти случайный сбой. Код первого раунда был перенесен после того, как инициализация боевой темы и появление всплывающего сообщения тактики. [+] Все *.файлы ers загружаются без ограничений по имени / количеству. Раньше только скрипт00.еро..script99.ДЗЗ были обработаны. [+] He: P поведение команды было исправлено. Функция телепорта со звуком вызывается только при наличии какой-либо координаты действительно изменился. Для первых трех параметров поддерживаются расширенные D-модификаторы. [+] Команда HE: C0 была переписана заново. Значения -1 и -2 для типа существа больше не рассматриваются как "обновление"/"деградация". Команда теперь поддерживает любые d-модификаторы. Опыт. параметр modifier теперь установлен только для установки. Ранее !!Он:C0 / 0/?y1/?y2/d5000 / 2 не увеличит игровой опыт. На самом деле, любой GET-синтаксис, используемый для того, чтобы заставить ERM-движок вообще игнорировать опыт стека. Эта ошибка была исправлена. Тип существа < 0 или число Обратите внимание, что во всех случаях возвращаемое значение опыта стека является тем, которое было перед применением каких-либо изменений. [ + ] Переписал команду HE: X, чтобы принять любое количество параметров и понять любые D-модификаторы. Пример: !!Он-1:X0 / 27 Xd1; станьте хозяином золотых драконов [+] Вводит множество новых D-модификаторов для всех команд ERM, за исключением GE:E/N, LE:E / N. d+# - целочисленное сложение d - # - целочисленное вычитание d * # - целочисленное умножение d:# - целочисленное деление d / # устанавливает биты из # (побитовая операция или операция) d& оставляет только # биты, если таковые имеются (побитовая и операция) d~ сбрасывает биты, указанные в #. d~17 сбрасывает биты 1 и 16 d%# вычисляет деление по модулю. Например, 10%4 = 2. д< d>>># сдвигает исходные биты значения вправо на позиции # (побитовое логическое смещение вправо. [ + ] Параметры функции (FU:P, DO: P), которые были переданы с помощью GET-синтаксиса, теперь инициализируются с помощью исходное значение переменной. Это поведение похоже на переход по ссылке в других языках программирования. Пример: !?FU (Add3):; ; (значение: x) !!VR (значение: x):+3; !?СМ0; !!VR (numHeads:y): S10; !!FU (Add3): P?(numHeads: y); 10 передается функции в качестве первого аргумента, 13 - результат [ + ] Улучшено !!RD: I с новым синтаксисом именованных параметров. !!RD:I^имя параметра^/?$значение параметра; ============================== Рекомендуемые параметры: ============================== ^dlgId^ - уникальный идентификатор диалогового окна рекрута. Используется для различения вложенных диалогов (да, это возможно). Многоразовый. ^townId^ - идентификатор города, для которого открывается диалоговое окно, или -1. ^dwellingId^ - идентификатор городского жилья,для которого открывается диалог или -1. 0..6 не модернизированный, 7..13 для модернизированных. Здания Орды (+X населения) рассматриваются как жилища, они влияют. ^slot^ - активный индекс логического слота. ^cost^ - стоимость одного монстра в текущем слоте в золоте. ^resource^ - специальный ресурс для монстра в текущем слоте. ^resourceCost^ - стоимость одиночного монстра в текущем слоте специального ресурса. ^ количество ^ - количество монстров, отобранных в данный момент для вербовки. maxQuantity-максимальное количество монстров, которое игрок может себе позволить. Пример: !?FU(OnRecruitDlgMouseClick); !!РД:I^dlgId^/?(dlgId:y) I^townId^/?(townId:y) I^dwellingId^/?(dwellingId:y) I^slot^/?(слот:y) I^cost^/?(стоимость: y); !!RD: I^resource^/?(ресурс: y) I^resourceCost^/?(resourceCost:y) I^количество^/?(количество: y) I^maxQuantity^/?(maxQuantity: y); !!IF: M^(dlgId:y) (townId:y) (dwellingId:y) (слот: y) (стоимость:y) (ресурс:y) (resourceCost:y) (количество:y) (maxQuantity:y)^; [ + ] Улучшено !!UN: c команда. Теперь он поддерживает все d-модификаторы. Доступен новый синтаксис со смещением от адреса: !!UN:C#addr / # offset/#size/$value; Era всегда вызывает GetRealAddr для #addr, таким образом !!UN: C поддерживает все расширенные / перемещенные игровые структуры. [ + ] Интерфейс WoG и кампании WoG были извлечены в соответствующие автономные моды. ЭРА теперь в основном Ванильная игра с улучшен двигатель ERM и другие возможности моддинга. [ + ] Добавлено !!БМ: Z?команда $addr для получения адреса структуры боевого стека. [ + ] Добавлено !!HE:Z?команда $addr для получения адреса структуры героя. [ + ] Введена поддержка ERM 2.0 для скриптов, начиная с "ZVSE2". [ + ] Удвоенный размер стека для h3era.исполняемый файл exe позволяет запускать уровень глубины до 150, Но лучше избегать такой глубины. [ + ] Редактор кампаний WoG загружает ресурсы из hmm35wog.pac и использует виртуальную файловую систему. Больше никаких исправлений кампании не требуется. [ + ] Добавлена расширенная поддержка перенаправления ресурсов с файлами wav/bik / smk, включая перенаправление отсутствующих ресурсов. [+] Добавлены новые события плагинов "OnAfterLoadLods", происходящие сразу после загрузки lods/pacs и "OnAfterLoadMedia", происходящие когда загружаются lod/pacs/snd / vids. [ * ] ERA рекомендуется устанавливать только поверх Heroes 3 Complete. Удаляются ресурсы,которые уже присутствуют в полных лодах. [- ] Восстановлена функциональность Data\Redirections\Missing\*.файлы json, которые используются для настройки перенаправлений только для недостающих ресурсов. [+] ERM quick vars (f..t) теперь локальны для триггеров. Используйте их безопасно. [ + ] Обновление редактора ERM. [ + ] Переписано ядро движка ERM. Значительно улучшена поддержка старых макросов ($macronam$). Просто для совершенства. [ + ] Извлек WOG campaigns в автономный мод, который был удален из установочного пакета Era. [ + ] "удалить защиту exe.bin " был применен к h3era.exe и удален как патч. [+] Многие ресурсы и функции были извлечены из WOG mod в отдельные моды: анимированные флаги объектов, анимированные деревья, Нет Предварительной Музыки, Вторичной Прокрутки Навыков, Быстрой Экономии, Быстрой Боевой Анимации, Улучшенных Боевых Украшений, WOG Interface, WOG Campaigns, Yona. [+] Добавлено новое событие "OnDetermineMonInfoDlgUpgrade", произошедшее, когда игра определяет, будет ли отображаться кнопка обновления в диалоговом окне monster info. Параметры: MonType, UpgradedType или -1, Town ID или -1, Hero ID или -1. -1 для UpgradedType означает отсутствие кнопки обновления (из-за неправильного типа города или соответствующего здания, которое не было построено, или монстра, не имеющего обновления). Вы можете изменить это значение, чтобы разрешить универсальное поведение, подобное Jelu, или любую систему обновления. Пример: ZVSE2 !?FU(OnDetermineMonInfoDlgUpgrade); !#VA (monType:x) (upgType:x) (town:x) (hero:x); !!VR (upgType): S (MON_GOLD_DRAGON); разрешить апгрейд чего-либо в золотых драконов [ + ] Приемники SN/RD/MP теперь поддерживают индексированные параметры, такие как vy6 или zi^myIndex^. [+] SN: D теперь можно использовать в бою, будучи равным BU: R. [ + ] Добавлена поддержка триггерных локальных динамических массивов. !!SN:M-1 / # / #/-1 выделит новый динамический массив с идентификатором, который будет автоматически освобожден после выхода текущего триггера. Таким образом нет соответствует !!SN: M# необходимо освободить этот временный массив. Его можно использовать, например, для больших вычислений или для передачи строковых аргументов функции. Пример: !?FU(OnAdventureMapRightMouseClick); !!SN:M-1/4/1 / -1; [выделить массив из 4 строк (-1 = auto ID, 4 = 4 элемента, 1 = типа строки, -1 = local to current trigger)] !!VR(dlgStrings:y): Sv1; [сохранить идентификатор массива] ; Строки настройки !!SN:M (dlgStrings)/0 / ^выберите бонус командира:^; !!SN:M (dlgStrings)/1/^1) Атака^; !!SN:M (dlgStrings)/2/^2) Скорость^; !!SN:M (dlgStrings)/3 / ^3) здоровье^; !!FU (PM_ShowDialog):P (dlgStrings); [pass 4 string to dialog showing function] ; здесь массив с идентификатором (dlgStrings) будет автоматически освобожден, как и SN:M(dlgStrings); !?FU(PM_ShowDialog); ; (dlgStrings:x) - динамический массив из 4 строк ; (пункты[3]: z) !!SN:M (dlgStrings)/0/?(подпись: z); !!SN:M (dlgStrings)/1/?(пункты[0]); !!SN:M (dlgStrings)/2/?(пункты[1]); !!SN:M (dlgStrings)/3/?(пункты[2]); !!IF:M^{(подпись)} (пункты[0]) (пункты[1]) (пункты[2])^; [- ] Исправлена утечка памяти при освобождении динамических массивов SN:M и некоторых других местах.