Fixed set/remove_script script functions

* they didn't set the script index number on non-critter objects.

Changed objects_in_radius to accept a radius of 0.

Edits to scripting documents.
This commit is contained in:
NovaRain
2026-04-23 22:24:37 +08:00
parent 91cc37dc17
commit fb47779d4c
5 changed files with 105 additions and 77 deletions
+13 -13
View File
@@ -164,23 +164,23 @@ ___
_*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)
- creates a permanent array (but not "saved")
- if `size >= 0`, creates a list with the given size
- if `size == -1`, creates a 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 array ID (valid until array is deleted)
#### `int temp_array(int size, int flags)`
- works exactly like `create_array`, only created array becomes "temporary"
- works exactly like `create_array`, only the created array becomes "temporary"
#### `void fix_array(int arrayID)`
- changes "temporary" array into "permanent" ("permanent" arrays are not automatically saved into savegames)
- changes a "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
- if used on lists, "key" must be numeric and within valid index range (0..size-1)
- if used on maps, "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;`
@@ -200,17 +200,17 @@ _*mixed means any type_
- 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
- searches for the first occurrence of the given value inside the given array
- if value is found, returns its 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)
- returns number of elements or key=>value pairs in the given array
- if array is not found, returns -1 (can be used to check if the given array exist)
#### `void save_array(mixed key, int arrayID)`
- makes the array saveable; it will be saved in **sfallgv.sav** file when saving the game
- array ID is associated with given "key"
- array ID is associated with the 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"
@@ -223,11 +223,11 @@ _*mixed means any type_
- 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
- can be checked if the given array is associative or not, by using index (-1): 0 - array is a list, 1 - array is a 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
- assigns value to the given key in an array, created by last `create_array` or `temp_array` call
- always returns 0
+36 -18
View File
@@ -794,12 +794,14 @@
doc: Should work like `art_change_fid_num` but in `reg_anim` sequence.
opcode: 0x825e
- name: reg_anim_take_out
detail: void reg_anim_take_out(ObjectPtr, holdFrameID, delay)
doc: Plays "take out weapon" animation for given `holdFrameID`. It is not required to have such weapon in critter's inventory.
detail: void reg_anim_take_out(ObjectPtr, int weaponCode, int delay)
doc: |
Plays "take out weapon" animation for the given `weaponCode` (see `WPN_ANIM_*` constants in **define_extra.h**).
- It is not required for the critter to have this type of weapon in its inventory.
opcode: 0x825f
- name: reg_anim_turn_towards
detail: void reg_anim_turn_towards(ObjectPtr, int tile/target, delay)
doc: Makes object change its direction to face given tile number or target object.
doc: Makes object change its direction to face the given tile number or target object.
opcode: 0x8260
- name: reg_anim_callback
detail: void reg_anim_callback(procedure proc)
@@ -816,7 +818,9 @@
items:
- name: art_exists
detail: int art_exists(int artFID)
doc: 'checks if given artFID exists in the game. Useful when you want to check if critter can use specific weapon: `art_exists((artFid bwand 0xffff0fff) bwor (weaponAnim * 0x1000))`.'
doc: |
Checks if the given `artFID` exists in the game.
- Useful when you want to check if critter can use specific weapon: `art_exists((artFid bwand 0xffff0fff) bwor (weaponAnim * 0x1000))`.
opcode: 0x8274
- name: refresh_pc_art
detail: void refresh_pc_art
@@ -852,14 +856,16 @@
opcode: 0x826d
- name: tile_get_objs
detail: array tile_get_objs(int tileNum, int elevation)
doc: Returns an array of all objects at given tile. It will include any hidden, dead or system objects (like cursor), so make sure to check properly when iterating.
doc: |
Returns an array of all objects at the given tile.
- It will include any hidden, dead or system objects (like cursor), so make sure to check properly when iterating.
opcode: 0x8270
- name: tile_refresh_display
detail: void tile_refresh_display
doc: Redraws the game scene (tiles, walls, objects, etc.).
- name: obj_blocking_tile
detail: ObjectPtr obj_blocking_tile(int tileNum, int elevation, int blockingType)
doc: Returns first object blocking given tile using given blocking function or 0 if tile is clear.
doc: Returns the first object blocking the given tile using the given blocking function, or 0 if the tile is clear.
opcode: 0x826f
- name: tile_by_position
@@ -870,20 +876,26 @@
macro: sfall.h
- name: get_tile_ground_fid
detail: int get_tile_ground_fid(int tileNum, int elevation)
doc: Returns FID of a ground tile at given tile number and elevation.
doc: Returns FID of a ground tile at the given tile number and elevation.
macro: sfall.h
- name: get_tile_roof_fid
detail: int get_tile_roof_fid(int tileNum, int elevation)
doc: Returns FID of a roof tile at given tile number and elevation. Note that FID of 1 is used when there is no actual roof.
doc: Returns FID of a roof tile at the given tile number and elevation. Note that FID of 1 is used when there is no actual roof.
macro: sfall.h
- name: obj_blocking_line
detail: ObjectPtr obj_blocking_line(ObjectPtr objFrom, int tileTo, int blockingType)
doc: Returns first object which blocks direct linear path from `objFrom` to `tileTo` using selected blocking function (see `BLOCKING_TYPE_*` constants in **sfall.h**). If path is clear (no blocker was encountered by selected function) - returns 0. `objFrom` is always excluded from calculations, but is required to be a valid object.
doc: |
Returns the first object which blocks direct linear path from `objFrom` to `tileTo` using selected blocking function (see `BLOCKING_TYPE_*` constants in **sfall.h**).
- If path is clear (no blocker was encountered by selected function) - returns 0.
- `objFrom` is always excluded from calculations, but is required to be a valid object.
opcode: 0x826e
- name: path_find_to
detail: array path_find_to(ObjectPtr objFrom, int tileTo, int blockingType)
doc: Returns the shortest path to a given tile using given blocking function as an array of tile directions (0..5) to move on each step. Array length equals to a number of steps. Empty array means that specified target cannot be reached.
doc: |
Returns the shortest path to a given tile using the given blocking function as an array of tile directions (0..5) to move on each step.
- Array length equals to a number of steps.
- Empty array means that specified target cannot be reached.
opcode: 0x8272
- name: Other
@@ -1062,7 +1074,7 @@
- name: create_spatial
detail: ObjectPtr create_spatial(int scriptID, int tile, int elevation, int radius)
doc: Creates new spatial script with given SID, at given tile, and radius.
doc: Creates new spatial script with the given scriptID at the given tile and radius.
opcode: 0x8273
- name: unwield_slot
@@ -1095,8 +1107,8 @@
- name: sprintf
detail: string sprintf(string format, any value)
doc: |
Formats given value using standart syntax of C `printf` function (google "printf" for format details). However, it is limited to formatting only 1 value.
- Can be used to get character by ASCII code ("%c").
Formats the given value using standard syntax of C `printf` function (google "printf" for format details). However, it is limited to formatting only 1 value.
- Can be used to get character by ASCII code (`%c`).
opcode: 0x8250
- name: typeof
detail: int typeof(any value)
@@ -1130,7 +1142,7 @@
opcode: 0x824f
- name: charcode
detail: int charcode(string text)
doc: Returns ASCII code for the first character in given string.
doc: Returns ASCII code for the first character in the given string.
opcode: 0x8251
- name: get_string_pointer
detail: int get_string_pointer(string text)
@@ -1427,7 +1439,7 @@
- name: spatial_radius
detail: int spatial_radius(ObjectPtr obj)
doc: Returns radius of spatial script, associated with given dummy-object (returned by `create_spatial`).
doc: Returns radius of spatial script, associated with the given dummy object (returned by `create_spatial`).
macro: sfall.h
- name: set_rest_heal_time
detail: void set_rest_heal_time(int time)
@@ -2010,12 +2022,16 @@
- name: set_script
detail: void set_script(ObjectPtr obj, int scriptID)
opcode: 0x81f4
doc: 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.
doc: |
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 scriptID when calling `set_script`, `map_enter_p_proc` will be SKIPPED. The `start` proc will always be run.
- name: get_script
detail: int get_script(ObjectPtr obj)
opcode: 0x81f5
doc: |
- accepts a pointer to an object and returns its scriptID (line number in `scripts.lst`), or 0 if the object is unscripted.
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.
- name: obj_is_carrying_obj
@@ -2058,7 +2074,9 @@
macro: sfall.h
- name: set_flags
detail: void set_flags(ObjectPtr obj, int flags)
doc: 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.
doc: |
Sets the current flags of an object.
- All flags are rewritten with the given `flags` integer, so first get the current flags with `get_flags` and use `bwor`/`bwand` to set/remove specific flags.
macro: sfall.h
- name: set_unique_id
+26 -24
View File
@@ -182,19 +182,20 @@ FUNCTION REFERENCE
- This function works in addition to the **WorldMapTimeMod** setting in **ddraw.ini** and the Pathfinder perk, rather than overriding it, so calling `set_map_time_multi(0.5)` when the player has 2 levels of pathfinder would result in time passing at 25% the normal speed on the world map.
-----
#### `void remove_script(object obj)`
- Accepts a pointer to an object and will remove the script from that object.
#### `int get_script(object 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.
-----
#### `void set_script(object obj, int scriptID)`
- Accepts a pointer to an object and **scriptID**, and applies the given script to an object (scriptID accepts the same values as `create_object_sid`)
- 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.
- Accepts a pointer to an object and **scriptID**, and applies the given script to an object (**scriptID** accepts the same values as `create_object_sid`)
- 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 **scriptID** when calling `set_script`, `map_enter_p_proc` will be SKIPPED. The `start` proc will always be run.
-----
#### `int get_script(object 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.
#### `void remove_script(object obj)`
- Accepts a pointer to an object and will remove the script from that object.
-----
#### `void set_self(object setObj)`
@@ -246,11 +247,11 @@ FUNCTION REFERENCE
-----
#### `int get_tile_ground_fid(int tileNum, int elevation)`
- Returns FID of a ground tile at given tile number and elevation.
- Returns FID of a ground tile at the given tile number and elevation.
-----
#### `int get_tile_roof_fid(int tileNum, int elevation)`
- Returns FID of a roof tile at given tile number and elevation. Note that FID of 1 is used when there is no actual roof.
- Returns FID of a roof tile at the given tile number and elevation. Note that FID of 1 is used when there is no actual roof.
-----
#### `void reg_anim_combat_check(int enable)`
@@ -275,12 +276,13 @@ FUNCTION REFERENCE
- Should work like `art_change_fid_num` but in `reg_anim` sequence.
-----
#### `void reg_anim_take_out(object obj, holdFrameID, int delay)`
- Plays "take out weapon" animation for given **holdFrameID**. It is not required to have such weapon in critter's inventory.
#### `void reg_anim_take_out(object obj, int weaponCode, int delay)`
- Plays "take out weapon" animation for the given `weaponCode` (see `WPN_ANIM_*` constants in **define_extra.h**).
- It is not required for the critter to have this type of weapon in its inventory.
-----
#### `void reg_anim_turn_towards(object obj, int/object tile/target, int delay)`
- Makes object change its direction to face given tile number or target object.
- Makes object change its direction to face the given tile number or target object.
-----
#### `void reg_anim_callback(procedure proc)`
@@ -349,7 +351,7 @@ FUNCTION REFERENCE
-----
#### `string sprintf(string format, any value)`
- Formats given value using standard syntax of C `printf` function (google "printf" for format details). However, it is limited to formatting only 1 value.
- Formats the given value using standard syntax of C `printf` function (google "printf" for format details). However, it is limited to formatting only 1 value.
- Can be used to get character by ASCII code (`%c`).
-----
@@ -358,7 +360,7 @@ FUNCTION REFERENCE
-----
#### `int charcode(string text)`
- Returns ASCII code for the first character in given string.
- Returns ASCII code for the first character in the given string.
-----
#### `div` operator (unsigned integer division)
@@ -415,7 +417,7 @@ FUNCTION REFERENCE
-----
#### `void register_hook_proc(int hookID, procedure proc)`
- Works just like `register_hook`, but allows to specify which procedure to use for given hook script (instead of `start`).
- Works just like `register_hook`, but allows to specify which procedure to use for the given hook script (instead of `start`).
- Use zero (0) as second argument to unregister hook script from current global script.
- Only use in global scripts.
- Second argument should be passed just like you pass procedures to functions like `gsay_option`, `giq_option`, etc. (name without quotes).
@@ -444,17 +446,17 @@ FUNCTION REFERENCE
-----
#### `object obj_blocking_line(object objFrom, int tileTo, int blockingType)`
- Returns first object which blocks direct linear path from objFrom to tileTo using selected blocking function (see `BLOCKING_TYPE_*` constants in **sfall.h**).
- Returns the first object which blocks direct linear path from `objFrom` to `tileTo` using selected blocking function (see `BLOCKING_TYPE_*` constants in **sfall.h**).
- If path is clear (no blocker was encountered by selected function) - returns 0.
- `objFrom` is always excluded from calculations, but is required to be a valid object.
-----
#### `object obj_blocking_tile(int tileNum, int elevation, int blockingType)`
- Returns first object blocking given tile using given blocking function or 0 if tile is clear.
- Returns the first object blocking the given tile using the given blocking function, or 0 if the tile is clear.
-----
#### `array tile_get_objs(int tileNum, int elevation)`
- Returns an array of all objects at given tile.
- Returns an array of all objects at the given tile.
- It will include any hidden, dead or system objects (like cursor), so make sure to check properly when iterating.
-----
@@ -463,17 +465,17 @@ FUNCTION REFERENCE
-----
#### `array path_find_to(object objFrom, int tileTo, int blockingType)`
- Returns the shortest path to a given tile using given blocking function as an array of tile directions (0..5) to move on each step.
- Returns the shortest path to a given tile using the given blocking function as an array of tile directions (0..5) to move on each step.
- Array length equals to a number of steps.
- Empty array means that specified target cannot be reached.
-----
#### `object create_spatial(int scriptID, int tile, int elevation, int radius)`
- Creates new spatial script with given SID, at given tile, and radius.
- Creates new spatial script with the given scriptID at the given tile and radius.
-----
#### `int art_exists(int artFID)`
- Checks if given **artFID** exists in the game.
- Checks if the given `artFID` exists in the game.
- Useful when you want to check if critter can use specific weapon: `art_exists((artFid bwand 0xFFFF0FFF) bwor (weaponAnim * 0x1000))`
-----
@@ -505,7 +507,7 @@ sfall_funcX metarule functions
----
#### spatial_radius
`int sfall_func1("spatial_radius", object obj)`
- Returns radius of spatial script, associated with given dummy-object (returned by `create_spatial`)
- Returns radius of spatial script, associated with the given dummy object (returned by `create_spatial`)
----
#### critter_inven_obj2
@@ -580,7 +582,7 @@ sfall_funcX metarule functions
#### set_flags
`void sfall_func2("set_flags", object 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
- All flags are rewritten with the given `flags` integer, so first get the current flags with `get_flags` and use `bwor`/`bwand` to set/remove specific flags
----
#### tile_refresh_display
+14 -14
View File
@@ -168,23 +168,23 @@ end
_*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)
- creates a permanent array (but not "saved")
- if `size >= 0`, creates a list with the given size
- if `size == -1`, creates a 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"
- works exactly like `create_array`, only the created array becomes "temporary"
* `void fix_array(int arrayID)`:
- changes "temporary" array into "permanent" ("permanent" arrays are not automatically saved into savegames)
- changes a "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
- if used on lists, "key" must be numeric and within valid index range (0..size-1)
- if used on maps, "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;`
@@ -204,17 +204,17 @@ _*mixed means any type_
- 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)
- searches for the first occurrence of the given value inside the given array
- if value is found, returns its 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)
- returns number of elements or key=>value pairs in the given array
- if array is not found, returns -1 (can be used to check if the given array exist)
* `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"
- arrayID is associated with the 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"
@@ -227,11 +227,11 @@ _*mixed means any type_
- 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
- can be checked if the given array is associative or not, by using index (-1): 0 - array is a list, 1 - array is a 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
- assigns value to the given key in an array, created by last `create_array` or `temp_array` call
- always returns 0
## Backward compatibility notes
+16 -8
View File
@@ -130,9 +130,10 @@ void op_get_npc_level(OpcodeContext& ctx) {
void op_remove_script(OpcodeContext& ctx) {
auto object = ctx.arg(0).object();
if (object->scriptId != 0xFFFFFFFF) {
if (object->scriptId != -1) {
fo::func::scr_remove(object->scriptId);
object->scriptId = 0xFFFFFFFF;
object->scriptId = -1;
object->scriptIndex = -1;
}
}
@@ -151,22 +152,29 @@ void op_set_script(OpcodeContext& ctx) {
unsigned long valArg = ctx.arg(1).rawValue();
long scriptIndex = valArg & ~0xF0000000;
if (scriptIndex == 0 || valArg > 0x8FFFFFFF) { // negative values are not allowed
ctx.printOpcodeError("%s() - invalid script index number.", ctx.getOpcodeName());
if (scriptIndex == 0 || scriptIndex > fo::var::maxScriptNum) { // negative values are not allowed
ctx.printOpcodeError("%s() - invalid script index number: %d", ctx.getOpcodeName(), scriptIndex);
return;
}
scriptIndex--;
if (object->scriptId != 0xFFFFFFFF) {
if (object->scriptId != -1) {
fo::func::scr_remove(object->scriptId);
object->scriptId = 0xFFFFFFFF;
object->scriptId = -1;
object->scriptIndex = -1;
}
if (object->IsCritter()) {
scriptType = fo::Scripts::ScriptTypes::SCRIPT_CRITTER;
} else {
scriptType = fo::Scripts::ScriptTypes::SCRIPT_ITEM;
}
fo::func::obj_new_sid_inst(object, scriptType, scriptIndex);
if (fo::func::obj_new_sid_inst(object, scriptType, scriptIndex) == -1) {
// if sid assignment failed, revert to the "removed" state
object->scriptId = -1;
object->scriptIndex = -1;
return;
}
object->scriptIndex = scriptIndex;
long scriptId = object->scriptId;
exec_script_proc(scriptId, start);
@@ -588,7 +596,7 @@ void mf_set_unique_id(OpcodeContext& ctx) {
void mf_objects_in_radius(OpcodeContext& ctx) {
long radius = ctx.arg(1).rawValue();
if (radius <= 0) radius = 1; else if (radius > 50) radius = 50;
if (radius < 0) radius = 0; else if (radius > 50) radius = 50;
long elev = ctx.arg(2).rawValue();
if (elev < 0) elev = 0; else if (elev > 2) elev = 2;
long type = (ctx.numArgs() > 3) ? ctx.arg(3).rawValue() : -1;