https://dropmefiles.com/QtkL3
Версия 3.9.16 (discord-сервер, канал era lab):
Code:
Version 3.9.16 (01/2025)
------------------------
[+] Added support for IME (Input Method Editor) input, used by Asian (Chinese/Japanese/Korean) languages.
[+] Added "Lang/*" directory support for zip archives in Data.
[+] Introduced another directory for ERM global library scripts: "Data/s/lib_end". Scripts from this directory will be loaded after all other map/global/library scripts.
Likewise "lib" directory, these scripts do not depend on UN:P5 WoG option state.
[+] Improved CombatManager::CastSpell function (used also in BM:C) by temporarily setting CombatManager->ControlSide to the side, controlling casting stack.
Casting stack may differ from active stack (it may be counter attack or arbitrary script logic). In native game casting stack is always current active stack.
"Fire wall", "land mines", "quick sands", "force field" and many other spells rely on which side is considered friendly (current). The bug with friendly master-gremlins, casting "land mines" from enemy hero side seems to be also fixed.
If stack is hypnotized, it's effective side is the side of controlling (hypnotizing) hero.
[+] Rewritten IF:D, IF:F, IF:E commands (multipurpose dialog implementation). Features:
-) Whenever string is accepted as a parameter, it may be any string or string literal. The value will be copied to global settings, no more dependency on z-variables.
-) Dialog IDs are totally ignored (better use 0 or -1 for them for readability). There is only one copy of dialog settings in memory.
-) Dialog settings are totally cleared before IF:D and after IF:E execution.
-) Fixed bugs with phantom empty strings instead of image paths or hints.
-) IF:F accepts 0..6 parameters. Empty parameter means "remove hint".
-) IF:E accepts the following syntaxes: IF:E(v-var index to store result) or IF:E?(any integer variable to store result).
[+] Extended VR:R command with optional 4-th parameter: VR:R(dummy)/(min)/(max)/(free_param);
In network battles deterministic random value generator is used, which generates values using current action ID, round ID and battle ID. An attempt to generate multiple random values in one action produces the same values like 44 44 44. To overcome this issue pass unique value to 4-th parameter for each iteration. It may be stack ID or loop counter, but better XOR it with pre-generated int32 constant, unique for the effect/spell/function, you implement. For instance, 1833290248 XOR stack ID is a good choice.
Example:
!?FU(OnBattleScreenMouseClick);
; The effect will be seen in network battles only and will not influence singleplayer
!#VA(v[3]:y);
!!VR(effectId:y):S1833290248; // Unique generated int32 value for our sequence, use any offline/online generator
!!re i/0/(v[SIZE])/1/-1;
!!VR(freeParam:y):S(effectId) Xi;
!!VR(v[i]):R0/1/100/(freeParam);
!!en;
!!IF:L^%(v[0]) %(v[1]) %(v[2])^;
[+] Added support for Phoenix Ressurection and Death Stare in network PvP battles.
[+] Updated "Era Erm Framework":
-) Added support for area shooting creatures to BattleStack_Shoot function.
-) Synchronized with Launcher "Era Erm Framework" version.
[+] Added the following export types and functions to era.dll:
(*
Customizable dialog with up to 4 external/internal pictures (bmp/jpg/png/pcx/pcx16,def?), optional input field and 4 selectable buttons with checkboxes.
All pointers may be null. All fields must be writable by dialog processing routines and must be considered "dirty" after dialog processing except the field, where result
values are written.
*)
PMultiPurposeDlgSetup = ^TMultiPurposeDlgSetup;
TMultiPurposeDlgSetup = packed record
Title: pchar; // Top dialog title
InputFieldLabel: pchar; // If specified, user will be able to enter arbitrary text in input field
ButtonsGroupLabel: pchar; // If specified, right buttons group will be displayed
InputBuf: pchar; // OUT. Field to write a pointer to a temporary buffer with user input. Copy this text to safe location immediately
SelectedItem: integer; // OUT. Field to write selected item index to (0-3 for buttons, -1 for Cancel)
ImagePaths: array [0..3] of pchar; // All paths are relative to game root directory or custom absolute paths
ImageHints: array [0..3] of pchar;
ButtonTexts: array [0..3] of pchar;
ButtonHints: array [0..3] of pchar;
ShowCancelBtn: TInt32Bool;
end;
TShowMultiPurposeDlgFunc = procedure (Setup: PMultiPurposeDlgSetup); stdcall;
(* Displayes customizable configured multipurpose dialog and returns selected button ID (1..4) or -1 for Cancel *)
function ShowMultiPurposeDlg (Setup: PMultiPurposeDlgSetup): integer; stdcall;
(* Replaces current multipurpose dialog handler/implementor. Returns old handler if any *)
function SetMultiPurposeDlgHandler (NewImpl: TShowMultiPurposeDlgFunc): {n} TShowMultiPurposeDlgFunc; stdcall;
(* Creates new plugin API instance for particular DLL plugin. Pass real dll name with extension. Returns plugin instance or NULL is plugin is already created *)
function CreatePlugin (Name: pchar) : {On} TPlugin; stdcall;
(* Installs new hook at specified address. Returns pointer to bridge with original code if any. Optionally specify address of a pointer to write applied patch structure
pointer to. It will allow to rollback the patch later. MinCodeSize specifies original code size to be erased (nopped). Use 0 in most cases. *)
function Hook (Addr: pointer; HandlerFunc: THookHandler; {n} AppliedPatch: ppointer; MinCodeSize, HookType: integer): {n} pointer; stdcall;
(* Returns true if applied patch was overwritten *)
function IsPatchOverwritten (AppliedPatch: pointer): TInt32Bool; stdcall;
(* Returns applied patch size in bytes (number of ovewritten bytes) *)
function GetAppliedPatchSize (AppliedPatch: pointer): integer; stdcall;
(* Generates random value in specified range with additional custom parameter used only in deterministic generators to produce different outputs for sequence of generations. For instance, if you need to generate random value in battle for each enemy stack, you could use stack ID or loop variable for FreeParam. But for better generation quality use (stackID XOR UNIQUE_ACTION_MASK) and define UNIQUE_ACTION_MASK constant as unique int32 pre-generated value. In network battles multiple random value generations with the same parameters produce the same output until next action is performed. This function allows to bring back randomness to multiple same time generations. *)
function RandomRangeWithFreeParam (MinValue, MaxValue, FreeParam: integer): integer; stdcall;
[+] Added "Debug.LogWindowMessagesOpt" option to "heroes 3.ini", enabling logging of main window messages and their parameters.
[+] Added the following translatable strings to "era.json":
- 'era.debug.game_saving_exception_warning': shown on savegame writing exception
- 'era.debug.debug_dump_confirmation': shown on any ERM error
- 'era.incompatible_savegame_version_warning': shown if game saving was performed on too old Era engine
[*] From now on, Era always asks permission to load global scripts on map start or scripts reloading if map has internal scripts. The permission text was changed from "skip" to "load" by default. The following language key must be re-translated: 'era.global_scripts_vs_map_scripts_warning'. WoG Option 5 is always set to 3 (ask for loading global scripts if map has internal scripts) before any scripts are loaded, thus there is no more necessity to keep it in WoG Options. UN:P5/# instruction in map internal scripts controls, wether map author forces global scripts loading or not.
[+] Included updated sources codes for the following plugins: "Buttons", "Erm Hooker", "WoG Native Dialogs", "Game Bug Fixes Extended". Thanks to baratorch and Hota team for sharing their header files.
[+] Included refactored Delphi and C++ Era SDK (API files).
[+] Included latest Era sources (Tools/Era/Sources/Era 3.9.16) and Virtual File System sources.
[*] Restored WoG cheat codes functionality in Easy Cheats mod, fixed documentation typos and added display of dumped array sizes.
[*] Updated "erm_hooker.era" plugin to reflect Era engine changes.
[*] Updated "buttons.era" plugin to reflect Era engine changes.
[*] Updated "wog native dialogs.era" plugin to be more tolerant of unsupported image types for IF:E dialogs.
[*] Increased stability of snd/vid resources processing (using splice hooks instead of patch hooks).
[*] "load only these scripts.txt" file support is deprecated. It will be removed in Era 4.X versions. Duplicate entries in this file are ignored from now.
[*] Updated "Era Erm Framework" mod to use "lib_end" directory for some scripts.
[!] Savegame file format was changed. Added format checking. Old savegames will be loaded without scripts/plugins data.
[-] Removed the following functions from era.dll: "CalcHookPatchSize", "ApiHook", "HookCode".
[-] Fixed crash in network game in savegame dialog: RMB on some dialog items leaded to an invalid attempt to update ScreenLog without having initialized textWidget field.
[-] Fixed wrong ERA version reporting.
Code:
Версия 3.9.16 (01/2025)
------------------------
[+] Добавлена поддержка IME (Input Method Editor), используемого азиатскими языками (китайским/японским/корейским).
[+] Добавлена поддержка каталога "Lang/*" для zip-архивов в Data.
[+] Добавлен еще один каталог для скриптов глобальной библиотеки ERM: "Data/s/lib_end". Скрипты из этого каталога будут загружаться после всех других скриптов map/global/library.
Аналогично каталогу "lib", эти скрипты не зависят от состояния параметра UN:P5 WoG.
[+] Улучшена функция CombatManager::castSpell (используемая также в BM:C), временно переведя CombatManager->ControlSide в режим управления стеком заклинаний.
Стек приведения может отличаться от активного стека (это может быть контратака или произвольная логика скрипта). В нативной игре стек приведения - это всегда текущий активный стек.
"Огненная стена", "наземные мины", "зыбучие пески", "силовое поле" и многие другие заклинания зависят от того, какая сторона считается дружественной (текущая). Также, похоже, исправлена ошибка с дружественными мастерами-гремлинами, которые бросали "наземные мины" со стороны вражеского героя.
Если стек загипнотизирован, то его эффективная сторона - это сторона управляющего (гипнотизирующего) героя.
[+] Переписаны команды IF:D, IF:F, IF:E (многоцелевая диалоговая реализация). Особенности:
-) Всякий раз, когда в качестве параметра принимается строка, это может быть любая строка или строковый литерал. Значение будет скопировано в глобальные настройки, больше не будет зависеть от z-переменных.
-) Идентификаторы диалоговых окон полностью игнорируются (для удобства чтения лучше использовать 0 или -1). В памяти сохранена только одна копия настроек диалога.
-) Настройки диалога полностью удалены до выполнения IF:D и после выполнения IF:E.
-) Исправлены ошибки с фантомными пустыми строками вместо путей к изображениям или подсказок.
-) IF:F принимает параметры 0..6. Пустой параметр означает "удалить подсказку".
-) IF:E принимает следующие синтаксисы: IF:E(индекс var для хранения результата) или IF:E?(любая целочисленная переменная для хранения результата).
[+] Расширенная команда VR:R с дополнительным 4-м параметром: VR:R(фиктивный)/(минимальный)/(максимальный)/(free_param);
В сетевых сражениях используется детерминированный генератор случайных величин, который генерирует значения, используя текущий идентификатор действия, идентификатор раунда и идентификатор битвы. Попытка сгенерировать несколько случайных величин в одном действии приводит к получению одинаковых значений, таких как 44 44 44. Чтобы решить эту проблему, передайте уникальное значение 4-му параметру для каждой итерации. Это может быть идентификатор стека или счетчик циклов, но лучше преобразовать его с помощью предварительно сгенерированной константы int32, уникальной для эффекта/заклинания/функции, которую вы реализуете. Например, хорошим выбором является идентификатор стека XOR 1833290248.
Пример:
!?ФУ(щелчок мыши на экране битвы);
; Эффект будет заметен только в сетевых сражениях и не повлияет на одиночную игру
!#VA(v[3]:y);
!!VR(effectId:y):S1833290248; // Уникальное сгенерированное значение int32 для нашей последовательности, используйте любой автономный/онлайн-генератор
!!re i/0/(v[РАЗМЕР])/1/-1;
!!VR(свободный параметр:y):S(идентификатор эффекта) Xi;
!!VR(v[i]):R0/1/100/(Свободный параметр);
!!ru;
!!ЕСЛИ: L^%(v[0]) %(v[1]) %(v[2])^;
[+] Добавлена поддержка Воскрешения Феникса и смертельного взгляда в сетевых PvP-сражениях.
[+] Обновлена "Платформа Erm Era".:
-) Добавлена поддержка локального отстрела существ в функции BattleStack_Shoot.
-) Синхронизирован с версией лаунчера "Era Erm Framework".
[+] Добавлены следующие типы экспорта и функции в era.dll:
(*
Настраиваемый диалог с 4 внешними/внутренними изображениями (bmp/jpg/png /pcx/pcx16, def?), дополнительным полем ввода и 4 кнопками выбора с флажками.
Все указатели могут быть пустыми. Все поля должны быть доступны для записи процедурами обработки диалога и должны считаться "грязными" после обработки диалога, за исключением поля, в которое записываются значения результата
.
*)
PMultiPurposeDlgSetup = ^TMultiPurposeDlgSetup Многопользовательская настройка;
TMultiPurposeDlgSetup = упакованная запись
Заголовок: pchar; // Заголовок верхнего диалогового окна
InputFieldLabel: pchar; // Если указано, пользователь сможет ввести произвольный текст в поле ввода
ButtonsGroupLabel: pchar; // Если указано, будет отображена группа правых кнопок
InputBuf: pchar; // OUT. Поле для записи указателя на временный буфер с помощью пользовательского ввода. Немедленно скопируйте этот текст в безопасное место
SelectedItem: integer; // OUT. Поле для записи индекса выбранного элемента (0-3 для кнопок, -1 для отмены)
ImagePaths: массив [0..3] из pchar; // Все пути относятся к корневому каталогу игры или пользовательским абсолютным путям
ImageHints: массив [0..3] из pchar;
ButtonTexts: массив [0..3] из pchar;
ButtonHints: массив [0..3] из pchar;
ShowCancelBtn: TInt32Bool;
конец;
TShowMultiPurposeDlgFunc = процедура (настройка: PMultiPurposeDlgSetup); стандартный вызов;
(* Отображает настраиваемый многофункциональный диалог и возвращает идентификатор выбранной кнопки (1..4) или -1 для отмены *)
функция ShowMultiPurposeDlg (настройка: PMultiPurposeDlgSetup): целое число; стандартный вызов;
(* Заменяет текущий универсальный обработчик диалоговых окон/разработчик. Возвращает старый обработчик, если таковой имеется *)
функция SetMultiPurposeDlgHandler (NewImpl: TShowMultiPurposeDlgFunc): _BOS_n} TShowMultiPurposeDlgFunc; стандартный вызов;
(* Создает новый экземпляр API плагина для конкретного плагина библиотеки DLL. Передает реальное имя библиотеки dll с расширением. Возвращает экземпляр плагина или значение NULL, если плагин уже создан *)
функция CreatePlugin (имя: pchar) : {On} TPlugin; stdcall;
(* Устанавливает новый hook по указанному адресу. Возвращает указатель на bridge с исходным кодом, если таковой имеется. При необходимости укажите адрес указателя для записи структуры примененного исправления
указатель на. Это позволит позже откатить исправление. MinCodeSize указывает размер исходного кода, который должен быть удален. В большинстве случаев используйте значение 0. *)
функция перехвата (Addr: указатель; HandlerFunc: THookHandler; {n} AppliedPatch: ppointer; MinCodeSize, HookType: целое число): _BOS_n} указатель; stdcall;
(* Возвращает значение true, если примененный патч был перезаписан *)
функция IsPatchOverwritten (AppliedPatch: указатель): TInt32Bool; stdcall;
(* Возвращает размер примененного исправления в байтах (количество перезаписанных байт) *)
функция GetAppliedPatchSize (AppliedPatch: указатель): целое число; стандартный вызов;
(* Генерирует случайное значение в заданном диапазоне с дополнительным пользовательским параметром, используемым только в детерминированных генераторах, для получения различных выходных данных для последовательности генераций. Например, если вам нужно генерировать случайное значение в бою для каждого вражеского стека, вы можете использовать stack ID или переменную цикла для FreeParam. Но для лучшего качества генерации используйте (stackId XOR UNIQUE_ACTION_MASK) и определите константу UNIQUE_ACTION_MASK как уникальное предварительно сгенерированное значение int32. В сетевых битвах несколько генераций случайных значений с одинаковыми параметрами выдают один и тот же результат до тех пор, пока не будет выполнено следующее действие. Эта функция позволяет вернуть случайность нескольким поколениям в одно и то же время. *)
функция RandomRangeWithFreeParam (MinValue, MaxValue, FreeParam: integer): целое число; стандартный вызов;
[+] Добавлено "Отладка.Опция "LogWindowMessagesOpt" заменена на "heroes 3.ini", что позволяет регистрировать сообщения в главном окне и их параметры.
[+] Добавлены следующие переводимые строки в "era.json".:
- 'era.debug.game_saving_exception_warning': отображается при исключении записи сохраненной игры
- 'era.debug.debug_dump_confirmation': отображается при любой ошибке ERM
- "era.incompatible_savegame_version_warning": отображается, если сохранение игры было выполнено на слишком старом движке Era.
[*] Отныне Era всегда запрашивает разрешение на загрузку глобальных скриптов при запуске карты или перезагрузке скриптов, если на карте есть внутренние скрипты. По умолчанию текст разрешения был изменен с "пропустить" на "загрузить". Следующий языковой ключ должен быть переведен заново: "era.global_scripts_vs_map_scripts_warning". Для параметра WoG 5 всегда устанавливается значение 3 (запрос на загрузку глобальных скриптов, если на карте есть внутренние скрипты) перед загрузкой любых скриптов, поэтому больше нет необходимости сохранять его в настройках WoG. UN:P5/# инструкция во внутренних скриптах карты определяет, принудительно ли автор карты загружает глобальные скрипты или нет.
[+] Добавлены обновленные исходные коды для следующих плагинов: "Buttons", "Erm Hooker", "WoG Native Dialogs", "Game Bug Fixes Extended". Спасибо baratorch и Hota team за то, что поделились своими заголовочными файлами.
[+] Включены переработанные Delphi и C++ Era SDK (файлы API).
[+] Включены последние исходные тексты Era (Tools/Era/Sources/Era 3.9.16) и исходные тексты виртуальной файловой системы.
[*] Восстановлена функциональность чит-кодов WoG в Easy Cheats mod, исправлены опечатки в документации и добавлено отображение размеров массива данных.
[*] Обновлен плагин "erm_hooker.era", отражающий изменения в движке Era.
[*] Обновлен плагин "buttons.era", отражающий изменения в движке Era.
[*] Обновлен плагин "wog native dialogs.era", который более терпим к неподдерживаемым типам изображений для диалогов IF:E.
[*] Повышена стабильность обработки snd/vid-ресурсов (с использованием сплайс-хуков вместо патч-хуков).
[*] "загружайте только эти файлы scripts.txt" поддержка файлов устарела. В версиях Era 4.X она будет удалена. Повторяющиеся записи в этом файле отныне игнорируются.
[*] Обновлен модуль "Era Erm Framework", позволяющий использовать каталог "lib_end" для некоторых скриптов.
[!] Изменен формат файла сохраненной игры. Добавлена проверка формата. Старые сохраненные игры будут загружаться без данных скриптов/плагинов.
[-] Удалены следующие функции из era.dll: "CalcHookPatchSize", "ApiHook", "HookCode".
[-] Исправлен сбой в сетевой игре в диалоге сохранения игры: ошибка в некоторых элементах диалога приводила к недопустимой попытке обновить ScreenLog без инициализации поля TextWidget.
[-] Исправлено неправильное сообщение о версии ERA.
Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
|