diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index a2e56717..df8ef480 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -388,6 +388,7 @@ #define set_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value) #define show_win sfall_func0("show_window") #define show_window(winName) sfall_func1("show_window", winName) +#define signal_close_game sfall_func0("signal_close_game") #define spatial_radius(obj) sfall_func1("spatial_radius", obj) #define string_compare(str1, str2) sfall_func2("string_compare", str1, str2) #define string_compare_locale(str1, str2, codePage) sfall_func3("string_compare", str1, str2, codePage) diff --git a/artifacts/scripting/sfall function notes.md b/artifacts/scripting/sfall function notes.md index c2ce94c1..a334e2ef 100644 --- a/artifacts/scripting/sfall function notes.md +++ b/artifacts/scripting/sfall function notes.md @@ -244,7 +244,7 @@ FUNCTION REFERENCE - 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. ----- -##### `void reg_anim_combat_check` +##### `void reg_anim_combat_check(int enable)` - Allows enabling all `reg_anim_*` functions in combat (including vanilla functions) if set to 0. It is automatically reset at the end of each frame, so you need to call it before `reg_anim_begin() ... reg_anim_end()` code block. **Some additional `reg_anim_*` functions were introduced. They all work in the same convention as vanilla functions and use the same underlying code.** @@ -1117,6 +1117,11 @@ sfall_funcX metarule functions - Plays the specified animation while simultaneously moving the object to the given tile - `delay`: delay from the previous animation. A value of -1 will execute the specified animation immediately after the previous one in the sequence ends +---- +#### signal_close_game +`void sfall_func0("signal_close_game")` +- Works in a similar way to vanilla function: `metarule(METARULE_SIGNAL_END_GAME, 0)`, but it will then close the game instead of only returning the player to the main menu + **** _See other documentation files (arrays.md, hookscripts.md) for related functions reference._ diff --git a/sfall/Modules/Scripting/Handlers/Anims.cpp b/sfall/Modules/Scripting/Handlers/Anims.cpp index 1ea69b25..990a4e16 100644 --- a/sfall/Modules/Scripting/Handlers/Anims.cpp +++ b/sfall/Modules/Scripting/Handlers/Anims.cpp @@ -33,14 +33,17 @@ void RegAnimCombatCheck(DWORD newValue) { char oldValue = regAnimCombatCheck; regAnimCombatCheck = (newValue > 0); if (oldValue != regAnimCombatCheck) { - SafeWrite8(0x459C97, regAnimCombatCheck); // reg_anim_func - SafeWrite8(0x459D4B, regAnimCombatCheck); // reg_anim_animate - SafeWrite8(0x459E3B, regAnimCombatCheck); // reg_anim_animate_reverse - SafeWrite8(0x459EEB, regAnimCombatCheck); // reg_anim_obj_move_to_obj - SafeWrite8(0x459F9F, regAnimCombatCheck); // reg_anim_obj_run_to_obj - SafeWrite8(0x45A053, regAnimCombatCheck); // reg_anim_obj_move_to_tile - SafeWrite8(0x45A10B, regAnimCombatCheck); // reg_anim_obj_run_to_tile - SafeWrite8(0x45AE53, regAnimCombatCheck); // reg_anim_animate_forever + const DWORD regAnimCombatChkAddr[] = { + 0x459C97, // reg_anim_func + 0x459D4B, // reg_anim_animate + 0x459E3B, // reg_anim_animate_reverse + 0x459EEB, // reg_anim_obj_move_to_obj + 0x459F9F, // reg_anim_obj_run_to_obj + 0x45A053, // reg_anim_obj_move_to_tile + 0x45A10B, // reg_anim_obj_run_to_tile + 0x45AE53 // reg_anim_animate_forever + }; + SafeWriteBatch(regAnimCombatCheck, regAnimCombatChkAddr); } } diff --git a/sfall/Modules/Scripting/Handlers/Metarule.cpp b/sfall/Modules/Scripting/Handlers/Metarule.cpp index a9250a09..23e16679 100644 --- a/sfall/Modules/Scripting/Handlers/Metarule.cpp +++ b/sfall/Modules/Scripting/Handlers/Metarule.cpp @@ -153,6 +153,7 @@ static const SfallMetarule metarules[] = { {"set_unjam_locks_time", mf_set_unjam_locks_time, 1, 1, -1, {ARG_INT}}, {"set_window_flag", mf_set_window_flag, 3, 3, -1, {ARG_INTSTR, ARG_INT, ARG_INT}}, {"show_window", mf_show_window, 0, 1, -1, {ARG_STRING}}, + {"signal_close_game", mf_signal_close_game, 0, 0}, {"spatial_radius", mf_spatial_radius, 1, 1, 0, {ARG_OBJECT}}, {"string_compare", mf_string_compare, 2, 3, 0, {ARG_STRING, ARG_STRING, ARG_INT}}, {"string_find", mf_string_find, 2, 3, -1, {ARG_STRING, ARG_STRING, ARG_INT}}, diff --git a/sfall/Modules/Scripting/Handlers/Misc.cpp b/sfall/Modules/Scripting/Handlers/Misc.cpp index c7ed51bc..b385333a 100644 --- a/sfall/Modules/Scripting/Handlers/Misc.cpp +++ b/sfall/Modules/Scripting/Handlers/Misc.cpp @@ -359,5 +359,13 @@ void mf_set_scr_name(OpcodeContext& ctx) { ObjectName::SetName(sid, ctx.arg(0).strValue()); } +void mf_signal_close_game(OpcodeContext& ctx) { + // force ESC key in the main menu + SafeWrite8(0x481B2A, 0xB8); + SafeWrite32(0x481B2B, VK_ESCAPE); // mov eax, 27 + + *fo::ptr::game_user_wants_to_quit = 2; // return to the main menu +} + } } diff --git a/sfall/Modules/Scripting/Handlers/Misc.h b/sfall/Modules/Scripting/Handlers/Misc.h index 7062df8f..4a878883 100644 --- a/sfall/Modules/Scripting/Handlers/Misc.h +++ b/sfall/Modules/Scripting/Handlers/Misc.h @@ -96,5 +96,7 @@ void mf_set_quest_failure_value(OpcodeContext&); void mf_set_scr_name(OpcodeContext&); +void mf_signal_close_game(OpcodeContext&); + } } diff --git a/sfall/version.h b/sfall/version.h index d0c9fc78..cce801e7 100644 --- a/sfall/version.h +++ b/sfall/version.h @@ -25,6 +25,6 @@ #define VERSION_MAJOR 3 #define VERSION_MINOR 8 #define VERSION_BUILD 43 -#define VERSION_REV 1 +#define VERSION_REV 2 -#define VERSION_STRING "3.8.43.1" +#define VERSION_STRING "3.8.43.2"