diff --git a/artifacts/scripting/functions.yml b/artifacts/scripting/functions.yml index d93fd064..3e05c3d7 100644 --- a/artifacts/scripting/functions.yml +++ b/artifacts/scripting/functions.yml @@ -1238,7 +1238,7 @@ opcode: 0x823c - name: get_sfall_arg_at detail: mixed get_sfall_arg_at(int argNum) - doc: Returns the value of hook argument with the specified argument number (first argument of hook starts from 0) + doc: Returns the value of hook argument with the specified argument number (first argument of hook starts at 0) macro: sfall.h - name: set_sfall_return detail: void set_sfall_return(any value) @@ -1495,6 +1495,13 @@ doc: Returns True if the specified name of metarule (sfall_funcX) function exists in the current version of sfall. macro: sfall.h + - name: opcode_exists + detail: bool opcode_exists(int opcodeNum) + doc: | + Returns True if an opcode with the specified number exists in the current version of sfall. + - `opcodeNum` starts at `0x8000`. + macro: sfall.h + - name: add_extra_msg_file detail: int add_extra_msg_file(string fileName) doc: | @@ -1723,7 +1730,7 @@ - returns the dimensions of a given PCX or FRM frame as a temp array in the form **[width, height]** - `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 + - `frame`: frame number, the first frame starts at zero - `rotation`: rotation to get the frame for, useful when reading FRM files by path macro: sfall.h @@ -1742,7 +1749,7 @@ - `x/y`: offset relative to the top-left corner of the window optional arguments: - - `frame`: frame number, the first frame starts from zero + - `frame`: frame number, the first frame starts at 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 @@ -1772,7 +1779,7 @@ - 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 + - `frame`: frame number, the first frame starts at 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))` diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index eacee997..abaab967 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -368,6 +368,7 @@ #define obj_is_openable(obj) sfall_func1("obj_is_openable", obj) #define obj_under_cursor(onlyCritter, includeDude) sfall_func2("obj_under_cursor", onlyCritter, includeDude) #define objects_in_radius(tile, radius, elev, type) sfall_func4("objects_in_radius", tile, radius, elev, type) +#define opcode_exists(opcodeNum) sfall_func1("opcode_exists", opcodeNum) #define outlined_object sfall_func0("outlined_object") #define overlay_create(winType) sfall_func2("interface_overlay", winType, 1) #define overlay_clear(winType) sfall_func2("interface_overlay", winType, 2) diff --git a/artifacts/scripting/sfall function notes.md b/artifacts/scripting/sfall function notes.md index 56e96032..c7181181 100644 --- a/artifacts/scripting/sfall function notes.md +++ b/artifacts/scripting/sfall function notes.md @@ -504,6 +504,12 @@ sfall_funcX metarule functions `bool sfall_func1("metarule_exist", string metaruleName)` - Returns True if the specified name of `sfall_funcX` metarule function exists in the current version of sfall +---- +#### opcode_exists +`bool sfall_func1("opcode_exists", int opcodeNum)` +- Returns True if an opcode with the specified number exists in the current version of sfall +- `opcodeNum` starts at `0x8000` + ---- #### spatial_radius `int sfall_func1("spatial_radius", object obj)` @@ -842,7 +848,7 @@ sfall_funcX metarule functions - `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 +- `frame`: frame number, the first frame starts at 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 - `noTransparent`: pass True to display an image without transparent background @@ -901,7 +907,7 @@ sfall_funcX metarule functions ---- #### get_sfall_arg_at `mixed sfall_func1("get_sfall_arg_at", int argNum)` -- Returns the value of hook argument with the specified argument number (*first argument of hook starts from 0*) +- Returns the value of hook argument with the specified argument number (*first argument of hook starts at 0*) ---- #### hide_window @@ -1028,7 +1034,7 @@ sfall_funcX metarule functions - `x/y`: offset relative to the top-left corner of the window **Optional arguments:** -- `frame`: frame number, the first frame starts from zero +- `frame`: frame number, the first frame starts at 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 @@ -1156,7 +1162,7 @@ sfall_funcX metarule functions - `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 +- `frame`: frame number, the first frame starts at zero - `rotation`: rotation to get the frame for, useful when reading FRM files by path ---- diff --git a/sfall/Modules/Scripting/Handlers/Core.cpp b/sfall/Modules/Scripting/Handlers/Core.cpp index 09e1c184..9ff3a0d8 100644 --- a/sfall/Modules/Scripting/Handlers/Core.cpp +++ b/sfall/Modules/Scripting/Handlers/Core.cpp @@ -23,6 +23,7 @@ #include "..\..\HookScripts\Common.h" #include "..\..\ScriptExtender.h" #include "..\Arrays.h" +#include "..\Opcodes.h" #include "Core.h" @@ -198,6 +199,10 @@ void mf_remove_timer_event(OpcodeContext& ctx) { } } +void mf_opcode_exists(OpcodeContext& ctx) { + ctx.setReturn(Opcodes::OpcodeExists(ctx.arg(0).intValue())); +} + __declspec(naked) void op_sfall_ver_major() { __asm { mov edx, VERSION_MAJOR; diff --git a/sfall/Modules/Scripting/Handlers/Core.h b/sfall/Modules/Scripting/Handlers/Core.h index 403b6639..4271a3d8 100644 --- a/sfall/Modules/Scripting/Handlers/Core.h +++ b/sfall/Modules/Scripting/Handlers/Core.h @@ -64,6 +64,8 @@ void mf_add_g_timer_event(OpcodeContext&); void mf_remove_timer_event(OpcodeContext&); +void mf_opcode_exists(OpcodeContext&); + void op_sfall_ver_major(); void op_sfall_ver_minor(); diff --git a/sfall/Modules/Scripting/Handlers/Metarule.cpp b/sfall/Modules/Scripting/Handlers/Metarule.cpp index 22e97cbf..12f4fafd 100644 --- a/sfall/Modules/Scripting/Handlers/Metarule.cpp +++ b/sfall/Modules/Scripting/Handlers/Metarule.cpp @@ -130,6 +130,7 @@ static const SfallMetarule metarules[] = { {"obj_is_openable", mf_obj_is_openable, 1, 1, 0, {ARG_OBJECT}}, {"obj_under_cursor", mf_obj_under_cursor, 2, 2, 0, {ARG_INT, ARG_INT}}, {"objects_in_radius", mf_objects_in_radius, 3, 4, 0, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}}, + {"opcode_exists", mf_opcode_exists, 1, 1, 0, {ARG_INT}}, {"outlined_object", mf_outlined_object, 0, 0}, {"real_dude_obj", mf_real_dude_obj, 0, 0}, {"reg_anim_animate_and_move", mf_reg_anim_animate_and_move, 4, 4, -1, {ARG_OBJECT, ARG_INT, ARG_INT, ARG_INT}}, diff --git a/sfall/Modules/Scripting/Opcodes.cpp b/sfall/Modules/Scripting/Opcodes.cpp index 9d11358a..e408c6b3 100644 --- a/sfall/Modules/Scripting/Opcodes.cpp +++ b/sfall/Modules/Scripting/Opcodes.cpp @@ -434,5 +434,15 @@ void Opcodes::InitNew() { } } +bool Opcodes::OpcodeExists(int opcode) { + constexpr int opcodeStart = 0x8000; + + if (opcode < opcodeStart || opcode >= opcodeStart + opcodeCount) return false; + opcode -= opcodeStart; + + if (opcodes[opcode] != defaultOpcodeHandler) return true; // raw handlers + return (opcodeInfoTable[opcode - sfallOpcodeStart] != nullptr); +} + } } diff --git a/sfall/Modules/Scripting/Opcodes.h b/sfall/Modules/Scripting/Opcodes.h index cda0bbc8..73104dff 100644 --- a/sfall/Modules/Scripting/Opcodes.h +++ b/sfall/Modules/Scripting/Opcodes.h @@ -28,6 +28,8 @@ namespace script class Opcodes { public: static void InitNew(); + + static bool OpcodeExists(int opcode); }; }