# alter_script function library

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

## Description

A collection of functions to edit blocks of a BCS file. Common structure: we go through the in-game BCS 'script'.bcs block by block. We specify up to 5 regexps (match and match1-match5), and check each against the decompiled block. On a match, we then do something (what, depends on the function). If the Boolean 'only_once' is set, we stop after the first match. If 'recompile' is set to 0, we don't recompile the script afterwards (this is mostly for debugging).

Alternately or additionally, a patch function 'match_function' can be specified, which should return one Boolean, 'value'. match_function is run on each decompiled block, and that block is only matched if the function returns 1. You can use the anonymous-function construct.

## Public functions

script_alter_block(only_once:b, recompile:b=1, script:s, patch:f, function:f, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, swap_out:s, swap_out1:s, swap_out2:s, swap_out3:s, swap_out4:s, swap_out5:s, swap_in:s, swap_in1:s, swap_in2:s, swap_in3:s, swap_in4:s, swap_in5:s)=() action

Up to 6 regexps ('swap_out', and 'swap_out1'-'swap_out5') are specified. Each is matched against any matched block via REPLACE_TEXTUALLY, and on a match, is swapped for (respectively) 'swap_in' or 'swap_in1'-'swap_in5'.

script_array_to_block(array:s)=(block:s) patch

Given 'array'', which should be of the form created by script_block_to_array, return the BAF block as 'block'.

script_clone_block(insert_above:b, only_once:b, recompile:b=1, script:s, patch:f, function:f, patch_original:f, function_original:f, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, swap_out:s, swap_out1:s, swap_out2:s, swap_out3:s, swap_out4:s, swap_out5:s, swap_in:s, swap_in1:s, swap_in2:s, swap_in3:s, swap_in4:s, swap_in5:s, original_swap_out:s, original_swap_out1:s, original_swap_out2:s, original_swap_out3:s, original_swap_out4:s, original_swap_out5:s, original_swap_in:s, original_swap_in1:s, original_swap_in2:s, original_swap_in3:s, original_swap_in4:s, original_swap_in5:s)=() action

Any matched block is copied directly below (or, if insert_above=1, directly above) the matched block. Up to 6 regexps ('swap_out', and 'swap_out1'-'swap_out5') are specified. Each is matched against the (decompiled) copied block via REPLACE_TEXTUALLY, and on a match, is swapped for (respectively) 'swap_in' or 'swap_in1'-'swap_in5'. The same happens to the original block, using 'original_swap_out'/'original_swap_out[1-5]' and 'original_swap_in'/'original_swap_in[1-5]'.

script_delete_block(only_once:b, recompile:b=1, script:s, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s)=() action

Any matched block is deleted.

script_disjunctive_delete(arguments:s)=() patch

Acting on the current file, which should be a single BAF block, delete any line that contains "arguments", so as to preserve logical structure (i.e. this can safely delete a line that might be inside an OR()).

script_insert_block(insert_above:b, only_once:b, recompile:b=1, script:s, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, insert:s, location:s, locbase:s, path:s)=() action

'insert' should be either a complete path to a BAF file, or the filename of a BAF file with location given in sfo fashion by 'location'/'locbase'/'path'. That file is inserted after (or, if insert_above=1, before) any matched block.

script_replace_block(only_once:b, recompile:b=1, script:s, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, insert:s, location:s, locbase:s, path:s)=() action

'insert' should be either a complete path to a BAF file, or the filename of a BAF file with location given in sfo fashion by 'location'/'locbase'/'path'. That file is substituted in to replace any matched block.

## Internal functions

These should not be called from outside the library itself.

ALTER_SCRIPT_BLOCK(only_once:b, recompile:b=1, script:s, patch:f, function:f, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, swap_out:s, swap_out1:s, swap_out2:s, swap_out3:s, swap_out4:s, swap_out5:s, swap_in:s, swap_in1:s, swap_in2:s, swap_in3:s, swap_in4:s, swap_in5:s)=() action

CLONE_SCRIPT_BLOCK(insert_above:b, only_once:b, recompile:b=1, script:s, patch:f, function:f, patch_original:f, function_original:f, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, swap_out:s, swap_out1:s, swap_out2:s, swap_out3:s, swap_out4:s, swap_out5:s, swap_in:s, swap_in1:s, swap_in2:s, swap_in3:s, swap_in4:s, swap_in5:s, original_swap_out:s, original_swap_out1:s, original_swap_out2:s, original_swap_out3:s, original_swap_out4:s, original_swap_out5:s, original_swap_in:s, original_swap_in1:s, original_swap_in2:s, original_swap_in3:s, original_swap_in4:s, original_swap_in5:s)=() action

DELETE_SCRIPT_BLOCK(only_once:b, recompile:b=1, script:s, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s)=() action

INSERT_SCRIPT_BLOCK(insert_above:b, only_once:b, recompile:b=1, script:s, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, insert:s, location:s, locbase:s, path:s)=() action

internal_script_block_master(insert_above:b, only_once:b, recompile:b=1, replace:b, script:s, patch:s, patch_original:s, match_function:s, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, internal_insert_data:s, swap_out:s, swap_out1:s, swap_out2:s, swap_out3:s, swap_out4:s, swap_out5:s, swap_in:s, swap_in1:s, swap_in2:s, swap_in3:s, swap_in4:s, swap_in5:s, original_swap_out:s, original_swap_out1:s, original_swap_out2:s, original_swap_out3:s, original_swap_out4:s, original_swap_out5:s, original_swap_in:s, original_swap_in1:s, original_swap_in2:s, original_swap_in3:s, original_swap_in4:s, original_swap_in5:s, type:s)=() action

This is actually the innards of the various functions in this library, all of which are hooks into it.

REPLACE_SCRIPT_BLOCK(only_once:b, recompile:b=1, script:s, match_function:f, match:s, match1:s, match2:s, match3:s, match4:s, match5:s, insert:s, location:s, locbase:s, path:s)=() action

script_block_to_array(block:s)=(length:s, array:a) patch

Given 'block', which should be a single BAF block, return an array 'array' whose keys are successive integers (from 0) and whose values are the successive lines of the block. Also return 'length', the number of lines in the block.