Code:
Version 3.9.4 (03/2023)
------------------------
[+] ERA finally got new icon. Credits: Nikt, suftfree, Elmore.
[-] Fixed map description truncation in scrollbar text dialogs without scroll bars.
[+] Added the following functions to Era ERM Framework:
  !?FU(BattleStack_MakeActive);
  ; Makes specified stack active/acting.
  !#VA(stackId:x); Stack ID to pass control to.
  !?FU(PrepareMultiPicDialog);
  ; Initializes IF:N dialog pictures. Call IF:N to show it afterwards.
  ; Automatically skips pairs with NO_PIC_TYPE type and pairs with PIC_TYPE_MONSTER type and negative subtype.
  ; Ignores more than 8 non-empty pairs. Always safe to call.
  ;
  ; Supports three call syntaxes:
  ;   P; dialog without pictures
  ;   P(first picture type)/(first picture subtype)/(second picture type)...
  ;   P(ID of dynamic array, containing picture pairs)
  !?FU(Array_CountValue);
  ; Returns number of array items, equal to specified value.
  !#VA(list:x);            Array ID.
  !#VA(value:x);           Value to count. Strings are supported.
  !#VA(result:x);          Result.
  !#VA(caseInsensitive:x); Optional. If true, strings will be compared case insensitively. Default: false.
  !?FU(Array_IndexOf);
  ; Returns index of the first array item with specified value or -1 in case of failure.
  !#VA(list:x);            Array ID.
  !#VA(value:x);           Value to search for.
  !#VA(result:x);          Result index or -1 in case of failure.
  !#VA(caseInsensitive:x); Optional. If true, strings will be compared case insensitively. Default: false.
  !?FU(Array_Find);
  ; Returns index of the first array item, for which custom callback function returns (TRUE) or -1 in case of failure.
  !#VA(list:x);      Array ID.
  !#VA(callback:x);  Callback function F(itemValue, ?result, [listId], [customArg]), where result is (TRUE) or (FALSE). (FALSE) is passed by default.
                  ;  listID is array ID and customArg is anything, specified as custom argument to Array_Find. Zero by default.
  !#VA(result:x);    Result index or -1 in case of failure.
  !#VA(customArg:x); Custom argument to pass to callback as the 4-th parameter.
  Examples:
  !?PI;
  !!FU(NewStrArray):P?(list:y);
  !!FU(Array_Push):P(list)/^banana^/^daemon^/^apple^/^juice^/^Apple^/^orange^/^apple^;
  !!FU(Array_CountValue):P(list)/^apple^/?(numOccurencies:y)/(TRUE);
  !!IF:M^%(numOccurencies)^; displays 3, because 'apple' occured 3 times in the array
  !!FU(NewStrArray):P?(list:y);
  !!FU(Array_Push):P(list)/^banana^/^daemon^/^juice^/^Apple^/^orange^/^apple^;
  !!FU(Array_IndexOf):P(list)/^apple^/?(itemIndex:y);
  !!IF:M^%(itemIndex)^; displays 5, index of the last array item
  !!FU(NewStrArray):P?(list:y);
  !!FU(Array_Push):P(list)/^banana^/^daemon^/^juice^/^Apple^/^orange^/^apple^;
  !!FU(Array_Find):P(list)/(edu_FilterDaemons)/?(itemIndex:y);
  !!IF:M^%(itemIndex)^; displays 1, because function edu_FilterDaemons returns (TRUE) only for 'daemon_n' and 'daemon' strings.
  !?FU(edu_FilterDaemons);
  !#VA(strPtr:x);
  !#VA(result:x);
  !!VR(result)|z(strPtr)=^daemon_n^/z(strPtr)=^daemon^:S(TRUE);
[*] Increased ERM engine static memory buffer size from 3 MB to 10 MB. The buffer is used for temporary strings storage during events and commands execution.
[*] Debug.LogDestination setting value in heroes3.ini became case insensitive.
[*] Removed '$OnGameLeave' private event support, used by HD-mod earlier. Added support for 'OnGameLeave' event as a replacement.
[-] Fixed bug, causing 'TServiceMemAllocator.Alloc failed. No page allocated' error. Memory was leaking if interpolated conditions where used in ERM event conditions.
[-] Fixed bug: x-variables modifications in "_Quit" events were not transferred to the results of original events.
[-] Fixed bug: custom network events and FU:D didn't work in battle.
[-] Fixed issues with HD-mod way of loading game from battle. OnGameEnter/OnGameLeave counter will not be corrupted if HD mod generates "OnGameLeave" event for ERA before quitting game loop. No more need in dollar prefix for event name.