diff --git a/arrays/index.html b/arrays/index.html index 1b88bd14..92ffa7ab 100644 --- a/arrays/index.html +++ b/arrays/index.html @@ -64,4 +64,4 @@ // kaboom!!! end end -

Array operators reference

*mixed means any type

Backward compatibility notes

For those who used arrays in their mods before sfall 3.4:


Table of contents

+

Array operators reference

*mixed means any type

Backward compatibility notes

For those who used arrays in their mods before sfall 3.4:


Table of contents

diff --git a/assets/js/search-data.json b/assets/js/search-data.json index 6c088479..19bf46fd 100644 --- a/assets/js/search-data.json +++ b/assets/js/search-data.json @@ -78,7 +78,7 @@ },"11": { "doc": "Arrays", "title": "Array operators reference", - "content": "*mixed means any type . | int create_array(int size, int flags): . | creates permanent array (but not “saved”) | if size >= 0, creates list with given size | if size == -1, creates map (associative array) | if size == -1 and flags == 2, creates a “lookup” map (associative array) in which the values of existing keys are read-only and can’t be updated. This type of array allows you to store a zero (0) key value . | NOTE: in earlier versions (up to 4.1.3/3.8.13) the second argument is not used, just use 0 | . | returns arrayID (valid until array is deleted) | . | int temp_array(int size, int flags): . | works exactly like create_array, only created array becomes “temporary” | . | void fix_array(int arrayID): . | changes “temporary” array into “permanent” (“permanent” arrays are not automatically saved into savegames) | . | void set_array(int arrayID, mixed key, mixed value): . | sets array value | if used on list, “key” must be numeric and within valid index range (0..size-1) | if used on map, key can be of any type | to “unset” a value from map, just set it to zero (0) . | NOTE: to add a value of 0 for the key, use the float value of 0.0 | . | this works exactly like statement: arrayID[key] := value; | . | mixed get_array(int arrayID, mixed key): . | returns array value by key or index | if key doesn’t exist or index is not in valid range, returns 0 | works exactly like expression: (arrayID[key]) | . | void resize_array(int arrayID, int size): . | changes array size | applicable to maps too, but only to reduce elements | there are number of special negative values of “size” which perform various operations on the array, use macros sort_array, sort_array_reverse, reverse_array, shuffle_array from sfall.h header | . | void free_array(int arrayID): . | deletes any array | if array was “saved”, it will be removed from a savegame | . | mixed scan_array(int arrayID, mixed value): . | searches for a first occurence of given value inside given array | if value is found, returns it’s index (for lists) or key (for maps) | if value is not found, returns -1 (be careful, as -1 can be a valid key for a map) | . | int len_array(int arrayID): . | returns number of elements or key=>value pairs in a given array | if array is not found, returns -1 (can be used to check if given array exist) | . | mixed array_key(int arrayID, int index): . | don’t use it directly; it is generated by the compiler in foreach loops | for lists, returns index back (no change) | for maps, returns a key at the specified numeric index (don’t rely on the order in which keys are stored though) | can be checked if given array is associative or not, by using index (-1): 0 - array is list, 1 - array is map | . | int arrayexpr(mixed key, mixed value): . | don’t use it directly; it is used by compiler to create array expressions | assigns value to a given key in an array, created by last create_array or temp_array call | always returns 0 | . | void save_array(mixed key, int arrayID): . | makes the array saveable; it will be saved in sfallgv.sav file when saving the game | arrayID is associated with given “key” | array becomes permanent (if it was temporary) and “saved” | key can be of any type (int, float or string) | if you specify 0 as the key for the array ID, it will make the array “unsaved” | . | int load_array(mixed key): . | loads array from savegame data by the same key provided in save_array | returns array ID or zero (0) if none found | . | . ", + "content": "*mixed means any type . | int create_array(int size, int flags): . | creates permanent array (but not “saved”) | if size >= 0, creates list with given size | if size == -1, creates map (associative array) | if size == -1 and flags == 2, creates a “lookup” map (associative array) in which the values of existing keys are read-only and can’t be updated. This type of array allows you to store a zero (0) key value . | NOTE: in earlier versions (up to 4.1.3/3.8.13) the second argument is not used, just use 0 | . | returns arrayID (valid until array is deleted) | . | int temp_array(int size, int flags): . | works exactly like create_array, only created array becomes “temporary” | . | void fix_array(int arrayID): . | changes “temporary” array into “permanent” (“permanent” arrays are not automatically saved into savegames) | . | void set_array(int arrayID, mixed key, mixed value): . | sets array value | if used on list, “key” must be numeric and within valid index range (0..size-1) | if used on map, key can be of any type | to “unset” a value from map, just set it to zero (0) . | NOTE: to add a value of 0 for the key, use the float value of 0.0 | . | this works exactly like statement: arrayID[key] := value; | . | mixed get_array(int arrayID, mixed key): . | returns array value by key or index | if key doesn’t exist or index is not in valid range, returns 0 | works exactly like expression: (arrayID[key]) | . | void resize_array(int arrayID, int size): . | changes array size | applicable to maps too, but only to reduce elements | there are number of special negative values of “size” which perform various operations on the array, use macros sort_array, sort_array_reverse, reverse_array, shuffle_array from sfall.h header | . | void free_array(int arrayID): . | deletes any array | if array was “saved”, it will be removed from a savegame | . | mixed scan_array(int arrayID, mixed value): . | searches for a first occurrence of given value inside given array | if value is found, returns it’s index (for lists) or key (for maps) | if value is not found, returns -1 (be careful, as -1 can be a valid key for a map) | . | int len_array(int arrayID): . | returns number of elements or key=>value pairs in a given array | if array is not found, returns -1 (can be used to check if given array exist) | . | mixed array_key(int arrayID, int index): . | don’t use it directly; it is generated by the compiler in foreach loops | for lists, returns index back (no change) | for maps, returns a key at the specified numeric index (don’t rely on the order in which keys are stored though) | can be checked if given array is associative or not, by using index (-1): 0 - array is list, 1 - array is map | . | int arrayexpr(mixed key, mixed value): . | don’t use it directly; it is used by compiler to create array expressions | assigns value to a given key in an array, created by last create_array or temp_array call | always returns 0 | . | void save_array(mixed key, int arrayID): . | makes the array saveable; it will be saved in sfallgv.sav file when saving the game | arrayID is associated with given “key” | array becomes permanent (if it was temporary) and “saved” | key can be of any type (int, float or string) | if you specify 0 as the key for the array ID, it will make the array “unsaved” | . | int load_array(mixed key): . | loads array from savegame data by the same key provided in save_array | returns array ID or zero (0) if none found | . | . ", "url": "/sfall/arrays/#array-operators-reference", "relUrl": "/arrays/#array-operators-reference" @@ -232,7 +232,7 @@ },"33": { "doc": "Explosions", "title": "Functions", - "content": ". | get_explosion_damage | item_make_explosive | metarule2_explosions | set_attack_explosion_art | set_attack_explosion_pattern | set_attack_explosion_radius | set_attack_is_explosion_fire | set_dynamite_damage | set_explosion_max_targets | set_explosion_radius | set_plastic_damage | . get_explosion_damage . sfall.h . array get_explosion_damage(itemPid) . Returns an array of the minimum and maximum damage of the explosive item. item_make_explosive . sfall.h . void item_make_explosive(int pid, int activePid, int minDamage, int maxDamage) . | makes the specified item (pid) an explosive item like Dynamite or Plastic Explosives | maxDamage is optional | activePid is for an item with an active timer, can be the same as the pid argument | the item proto must be “Misc Item” type and have “Use” action flag | minDamage/maxDamage are the minimum and maximum explosion damage | using the function on an item that is already set as an explosive will override its previous settings | NOTE: this function does not work for pids of Dynamite and Plastic Explosives | . metarule2_explosions . int metarule2_explosions(int arg1, int arg2) . Was made as a dirty easy hack to allow dynamically change some explosion parameters (ranged attack). All changed parameters are reset to vanilla state automatically after each attack action. set_attack_explosion_art . sfall.h . void set_attack_explosion_art(x, y) . Y not used and X is a misc frame ID (last 3 bytes, without object type) to use for the next explosion. set_attack_explosion_pattern . sfall.h . void set_attack_explosion_pattern(x, y) . Currently Y is not used and X means: 1 - reduced explosion pattern (3 effects are spawned instead of 7), 0 - full pattern. set_attack_explosion_radius . sfall.h . void set_attack_explosion_radius(x) . Changes radius at which explosion will hit secondary targets for the next attack (from the experiments it is limited to something around 8 by the engine). set_attack_is_explosion_fire . sfall.h . void set_attack_is_explosion_fire . If you call this right before using a weapon with fire damage type (e.g. in HOOK_AFTERHITROLL), it will produce explosion effects (and radius damage) just like “explosion” type, but all targets will still receive fire damage. set_dynamite_damage . sfall.h . void set_dynamite_damage(minDmg, maxDmg) . Sets the minimum and maximum damage for Dynamite. Changed damage will be reset each time the player reloads the game. set_explosion_max_targets . sfall.h . void set_explosion_max_targets(x) . Sets the maximum number of additional targets for an explosion, valid range: 1..6 (default is 6). set_explosion_radius . sfall.h . void set_explosion_radius(grenade, rocket) . Sets a permanent radius of the explosion for grenades and/or rockets. Passing 0 means not changing the corresponding radius. Changed radius will be reset each time the player reloads the game. set_plastic_damage . sfall.h . void set_plastic_damage(minDmg, maxDmg) . Sets the minimum and maximum damage for Plastic Explosives. Changed damage will be reset each time the player reloads the game. ", + "content": ". | get_explosion_damage | item_make_explosive | metarule2_explosions | set_attack_explosion_art | set_attack_explosion_pattern | set_attack_explosion_radius | set_attack_is_explosion_fire | set_dynamite_damage | set_explosion_max_targets | set_explosion_radius | set_plastic_damage | . get_explosion_damage . sfall.h . array get_explosion_damage(itemPid) . Returns an array of the minimum and maximum damage of the explosive item. item_make_explosive . sfall.h . void item_make_explosive(int pid, int activePid, int minDamage, int maxDamage) . | makes the specified item (pid) an explosive item like Dynamite or Plastic Explosives | maxDamage is optional | activePid is for an item with an active timer, can be the same as the pid argument | the item proto must be the Misc Item type and have the Use action flag | minDamage/maxDamage are the minimum and maximum explosion damage | using the function on an item that is already set as an explosive will override its previous settings | NOTE: this function does not work for pids of Dynamite and Plastic Explosives | . metarule2_explosions . int metarule2_explosions(int arg1, int arg2) . Was made as a dirty easy hack to allow dynamically change some explosion parameters (ranged attack). All changed parameters are reset to vanilla state automatically after each attack action. set_attack_explosion_art . sfall.h . void set_attack_explosion_art(x, y) . Y not used and X is a misc frame ID (last 3 bytes, without object type) to use for the next explosion. set_attack_explosion_pattern . sfall.h . void set_attack_explosion_pattern(x, y) . Currently Y is not used and X means: 1 - reduced explosion pattern (3 effects are spawned instead of 7), 0 - full pattern. set_attack_explosion_radius . sfall.h . void set_attack_explosion_radius(x) . Changes radius at which explosion will hit secondary targets for the next attack (from the experiments it is limited to something around 8 by the engine). set_attack_is_explosion_fire . sfall.h . void set_attack_is_explosion_fire . If you call this right before using a weapon with fire damage type (e.g. in HOOK_AFTERHITROLL), it will produce explosion effects (and radius damage) just like “explosion” type, but all targets will still receive fire damage. set_dynamite_damage . sfall.h . void set_dynamite_damage(minDmg, maxDmg) . Sets the minimum and maximum damage for Dynamite. Changed damage will be reset each time the player reloads the game. set_explosion_max_targets . sfall.h . void set_explosion_max_targets(x) . Sets the maximum number of additional targets for an explosion, valid range: 1..6 (default is 6). set_explosion_radius . sfall.h . void set_explosion_radius(grenade, rocket) . Sets a permanent radius of the explosion for grenades and/or rockets. Passing 0 means not changing the corresponding radius. Changed radius will be reset each time the player reloads the game. set_plastic_damage . sfall.h . void set_plastic_damage(minDmg, maxDmg) . Sets the minimum and maximum damage for Plastic Explosives. Changed damage will be reset each time the player reloads the game. ", "url": "/sfall/explosions/#functions", "relUrl": "/explosions/#functions" @@ -267,7 +267,7 @@ },"38": { "doc": "Global scripts", "title": "Global scripts", - "content": "As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object. (i.e. using self_obj without using set_self first will crash the script.) To use a global script, the script must have a name which begins with gl and contains a procedure called start, map_enter_p_proc, map_exit_p_proc, or map_update_p_proc. The start procedure will be executed once when the player loads a saved game or starts a new game. The map_*_p_proc procedures will be executed once when a map is being entered/left/updated. If you wish the script to be executed repeatedly, call set_global_script_repeat on the first run of the start procedure using the number of frames between each run as the argument. (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.) . Global scripts have multiple modes, which can be set using the set_global_script_type function. | In the default mode (i.e. mode 0) their execution is linked to the local map game loop, so the script will not run in dialogs or on the world map. [Using mode 1 requires the input wrapper to be enabled. Use available_global_script_types to check what is available.] - Obsolete. | In mode 1 their execution is linked to the player input, and so they will run whenever the mouse cursor is visible on screen, including the world map, character dialogs etc. | In mode 2, execution is linked to the world map loop, so the script will only be executed on the world map and not on the local map or in any dialog windows. | Mode 3 is a combination of modes 0 and 2, so scripts will be executed on both local maps and the world map, but not in dialog windows. | . ", + "content": "As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object (i.e. using self_obj without using set_self first will crash the script). To use a global script, the script must have a name which begins with gl and contains a procedure called start, map_enter_p_proc, map_exit_p_proc, or map_update_p_proc. The start procedure will be executed once when the player loads a saved game or starts a new game. The map_*_p_proc procedures will be executed once when a map is being entered/left/updated. If you wish the script to be executed repeatedly, call set_global_script_repeat on the first run of the start procedure using the number of frames between each run as the argument (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.). Global scripts have multiple modes, which can be set using the set_global_script_type function. | In the default mode (i.e. mode 0) their execution is linked to the local map game loop, so the script will not run in dialogs or on the world map. [Using mode 1 requires the input wrapper to be enabled. Use available_global_script_types to check what is available.] - Obsolete. | In mode 1 their execution is linked to the player input, and so they will run whenever the mouse cursor is visible on screen, including the world map, character dialogs etc. | In mode 2, execution is linked to the world map loop, so the script will only be executed on the world map and not on the local map or in any dialog windows. | Mode 3 is a combination of modes 0 and 2, so scripts will be executed on both local maps and the world map, but not in dialog windows. | . ", "url": "/sfall/global-scripts/", "relUrl": "/global-scripts/" @@ -309,7 +309,7 @@ },"44": { "doc": "Hook functions", "title": "Functions", - "content": ". | get_sfall_arg | get_sfall_arg_at | get_sfall_args | init_hook | register_hook | register_hook_proc | register_hook_proc_spec | set_sfall_arg | set_sfall_return | . get_sfall_arg . mixed get_sfall_arg() . Gets the next argument from sfall. Each time it’s called it returns the next argument, or otherwise it returns 0 if there are no more arguments left. You can arbitrarily get the value of any argument using the sfall_func1(\"get_sfall_arg_at\", argNum) function. get_sfall_arg_at . sfall.h . mixed get_sfall_arg_at(int argNum) . Gets the value of hook argument with the specified argument number (first argument of hook starts from 0) . get_sfall_args . int get_sfall_args() . Returns all hook arguments as a new temp array. init_hook . int init_hook() . The hook script equivalent of game_loaded; it returns 1 when the script is loaded for the first time or when the player reloads the game, and 0 otherwise. register_hook . void register_hook(int hookID) . Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, start proc will be executed in current global script. You can use all above functions like normal. register_hook_proc . void register_hook_proc(int hookID, proc procedure) . The same as register_hook, except that you specifically define which procedure in the current script should be called as a hook (instead of “start” by default). Pass procedure the same as how you use dialog option functions. This IS the recommended way to use hook scripts, as it gives both modularity (each mod logic in a separate global script, no conflicts if you don’t use “hs_*.int” scripts) and flexibility (you can place all related hook scripts for specific mod in a single script!). Use zero (0) as second argument to unregister hook script from current global script. NOTE: you can hook several scripts to a single hook point, for example if it’s different mods from different authors or just some different aspects of one larger mod. In this case scripts are executed in reverse order of how they were registered. When one of the scripts in a chain returns value with set_sfall_return, the next script may override this value if calls set_sfall_return again. Sometimes you need to multiply certain value in a chain of hook scripts. Example: let’s say we have a Mod A which reduces all “to hit” chances by 50%. The code might look like this: . original_chance = get_sfall_arg; set_sfall_return(original_chance / 2); . Mod B also want to affect hit chances globally, by increasing them by 50%. Now in order for both mods to work well together, we need to add this line to Mod A hook script: . set_sfall_arg(0, (original_chance / 2)); . This basically changes hook argument for the next script. Mod B code: . original_chance = get_sfall_arg; set_sfall_return(original_chance * 1.5); set_sfall_arg(0, (original_chance * 1.5)); . So if you combine both mods together, they will run in chain and the end result will be a 75% from original hit chance (hook register order doesn’t matter in this case, if you use set_sfall_arg in both hooks). The defines to use for the hookID are in sfall.h. register_hook_proc_spec . void register_hook_proc_spec(int hookID, procedure proc) . Works very similar to register_hook_proc, except that it registers the current script at the end of the hook script execution chain (i.e. the script will be executed after all previously registered scripts for the same hook, including the hs_*.int script). All scripts hooked to a single hook point with this function are executed in exact order of how they were registered, as opposed to the description below, which refers to using register_hook/register_hook_proc functions. set_sfall_arg . void set_sfall_arg(int argNum, int value) . Changes argument value. The argument number (argNum) is 0-indexed. This is useful if you have several hook scripts attached to one hook point (see register_hook_proc). set_sfall_return . void set_sfall_return(int value) . Used to return the new values from the script. Each time it’s called it sets the next value, or if you’ve already set all return values it does nothing. ", + "content": ". | get_sfall_arg | get_sfall_arg_at | get_sfall_args | init_hook | register_hook | register_hook_proc | register_hook_proc_spec | set_sfall_arg | set_sfall_return | . get_sfall_arg . mixed get_sfall_arg() . Gets the next argument from sfall. Each time it’s called it returns the next argument, or otherwise it returns 0 if there are no more arguments left. You can arbitrarily get the value of any argument using the sfall_func1(\"get_sfall_arg_at\", argNum) function. get_sfall_arg_at . sfall.h . mixed get_sfall_arg_at(int argNum) . Gets the value of hook argument with the specified argument number (first argument of hook starts from 0) . get_sfall_args . int get_sfall_args() . Returns all hook arguments as a new temp array. init_hook . int init_hook() . The hook script equivalent of game_loaded; it returns 1 when the script is loaded for the first time or when the player reloads the game, and 0 otherwise. register_hook . void register_hook(int hookID) . Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, start procedure will be executed in current global script. You can use all above functions like normal. register_hook_proc . void register_hook_proc(int hookID, proc procedure) . The same as register_hook, except that you specifically define which procedure in the current script should be called as a hook (instead of “start” by default). Pass procedure the same as how you use dialog option functions. This IS the recommended way to use hook scripts, as it gives both modularity (each mod logic in a separate global script with no conflicts) and flexibility. You can place all related hook scripts for a specific mod in one global script! . Use zero (0) as second argument to unregister hook script from current global script. NOTE: you can hook several scripts to a single hook point, for example if it’s different mods from different authors or just some different aspects of one larger mod. When one of the scripts in a chain returns value with set_sfall_return, the next script may override this value if calls set_sfall_return again. Example: Sometimes you need to multiply certain value in a chain of hook scripts. Let’s say we have a Mod A which reduces all “to hit” chances by 50%. The code might look like this: . original_chance = get_sfall_arg; set_sfall_return(original_chance / 2); . Mod B also want to affect hit chances globally, by increasing them by 50%. Now in order for both mods to work well together, we need to add this line to Mod A hook script: . set_sfall_arg(0, (original_chance / 2)); . This basically changes hook argument for the next script. Mod B code: . original_chance = get_sfall_arg; set_sfall_return(original_chance * 1.5); set_sfall_arg(0, (original_chance * 1.5)); . So if you combine both mods together, they will run in chain and the end result will be a 75% from original hit chance (hook register order doesn’t matter in this case, if you use set_sfall_arg in both hooks). The defines to use for the hookID are in sfall.h. register_hook_proc_spec . void register_hook_proc_spec(int hookID, procedure proc) . Works the same as register_hook_proc, except that it registers the current script at the end of the hook script execution chain (i.e. the script will be executed after all previously registered scripts for the same hook, including the hs_<name>.int script). In addition, all scripts hooked to a single hook point with this function are executed in the exact order of how they were registered. In the case of using register_hook and register_hook_proc functions, scripts are executed in reverse order of how they were registered. The execution chain of script procedures for a hook is as follows: 1. Procedures registered with register_hook and register_hook_proc functions (executed in reverse order of registration). 2. The hs_<name>.int script. 3. Procedures registered with the register_hook_proc_spec function (executed in the exact order of registration). set_sfall_arg . void set_sfall_arg(int argNum, int value) . Changes argument value. The argument number (argNum) is 0-indexed. This is useful if you have several hook scripts attached to one hook point (see register_hook_proc). set_sfall_return . void set_sfall_return(int value) . Used to return the new values from the script. Each time it’s called it sets the next value, or if you’ve already set all return values it does nothing. ", "url": "/sfall/hook-functions/#functions", "relUrl": "/hook-functions/#functions" @@ -428,7 +428,7 @@ },"61": { "doc": "Hook types", "title": "DescriptionObj", - "content": "HOOK_DESCRIPTIONOBJ (hs_descriptionobj.int) . Runs when using the examine action icon to display the description of an object. You can override the description text. An example usage would be to add an additional description to the item based on player’s stats/skills. Does not run if the script of the object overrides the description. Obj arg0 - the object int ret0 - a pointer to the new text received by using \"get_string_pointer\" function . ", + "content": "HOOK_DESCRIPTIONOBJ (hs_descriptionobj.int) . Runs when using the examine action icon to display the description of an object. You can override the description text. An example usage would be to add an additional description to the item based on player’s stats/skills. Does not run if the script of the object overrides the description. Obj arg0 - the object int ret0 - a pointer to the new text received by using the get_string_pointer function . ", "url": "/sfall/hook-types/#descriptionobj", "relUrl": "/hook-types/#descriptionobj" @@ -470,7 +470,7 @@ },"67": { "doc": "Hook types", "title": "InventoryMove", - "content": "HOOK_INVENTORYMOVE (hs_inventorymove.int) . Runs before moving items between inventory slots in dude interface. You can override the action. What you can NOT do with this hook: . | force moving items to inappropriate slots (like gun in armor slot) What you can do: | restrict player from using specific weapons or armors | add AP costs for all inventory movement including reloading | apply or remove some special scripted effects depending on PC’s armor | . int arg0 - Target slot: 0 - main backpack 1 - left hand 2 - right hand 3 - armor slot 4 - weapon, when reloading it by dropping ammo 5 - container, like bag/backpack 6 - dropping on the ground 7 - picking up item 8 - dropping item on the character portrait Item arg1 - Item being moved Item arg2 - Item being replaced, weapon being reloaded, or container being filled (can be 0) int ret0 - Override setting (-1 - use engine handler, any other value - prevent relocation of item/reloading weapon/picking up item) . ", + "content": "HOOK_INVENTORYMOVE (hs_inventorymove.int) . Runs before moving items between inventory slots in dude interface. You can override the action. What you can NOT do with this hook: . | force moving items to inappropriate slots (like gun in armor slot) What you can do: | restrict player from using specific weapons or armors | add AP costs for all inventory movement including reloading | apply or remove some special scripted effects depending on PC’s armor | . int arg0 - Target slot: 0 - main backpack 1 - left hand 2 - right hand 3 - armor slot 4 - weapon, when reloading it by dropping ammo 5 - container, like bag/backpack 6 - dropping on the ground 7 - picking up item 8 - dropping item on the character portrait Item arg1 - Item being moved Item arg2 - Item being replaced, weapon being reloaded, or container being filled (can be 0) int ret0 - Override setting (-1 - use engine handler, any other value - prevent relocation of item/reloading weapon/picking up item) . Notes for the event of dropping items on the ground: . | the event is called for each item when dropping multiple items from the stack | for ammo type items, the number of dropped ammo in a pack can be found by using the get_weapon_ammo_count function | for the PID_BOTTLE_CAPS item, the event is called only once, and the number of dropped units can be found from the value of the OBJ_DATA_CUR_CHARGES object field (or with the get_weapon_ammo_count function) | . ", "url": "/sfall/hook-types/#inventorymove", "relUrl": "/hook-types/#inventorymove" @@ -631,7 +631,7 @@ },"90": { "doc": "Hook types", "title": "UseSkillOn", - "content": "HOOK_USESKILLON (hs_useskillon.int) . Runs before using any skill on any object. Lets you override the critter that uses the skill. NOTE: The user critter can’t be overridden when using Steal skill. Critter arg0 - the user critter (usually dude_obj) Obj arg1 - the target object/critter int arg2 - skill being used int ret0 - a new critter to override the user critter. Pass -1 to cancel the skill use, pass 0 to skip this return value int ret1 - pass 1 to allow the skill being used in combat (only for dude_obj or critter being controlled by the player) . ", + "content": "HOOK_USESKILLON (hs_useskillon.int) . Runs before using any skill on any object. Lets you override the critter that uses the skill. NOTE: The user critter can’t be overridden when using Steal skill. Critter arg0 - the user critter (usually dude_obj) Obj arg1 - the target object/critter int arg2 - skill being used int ret0 - a new critter to override the user critter. Pass -1 to cancel the skill use, pass 0 to skip this return value int ret1 - pass 1 to allow the skill to be used in combat (only for dude_obj or critter being controlled by the player) . ", "url": "/sfall/hook-types/#useskillon", "relUrl": "/hook-types/#useskillon" @@ -652,7 +652,7 @@ },"93": { "doc": "Hooks", "title": "Hooks compatibility", - "content": "To aid in mods compatibility, avoid using hs_xxx .int scripts. Instead it is recommended to use a normal global script combined with register_hook_proc or register_hook. Example setup for a hook-script based mod: . procedure tohit_hook_handler begin display_msg(\"Modifying hit_hook \" + get_sfall_arg); set_hit_chance_max(100); set_sfall_return(100); end procedure start begin if game_loaded then begin register_hook_proc(HOOK_TOHIT, tohit_hook_handler); end end . ", + "content": "To aid in mods compatibility, avoid using the predefined hs_<name>.int scripts. Instead it is recommended to use a normal global script combined with register_hook_proc or register_hook. Example setup for a hook-script based mod: . procedure tohit_hook_handler begin display_msg(\"Modifying hit_hook \" + get_sfall_arg); set_hit_chance_max(100); set_sfall_return(100); end procedure start begin if game_loaded then begin register_hook_proc(HOOK_TOHIT, tohit_hook_handler); end end . ", "url": "/sfall/hooks/#hooks-compatibility", "relUrl": "/hooks/#hooks-compatibility" @@ -855,28 +855,28 @@ },"122": { "doc": "Objects and scripts", "title": "Functions", - "content": ". | dialog_obj | get_flags | get_object_data | get_script | loot_obj | obj_is_carrying_obj | obj_is_openable | obj_under_cursor | real_dude_obj | remove_script | set_dude_obj | set_flags | set_object_data | set_scr_name | set_script | set_self | set_unique_id | . dialog_obj . sfall.h . ObjectPtr dialog_obj() . Returns a pointer to the object (critter) the player is having a conversation or bartering with. get_flags . sfall.h . int get_flags(ObjectPtr obj) . Gets the current value of object flags (see define_extra.h for available flags). get_object_data . sfall.h . get_object_data(ObjectPtr object, int offset) . Returns the data at the specified offset of an object (see OBJ_DATA_* constants in define_extra.h for offsets). get_script . int get_script(ObjectPtr) . | accepts a pointer to an object and returns its scriptID (line number in scripts.lst), or 0 if the object is unscripted. | returns -1 on argument error. | . loot_obj . sfall.h . ObjectPtr loot_obj() . Returns a pointer to the target object (container or critter) of the loot screen. obj_is_carrying_obj . int (ObjectPtr invenObj, ObjectPtr itemObj) . Returns number of itemObj inside invenObj’s inventory, note that both arguments are object pointers. useful when dealing with different stacks of same item (obj_is_carrying_obj_pid just returns total for all stacks of the same PID.) . obj_is_openable . sfall.h . bool obj_is_openable(object obj) . Returns True if the object is openable (i.e. has an opening/closing animation) . obj_under_cursor . sfall.h . ObjectPtr obj_under_cursor(bool onlyCritter, bool includeDude) . Returns the object under the cursor on the main game screen. | onlyCritter: . | True - only checks critters and ignores their cover (roof tiles, walls, scenery, etc.) | False - checks all objects (can’t check critters under objects) | . | passing False to the includeDude argument will ignore dude_obj . | NOTE: to get an object located on a tile when the cursor is in movement mode (hexagon cursor), use the tile_under_cursor function | . | . real_dude_obj . sfall.h . ObjectPtr real_dude_obj() . Returns the initial dude_obj after set_dude_obj was used. remove_script . void remove_script(ObjectPtr) . Accepts a pointer to an object and will remove the script from that object. set_dude_obj . sfall.h . void set_dude_obj(ObjectPtr critter) . Take control of a given critter. Passing value 0 will reset control back to “real” dude. set_flags . sfall.h . void set_flags(ObjectPtr obj, int flags) . Sets the current flags of an object. All flags are rewritten with given integer, so first get current flags with get_flags and use bwor/bwand to set/remove specific flag. set_object_data . sfall.h . set_object_data(ObjectPtr object, int offset, int data) . Sets the data at the specified offset of an object. set_scr_name . sfall.h . void set_scr_name(string name) . Overrides the name of the script object that was set from scrname.msg. | The changed name will be reset each time the player leaves the map or reloads the game | Passing an empty string (“”) to the name argument or omitting it will allow the game to get the name for the object from pro_*.msg files | NOTE: this function is intended for use in normal game scripts and overrides the name only once for the same object until reset | . set_script . void set_script(ObjectPtr, int scriptID) . Accepts a pointer to an object and scriptID, and applies the given script to an object (scriptID accept the same values as create_object_sid from sfall 3.6). If used on an object that is already scripted, it will remove the existing script first; you cannot have multiple scripts attached to a single object. Calling set_script on self_obj will have all sorts of wacky side effects, and should be avoided. If you add 0x80000000 to the sid when calling set_script, map_enter_p_proc will be SKIPPED. The start proc will always be run. set_self . void set_self(ObjectPtr) . Overrides the script’s self_obj for the next function call. | It is primarily used to allow the calling of functions which take an implicit self_obj parameter (e.g. drop_obj) from global scripts, but it can also be used from normal scripts. | self_obj will be reverted to its original value after the next function call. | Calling set_self(0) will also revert self_obj to its original value. It is recommended to call this after each use of set_self in normal scripts in order to avoid unforeseen side effects. | source_obj, target_obj, and similar functions will not work if preceded by set_self. | NOTE: for use_obj, use_obj_on_obj vanilla functions to work correctly, it is required to call set_self twice. You can also access the local variables in the script of an object after calling set_self twice. | . set_unique_id . sfall.h . int set_unique_id(ObjectPtr object, int flag) . Assigns a unique ID number to the object and returns it. If a unique ID number has already been assigned to an object, then ID number is returned without reassignment. flag is optional. | items with unique IDs will not stack with other items of the same type in the inventory | to just get the current ID number of an object, use get_object_data(object, OBJ_DATA_ID) | unique ID numbers are saved in your savegame, and have a range from 0x10000000 to 0x7FFFFFFF | there is also a unique ID number range for the player and party members from 18000 to 83535 | to assign a new ID number generated by the engine to the object (i.e. unassign a unique ID), call the function with two arguments and pass -1 for the flag argument | . ", + "content": ". | dialog_obj | get_flags | get_object_data | get_script | loot_obj | obj_is_carrying_obj | obj_is_openable | obj_under_cursor | real_dude_obj | remove_script | set_dude_obj | set_flags | set_object_data | set_scr_name | set_script | set_self | set_unique_id | . dialog_obj . sfall.h . ObjectPtr dialog_obj() . Returns a pointer to the object (critter) the player is having a conversation or bartering with. get_flags . sfall.h . int get_flags(ObjectPtr obj) . Gets the current value of object flags (see define_extra.h for available flags). get_object_data . sfall.h . get_object_data(ObjectPtr object, int offset) . Returns the data at the specified offset of an object (see OBJ_DATA_* constants in define_extra.h for offsets). get_script . int get_script(ObjectPtr obj) . | accepts a pointer to an object and returns its scriptID (line number in scripts.lst), or 0 if the object is unscripted. | returns -1 on argument error. | . loot_obj . sfall.h . ObjectPtr loot_obj() . Returns a pointer to the target object (container or critter) of the loot screen. obj_is_carrying_obj . int (ObjectPtr invenObj, ObjectPtr itemObj) . Returns number of itemObj inside invenObj’s inventory, note that both arguments are object pointers. useful when dealing with different stacks of same item (obj_is_carrying_obj_pid just returns total for all stacks of the same PID.) . obj_is_openable . sfall.h . bool obj_is_openable(object obj) . Returns True if the object is openable (i.e. has an opening/closing animation), False otherwise . obj_under_cursor . sfall.h . ObjectPtr obj_under_cursor(bool onlyCritter, bool includeDude) . Returns the object under the cursor on the main game screen. | onlyCritter: . | True - only checks critters and ignores their cover (roof tiles, walls, scenery, etc.) | False - checks all objects (can’t check critters under objects) | . | passing False to the includeDude argument will ignore dude_obj . | NOTE: to get an object located on a tile when the cursor is in movement mode (hexagon cursor), use the tile_under_cursor function | . | . real_dude_obj . sfall.h . ObjectPtr real_dude_obj() . Returns the initial dude_obj after set_dude_obj was used. remove_script . void remove_script(ObjectPtr obj) . Accepts a pointer to an object and will remove the script from that object. set_dude_obj . sfall.h . void set_dude_obj(ObjectPtr critter) . Take control of a given critter. Passing value 0 will reset control back to “real” dude. set_flags . sfall.h . void set_flags(ObjectPtr obj, int flags) . Sets the current flags of an object. All flags are rewritten with given integer, so first get current flags with get_flags and use bwor/bwand to set/remove specific flag. set_object_data . sfall.h . set_object_data(ObjectPtr object, int offset, int data) . Sets the data at the specified offset of an object. set_scr_name . sfall.h . void set_scr_name(string name) . Overrides the name of the script object that was set from scrname.msg. | The changed name will be reset each time the player leaves the map or reloads the game | Passing an empty string (“”) to the name argument or omitting it will allow the game to get the name for the object from pro_*.msg files | NOTE: this function is intended for use in normal game scripts and overrides the name only once for the same object until reset | . set_script . void set_script(ObjectPtr obj, int scriptID) . Accepts a pointer to an object and scriptID, and applies the given script to an object (scriptID accept the same values as create_object_sid from sfall 3.6). If used on an object that is already scripted, it will remove the existing script first; you cannot have multiple scripts attached to a single object. Calling set_script on self_obj will have all sorts of wacky side effects, and should be avoided. If you add 0x80000000 to the sid when calling set_script, map_enter_p_proc will be SKIPPED. The start proc will always be run. set_self . void set_self(ObjectPtr setObj) . Overrides the script’s self_obj for the next function call. | It is primarily used to allow the calling of functions which take an implicit self_obj parameter (e.g. drop_obj) from global scripts, but it can also be used from normal scripts. | self_obj will be reverted to its original value after the next function call. | Calling set_self(0) will also revert self_obj to its original value. It is recommended to call this after each use of set_self in normal scripts in order to avoid unforeseen side effects. | source_obj, target_obj, and similar functions will not work if preceded by set_self. | NOTE: for use_obj, use_obj_on_obj vanilla functions to work correctly, it is required to call set_self twice. You can also access the local variables in the script of an object after calling set_self twice. | . set_unique_id . sfall.h . int set_unique_id(ObjectPtr object, int flag) . Assigns a unique ID number to the object and returns it. If a unique ID number has already been assigned to an object, then ID number is returned without reassignment. flag is optional. | items with unique IDs will not stack with other items of the same type in the inventory | to just get the current ID number of an object, use get_object_data(object, OBJ_DATA_ID) | unique ID numbers are saved in your savegame, and have a range from 0x10000000 to 0x7FFFFFFF | there is also a unique ID number range for the player and party members from 18000 to 83535 | to assign a new ID number generated by the engine to the object (i.e. unassign a unique ID), call the function with two arguments and pass -1 for the flag argument | . ", "url": "/sfall/objects-and-scripts/#functions", "relUrl": "/objects-and-scripts/#functions" },"123": { "doc": "Optimization", "title": "Optimization", - "content": ". | sslc -O option | Writing your own code | . The executation speed of scripts is not typically important in an unmodded game, given the difference in performance between a modern computer and what Fallout was designed for. When you start adding mods to the mix there’s the potential for problems again, since sfall’s global script system means that you can have a large amount of scripts being run every single frame. ", + "content": ". | sslc -O option | Writing your own code | . The execution speed of scripts is not typically important in an unmodded game, given the difference in performance between a modern computer and what Fallout was designed for. When you start adding mods to the mix there’s the potential for problems again, since sfall’s global script system means that you can have a large amount of scripts being run every single frame. ", "url": "/sfall/optimization/", "relUrl": "/optimization/" },"124": { "doc": "Optimization", "title": "sslc -O option", - "content": "The sfall build of sslc supports a -O command line option to perform an optimization pass over the generated code. This isn’t a magic make-my-code-go-faster bullet; most of what it does is very limited in scope. It’s primary purpose was to strip out the procedures and variables which get automatically pulled into every script that includes define.h, whether you use them or not, and to do something about the additional variables that get created by foreach loops. There are several levels of optimization available: . | -O1 - Basic, only removes unreferenced globals variables and procedures, code itself remains untouched. | -O2 - Full, most code optimizations are on, but only those that were tested on complex scripts. | -O3 - Experimental, provides most efficiency, but tend to break some complex code due to bugs. | . The following optimizations are performed: . | constant expression folding: if an expression depends only on values which are known at compile time, then the expression is replaced by its result. a := 2 + 2; -> a := 4; . | constant variable initialization: All variables are initialised to some value, (‘0’, if you don’t specify anything else,) so sslc attempts to make use of that fact to remove the first assignment to a variable if the first assignment is a constant expression. variable a; -> variable a := 4; a := 4; -> . | constant propagation: checks for values assigned to variables which can be computed at compile time, and replaces relevent references to the symbol by the constant. The original store is not removed by this optimization. Global variables are considered for this optimization only if they are not marked import or export, and are not assigned to anywhere in the script. a := 4; -> a := 4; foo(a); -> foo(4); . | dead code removal: Checks for and removes code which cannot be reached, either because it is hidden behind a return or because the argument to an if statement can be computed at compile time. if (True) then begin -> display_msg(\"foo\"); display_msg(\"foo\"); -> end else begin -> display_msg(\"bar\"); -> end -> . | unreferenced variable elimination: Checks for variables which are never referenced, and removes them. Also applies to global variables, as long as they are not marked for export. variable i, j, k; -> variable i; i := 1; -> i := 1; return; -> return; . | unreferenced procedure elimination: Checks for any procedures which are never called, and removes them. procedure foo begin return \"foo\"; end -> procedure foo begin return \"foo\"; end procedure bar begin return \"bar\"; end -> procedure start begin procedure start begin -> display_msg(foo); display_msg(foo); -> end end -> . | dead store removal: Removes variable assignments if the result of the variable is unused, and if the expression used to compute the value of the variable is provably free of side effects. (See pure keyword) a := \"moo\"; -> a := \"foo\"; a := \"foo\"; -> display_msg(a); display_msg(a); -> a := \"bar\"; -> . | store combination: Where there are two stores in a row to the same variable, the two expressions are combined. var1 := var2; -> var1 := var2 + var3; var1 += var3; -> . | variable combination: Where usage regions of variables do not overlap, combine the variables to provide additional candidates for unreferenced variable elimination. Very useful for scripts containing multiple foreach loops, which generate 2 or 3 hidden variables each. a := \"foo\"; -> a := \"foo\"; display_msg(a); -> display_msg(a); b := \"bar\"; -> a := \"bar\"; display_msg(b); -> display_msg(a); . | namelist compression: Fallout stores the names of all file scope variables and procedures in a namelist which is saved into the .int. Any of these that are unreferenced can be removed, and the names of global variables can be modified to make them shorter. | . ", + "content": "The sfall build of sslc supports a -O command line option to perform an optimization pass over the generated code. This isn’t a magic make-my-code-go-faster bullet; most of what it does is very limited in scope. It’s primary purpose was to strip out the procedures and variables which get automatically pulled into every script that includes define.h, whether you use them or not, and to do something about the additional variables that get created by foreach loops. There are several levels of optimization available: . | -O1 - Basic, only removes unreferenced globals variables and procedures, code itself remains untouched. | -O2 - Full, most code optimizations are on, but only those that were tested on complex scripts. | -O3 - Experimental, provides most efficiency, but tend to break some complex code due to bugs. | . The following optimizations are performed: . | constant expression folding: if an expression depends only on values which are known at compile time, then the expression is replaced by its result. a := 2 + 2; -> a := 4; . | constant variable initialization: All variables are initialised to some value, (‘0’, if you don’t specify anything else,) so sslc attempts to make use of that fact to remove the first assignment to a variable if the first assignment is a constant expression. variable a; -> variable a := 4; a := 4; -> . | constant propagation: checks for values assigned to variables which can be computed at compile time, and replaces relevant references to the symbol by the constant. The original store is not removed by this optimization. Global variables are considered for this optimization only if they are not marked import or export, and are not assigned to anywhere in the script. a := 4; -> a := 4; foo(a); -> foo(4); . | dead code removal: Checks for and removes code which cannot be reached, either because it is hidden behind a return or because the argument to an if statement can be computed at compile time. if (True) then begin -> display_msg(\"foo\"); display_msg(\"foo\"); -> end else begin -> display_msg(\"bar\"); -> end -> . | unreferenced variable elimination: Checks for variables which are never referenced, and removes them. Also applies to global variables, as long as they are not marked for export. variable i, j, k; -> variable i; i := 1; -> i := 1; return; -> return; . | unreferenced procedure elimination: Checks for any procedures which are never called, and removes them. procedure foo begin return \"foo\"; end -> procedure foo begin return \"foo\"; end procedure bar begin return \"bar\"; end -> procedure start begin procedure start begin -> display_msg(foo); display_msg(foo); -> end end -> . | dead store removal: Removes variable assignments if the result of the variable is unused, and if the expression used to compute the value of the variable is provably free of side effects. (See pure keyword) a := \"moo\"; -> a := \"foo\"; a := \"foo\"; -> display_msg(a); display_msg(a); -> a := \"bar\"; -> . | store combination: Where there are two stores in a row to the same variable, the two expressions are combined. var1 := var2; -> var1 := var2 + var3; var1 += var3; -> . | variable combination: Where usage regions of variables do not overlap, combine the variables to provide additional candidates for unreferenced variable elimination. Very useful for scripts containing multiple foreach loops, which generate 2 or 3 hidden variables each. a := \"foo\"; -> a := \"foo\"; display_msg(a); -> display_msg(a); b := \"bar\"; -> a := \"bar\"; display_msg(b); -> display_msg(a); . | namelist compression: Fallout stores the names of all file scope variables and procedures in a namelist which is saved into the .int. Any of these that are unreferenced can be removed, and the names of global variables can be modified to make them shorter. | . ", "url": "/sfall/optimization/#sslc--o-option", "relUrl": "/optimization/#sslc--o-option" },"125": { "doc": "Optimization", "title": "Writing your own code", - "content": ". | Don’t have global scripts running any more often that you need them to. Not everything needs to be run every single frame. | Never concat constant strings with the + operator, as it forces the operation to be done at runtime. The compiler can cope with constant strings being placed next to each other without the need for a +, which results in far more efficient code as the combination is done at lex time. #define GLOB_PREFIX \"ts__\" -> #define GLOB_PREFIX \"ts__\" procedure start begin -> procedure start begin set_sfall_global(GLOB_PREFIX + \"foo1\", 0); -> set_sfall_global(GLOB_PREFIX \"foo1\", 0); end -> end . | Avoid function calls in while loops. Function calls are expensive in comparison to variable lookups, so it’s more efficient to move the function call out of the loop and store the result in a variable. while i < len_array(array) do begin -> tmp := len_array(array); ... -> while i < tmp do begin end -> ... -> end . | Mark functions with pure or inline where relevent. | pure is a hint to the optimizer that a procedure has no side effects. (i.e. there’s no way to tell that it’s been called aside from its return value.) Pure procedures cannot modify global variables, or call any other procedure that isn’t itself pure. Functions marked with pure can only be used in expressions (i.e. you cannot use the call <procedure> syntax to call them.) If there are non-pure terms in an expression, it prevents that expression being considered for dead store removal. Where no such optimizations can be performed, or if optimization is disabled, marking a procedure with pure will have no effect on the compiled code. | inline is an instruction to the compiler to replace calls to the marked procedure with a copy of the procedures code instead of having a seperate call. Inlined procedures cannot use the return command, cannot be predefined, and cannot be used as part of an expression. Inlining if a procedure is only going to be called once is always a win, but if there are multiple calls to a procedure you will end up bloating the size of the generated code. | . | . ", + "content": ". | Don’t have global scripts running any more often that you need them to. Not everything needs to be run every single frame. | Never concat constant strings with the + operator, as it forces the operation to be done at runtime. The compiler can cope with constant strings being placed next to each other without the need for a +, which results in far more efficient code as the combination is done at lex time. #define GLOB_PREFIX \"ts__\" -> #define GLOB_PREFIX \"ts__\" procedure start begin -> procedure start begin set_sfall_global(GLOB_PREFIX + \"foo1\", 0); -> set_sfall_global(GLOB_PREFIX \"foo1\", 0); end -> end . | Avoid function calls in while loops. Function calls are expensive in comparison to variable lookups, so it’s more efficient to move the function call out of the loop and store the result in a variable. while i < len_array(array) do begin -> tmp := len_array(array); ... -> while i < tmp do begin end -> ... -> end . | Mark functions with pure or inline where relevant. | pure is a hint to the optimizer that a procedure has no side effects. (i.e. there’s no way to tell that it’s been called aside from its return value.) Pure procedures cannot modify global variables, or call any other procedure that isn’t itself pure. Functions marked with pure can only be used in expressions (i.e. you cannot use the call <procedure> syntax to call them.) If there are non-pure terms in an expression, it prevents that expression being considered for dead store removal. Where no such optimizations can be performed, or if optimization is disabled, marking a procedure with pure will have no effect on the compiled code. | inline is an instruction to the compiler to replace calls to the marked procedure with a copy of the procedures code instead of having a separate call. Inlined procedures cannot use the return command, cannot be predefined, and cannot be used as part of an expression. Inlining if a procedure is only going to be called once is always a win, but if there are multiple calls to a procedure you will end up bloating the size of the generated code. | . | . ", "url": "/sfall/optimization/#writing-your-own-code", "relUrl": "/optimization/#writing-your-own-code" @@ -1030,7 +1030,7 @@ },"147": { "doc": "SSLC", "title": "Additional supported syntax", - "content": "Syntax which requires sfall for compiled scripts to be interpreted is marked by asterisk (*). | Optional arguments in user-defined procedures. You can only use constants for default values. It basically puts those constants in place of omitted arguments. | new: procedure test(variable x, variable y := 0, variable z := -1) begin ... end ... call test(\"value\"); . | old: procedure test(variable x, variable y, variable z) begin ... end ... call test(\"value\", 0, -1); . | . | New logical operators AndAlso, OrElse for short-circuit evaluation of logical expressions. Using these operators allow the right part of logical expressions not to be evaluated (executed, computed) if the result is already known. This can improve the performance of running scripts. Example: if (obj andAlso obj_pid(obj) == PID_STIMPAK) then ... If obj is null, the second condition will not be checked and your script won’t fail with “obj is null” error in debug.log . This also has an effect that a value of last computed argument is returned as a result of whole expressions, instead of always false (0) or true (1): . obj := false; display_msg(obj orElse \"something\"); // will print \"something\" . You can also use the -s option to enable short-circuit evaluation for all the AND, OR operators in the script. NOTE: Be aware that it may break some old scripts because operators behavior is changed slightly. | Conditional expressions (Python-inspired), also known as ternary operator: . | new: X := value1 if (condition) else value2 . | old: if (condition) then X := value1; else X := value2; . | . | To assign values, you can use the alternative assignment operator from C/Java instead of Pascal syntax. | new: x = 5; . | old: x := 5; . | . | Multiple variable declaration: Multiple variables can be declared on one line, seperated by commas. This is an alterative to the ugly begin/end block, or the bulky single variable per line style. | new: variable a, b, c; . | old: variable begin a; b; c; end . | . | Variable initialization with expressions: You can now initialize local variables with complex expressions instead of constants. | new: variable tile := tile_num(dude_obj); . | old: variable tile; tile := tile_num(dude_obj); . NOTE: If your expression starts with a constant (eg. 2 + 2), enclose it in parentheses, otherwise compiler will be confused and give you errors. | . | Hexadecimal numerical constants: Simply prefix a number with 0x to create a hexadecimal. The numbers 0 to 9 and letters A to F are allowed in the number. The number may not have a decimal point. | new: a := 0x1000; . | old: a := 4096; . | . | Increment/decrement operators: ++ and -- can be used as shorthand for += 1 and -= 1 respectively. They are mearly a syntactic shorthand to improve readability, and so their use is only allowed where += 1 would normally be allowed. | new: a++; . | old: a += 1; . | . | break & continue statements: They work just like in most high-level languages. break jumps out of the loop. continue jumps right to the beginning of the next iteration (see for and foreach sections for additional details). | new: while (i < N) begin // ... if (/* some condition */) then break; // ... end . | old: while (i < N and not(breakFlag)) begin // ... if (/* condition */) then breakFlag := true; // ... end . | new: for (i := 0; i < N; i++) begin // ... if (/* condition */) then begin // action continue; end // else actions end . | old: for (i := 0; i < N; i++) begin // ... if (/* condition */) then begin // action end else begin // else actions end end . | . | for loops: Another piece of syntactic shorthand, to shorten while loops in many cases. Parentheses around the loop statements are recommended but not required (when not using parentheses, a semicolon is required after the 3rd loop statement). | new: for (i := 0; i < 5; i++) begin display_msg(\"i = \" + i); end . | old: i := 0; while (i < 5) do begin display_msg(\"i = \" + i); i++; end . NOTE: continue statement in a for loop will recognize increment statement (third statement in parentheses) and will execute it before jumping back to the beginning of loop. This way you will not get an endless loop. | . | switch statements: A shorthand way of writing big if then else if... blocks . | new: switch get_attack_type begin case ATKTYPE_PUNCH: display_msg(\"punch\"); case ATKTYPE_KICK: display_msg(\"kick\"); default: display_msg(\"something else\"); end . | old: variable tmp; tmp := get_attack_type; if tmp == ATKTYPE_PUNCH then begin display_msg(\"punch\"); end else if tmp == ATKTYPE_KICK then begin display_msg(\"kick\"); end else begin display_msg(\"something else\"); end . | . | Empty statements in blocks are allowed: This is just a convenience to save scripters a bit of memory. Some of the macros in the Fallout headers include their own semicolons while others do not. With the original compiler you had to remember which was which, and if you got it wrong the script would not compile. Now it’s always safe to include your own semicolon, even if the macro already had its own. For example, this would not compile with the original sslc, but will with the sfall edition: #define my_macro diplay_msg(\"foo\"); procedure start begin my_macro; end . NOTE: Does not work currently. | Procedure stringify operator @: Designed to make callback-procedures a better option and allow for basic functional programming. Basically it replaces procedure names preceeded by @ by a string constant. | old: callbackVar := \"Node000\"; call callbackVar; . | new: callbackVar := @Node000; call callbackVar; . Not many people know that since vanilla Fallout you can call procedures by “calling a variable” containing it’s name as a string value. There was a couple of problems using this: . | optimizer wasn’t aware that you are referencing a procedure, and could remove it, if you don’t call it explicitly (can be solved by adding making procedure critical) | you couldn’t see all references of a procedure from a Script Editor | it was completely not obvious that you could do such a thing, it was a confusing syntax | . | (*) Arrays: In vanilla Fallout, arrays had to be constructed by reserving a block of global/map variables. Since sfall 2.7, specific array targeted functions have been available, but they are fairly messy and long winded to use. The compiler provides additional syntactic shorthand for accessing and setting array variables, as well as for array creation. When declaring an array variable, put a constant integer in []` to give the number of elements in the array. (before sfall 3.4 you had to specify size in bytes for array elements, now it’s not required, see “Arrays” page for more information) . | new: procedure bingle begin variable a[2]; a[0] := 5; a[a[0] - 4] := a[0] + 4; display_msg(\"a[0]=\" + a[0] + \", a[1]=\" + a[1]); end . | old: procedure bingle begin variable a; a := temp_array(2, 4); set_array(a, 0, 5); set_array(a, get_array(a, 0) - 4, get_array(a, 0) + 4); display_msg(\"a[0]=\" + get_array(a, 0) + \", a[1]=\" + get_array(a, 1)); end . | . | (*) Array expressions: Sometimes you need to construct an array of elements and you will probably want to do it in just one expression. This is now possible: . | new: list := [\"A\", \"B\", \"C\", \"D\"]; . | old: list := temp_array(4, 2); list[0] := \"A\"; list[1] := \"B\"; list[2] := \"C\"; list[3] := \"D\"; . Syntax specific for associative arrays is also available. (see “Arrays” page for full introduction to this type of arrays). | . | (*) Map array expressions: map := {5: \"five\", 10: \"ten\", 15: \"fifteen\", 20: \"twelve\"}; . | (*) The dot . syntax to access elements of associative arrays and allow to work with arrays like objects: trap.radius := 3; trap.tile := tile_num(dude_obj); . You can chain dot and bracket syntax to access elements of multi-dimensional arrays: . collectionList[5].objectList[5].name += \" foo\"; . NOTE: When using incremental operators like +=, *=, ++, -- compiler will use additional temp variable to get an array at penultimate level in order to avoid making the same chain of get_array calls twice. | (*) foreach loops: A shorthand method of looping over all elements in an array. Syntax is foreach (<symbol> in <expression>). | new: procedure bingle begin variable critter; foreach (critter in list_as_array(LIST_CRITTERS)) begin display_msg(\"\" + critter); end end . | old: procedure bingle begin variable begin critter; array; len; count; end array := list_as_array(LIST_CRITTERS); len := len_array(array); count := 0; while count < len do begin critter := array[count]; display_msg(\"\" + critter); end end . | . If you want an index array element (or key for “maps”) at each iteration, use syntax: foreach (<symbol>: <symbol> in <expression>) . foreach (pid: price in itemPriceMap) begin if (itemPid == pid) then itemPrice := price; end . If you want to add additional condition for continuing the loop, use syntax: foreach (<symbol> in <expression> while <expression>). In this case loop will iterate over elements of an array until last element or until “while” expression is true (whatever comes first). NOTE: Just like for loop, continue statement will respect increments of a hidden counter variable, so you can safely use it inside foreach. | . ", + "content": "Syntax which requires sfall for compiled scripts to be interpreted is marked by asterisk (*). | Optional arguments in user-defined procedures. You can only use constants for default values. It basically puts those constants in place of omitted arguments. | new: procedure test(variable x, variable y := 0, variable z := -1) begin ... end ... call test(\"value\"); . | old: procedure test(variable x, variable y, variable z) begin ... end ... call test(\"value\", 0, -1); . | . | New logical operators AndAlso, OrElse for short-circuit evaluation of logical expressions. Using these operators allow the right part of logical expressions not to be evaluated (executed, computed) if the result is already known. This can improve the performance of running scripts. Example: if (obj andAlso obj_pid(obj) == PID_STIMPAK) then ... If obj is null, the second condition will not be checked and your script won’t fail with “obj is null” error in debug.log . This also has an effect that a value of last computed argument is returned as a result of whole expressions, instead of always false (0) or true (1): . obj := false; display_msg(obj orElse \"something\"); // will print \"something\" . You can also use the -s option to enable short-circuit evaluation for all the AND, OR operators in the script. NOTE: Be aware that it may break some old scripts because operators behavior is changed slightly. | Conditional expressions (Python-inspired), also known as ternary operator: . | new: X := value1 if (condition) else value2 . | old: if (condition) then X := value1; else X := value2; . | . | To assign values, you can use the alternative assignment operator from C/Java instead of Pascal syntax. | new: x = 5; . | old: x := 5; . | . | Multiple variable declaration: Multiple variables can be declared on one line, separated by commas. This is an alternative to the ugly begin/end block, or the bulky single variable per line style. | new: variable a, b, c; . | old: variable begin a; b; c; end . | . | Variable initialization with expressions: You can now initialize local variables with complex expressions instead of constants. | new: variable tile := tile_num(dude_obj); . | old: variable tile; tile := tile_num(dude_obj); . NOTE: If your expression starts with a constant (eg. 2 + 2), enclose it in parentheses, otherwise compiler will be confused and give you errors. | . | Hexadecimal numerical constants: Simply prefix a number with 0x to create a hexadecimal. The numbers 0 to 9 and letters A to F are allowed in the number. The number may not have a decimal point. | new: a := 0x1000; . | old: a := 4096; . | . | Increment/decrement operators: ++ and -- can be used as shorthand for += 1 and -= 1 respectively. They are merely a syntactic shorthand to improve readability, and so their use is only allowed where += 1 would normally be allowed. | new: a++; . | old: a += 1; . | . | break & continue statements: They work just like in most high-level languages. break jumps out of the loop. continue jumps right to the beginning of the next iteration (see for and foreach sections for additional details). | new: while (i < N) begin // ... if (/* some condition */) then break; // ... end . | old: while (i < N and not(breakFlag)) begin // ... if (/* condition */) then breakFlag := true; // ... end . | new: for (i := 0; i < N; i++) begin // ... if (/* condition */) then begin // action continue; end // else actions end . | old: for (i := 0; i < N; i++) begin // ... if (/* condition */) then begin // action end else begin // else actions end end . | . | for loops: Another piece of syntactic shorthand, to shorten while loops in many cases. Parentheses around the loop statements are recommended but not required (when not using parentheses, a semicolon is required after the 3rd loop statement). | new: for (i := 0; i < 5; i++) begin display_msg(\"i = \" + i); end . | old: i := 0; while (i < 5) do begin display_msg(\"i = \" + i); i++; end . NOTE: continue statement in a for loop will recognize increment statement (third statement in parentheses) and will execute it before jumping back to the beginning of loop. This way you will not get an endless loop. | . | switch statements: A shorthand way of writing big if then else if... blocks . | new: switch get_attack_type begin case ATKTYPE_PUNCH: display_msg(\"punch\"); case ATKTYPE_KICK: display_msg(\"kick\"); default: display_msg(\"something else\"); end . | old: variable tmp; tmp := get_attack_type; if tmp == ATKTYPE_PUNCH then begin display_msg(\"punch\"); end else if tmp == ATKTYPE_KICK then begin display_msg(\"kick\"); end else begin display_msg(\"something else\"); end . | . | Empty statements in blocks are allowed: This is just a convenience to save scripters a bit of memory. Some of the macros in the Fallout headers include their own semicolons while others do not. With the original compiler you had to remember which was which, and if you got it wrong the script would not compile. Now it’s always safe to include your own semicolon, even if the macro already had its own. For example, this would not compile with the original sslc, but will with the sfall edition: #define my_macro display_msg(\"foo\"); procedure start begin my_macro; end . NOTE: Does not work currently. | Procedure stringify operator @: Designed to make callback-procedures a better option and allow for basic functional programming. Basically it replaces procedure names preceded by @ by a string constant. | old: callbackVar := \"Node000\"; call callbackVar; . | new: callbackVar := @Node000; call callbackVar; . Not many people know that since vanilla Fallout you can call procedures by “calling a variable” containing it’s name as a string value. There was a couple of problems using this: . | optimizer wasn’t aware that you are referencing a procedure, and could remove it, if you don’t call it explicitly (can be solved by adding making procedure critical) | you couldn’t see all references of a procedure from a Script Editor | it was completely not obvious that you could do such a thing, it was a confusing syntax | . | (*) Arrays: In vanilla Fallout, arrays had to be constructed by reserving a block of global/map variables. Since sfall 2.7, specific array targeted functions have been available, but they are fairly messy and long winded to use. The compiler provides additional syntactic shorthand for accessing and setting array variables, as well as for array creation. When declaring an array variable, put a constant integer in []` to give the number of elements in the array. (before sfall 3.4 you had to specify size in bytes for array elements, now it’s not required, see “Arrays” page for more information) . | new: procedure bingle begin variable a[2]; a[0] := 5; a[a[0] - 4] := a[0] + 4; display_msg(\"a[0]=\" + a[0] + \", a[1]=\" + a[1]); end . | old: procedure bingle begin variable a; a := temp_array(2, 4); set_array(a, 0, 5); set_array(a, get_array(a, 0) - 4, get_array(a, 0) + 4); display_msg(\"a[0]=\" + get_array(a, 0) + \", a[1]=\" + get_array(a, 1)); end . | . | (*) Array expressions: Sometimes you need to construct an array of elements and you will probably want to do it in just one expression. This is now possible: . | new: list := [\"A\", \"B\", \"C\", \"D\"]; . | old: list := temp_array(4, 2); list[0] := \"A\"; list[1] := \"B\"; list[2] := \"C\"; list[3] := \"D\"; . Syntax specific for associative arrays is also available. (see “Arrays” page for full introduction to this type of arrays). | . | (*) Map array expressions: map := {5: \"five\", 10: \"ten\", 15: \"fifteen\", 20: \"twelve\"}; . | (*) The dot . syntax to access elements of associative arrays and allow to work with arrays like objects: trap.radius := 3; trap.tile := tile_num(dude_obj); . You can chain dot and bracket syntax to access elements of multi-dimensional arrays: . collectionList[5].objectList[5].name += \" foo\"; . NOTE: When using incremental operators like +=, *=, ++, -- compiler will use additional temp variable to get an array at penultimate level in order to avoid making the same chain of get_array calls twice. | (*) foreach loops: A shorthand method of looping over all elements in an array. Syntax is foreach (<symbol> in <expression>). | new: procedure bingle begin variable critter; foreach (critter in list_as_array(LIST_CRITTERS)) begin display_msg(\"\" + critter); end end . | old: procedure bingle begin variable begin critter; array; len; count; end array := list_as_array(LIST_CRITTERS); len := len_array(array); count := 0; while count < len do begin critter := array[count]; display_msg(\"\" + critter); end end . | . If you want an index array element (or key for “maps”) at each iteration, use syntax: foreach (<symbol>: <symbol> in <expression>) . foreach (pid: price in itemPriceMap) begin if (itemPid == pid) then itemPrice := price; end . If you want to add additional condition for continuing the loop, use syntax: foreach (<symbol> in <expression> while <expression>). In this case loop will iterate over elements of an array until last element or until “while” expression is true (whatever comes first). NOTE: Just like for loop, continue statement will respect increments of a hidden counter variable, so you can safely use it inside foreach. | . ", "url": "/sfall/sslc/#additional-supported-syntax", "relUrl": "/sslc/#additional-supported-syntax" @@ -1072,7 +1072,7 @@ },"153": { "doc": "Stats", "title": "Functions", - "content": ". | get_critter_base_stat | get_critter_extra_stat | get_pc_base_stat | get_pc_extra_stat | get_stat_max | get_stat_min | set_critter_base_stat | set_critter_extra_stat | set_pc_base_stat | set_pc_extra_stat | . get_critter_base_stat . int get_critter_base_stat(CritterPtr, int StatID) . get_critter_extra_stat . int get_critter_extra_stat(CritterPtr, int StatID) . get_pc_base_stat . int get_pc_base_stat(int StatID) . get_pc_extra_stat . int get_pc_extra_stat(int StatID) . get_stat_max . get_stat_max(int stat, bool who = False) . | Returns the maximum set value of the specified stat (see set_stat_max functions) | who: 0 (false) or omitting the argument - returns the value of the player, 1 (true) - returns the value set for other critters | . get_stat_min . get_stat_min(int stat, bool who = False) . | Returns the minimum set value of the specified stat (see set_stat_min functions) | who: 0 (false) or omitting the argument - returns the value of the player, 1 (true) - returns the value set for other critters | . set_critter_base_stat . void set_critter_base_stat(CritterPtr, int StatID, int value) . set_critter_extra_stat . void set_critter_extra_stat(CritterPtr, int StatID, int value) . set_pc_base_stat . void set_pc_base_stat(int StatID, int value) . set_pc_extra_stat . void set_pc_extra_stat(int StatID, int value) . ", + "content": ". | get_critter_base_stat | get_critter_extra_stat | get_pc_base_stat | get_pc_extra_stat | get_stat_max | get_stat_min | set_critter_base_stat | set_critter_extra_stat | set_pc_base_stat | set_pc_extra_stat | . get_critter_base_stat . int get_critter_base_stat(CritterPtr, int StatID) . get_critter_extra_stat . int get_critter_extra_stat(CritterPtr, int StatID) . get_pc_base_stat . int get_pc_base_stat(int StatID) . get_pc_extra_stat . int get_pc_extra_stat(int StatID) . get_stat_max . get_stat_max(int stat, bool who = False) . | Returns the maximum set value of the specified stat (see set_stat_max functions) | who: 0 (False) or omitting the argument - returns the value of the player, 1 (True) - returns the value set for other critters | . get_stat_min . get_stat_min(int stat, bool who = False) . | Returns the minimum set value of the specified stat (see set_stat_min functions) | who: 0 (False) or omitting the argument - returns the value of the player, 1 (True) - returns the value set for other critters | . set_critter_base_stat . void set_critter_base_stat(CritterPtr, int StatID, int value) . set_critter_extra_stat . void set_critter_extra_stat(CritterPtr, int StatID, int value) . set_pc_base_stat . void set_pc_base_stat(int StatID, int value) . set_pc_extra_stat . void set_pc_extra_stat(int StatID, int value) . ", "url": "/sfall/stats/#functions", "relUrl": "/stats/#functions" @@ -1086,7 +1086,7 @@ },"155": { "doc": "Strings", "title": "Functions", - "content": ". | charcode | get_string_pointer | string_format | string_split | string_to_case | strlen | substr | . charcode . int charcode(string text) . Returns ASCII code for the first character in given string. get_string_pointer . sfall.h . int get_string_pointer(string text) . Returns a pointer to a string variable or to a text. string_format . sfall.h . string string_format(string format, any val1, any val2, ...) . Formats given value using standard syntax of C printf function (google “printf” for format details). However it is limited to formatting up to 4 values. | formatting is only supported for %s and %d, and the format string is limited to 1024 characters | . string_split . array string_split(string, split) . Takes a string and a seperator, searches the string for all instances of the seperator, and returns a temp array filled with the pieces of the string split at each instance. If you give an empty string as the seperator, the string is split into individual characters. You can use this to search for a substring in a string like this: strlen(get_array(string_split(haystack, needle), 0)) . string_to_case . string sfall_func2(\"string_to_case\", string text, int toCase) . Converts all letters in the given string to the specified case. toCase: 0 - lowercase, 1 - uppercase . NOTE: this function works only for English letters of A-Z/a-z. strlen . int strlen(string text) . Returns string length. substr . string substr(string, start, length) . Cuts a substring from a string starting at “start” up to “length” characters. The first character position is 0 (zero). | If start is negative - it indicates starting position from the end of the string (for example substr(\"test\", -2, 2) will return last 2 charactes: “st”). | If length is negative - it means so many characters will be omitted from the end of string (example: substr(\"test\", 0, -2) will return string without last 2 characters: “te”). | If length is zero - it will return a string from the starting position to the end of the string New behavior for sfall 4.2.2/3.8.22 | . ", + "content": ". | charcode | get_string_pointer | string_format | string_split | string_to_case | strlen | substr | . charcode . int charcode(string text) . Returns ASCII code for the first character in given string. get_string_pointer . sfall.h . int get_string_pointer(string text) . Returns a pointer to a string variable or to a text. string_format . sfall.h . string string_format(string format, any val1, any val2, ...) . Formats given value using standard syntax of C printf function (google “printf” for format details). However it is limited to formatting up to 4 values. | formatting is only supported for %s and %d, and the format string is limited to 1024 characters | . string_split . array string_split(string text, split) . Takes a string and a seperator, searches the string for all instances of the seperator, and returns a temp array filled with the pieces of the string split at each instance. If you give an empty string as the seperator, the string is split into individual characters. You can use this to search for a substring in a string like this: strlen(get_array(string_split(haystack, needle), 0)) . string_to_case . string sfall_func2(\"string_to_case\", string text, int toCase) . Converts all letters in the given string to the specified case. toCase: 0 - lowercase, 1 - uppercase . NOTE: this function works only for English letters of A-Z/a-z. strlen . int strlen(string text) . Returns string length. substr . string substr(string text, start, length) . Cuts a substring from a string starting at “start” up to “length” characters. The first character position is 0 (zero). | If start is negative - it indicates starting position from the end of the string (for example substr(\"test\", -2, 2) will return last 2 charactes: “st”). | If length is negative - it means so many characters will be omitted from the end of string (example: substr(\"test\", 0, -2) will return string without last 2 characters: “te”). | If length is zero - it will return a string from the starting position to the end of the string New behavior for sfall 4.2.2/3.8.22 | . ", "url": "/sfall/strings/#functions", "relUrl": "/strings/#functions" @@ -1191,7 +1191,7 @@ },"170": { "doc": "Windows and images", "title": "Functions", - "content": ". | create_win | draw_image | draw_image_scaled | get_window_attribute | get_window_under_mouse | interface_art_draw | interface_print | message_box | nterface_overlay | set_window_flag | win_fill_color | . create_win . sfall.h . void create_win(string winName, int x, int y, int width, int height, int flags) . flags argument is optional. Works just like vanilla CreateWin function, but creates a window with MoveOnTop flag if the flags argument is not specified, and allows to set additional flags for the created window. MoveOnTop flag allows the created window to be placed on top of the game interface. draw_image . sfall.h . void draw_image(string/int artFile/artId, int frame, int x, int y, bool noTransparent) . | displays the specified PCX or FRM image in the active window created by vanilla CreateWin or sfall’s create_win script function | artFile/artId: path to the PCX/FRM file (e.g. art\\\\inven\\\\5mmap.frm), or its FRM ID number (e.g. 0x7000026, see specification of the FID format) optional arguments: | frame: frame number, the first frame starts from zero | x/y: offset relative to the top-left corner of the window | noTransparent: pass True to display an image without transparent background | NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4(\"draw_image\", pathFile, frame, x, y)) | . draw_image_scaled . sfall.h . void draw_image_scaled(string/int artFile/artId, int frame, int x, int y, int width, int height) . | displays the specified PCX or FRM image in the active window created by vanilla CreateWin or sfall’s create_win script function | artFile/artId: path to the PCX/FRM file (e.g. art\\\\inven\\\\5mmap.frm), or its FRM ID number (e.g. 0x7000026, see specification of the FID format) optional arguments: | frame: frame number, the first frame starts from zero | x/y: offset relative to the top-left corner of the window | width/height: the new width/height to scale the image to. Pass -1 to either width or height to keep the aspect ratio when scaling | NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4(\"draw_image\", pathFile, frame, x, y)) | if called without x/y/width/height arguments, the image will be scaled to fit the window without transparent background | . get_window_attribute . int sfall_func1(\"get_window_attribute\", int winType) . Alternative form: int sfall_func2(\"get_window_attribute\", int winType, int attrType) Returns the attribute of the specified interface window by the attrType argument. | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) | attrType: 0 - checks and returns a value of 1 if the specified interface window is created by the game (same as without the argument) 1 - X position, 2 - Y position (relative to the top-left corner of the game screen) 3 - interface width size, 4 - interface height size -1 - returns an associative array of keys (left, top, right, bottom) and values that define the position of the window rectangle (use standard syntax to access array values, e.g. winRect.top, winRect.bottom) | returns -1 if the specified attribute cannot be obtained | . get_window_under_mouse . int get_window_under_mouse() . interface_art_draw . int sfall_func4(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y) . int sfall_func4(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y) int sfall_func5(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y, int frame) int sfall_func6(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y, int frame, array param) . | draws the specified PCX or FRM image in the game interface window, returns -1 on any error | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) this also takes the value of the flag (0x1000000) to prevent immediate redrawing of the interface window | artFile/artId: path to the PCX/FRM file (e.g. art\\\\inven\\\\5mmap.frm), or its FRM ID number (e.g. 0x7000026, see specification of the FID format) | x/y: offset relative to the top-left corner of the window | . optional arguments: . | frame: frame number, the first frame starts from zero | param: an array which specifies additional parameters, where: index 0 - sprite direction for multi-directional FRM index 1/index 2 - the new width/height to scale the image to. Pass -1 to use the original width/height | . interface_print . int sfall_func5(\"interface_print\", string text, int winType, int x, int y, int color) . int sfall_func5(\"interface_print\", string text, int winType, int x, int y, int color) int sfall_func6(\"interface_print\", string text, int winType, int x, int y, int color, int width) . | displays the text in the specified interface window with the current font. Use vanilla SetFont function to set the font | returns the count of lines printed, or -1 on any error | text: the text to be printed. Use the \\n control character to move text to a new line (example: “Hello\\nWorld!”) | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) | x/y: offset relative to the top-left corner of the window | color: the color index in the game palette. Pass 0 if the text color was previously set by vanilla SetTextColor function It can also take additional flags (via bwor) for displaying text: . | 0x0010000 - adds a shadow to the text, the ‘textshadow’ compiler constant | 0x1000000 - prevents immediate redrawing of the interface window, the textdirect compiler constant (works the other way around) | 0x2000000 - fills the background of the text with black color, the textnofill compiler constant (works the other way around) | . | width (optional): the maximum width of the text. The text will be wrapped to fit within the specified width | . message_box . int sfall_func4(\"message_box\", string message, int flags, int color1, int color2) . Creates a dialog box with text and returns the result of pressing the button: 0 - No (Escape), 1 - Yes/Done (Enter). Returns -1 if for some reason the dialog box cannot be created. - message: the text in the dialog box. Use the `\\n` control character to move text to a new line (example: \"Hello\\nWorld!\") optional arguments: - flags: mode flags (see `MSGBOX_*` constants in define_extra.h). Pass -1 to skip setting the flags (default flags are NORMAL and YESNO) - color1/color2: the color index in the game palette. `color1` sets the text color for the first line, and `color2` for all subsequent lines of text (default color is 145) . nterface_overlay . sfall_func2(\"interface_overlay\", int winType, int mode) . Alternative form: int sfall_func6(\"interface_overlay\", int winType, 2, int x, int y, int width, int height). Creates an additional drawing surface above the graphic layer of the specified interface window. All subsequent calls of interface_art_draw and interface_print functions will draw on it. | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) | mode: 1 - creates a new overlay surface 2 - clears the overlay area or the specified rectangle defined by the x, y, width, height arguments 0 - destroys the created overlay surface (frees up the memory allocated to the surface) | . set_window_flag . sfall.h . void set_window_flag(string winName/int winID, int flag, bool value) . Changes the specified flag for the created script or game interface window. | winName: the window name, assigned to the window by the CreateWin/create_win function | winID: the ID number of the interface or script window obtained with the get_window_under_mouse function, or 0 for the current game interface | flag: the flag to change (see WIN_FLAG_* constants in define_extra.h) | value: true - set the flag, false - unset the flag | . win_fill_color . int win_fill_color(int x, int y, int width, int height, int color) . Fills the rectangle area of the currently selected script window with the specified color, or clears the window with transparent (index 0) color (call the function without arguments). | color: the color index in the game palette (from 0 to 255) | . ", + "content": ". | create_win | draw_image | draw_image_scaled | get_window_attribute | get_window_under_mouse | interface_art_draw | interface_print | message_box | nterface_overlay | set_window_flag | win_fill_color | . create_win . sfall.h . void create_win(string winName, int x, int y, int width, int height, int flags) . flags argument is optional. Works just like vanilla CreateWin function, but creates a window with MoveOnTop flag if the flags argument is not specified, and allows to set additional flags for the created window. MoveOnTop flag allows the created window to be placed on top of the game interface. draw_image . sfall.h . void draw_image(string/int artFile/artId, int frame, int x, int y, bool noTransparent) . | displays the specified PCX or FRM image in the active window created by vanilla CreateWin or sfall’s create_win script function | artFile/artId: path to the PCX/FRM file (e.g. art\\\\inven\\\\5mmap.frm), or its FRM ID number (e.g. 0x7000026, see specification of the FID format) optional arguments: | frame: frame number, the first frame starts from zero | x/y: offset relative to the top-left corner of the window | noTransparent: pass True to display an image without transparent background | NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4(\"draw_image\", pathFile, frame, x, y)) | . draw_image_scaled . sfall.h . void draw_image_scaled(string/int artFile/artId, int frame, int x, int y, int width, int height) . | displays the specified PCX or FRM image in the active window created by vanilla CreateWin or sfall’s create_win script function | artFile/artId: path to the PCX/FRM file (e.g. art\\\\inven\\\\5mmap.frm), or its FRM ID number (e.g. 0x7000026, see specification of the FID format) optional arguments: | frame: frame number, the first frame starts from zero | x/y: offset relative to the top-left corner of the window | width/height: the new width/height to scale the image to. Pass -1 to either width or height to keep the aspect ratio when scaling | NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4(\"draw_image\", pathFile, frame, x, y)) | if called without x/y/width/height arguments, the image will be scaled to fit the window without transparent background | . get_window_attribute . int sfall_func1(\"get_window_attribute\", int winType) . Alternative form: int sfall_func2(\"get_window_attribute\", int winType, int attrType) Returns the attribute of the specified interface window by the attrType argument. | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) | attrType: 0 - checks and returns a value of 1 if the specified interface window is created by the game (same as without the argument) 1 - X position, 2 - Y position (relative to the top-left corner of the game screen) 3 - interface width size, 4 - interface height size -1 - returns an associative array of keys (left, top, right, bottom) and values that define the position of the window rectangle (use standard syntax to access array values, e.g. winRect.top, winRect.bottom) | returns -1 if the specified attribute cannot be obtained | . get_window_under_mouse . int get_window_under_mouse() . interface_art_draw . int sfall_func4(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y) . int sfall_func4(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y) int sfall_func5(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y, int frame) int sfall_func6(\"interface_art_draw\", int winType, string artFile/int artID, int x, int y, int frame, array param) . | draws the specified PCX or FRM image in the game interface window, returns -1 on any error | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) this also takes the value of the flag (0x1000000) to prevent immediate redrawing of the interface window | artFile/artId: path to the PCX/FRM file (e.g. art\\\\inven\\\\5mmap.frm), or its FRM ID number (e.g. 0x7000026, see specification of the FID format) | x/y: offset relative to the top-left corner of the window | . optional arguments: . | frame: frame number, the first frame starts from zero | param: an array which specifies additional parameters, where: index 0 - sprite direction for multi-directional FRM index 1/index 2 - the new width/height to scale the image to. Pass -1 to use the original width/height | . interface_print . int sfall_func5(\"interface_print\", string text, int winType, int x, int y, int color) . int sfall_func5(\"interface_print\", string text, int winType, int x, int y, int color) int sfall_func6(\"interface_print\", string text, int winType, int x, int y, int color, int width) . | displays the text in the specified interface window with the current font. Use vanilla SetFont function to set the font | returns the count of lines printed, or -1 on any error | text: the text to be printed. Use the \\n control character to move text to a new line (example: “Hello\\nWorld!”) | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) | x/y: offset relative to the top-left corner of the window | color: the color index in the game palette. Pass 0 if the text color was previously set by vanilla SetTextColor function It can also take additional flags (via bwor) for displaying text: . | 0x0010000 - adds a shadow to the text, the ‘textshadow’ compiler constant | 0x1000000 - prevents immediate redrawing of the interface window, the textdirect compiler constant (works the other way around) | 0x2000000 - fills the background of the text with black color, the textnofill compiler constant (works the other way around) | . | width (optional): the maximum width of the text. The text will be wrapped to fit within the specified width | . message_box . int sfall_func4(\"message_box\", string message, int flags, int color1, int color2) . Creates a dialog box with text and returns the result of pressing the button: 0 - No (Escape), 1 - Yes/Done (Enter). Returns -1 if for some reason the dialog box cannot be created. - message: the text in the dialog box. Use the `\\n` control character to move text to a new line (example: \"Hello\\nWorld!\") optional arguments: - flags: mode flags (see `MSGBOX_*` constants in define_extra.h). Pass -1 to skip setting the flags (default flags are NORMAL and YESNO) - color1/color2: the color index in the game palette. `color1` sets the text color for the first line, and `color2` for all subsequent lines of text (default color is 145) . nterface_overlay . sfall_func2(\"interface_overlay\", int winType, int mode) . Alternative form: int sfall_func6(\"interface_overlay\", int winType, 2, int x, int y, int width, int height). Creates an additional drawing surface above the graphic layer of the specified interface window. All subsequent calls of interface_art_draw and interface_print functions will draw on it. | winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) | mode: 1 - creates a new overlay surface 2 - clears the overlay area or the specified rectangle defined by the x, y, width, height arguments 0 - destroys the created overlay surface (frees up the memory allocated to the surface) | . set_window_flag . sfall.h . void set_window_flag(string winName/int winID, int flag, bool value) . Changes the specified flag for the created script or game interface window. | winName: the window name, assigned to the window by the CreateWin/create_win function | winID: the ID number of the interface or script window obtained with the get_window_under_mouse function, or 0 for the current game interface | flag: the flag to change (see WIN_FLAG_* constants in define_extra.h) | value: True - set the flag, False - unset the flag | . win_fill_color . int win_fill_color(int x, int y, int width, int height, int color) . Fills the rectangle area of the currently selected script window with the specified color, or clears the window with transparent (index 0) color (call the function without arguments). | color: the color index in the game palette (from 0 to 255) | . ", "url": "/sfall/windows-and-images/#functions", "relUrl": "/windows-and-images/#functions" diff --git a/explosions/index.html b/explosions/index.html index 9457a57f..4628fac9 100644 --- a/explosions/index.html +++ b/explosions/index.html @@ -1,6 +1,6 @@ Explosions | sfall Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Explosions

Functions


get_explosion_damage

sfall.h

array get_explosion_damage(itemPid)
 

Returns an array of the minimum and maximum damage of the explosive item.


item_make_explosive

sfall.h

void item_make_explosive(int pid, int activePid, int minDamage, int maxDamage)
-
  • makes the specified item (pid) an explosive item like Dynamite or Plastic Explosives
  • maxDamage is optional
  • activePid is for an item with an active timer, can be the same as the pid argument
  • the item proto must be “Misc Item” type and have “Use” action flag
  • minDamage/maxDamage are the minimum and maximum explosion damage
  • using the function on an item that is already set as an explosive will override its previous settings
  • NOTE: this function does not work for pids of Dynamite and Plastic Explosives

metarule2_explosions

int metarule2_explosions(int arg1, int arg2)
+
  • makes the specified item (pid) an explosive item like Dynamite or Plastic Explosives
  • maxDamage is optional
  • activePid is for an item with an active timer, can be the same as the pid argument
  • the item proto must be the Misc Item type and have the Use action flag
  • minDamage/maxDamage are the minimum and maximum explosion damage
  • using the function on an item that is already set as an explosive will override its previous settings
  • NOTE: this function does not work for pids of Dynamite and Plastic Explosives

metarule2_explosions

int metarule2_explosions(int arg1, int arg2)
 

Was made as a dirty easy hack to allow dynamically change some explosion parameters (ranged attack). All changed parameters are reset to vanilla state automatically after each attack action.


set_attack_explosion_art

sfall.h

void set_attack_explosion_art(x, y)
 

Y not used and X is a misc frame ID (last 3 bytes, without object type) to use for the next explosion.


set_attack_explosion_pattern

sfall.h

void set_attack_explosion_pattern(x, y)
 

Currently Y is not used and X means: 1 - reduced explosion pattern (3 effects are spawned instead of 7), 0 - full pattern.


set_attack_explosion_radius

sfall.h

void set_attack_explosion_radius(x)
diff --git a/feed.xml b/feed.xml
index 1b2e9726..b1da87eb 100644
--- a/feed.xml
+++ b/feed.xml
@@ -1 +1 @@
-Jekyll2023-03-20T02:05:46+00:00/sfall/feed.xmlsfallSfall documentation
\ No newline at end of file
+Jekyll2023-03-31T14:16:06+00:00/sfall/feed.xmlsfallSfall documentation
\ No newline at end of file
diff --git a/global-scripts/index.html b/global-scripts/index.html
index 30547906..c13271fb 100644
--- a/global-scripts/index.html
+++ b/global-scripts/index.html
@@ -1 +1 @@
-           Global scripts | sfall                        Skip to main content   Link      Menu      Expand       (external link)    Document      Search       Copy       Copied        

Global scripts

As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object. (i.e. using self_obj without using set_self first will crash the script.) To use a global script, the script must have a name which begins with gl and contains a procedure called start, map_enter_p_proc, map_exit_p_proc, or map_update_p_proc. The start procedure will be executed once when the player loads a saved game or starts a new game. The map_*_p_proc procedures will be executed once when a map is being entered/left/updated. If you wish the script to be executed repeatedly, call set_global_script_repeat on the first run of the start procedure using the number of frames between each run as the argument. (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.)

Global scripts have multiple modes, which can be set using the set_global_script_type function.

  • In the default mode (i.e. mode 0) their execution is linked to the local map game loop, so the script will not run in dialogs or on the world map. [Using mode 1 requires the input wrapper to be enabled. Use available_global_script_types to check what is available.] - Obsolete.
  • In mode 1 their execution is linked to the player input, and so they will run whenever the mouse cursor is visible on screen, including the world map, character dialogs etc.
  • In mode 2, execution is linked to the world map loop, so the script will only be executed on the world map and not on the local map or in any dialog windows.
  • Mode 3 is a combination of modes 0 and 2, so scripts will be executed on both local maps and the world map, but not in dialog windows.
+ Global scripts | sfall Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Global scripts

As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object (i.e. using self_obj without using set_self first will crash the script).

To use a global script, the script must have a name which begins with gl and contains a procedure called start, map_enter_p_proc, map_exit_p_proc, or map_update_p_proc. The start procedure will be executed once when the player loads a saved game or starts a new game. The map_*_p_proc procedures will be executed once when a map is being entered/left/updated. If you wish the script to be executed repeatedly, call set_global_script_repeat on the first run of the start procedure using the number of frames between each run as the argument (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.).

Global scripts have multiple modes, which can be set using the set_global_script_type function.

  • In the default mode (i.e. mode 0) their execution is linked to the local map game loop, so the script will not run in dialogs or on the world map. [Using mode 1 requires the input wrapper to be enabled. Use available_global_script_types to check what is available.] - Obsolete.
  • In mode 1 their execution is linked to the player input, and so they will run whenever the mouse cursor is visible on screen, including the world map, character dialogs etc.
  • In mode 2, execution is linked to the world map loop, so the script will only be executed on the world map and not on the local map or in any dialog windows.
  • Mode 3 is a combination of modes 0 and 2, so scripts will be executed on both local maps and the world map, but not in dialog windows.
diff --git a/hook-functions/index.html b/hook-functions/index.html index 853ef539..a10c7da2 100644 --- a/hook-functions/index.html +++ b/hook-functions/index.html @@ -3,14 +3,14 @@

Gets the value of hook argument with the specified argument number (first argument of hook starts from 0)


get_sfall_args

int get_sfall_args()
 

Returns all hook arguments as a new temp array.


init_hook

int init_hook()
 

The hook script equivalent of game_loaded; it returns 1 when the script is loaded for the first time or when the player reloads the game, and 0 otherwise.


register_hook

void register_hook(int hookID)
-

Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, start proc will be executed in current global script. You can use all above functions like normal.


register_hook_proc

void register_hook_proc(int hookID, proc procedure)
-

The same as register_hook, except that you specifically define which procedure in the current script should be called as a hook (instead of “start” by default). Pass procedure the same as how you use dialog option functions. This IS the recommended way to use hook scripts, as it gives both modularity (each mod logic in a separate global script, no conflicts if you don’t use “hs_*.int” scripts) and flexibility (you can place all related hook scripts for specific mod in a single script!).

Use zero (0) as second argument to unregister hook script from current global script.

NOTE: you can hook several scripts to a single hook point, for example if it’s different mods from different authors or just some different aspects of one larger mod. In this case scripts are executed in reverse order of how they were registered. When one of the scripts in a chain returns value with set_sfall_return, the next script may override this value if calls set_sfall_return again. Sometimes you need to multiply certain value in a chain of hook scripts.

Example: let’s say we have a Mod A which reduces all “to hit” chances by 50%. The code might look like this:

original_chance = get_sfall_arg;
+

Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, start procedure will be executed in current global script. You can use all above functions like normal.


register_hook_proc

void register_hook_proc(int hookID, proc procedure)
+

The same as register_hook, except that you specifically define which procedure in the current script should be called as a hook (instead of “start” by default). Pass procedure the same as how you use dialog option functions. This IS the recommended way to use hook scripts, as it gives both modularity (each mod logic in a separate global script with no conflicts) and flexibility. You can place all related hook scripts for a specific mod in one global script!

Use zero (0) as second argument to unregister hook script from current global script.

NOTE: you can hook several scripts to a single hook point, for example if it’s different mods from different authors or just some different aspects of one larger mod. When one of the scripts in a chain returns value with set_sfall_return, the next script may override this value if calls set_sfall_return again.

Example: Sometimes you need to multiply certain value in a chain of hook scripts. Let’s say we have a Mod A which reduces all “to hit” chances by 50%. The code might look like this:

original_chance = get_sfall_arg;
 set_sfall_return(original_chance / 2);
-

Mod B also want to affect hit chances globally, by increasing them by 50%. Now in order for both mods to work well together, we need to add this line to Mod A hook script:

set_sfall_arg(0, (original_chance / 2));
-

This basically changes hook argument for the next script. Mod B code:

original_chance = get_sfall_arg;
+

Mod B also want to affect hit chances globally, by increasing them by 50%. Now in order for both mods to work well together, we need to add this line to Mod A hook script:

set_sfall_arg(0, (original_chance / 2));
+

This basically changes hook argument for the next script. Mod B code:

original_chance = get_sfall_arg;
 set_sfall_return(original_chance * 1.5);
 set_sfall_arg(0, (original_chance * 1.5));
 

So if you combine both mods together, they will run in chain and the end result will be a 75% from original hit chance (hook register order doesn’t matter in this case, if you use set_sfall_arg in both hooks).

The defines to use for the hookID are in sfall.h.


register_hook_proc_spec

void register_hook_proc_spec(int hookID, procedure proc)
-

Works very similar to register_hook_proc, except that it registers the current script at the end of the hook script execution chain (i.e. the script will be executed after all previously registered scripts for the same hook, including the hs_*.int script). All scripts hooked to a single hook point with this function are executed in exact order of how they were registered, as opposed to the description below, which refers to using register_hook/register_hook_proc functions.


set_sfall_arg

void set_sfall_arg(int argNum, int value)
-

Changes argument value. The argument number (argNum) is 0-indexed. This is useful if you have several hook scripts attached to one hook point (see register_hook_proc).


set_sfall_return

void set_sfall_return(int value)
+

Works the same as register_hook_proc, except that it registers the current script at the end of the hook script execution chain (i.e. the script will be executed after all previously registered scripts for the same hook, including the hs_<name>.int script). In addition, all scripts hooked to a single hook point with this function are executed in the exact order of how they were registered. In the case of using register_hook and register_hook_proc functions, scripts are executed in reverse order of how they were registered. The execution chain of script procedures for a hook is as follows: 1. Procedures registered with register_hook and register_hook_proc functions (executed in reverse order of registration). 2. The hs_<name>.int script. 3. Procedures registered with the register_hook_proc_spec function (executed in the exact order of registration).


set_sfall_arg

void set_sfall_arg(int argNum, int value)
+

Changes argument value. The argument number (argNum) is 0-indexed. This is useful if you have several hook scripts attached to one hook point (see register_hook_proc).


set_sfall_return

void set_sfall_return(int value)
 

Used to return the new values from the script. Each time it’s called it sets the next value, or if you’ve already set all return values it does nothing.

diff --git a/hook-types/index.html b/hook-types/index.html index 1fcff014..829f6e7c 100644 --- a/hook-types/index.html +++ b/hook-types/index.html @@ -121,7 +121,7 @@ int arg3 - 1 if the hex would normally be blocking Obj ret0 - 0 if the hex doesn't block, or any sort of object pointer if it does

DescriptionObj

HOOK_DESCRIPTIONOBJ (hs_descriptionobj.int)

Runs when using the examine action icon to display the description of an object. You can override the description text. An example usage would be to add an additional description to the item based on player’s stats/skills.

Does not run if the script of the object overrides the description.

Obj     arg0 - the object
 
-int     ret0 - a pointer to the new text received by using "get_string_pointer" function
+int     ret0 - a pointer to the new text received by using the get_string_pointer function
 

Encounter

HOOK_ENCOUNTER (hs_encounter.int)

Runs whenever a random encounter occurs (except the Horrigan meeting and scripted encounters), or when the player enters a local map from the world map. You can override the map for loading or the encounter.

int     arg0 - event type: 0 - when a random encounter occurs, 1 - when the player enters from the world map
 int     arg1 - the map ID that the encounter will load (see MAPS.h or Maps.txt)
 int     arg2 - 1 when the encounter occurs is a special encounter, 0 otherwise
@@ -153,7 +153,7 @@ int     arg3 - 1 when wielding, 0 when unwielding
 int     arg4 - 1 when removing an equipped item from inventory, 0 otherwise
 
 int     ret0 - overrides hard-coded handler (-1 - use engine handler, any other value - override) - NOT RECOMMENDED
-

InventoryMove

HOOK_INVENTORYMOVE (hs_inventorymove.int)

Runs before moving items between inventory slots in dude interface. You can override the action. What you can NOT do with this hook:

int     arg0 - Target slot:
+

InventoryMove

HOOK_INVENTORYMOVE (hs_inventorymove.int)

Runs before moving items between inventory slots in dude interface. You can override the action.

What you can NOT do with this hook:

int     arg0 - Target slot:
                0 - main backpack
                1 - left hand
                2 - right hand
@@ -167,7 +167,7 @@ Item    arg1 - Item being moved
 Item    arg2 - Item being replaced, weapon being reloaded, or container being filled (can be 0)
 
 int     ret0 - Override setting (-1 - use engine handler, any other value - prevent relocation of item/reloading weapon/picking up item)
-

ItemDamage

HOOK_ITEMDAMAGE (hs_itemdamage.int)

Runs when retrieving the damage rating of the player’s used weapon. (Which may be their fists.)

int     arg0 - The default min damage
+

Notes for the event of dropping items on the ground:

ItemDamage

HOOK_ITEMDAMAGE (hs_itemdamage.int)

Runs when retrieving the damage rating of the player’s used weapon. (Which may be their fists.)

int     arg0 - The default min damage
 int     arg1 - The default max damage
 Item    arg2 - The weapon used (0 if unarmed)
 Critter arg3 - The critter doing the attacking
@@ -310,7 +310,7 @@ Obj     arg1 - the target object/critter
 int     arg2 - skill being used
 
 int     ret0 - a new critter to override the user critter. Pass -1 to cancel the skill use, pass 0 to skip this return value
-int     ret1 - pass 1 to allow the skill being used in combat (only for dude_obj or critter being controlled by the player)
+int     ret1 - pass 1 to allow the skill to be used in combat (only for dude_obj or critter being controlled by the player)
 

WithinPerception

HOOK_WITHINPRECEPTION (hs_withinperception.int)

Runs when checking if one critter sees another critter. This is used in different situations like combat AI. You can override the result.

NOTE: obj_can_see_obj calls this first when deciding if critter can possibly see another critter with regard to perception, lighting, sneak factors.
If check fails, the end result is false. If check succeeds (e.g. critter is within perception range), another check is made if there is any blocking tile between two critters (which includes stuff like windows, large bushes, barrels, etc.) and if there is - check still fails.
You can override “within perception” check by returning 0 or 1, OR, as a convenience, you can also override blocking check after the perception check by returning 2 instead. In this case you should add “line of sight” check inside your hook script, otherwise critters will detect you through walls.

This is fired after the default calculation is made.

Critter arg0 - Watcher object
 Obj     arg1 - Target object
 int     arg2 - Result of vanilla function: 1 - within perception range, 0 - otherwise
diff --git a/hooks/index.html b/hooks/index.html
index cd3f1684..11822846 100644
--- a/hooks/index.html
+++ b/hooks/index.html
@@ -1,4 +1,4 @@
-           Hooks | sfall                        Skip to main content   Link      Menu      Expand       (external link)    Document      Search       Copy       Copied        

Hooks

Hook scripts are specially named scripts that are run by sfall at specific points to allow mods to override normally hardcoded behaviour in a more flexible way than sfall’s normal ini configuration.

In addition to the bit of code it overrides, the script will be run once when first loaded and again at each player reload to allow for setup. Hook scripts have access to a set of arguments supplied to sfall, but aren’t required to use them all. They also return one or more values, but again they’re optional, and you only need to return a value if you want to override the default.

See hook types and hook functions reference for details.

Hooks compatibility

To aid in mods compatibility, avoid using hs_xxx .int scripts. Instead it is recommended to use a normal global script combined with register_hook_proc or register_hook.

Example setup for a hook-script based mod:

procedure tohit_hook_handler begin
+           Hooks | sfall                        Skip to main content   Link      Menu      Expand       (external link)    Document      Search       Copy       Copied        

Hooks

Hook scripts are specially named scripts that are run by sfall at specific points to allow mods to override normally hardcoded behaviour in a more flexible way than sfall’s normal ini configuration.

In addition to the bit of code it overrides, the script will be run once when first loaded and again at each player reload to allow for setup. Hook scripts have access to a set of arguments supplied to sfall, but aren’t required to use them all. They also return one or more values, but again they’re optional, and you only need to return a value if you want to override the default.

See hook types and hook functions reference for details.

Hooks compatibility

To aid in mods compatibility, avoid using the predefined hs_<name>.int scripts. Instead it is recommended to use a normal global script combined with register_hook_proc or register_hook.

Example setup for a hook-script based mod:

procedure tohit_hook_handler begin
    display_msg("Modifying hit_hook " + get_sfall_arg);
    set_hit_chance_max(100);
    set_sfall_return(100);
diff --git a/objects-and-scripts/index.html b/objects-and-scripts/index.html
index 51b22dde..a1468e4c 100644
--- a/objects-and-scripts/index.html
+++ b/objects-and-scripts/index.html
@@ -1,18 +1,18 @@
            Objects and scripts | sfall                        Skip to main content   Link      Menu      Expand       (external link)    Document      Search       Copy       Copied        

Objects and scripts

Functions


dialog_obj

sfall.h

ObjectPtr dialog_obj()
 

Returns a pointer to the object (critter) the player is having a conversation or bartering with.


get_flags

sfall.h

int get_flags(ObjectPtr obj)
 

Gets the current value of object flags (see define_extra.h for available flags).


get_object_data

sfall.h

get_object_data(ObjectPtr object, int offset)
-

Returns the data at the specified offset of an object (see OBJ_DATA_* constants in define_extra.h for offsets).


get_script

int get_script(ObjectPtr)
+

Returns the data at the specified offset of an object (see OBJ_DATA_* constants in define_extra.h for offsets).


get_script

int get_script(ObjectPtr obj)
 
  • accepts a pointer to an object and returns its scriptID (line number in scripts.lst), or 0 if the object is unscripted.
  • returns -1 on argument error.

loot_obj

sfall.h

ObjectPtr loot_obj()
 

Returns a pointer to the target object (container or critter) of the loot screen.


obj_is_carrying_obj

int (ObjectPtr invenObj, ObjectPtr itemObj)
 

Returns number of itemObj inside invenObj’s inventory, note that both arguments are object pointers. useful when dealing with different stacks of same item (obj_is_carrying_obj_pid just returns total for all stacks of the same PID.)


obj_is_openable

sfall.h

bool obj_is_openable(object obj)
-

Returns True if the object is openable (i.e. has an opening/closing animation)


obj_under_cursor

sfall.h

ObjectPtr obj_under_cursor(bool onlyCritter, bool includeDude)
+

Returns True if the object is openable (i.e. has an opening/closing animation), False otherwise


obj_under_cursor

sfall.h

ObjectPtr obj_under_cursor(bool onlyCritter, bool includeDude)
 

Returns the object under the cursor on the main game screen.

  • onlyCritter:
    • True - only checks critters and ignores their cover (roof tiles, walls, scenery, etc.)
    • False - checks all objects (can’t check critters under objects)
  • passing False to the includeDude argument will ignore dude_obj
    • NOTE: to get an object located on a tile when the cursor is in movement mode (hexagon cursor), use the tile_under_cursor function

real_dude_obj

sfall.h

ObjectPtr real_dude_obj()
-

Returns the initial dude_obj after set_dude_obj was used.


remove_script

void remove_script(ObjectPtr)
+

Returns the initial dude_obj after set_dude_obj was used.


remove_script

void remove_script(ObjectPtr obj)
 

Accepts a pointer to an object and will remove the script from that object.


set_dude_obj

sfall.h

void set_dude_obj(ObjectPtr critter)
 

Take control of a given critter. Passing value 0 will reset control back to “real” dude.


set_flags

sfall.h

void set_flags(ObjectPtr obj, int flags)
 

Sets the current flags of an object. All flags are rewritten with given integer, so first get current flags with get_flags and use bwor/bwand to set/remove specific flag.


set_object_data

sfall.h

set_object_data(ObjectPtr object, int offset, int data)
 

Sets the data at the specified offset of an object.


set_scr_name

sfall.h

void set_scr_name(string name)
-

Overrides the name of the script object that was set from scrname.msg.

  • The changed name will be reset each time the player leaves the map or reloads the game
  • Passing an empty string (“”) to the name argument or omitting it will allow the game to get the name for the object from pro_*.msg files
  • NOTE: this function is intended for use in normal game scripts and overrides the name only once for the same object until reset

set_script

void set_script(ObjectPtr, int scriptID)
-

Accepts a pointer to an object and scriptID, and applies the given script to an object (scriptID accept the same values as create_object_sid from sfall 3.6). If used on an object that is already scripted, it will remove the existing script first; you cannot have multiple scripts attached to a single object. Calling set_script on self_obj will have all sorts of wacky side effects, and should be avoided. If you add 0x80000000 to the sid when calling set_script, map_enter_p_proc will be SKIPPED. The start proc will always be run.


set_self

void set_self(ObjectPtr)
+

Overrides the name of the script object that was set from scrname.msg.

  • The changed name will be reset each time the player leaves the map or reloads the game
  • Passing an empty string (“”) to the name argument or omitting it will allow the game to get the name for the object from pro_*.msg files
  • NOTE: this function is intended for use in normal game scripts and overrides the name only once for the same object until reset

set_script

void set_script(ObjectPtr obj, int scriptID)
+

Accepts a pointer to an object and scriptID, and applies the given script to an object (scriptID accept the same values as create_object_sid from sfall 3.6). If used on an object that is already scripted, it will remove the existing script first; you cannot have multiple scripts attached to a single object. Calling set_script on self_obj will have all sorts of wacky side effects, and should be avoided. If you add 0x80000000 to the sid when calling set_script, map_enter_p_proc will be SKIPPED. The start proc will always be run.


set_self

void set_self(ObjectPtr setObj)
 

Overrides the script’s self_obj for the next function call.

  • It is primarily used to allow the calling of functions which take an implicit self_obj parameter (e.g. drop_obj) from global scripts, but it can also be used from normal scripts.
  • self_obj will be reverted to its original value after the next function call.
  • Calling set_self(0) will also revert self_obj to its original value. It is recommended to call this after each use of set_self in normal scripts in order to avoid unforeseen side effects.
  • source_obj, target_obj, and similar functions will not work if preceded by set_self.
  • NOTE: for use_obj, use_obj_on_obj vanilla functions to work correctly, it is required to call set_self twice. You can also access the local variables in the script of an object after calling set_self twice.

set_unique_id

sfall.h

int set_unique_id(ObjectPtr object, int flag)
 

Assigns a unique ID number to the object and returns it. If a unique ID number has already been assigned to an object, then ID number is returned without reassignment. flag is optional.

  • items with unique IDs will not stack with other items of the same type in the inventory
  • to just get the current ID number of an object, use get_object_data(object, OBJ_DATA_ID)
  • unique ID numbers are saved in your savegame, and have a range from 0x10000000 to 0x7FFFFFFF
  • there is also a unique ID number range for the player and party members from 18000 to 83535
  • to assign a new ID number generated by the engine to the object (i.e. unassign a unique ID), call the function with two arguments and pass -1 for the flag argument
diff --git a/optimization/index.html b/optimization/index.html index 3806d707..cb6dbc21 100644 --- a/optimization/index.html +++ b/optimization/index.html @@ -1,7 +1,7 @@ - Optimization | sfall Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Optimization

The executation speed of scripts is not typically important in an unmodded game, given the difference in performance between a modern computer and what Fallout was designed for. When you start adding mods to the mix there’s the potential for problems again, since sfall’s global script system means that you can have a large amount of scripts being run every single frame.

sslc -O option

The sfall build of sslc supports a -O command line option to perform an optimization pass over the generated code. This isn’t a magic make-my-code-go-faster bullet; most of what it does is very limited in scope. It’s primary purpose was to strip out the procedures and variables which get automatically pulled into every script that includes define.h, whether you use them or not, and to do something about the additional variables that get created by foreach loops.

There are several levels of optimization available:

  • -O1 - Basic, only removes unreferenced globals variables and procedures, code itself remains untouched.
  • -O2 - Full, most code optimizations are on, but only those that were tested on complex scripts.
  • -O3 - Experimental, provides most efficiency, but tend to break some complex code due to bugs.

The following optimizations are performed:

  • constant expression folding: if an expression depends only on values which are known at compile time, then the expression is replaced by its result.
    a := 2 + 2;  -> a := 4;
    +           Optimization | sfall                        Skip to main content   Link      Menu      Expand       (external link)    Document      Search       Copy       Copied        

    Optimization

    The execution speed of scripts is not typically important in an unmodded game, given the difference in performance between a modern computer and what Fallout was designed for. When you start adding mods to the mix there’s the potential for problems again, since sfall’s global script system means that you can have a large amount of scripts being run every single frame.

    sslc -O option

    The sfall build of sslc supports a -O command line option to perform an optimization pass over the generated code. This isn’t a magic make-my-code-go-faster bullet; most of what it does is very limited in scope. It’s primary purpose was to strip out the procedures and variables which get automatically pulled into every script that includes define.h, whether you use them or not, and to do something about the additional variables that get created by foreach loops.

    There are several levels of optimization available:

    • -O1 - Basic, only removes unreferenced globals variables and procedures, code itself remains untouched.
    • -O2 - Full, most code optimizations are on, but only those that were tested on complex scripts.
    • -O3 - Experimental, provides most efficiency, but tend to break some complex code due to bugs.

    The following optimizations are performed:

    • constant expression folding: if an expression depends only on values which are known at compile time, then the expression is replaced by its result.
      a := 2 + 2;  -> a := 4;
       
    • constant variable initialization: All variables are initialised to some value, (‘0’, if you don’t specify anything else,) so sslc attempts to make use of that fact to remove the first assignment to a variable if the first assignment is a constant expression.
      variable a;  -> variable a := 4;
       a := 4;      ->
      -
    • constant propagation: checks for values assigned to variables which can be computed at compile time, and replaces relevent references to the symbol by the constant. The original store is not removed by this optimization. Global variables are considered for this optimization only if they are not marked import or export, and are not assigned to anywhere in the script.
      a := 4;  -> a := 4;
      +
    • constant propagation: checks for values assigned to variables which can be computed at compile time, and replaces relevant references to the symbol by the constant. The original store is not removed by this optimization. Global variables are considered for this optimization only if they are not marked import or export, and are not assigned to anywhere in the script.
      a := 4;  -> a := 4;
       foo(a);  -> foo(4);
       
    • dead code removal: Checks for and removes code which cannot be reached, either because it is hidden behind a return or because the argument to an if statement can be computed at compile time.
      if (True) then begin   -> display_msg("foo");
         display_msg("foo");  ->
      @@ -35,4 +35,4 @@ end                                           -> end
         ...                                         -> while i < tmp do begin
       end                                           ->   ...
                                                     -> end
      -
    • Mark functions with pure or inline where relevent.

      • pure is a hint to the optimizer that a procedure has no side effects. (i.e. there’s no way to tell that it’s been called aside from its return value.) Pure procedures cannot modify global variables, or call any other procedure that isn’t itself pure. Functions marked with pure can only be used in expressions (i.e. you cannot use the call <procedure> syntax to call them.) If there are non-pure terms in an expression, it prevents that expression being considered for dead store removal. Where no such optimizations can be performed, or if optimization is disabled, marking a procedure with pure will have no effect on the compiled code.

      • inline is an instruction to the compiler to replace calls to the marked procedure with a copy of the procedures code instead of having a seperate call. Inlined procedures cannot use the return command, cannot be predefined, and cannot be used as part of an expression. Inlining if a procedure is only going to be called once is always a win, but if there are multiple calls to a procedure you will end up bloating the size of the generated code.

    +
  • Mark functions with pure or inline where relevant.

    • pure is a hint to the optimizer that a procedure has no side effects. (i.e. there’s no way to tell that it’s been called aside from its return value.) Pure procedures cannot modify global variables, or call any other procedure that isn’t itself pure. Functions marked with pure can only be used in expressions (i.e. you cannot use the call <procedure> syntax to call them.) If there are non-pure terms in an expression, it prevents that expression being considered for dead store removal. Where no such optimizations can be performed, or if optimization is disabled, marking a procedure with pure will have no effect on the compiled code.

    • inline is an instruction to the compiler to replace calls to the marked procedure with a copy of the procedures code instead of having a separate call. Inlined procedures cannot use the return command, cannot be predefined, and cannot be used as part of an expression. Inlining if a procedure is only going to be called once is always a win, but if there are multiple calls to a procedure you will end up bloating the size of the generated code.

diff --git a/sslc/index.html b/sslc/index.html index 327a0e3a..5289bb16 100644 --- a/sslc/index.html +++ b/sslc/index.html @@ -32,14 +32,14 @@ else X := value2;
  • To assign values, you can use the alternative assignment operator from C/Java instead of Pascal syntax.
    • new:
      x = 5;
       
    • old:
      x := 5;
      -
  • Multiple variable declaration: Multiple variables can be declared on one line, seperated by commas. This is an alterative to the ugly begin/end block, or the bulky single variable per line style.
    • new:
      variable a, b, c;
      +
  • Multiple variable declaration: Multiple variables can be declared on one line, separated by commas. This is an alternative to the ugly begin/end block, or the bulky single variable per line style.
    • new:
      variable a, b, c;
       
    • old:
      variable begin a; b; c; end
       
  • Variable initialization with expressions: You can now initialize local variables with complex expressions instead of constants.
    • new:
      variable tile := tile_num(dude_obj);
       
    • old:
      variable tile;
       tile := tile_num(dude_obj);
       

      NOTE: If your expression starts with a constant (eg. 2 + 2), enclose it in parentheses, otherwise compiler will be confused and give you errors.

  • Hexadecimal numerical constants: Simply prefix a number with 0x to create a hexadecimal. The numbers 0 to 9 and letters A to F are allowed in the number. The number may not have a decimal point.
    • new:
      a := 0x1000;
       
    • old:
      a := 4096;
      -
  • Increment/decrement operators: ++ and -- can be used as shorthand for += 1 and -= 1 respectively. They are mearly a syntactic shorthand to improve readability, and so their use is only allowed where += 1 would normally be allowed.
    • new:
      a++;
      +
  • Increment/decrement operators: ++ and -- can be used as shorthand for += 1 and -= 1 respectively. They are merely a syntactic shorthand to improve readability, and so their use is only allowed where += 1 would normally be allowed.
    • new:
      a++;
       
    • old:
      a += 1;
       
  • break & continue statements: They work just like in most high-level languages. break jumps out of the loop. continue jumps right to the beginning of the next iteration (see for and foreach sections for additional details).
    • new:
      while (i < N) begin
         // ...
      @@ -89,12 +89,12 @@ end else if tmp == ATKTYPE_KICK then begin
       end else begin
         display_msg("something else");
       end
      -
  • Empty statements in blocks are allowed: This is just a convenience to save scripters a bit of memory. Some of the macros in the Fallout headers include their own semicolons while others do not. With the original compiler you had to remember which was which, and if you got it wrong the script would not compile. Now it’s always safe to include your own semicolon, even if the macro already had its own. For example, this would not compile with the original sslc, but will with the sfall edition:
    #define my_macro diplay_msg("foo");
    +
  • Empty statements in blocks are allowed: This is just a convenience to save scripters a bit of memory. Some of the macros in the Fallout headers include their own semicolons while others do not. With the original compiler you had to remember which was which, and if you got it wrong the script would not compile. Now it’s always safe to include your own semicolon, even if the macro already had its own. For example, this would not compile with the original sslc, but will with the sfall edition:
    #define my_macro display_msg("foo");
     
     procedure start begin
       my_macro;
     end
    -

    NOTE: Does not work currently.

  • Procedure stringify operator @: Designed to make callback-procedures a better option and allow for basic functional programming. Basically it replaces procedure names preceeded by @ by a string constant.
    • old:
      callbackVar := "Node000";
      +

      NOTE: Does not work currently.

    • Procedure stringify operator @: Designed to make callback-procedures a better option and allow for basic functional programming. Basically it replaces procedure names preceded by @ by a string constant.
      • old:
        callbackVar := "Node000";
         call callbackVar;
         
      • new:
        callbackVar := @Node000;
         call callbackVar;
        diff --git a/stats/index.html b/stats/index.html
        index 92f8fde6..64b735f1 100644
        --- a/stats/index.html
        +++ b/stats/index.html
        @@ -3,8 +3,8 @@
         

        get_pc_base_stat

        int get_pc_base_stat(int StatID)
         

        get_pc_extra_stat

        int get_pc_extra_stat(int StatID)
         

        get_stat_max

        get_stat_max(int stat, bool who = False)
        -
        • Returns the maximum set value of the specified stat (see set_stat_max functions)
        • who: 0 (false) or omitting the argument - returns the value of the player, 1 (true) - returns the value set for other critters

        get_stat_min

        get_stat_min(int stat, bool who = False)
        -
        • Returns the minimum set value of the specified stat (see set_stat_min functions)
        • who: 0 (false) or omitting the argument - returns the value of the player, 1 (true) - returns the value set for other critters

        set_critter_base_stat

        void set_critter_base_stat(CritterPtr, int StatID, int value)
        +
        • Returns the maximum set value of the specified stat (see set_stat_max functions)
        • who: 0 (False) or omitting the argument - returns the value of the player, 1 (True) - returns the value set for other critters

        get_stat_min

        get_stat_min(int stat, bool who = False)
        +
        • Returns the minimum set value of the specified stat (see set_stat_min functions)
        • who: 0 (False) or omitting the argument - returns the value of the player, 1 (True) - returns the value set for other critters

        set_critter_base_stat

        void set_critter_base_stat(CritterPtr, int StatID, int value)
         

        set_critter_extra_stat

        void set_critter_extra_stat(CritterPtr, int StatID, int value)
         

        set_pc_base_stat

        void set_pc_base_stat(int StatID, int value)
         

        set_pc_extra_stat

        void set_pc_extra_stat(int StatID, int value)
        diff --git a/strings/index.html b/strings/index.html
        index 1ac0eb0d..fb1ee906 100644
        --- a/strings/index.html
        +++ b/strings/index.html
        @@ -1,9 +1,9 @@
                    Strings | sfall                        Skip to main content   Link      Menu      Expand       (external link)    Document      Search       Copy       Copied        

        Strings

        Functions


        charcode

        int charcode(string text)
         

        Returns ASCII code for the first character in given string.


        get_string_pointer

        sfall.h

        int get_string_pointer(string text)
         

        Returns a pointer to a string variable or to a text.


        string_format

        sfall.h

        string string_format(string format, any val1, any val2, ...)
        -

        Formats given value using standard syntax of C printf function (google “printf” for format details). However it is limited to formatting up to 4 values.

        • formatting is only supported for %s and %d, and the format string is limited to 1024 characters

        string_split

        array string_split(string, split)
        +

        Formats given value using standard syntax of C printf function (google “printf” for format details). However it is limited to formatting up to 4 values.

        • formatting is only supported for %s and %d, and the format string is limited to 1024 characters

        string_split

        array string_split(string text, split)
         

        Takes a string and a seperator, searches the string for all instances of the seperator, and returns a temp array filled with the pieces of the string split at each instance. If you give an empty string as the seperator, the string is split into individual characters. You can use this to search for a substring in a string like this: strlen(get_array(string_split(haystack, needle), 0))


        string_to_case

        string sfall_func2("string_to_case", string text, int toCase)
         

        Converts all letters in the given string to the specified case.

        toCase: 0 - lowercase, 1 - uppercase
         

        NOTE: this function works only for English letters of A-Z/a-z.


        strlen

        int strlen(string text)
        -

        Returns string length.


        substr

        string substr(string, start, length)
        +

        Returns string length.


        substr

        string substr(string text, start, length)
         

        Cuts a substring from a string starting at “start” up to “length” characters. The first character position is 0 (zero).

        • If start is negative - it indicates starting position from the end of the string (for example substr("test", -2, 2) will return last 2 charactes: “st”).
        • If length is negative - it means so many characters will be omitted from the end of string (example: substr("test", 0, -2) will return string without last 2 characters: “te”).
        • If length is zero - it will return a string from the starting position to the end of the string New behavior for sfall 4.2.2/3.8.22
        diff --git a/windows-and-images/index.html b/windows-and-images/index.html index 1b7fe6c3..115fb9f2 100644 --- a/windows-and-images/index.html +++ b/windows-and-images/index.html @@ -17,5 +17,5 @@ optional arguments: - color1/color2: the color index in the game palette. `color1` sets the text color for the first line, and `color2` for all subsequent lines of text (default color is 145)

        nterface_overlay

        sfall_func2("interface_overlay", int winType, int mode)
         

        Alternative form: int sfall_func6("interface_overlay", int winType, 2, int x, int y, int width, int height).

        Creates an additional drawing surface above the graphic layer of the specified interface window. All subsequent calls of interface_art_draw and interface_print functions will draw on it.

        • winType: the type number of the interface window (see WINTYPE_* constants in sfall.h)
        • mode: 1 - creates a new overlay surface 2 - clears the overlay area or the specified rectangle defined by the x, y, width, height arguments 0 - destroys the created overlay surface (frees up the memory allocated to the surface)

        set_window_flag

        sfall.h

        void set_window_flag(string winName/int winID, int flag, bool value)
        -

        Changes the specified flag for the created script or game interface window.

        • winName: the window name, assigned to the window by the CreateWin/create_win function
        • winID: the ID number of the interface or script window obtained with the get_window_under_mouse function, or 0 for the current game interface
        • flag: the flag to change (see WIN_FLAG_* constants in define_extra.h)
        • value: true - set the flag, false - unset the flag

        win_fill_color

        int win_fill_color(int x, int y, int width, int height, int color)
        +

        Changes the specified flag for the created script or game interface window.

        • winName: the window name, assigned to the window by the CreateWin/create_win function
        • winID: the ID number of the interface or script window obtained with the get_window_under_mouse function, or 0 for the current game interface
        • flag: the flag to change (see WIN_FLAG_* constants in define_extra.h)
        • value: True - set the flag, False - unset the flag

        win_fill_color

        int win_fill_color(int x, int y, int width, int height, int color)
         

        Fills the rectangle area of the currently selected script window with the specified color, or clears the window with transparent (index 0) color (call the function without arguments).

        • color: the color index in the game palette (from 0 to 255)