# lib_ietool function library

Dependencies: lib_2da, lib_2daq, lib_anon, lib_array, lib_fn, lib_ini, lib_script, lib_sfo, lib_ssl, lib_sugar, lib_tools, lib_ui

## Description

This library contains some tools to do core/miscellaneous manipulations of IE files. By convention functions here don't have ietool_ as a prefix.

Functions here should have no external dependencies.

## Public functions

add_basic_spell_ability()=() patch

Add a standard (innate) ability to the currently-being-patched spell, assumed to be a blank freshly-created v1 spell from WEIDU's CREATE command. (For lightweight spell-creation.)

add_to_lua_lang(array:a)=() dimorphic

Given a k=>v array 'array' with entries like MY_TEXT_STRING=>1234, go through each entry, and for each, get the string with tra ref 1234 in the current tra file and set TEXT_STRING equal to it in the current EE language file (e.g., en_us.lua).

Exits with a warning if not on EE.

all_to_utf8(permanent:b, tra_path:s="MOD_FOLDER/lang")=() action

Given the (full) path to your tra files (default: MOD_FOLDER/lang), convert all the files in all languages to UTF-8 (with lowercased filenames), leaving no detritus (no fl#utf files). If permanent=1, will persist through uninstall.

copy_item_to_spell(abil_ind:i, item:s, spell:s)=() action

Take ability 'abil_ind' (default=0) from item 'item'. Build a new spell, 'spell', that casts that ability as its only ability.

ext(uppercase:b)=(ext:s, version:s) patch

Returns the extension of the currently-being-patched file, if we can tell. (we can tell for 2da, are, chr, cre, dlg, gam, itm, pro, spl, sto, vef, vvc, wed, and wmp) Also return its version

By default we return lowercase; if you want it in uppercase, set uppercase=1.

extend(inline:i, ssl:i, tv:i, allow_missing:i, script:s, files:s, file:s, location:s, locbase:s, path:s, top:s, bottom:s, variables:s)=() action

Extend the script(s) 'script' (legacy synonyms: file, files) with 'top' at the top and/or 'bottom' at the bottom. top and bottom location is specified in the usual SFO way. If inline=1, 'top' and 'bottom' are assumed inlined at .../stratagems-inline

If ssl=1, assume 'top' and 'bottom' are ssl scripts, and pass 'variables' to the SSL parser. If tv=1, prepend to each script. If allow_missing=1, skip silently any missing script (default is to WARN).

extend_area_script(inline:i, ssl:i, area:s, location:s, locbase:s, path:s, top:s, bottom:s, variables:s)=() dimorphic

Extend the area script of area 'area' with 'top' at the top and/or 'bottom' at the bottom. If the script doesn't exist, we create one, using standard conventions. 'area' can be a list of areas, in which case each one is extended. Same input conventions as 'extend'.

extend_worldscripts(inline:i, ssl:i, location:s, locbase:s, path:s, top:s, bottom:s, variables:s)=() dimorphic

Extend the global scripts (baldur, baldur25, and whatever is in campaign.2da worldscript column). Same input conventions as 'extend'.

handle_unusable(arguments:s)=(value:s) dimorphic

Take as input a string, assumed to be an item description. If on EE, remove the 'not usable by:' bit.

insert_script(script_array:s, script:s, arguments:s, loc:s)=(script_array:a) dimorphic

Given a numbered-from-0 array of scripts 'script_array', and a new script 'script' (synonym: 'arguments'), insert the new script in position 'loc'. Insert position can be 'high', 'low', 'after x' (defaults to 'high' if x isn't present), or 'before x' (defaults to 'low' if x isn't present). If there isn't space, merge the two lowest scripts to make space.

install(overwrite:b=1, inline:b, arguments:s, files:s, file:s, location:s, locbase:s, path:s, postfix:s, ext:s)=() action

'arguments' (synonym: 'files'; synonym:'file') is a list of files (including extensions) located at the location given by path/location/locbase. Each is copied over to the override; if any are BAF/D, they are COMPILE EVALUATE_BUFFERred; if they are SSL, they are compiled to BCS; if they are v1 CREs, we run FJ_CRE_EFF_V2 to force V2 effects. If they are 2da/ids/ini files, we EVALUATE_BUFFER. If none of 'location', 'locbase', and 'path' are set, set location=resource. If overwrite=0, don't overwrite already-present files (does not affect scripts).

If 'ext' (legacy synonym: 'postfix') is set, automatically add that file extension (so LAF install STR_VAR files="script1 script2" ext=baf ... END installs script1.baf and script2.baf).

If the argument is 'all', apply to every file at the path. If both 'ext' and 'all' are set, apply to every file at the path with that file extension.

level_at_xp(xp:i, num_classes:i=1, class:s)=(level:s) dimorphic

Returns the level of a character with the given amount of XP. num_classes should be 1 for single-class PCs, 2 for double-class, 3 for triple-class. Class should be class.ids entry.

merge_scripts(top:s, bottom:s, script:s)=(script:s) dimorphic

If both 'top' and 'bottom' exist, merge them into a new script, and give it a guaranteed-unique name unless a name is specified. In any case, return the name. If one doesn't exist, return the name of the other.

remove_joinable_spells(remove_known:i=1, remove_memorized:i=1, exclude_array:s)=() action

Deletes the 'known' and 'memorized' spell lists (SPPR/SPWI namespace only) from all party-joinable NPCs, making an exception for any NPC with a dv on the k=>_ list 'exclude_array'

resolve_dv(creature:s, default:s)=(dv:s) dimorphic

Given a creature's file resref, returns the scriptname (death variable) of the creature. If it has none, assign it one. By default, the assigned scriptname is its resref; you can override this by setting 'default'.

resolve_sectype(strref:i="-1", sectype:s, arguments:s, string:s)=(sectype_value:s, value:s) dimorphic

Given a sectype 'sectype' (synonym: 'arguments') and associated string (STR_VAR 'string') or tlk entry (INT_VAR 'strref'), check if the sectype is already present. If it is, set its string to the specified string. If it isn't, add it, with that string. Either way, return its value as 'sectype_value' (synonym: 'value').

If both the strref and string are specified, default to the string (and log a warning). If string is "" (the default), use strref=-1 rather than an actual blank string.

resolve_splprot_entry(stat:i, val:i, value:i, relation_number:i, relation:s, description:s)=(value:s) dimorphic

Given 'stat', 'val' (legacy synonym: 'value'), and either 'relation_number' or 'relation', return an appropriate entry in splprot.2da, adding it if necessary. (see IESDP opcode documentation for opcode 324).

'Relation' can be:

- 'equals'/'equal' (resolves to 1)
- 'less'/'less_than' (resolves to 2)
- 'greater'/'greater_than' (resolves to 3)
- 'less_than_equal'/'less_than_equals'/'less_equal' (resolves to 0)
- 'greater_equal'/'greater_equals' (resolves to 4)
- 'not_equal' (resolves to 5)

'description', if set, is added to the bare number of a new entry, following the 2.6 EE style. (Existing entries do not gain descriptions.)

resolve_statdesc(check_first:i="-1", strref:i="-1", string:s, bam:s, bam_name:s, path:s, location:s, locbase:s)=(stat_num:s) dimorphic

Adds a new line to statdesc.2da. You need to specify:

- the strref of a string, 'strref' (or you can specify the string directly, 'string', and it will be added to dialog.tlk)
- the name ('bam') of the bam file to be used for the line. (It can be an in-game file, or one to be copied over from your mod directory - SFO will see if it exists, and try to copy it if it doesn't.)
- the location of the bam file, if it is in your mod directory, specified SFO-style via 'location','locbase','path'.
- the actual name to be used for the bam file, 'bam_name'. If you leave it blank, 'bam' will be used instead (always do this if you are using an in-game file). If you set it to 'auto', a unique name will be auto-generated.

If you set the INT_VAR 'check_first', SFO will first check that line number to see if it exists. If it does, its line will be returned and no new line will be added; however, the description will be set if it is currently blank.

If you set the bam to "****", no bam will be used.