Hello, friends. Today, we ship build .34 to DEV. Please test it against your custom content and on your servers! It contains: [h2]Fixes[/h2] [list] [*] Apple M1: Fixed audio crackle when decoding mp3 files, including voiceovers. [*] Pathfinding: Fixed a case where pathing was bailed on too early, resulting in incorrect behaviour that was regressed in the previous patch. [*] Facelift tilesets tts02 tcm02: Addressed various texture and model issues. [*] ResMan: Fixed two memleaks where it wouldn’t release loaded data instances. [*] Renderer: Minor fixes to animation start consistency. [*] Renderer: Fixed animated skinmesh parts going out of sync/being one frame behind. [*] Renderer: Fixed rough surfaces having a milky sheen at some viewing aspects, especially when using height maps. [/list] [h2]QoL Improvements[/h2] [list] [*] Game: Disable ctrl-drag selection box on clients when server.player-party-control is off (the default). Note that clients will have to reconnect if you toggle this setting while a game is up. [*] NWSync: Repositories are now collapsible in the main UI view; this state is remembered in settings.tml. [*] NWSync: Module versions can now hold a `localalias` field that is used to backreference for StartNewModule(“originalfilename”). [*] NWSync: Better support for repository-side statistics. [*] NWSync: Hide modules, campaigns and adverts with empty name labels. [*] NWSync: Don’t reject repository.json if advert buttons have empty labels and URLs. [*] Launch Game UI/Repo Manager: Fixed “Show Advert” checkbox label being cut off. [*] Launch Game UI: Fixed “Advert” panel type displaying a STRREF instead of text when no label is defined in repository.json. [/list] [h2]Scriptable UI[/h2] [list] [*] Nui: Fixed crash when calling SetGroupLayout() with invalid data. [*] Nui: Fixed scrollbar size for textedit. [*] Nui: Text can now override border and scrollbars properties. [*] Nui: Fixed draw_list scissoring breaking succeeding widget rendering. [*] Nui: Fixed draw_list scissoring leaving a stale scissor on the GL stack for nested widgets. [*] Nui: Fixed entries in a list view not scissoring draw_list correctly when scrolling out of view. [*] Nui: list(): Fixed textedit() widget not working in lists. [*] Nui: list(): Scrollbars now configurable. [*] Nui: list(): Fix spacers not advancing row layout correctly. [*] Nui: Never allow binds to update during construction. This fixes list() array binds degrading to scalar values, among other. [*] Nui: textedit(): Fixed placeholder sometimes rendering on the succeeding widget instead. [*] Nui: textedit(): Fixed range event triggering too often or with wrong values. [*] Nui: Added demo code for spreadsheet UI. [*] Nui: Fixed “list” widget not showing a vertical scrollbar in AUTO mode. [/list] [h2]Premium Modules [/h2] [list] [*] Tyrants of the Moonsea: Fixed ship's cabin navigation map occasionally disabling erroneously. [/list] [h2]New Script Commands[/h2] [code]// Returns the number of script instructions remaining for the currently-running script. // Once this value hits zero, the script will abort with TOO MANY INSTRUCTIONS. // The instruction limit is configurable by the user, so if you have a really long-running // process, this value can guide you with splitting it up into smaller, discretely schedulable parts. // Note: Running this command and checking/handling the value also takes up some instructions. int GetScriptInstructionsRemaining(); // Returns a modified copy of jArray with the value order changed according to nTransform: // * JSON_ARRAY_SORT_ASCENDING, JSON_ARRAY_SORT_DESCENDING // Sorting is dependent on the type and follows json standards (.e.g. 99 < "100"). // * JSON_ARRAY_SHUFFLE // Randomises the order of elements. // * JSON_ARRAY_REVERSE // Reverses the array. // * JSON_ARRAY_UNIQUE // Returns a modified copy of jArray with duplicate values removed. // Coercable but different types are not considered equal (e.g. 99 != "99"); int/float equivalence however applies: 4.0 == 4. // Order is preserved. // * JSON_ARRAY_COALESCE // Returns the first non-null entry. Empty-ish values (e.g. "", 0) are not considered null, only the json scalar type. json JsonArrayTransform(json jArray, int nTransform); // Returns the nth-matching index or key of jNeedle in jHaystack. // Supported haystacks: object, array // Ordering behaviour for objects is unspecified. // Return null when not found or on any error. json JsonFind(json jHaystack, json jNeedle, int nNth = 0, int nConditional = JSON_FIND_EQUAL); // Returns a copy of the range (nBeginIndex, nEndIndex) inclusive of jArray. // Negative nEndIndex values count from the other end. // Out-of-bound values are clamped to the array range. // Examples: // json a = JsonParse("[0, 1, 2, 3, 4]"); // JsonArrayGetRange(a, 0, 1) // => [0, 1] // JsonArrayGetRange(a, 1, -1) // => [1, 2, 3, 4] // JsonArrayGetRange(a, 0, 4) // => [0, 1, 2, 3, 4] // JsonArrayGetRange(a, 0, 999) // => [0, 1, 2, 3, 4] // JsonArrayGetRange(a, 1, 0) // => [] // JsonArrayGetRange(a, 1, 1) // => [1] // Returns a null type on error, including type mismatches. json JsonArrayGetRange(json jArray, int nBeginIndex, int nEndIndex); // Returns the result of a set operation on two arrays. // Operations: // * JSON_SET_SUBSET (v <= o): // Returns true if every element in jValue is also in jOther. // * JSON_SET_UNION (v | o): // Returns a new array containing values from both sides. // * JSON_SET_INTERSECT (v & o): // Returns a new array containing only values common to both sides. // * JSON_SET_DIFFERENCE (v - o): // Returns a new array containing only values not in jOther. // * JSON_SET_SYMMETRIC_DIFFERENCE (v ^ o): // Returns a new array containing all elements present in either array, but not both. json JsonSetOp(json jValue, int nOp, json jOther); // Returns the column name of s2DA at nColumn index (starting at 0). // Returns "" if column nColumn doesn't exist (at end). string Get2DAColumn(string s2DA, int nColumnIdx); // Returns the number of defined rows in the 2da s2DA. int Get2DARowCount(string s2DA);[/code]