From e93d878d1d77753128e6b6f9d9fd5ad3b6cbf2f6 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 17 Nov 2019 08:32:03 +0800 Subject: [PATCH] Added a new hook: HOOK_STDPROCEDURE_END * as an extension to HOOK_STDPROCEDURE hook script. Updated documents. --- artifacts/scripting/headers/sfall.h | 13 +++--- artifacts/scripting/hookscripts.txt | 15 ++++--- artifacts/scripting/sfall function notes.txt | 25 ++++++----- sfall/Modules/HookScripts.cpp | 1 + sfall/Modules/HookScripts.h | 1 + sfall/Modules/HookScripts/ObjectHs.cpp | 46 +++++++++++++++++--- sfall/Modules/HookScripts/ObjectHs.h | 1 + 7 files changed, 70 insertions(+), 32 deletions(-) diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index d616f8c1..748de311 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -63,6 +63,7 @@ #define HOOK_SETLIGHTING (38) #define HOOK_SNEAK (39) #define HOOK_STDPROCEDURE (40) +#define HOOK_STDPROCEDURE_END (41) //Valid arguments to list_begin #define LIST_CRITTERS (0) @@ -249,9 +250,9 @@ // sfall_funcX macros #define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name) -#define add_global_timer_event(time, param) sfall_func2("add_g_timer_event", time, param) +#define add_global_timer_event(time, fixedParam) sfall_func2("add_g_timer_event", time, fixedParam) #define add_iface_tag sfall_func0("add_iface_tag") -#define add_trait(traitId) sfall_func1("add_trait", traitId) +#define add_trait(traitID) sfall_func1("add_trait", traitID) #define art_cache_clear sfall_func0("art_cache_clear") #define attack_is_aimed sfall_func0("attack_is_aimed") #define car_gas_amount sfall_func0("car_gas_amount") @@ -287,17 +288,17 @@ #define intface_redraw sfall_func0("intface_redraw") #define intface_show sfall_func0("intface_show") #define inventory_redraw(invSide) sfall_func1("inventory_redraw", invSide) -#define item_make_explosive(pid, aPid, min, max) sfall_func4("item_make_explosive", pid, aPid, min, max) +#define item_make_explosive(pid, activePid, min, max) sfall_func4("item_make_explosive", pid, activePid, min, max) #define item_weight(obj) sfall_func1("item_weight", obj) #define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj) #define loot_obj sfall_func0("loot_obj") -#define metarule_exist(metarule) sfall_func1("metarule_exist", metarule) +#define metarule_exist(metaruleName) sfall_func1("metarule_exist", metaruleName) #define npc_engine_level_up(toggle) sfall_func1("npc_engine_level_up", toggle) -#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude) +#define obj_under_cursor(onlyCritter, includeDude) sfall_func2("obj_under_cursor", onlyCritter, includeDude) #define outlined_object sfall_func0("outlined_object") #define real_dude_obj sfall_func0("real_dude_obj") #define remove_all_timer_events sfall_func0("remove_timer_event") -#define remove_timer_event(param) sfall_func1("remove_timer_event", param) +#define remove_timer_event(fixedParam) sfall_func1("remove_timer_event", fixedParam) #define set_can_rest_on_map(map, elev, value) sfall_func3("set_can_rest_on_map", map, elev, value) #define set_car_intface_art(artIndex) sfall_func1("set_car_intface_art", artIndex) #define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode) diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt index 8fdf0500..882d70ad 100644 --- a/artifacts/scripting/hookscripts.txt +++ b/artifacts/scripting/hookscripts.txt @@ -286,10 +286,10 @@ int ret1 - the new AP cost ------------------------------------------- (DEPRECATED) -hs_hexmoveblocking.int -hs_hexaiblocking.int -hs_hexshootblocking.int -hs_hexsightblocking.int +HOOK_HEXMOVEBLOCKING (hs_hexmoveblocking.int) +HOOK_HEXAIBLOCKING (hs_hexaiblocking.int) +HOOK_HEXSHOOTBLOCKING (hs_hexshootblocking.int) +HOOK_HEXSIGHTBLOCKING (hs_hexsightblocking.int) Runs when checking to see if a hex blocks movement or shooting. (or ai-ing, presumably...) @@ -636,13 +636,14 @@ int ret2 - overrides the duration time for the current result ------------------------------------------- -HOOK_STDPROCEDURE (hs_stdprocedure.int) +HOOK_STDPROCEDURE, HOOK_STDPROCEDURE_END (hs_stdprocedure.int) -Runs before Fallout executes a standard procedure (handler) in any script of any object. +Runs before or after Fallout engine executes a standard procedure (handler) in any script of any object. NOTE: this hook will not be executed for "start", critter_p_proc, timed_event_p_proc, and map_update_p_proc procedures. int arg1 - the number of the standard script handler (see define.h) Obj arg2 - the object that owns this handler (self_obj) Obj arg3 - the object that called this handler (source_obj, can be 0) +int arg4 - 1 after procedure execution (for HOOK_STDPROCEDURE_END), 0 otherwise -int ret1 - pass -1 to cancel the execution of the handler +int ret1 - pass -1 to cancel the execution of the handler (only for HOOK_STDPROCEDURE) diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index ea82897d..fbdf1c49 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -520,7 +520,7 @@ Some utility/math functions are available: > void sfall_func0("inventory_redraw") > void sfall_func1("inventory_redraw", int invSide) - redraws inventory list in the inventory/use inventory item on/loot/barter screens -- invSide specifies which side needs to be redrawn: 0 - the player, 1 - target (container/NPC in loot/barter screens), -1 - both sides +- invSide specifies which side needs to be redrawn: 0 - the player, 1 - target (container/NPC in loot/barter screens), -1 - both sides (same as without argument) > void sfall_func3("item_make_explosive", int pid, int activePid, int damage) > void sfall_func4("item_make_explosive", int pid, int activePid, int min, int max) @@ -559,10 +559,11 @@ Some utility/math functions are available: > object sfall_func0("dialog_obj") - returns a pointer to the object (critter) the player is having a conversation or bartering with -> object sfall_func2("obj_under_cursor", bool crSwitch, bool inclDude) +> object sfall_func2("obj_under_cursor", bool onlyCritter, bool includeDude) - returns the object under the cursor on the main game screen -- crSwitch: 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 inclDude argument will ignore dude_obj +- 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 > object sfall_func0("loot_obj") - returns a pointer to the target object (container or critter) of the loot screen @@ -631,29 +632,29 @@ optional argument: - can take off player's equipped item when the inventory is opened, or the player is in the barter screen - slot: 0 - armor slot, 1 - right slot, 2 - left slot (see INVEN_TYPE_* in define.h) -> void sfall_func1("add_trait", int traitId) +> void sfall_func1("add_trait", int traitID) - adds the specified trait to the player > int sfall_func0("get_inven_ap_cost") - returns the current AP cost to access the inventory in combat -> void sfall_func2("add_g_timer_event", int time, int param) +> void sfall_func2("add_g_timer_event", int time, int fixedParam) - adds a timer event that calls the timed_event_p_proc procedure in the current global script - time: the number of ticks after which the event timer is triggered -- param: the value that is passed to the timed_event_p_proc procedure for the fixed_param function +- fixedParam: the value that is passed to the timed_event_p_proc procedure for the fixed_param function > void sfall_func0("remove_timer_event") - clears all set timer events for the current global script -> void sfall_func1("remove_timer_event", int param) -- removes all timer events with the specified 'param' value for the current global script +> void sfall_func1("remove_timer_event", int fixedParam) +- removes all timer events with the specified 'fixedParam' value for the current global script > mixed sfall_func1("get_sfall_arg_at", int argNum) -- gets the value of hook argument with the specified argument number (argNum, first argument starts from 0) +- gets the value of hook argument with the specified argument number (argNum, first argument of hook starts from 0) > void sfall_func0("hide_window") > void sfall_func1("hide_window", string winName) -- hides the specified or currently selected/active script window +- hides the specified or currently active (selected) script window - winName: the window name, assigned to the window by the CreateWin/create_win function > void sfall_func0("show_window") @@ -664,7 +665,7 @@ optional argument: > void sfall_func3("set_window_flag", string/int winName/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 +- 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 diff --git a/sfall/Modules/HookScripts.cpp b/sfall/Modules/HookScripts.cpp index bad7d618..1a8a50ae 100644 --- a/sfall/Modules/HookScripts.cpp +++ b/sfall/Modules/HookScripts.cpp @@ -91,6 +91,7 @@ static HooksInjectInfo injectHooks[] = { {HOOK_SETLIGHTING, Inject_SetLightingHook, false}, {HOOK_SNEAK, Inject_SneakCheckHook, false}, {HOOK_STDPROCEDURE, Inject_ScriptProcedureHook, false}, + {HOOK_STDPROCEDURE_END, Inject_ScriptProcedureHook2, false}, }; bool HookScripts::injectAllHooks; diff --git a/sfall/Modules/HookScripts.h b/sfall/Modules/HookScripts.h index 2f5910ad..0cc9eb86 100644 --- a/sfall/Modules/HookScripts.h +++ b/sfall/Modules/HookScripts.h @@ -67,6 +67,7 @@ enum HookType HOOK_SETLIGHTING = 38, HOOK_SNEAK = 39, HOOK_STDPROCEDURE = 40, + HOOK_STDPROCEDURE_END = 41, HOOK_COUNT }; diff --git a/sfall/Modules/HookScripts/ObjectHs.cpp b/sfall/Modules/HookScripts/ObjectHs.cpp index edc05be0..682b3ff0 100644 --- a/sfall/Modules/HookScripts/ObjectHs.cpp +++ b/sfall/Modules/HookScripts/ObjectHs.cpp @@ -72,7 +72,7 @@ static void __declspec(naked) UseObjHook() { mov args[4], edx; // object pushad; } - + argCount = 2; RunHookScript(HOOK_USEOBJ); @@ -237,16 +237,23 @@ skip: static DWORD __fastcall StdProcedureHook_Script(long numHandler, fo::ScriptInstance* script, DWORD procTable) { BeginHook(); - argCount = 3; + argCount = 4; args[0] = numHandler; args[1] = (DWORD)script->selfObject; args[2] = (DWORD)script->sourceObject; - RunHookScript(HOOK_STDPROCEDURE); - if (cRet > 0) { - long retval = rets[0]; - if (retval == -1) procTable = retval; + if (procTable) { + args[3] = 0; + RunHookScript(HOOK_STDPROCEDURE); + + if (cRet > 0) { + long retval = rets[0]; + if (retval == -1) procTable = retval; + } + } else { + args[3] = 1; + RunHookScript(HOOK_STDPROCEDURE_END); } EndHook(); return procTable; @@ -278,6 +285,26 @@ end: } } +static void __declspec(naked) After_ScriptStdProcedureHook() { + using namespace fo::ScriptProc; + __asm { + call fo::funcoffs::executeProcedure_; + cmp ecx, critter_p_proc; + je skip; + cmp ecx, timed_event_p_proc; + je skip; + cmp ecx, map_update_p_proc; + je skip; + cmp ecx, start; + jle skip; + mov edx, [esp + 0x28 - 0x18 + 4]; // script + push 0; // procTable + call StdProcedureHook_Script; // ecx - numHandler +skip: + retn; + } +} + void Inject_UseObjOnHook() { HookCalls(UseObjOnHook, { 0x49C606, 0x473619 }); @@ -311,6 +338,10 @@ void Inject_ScriptProcedureHook() { MakeCall(0x4A491F, ScriptStdProcedureHook); } +void Inject_ScriptProcedureHook2() { + HookCall(0x4A49A7, After_ScriptStdProcedureHook); +} + void InitObjectHookScripts() { LoadHookScript("hs_useobjon", HOOK_USEOBJON); @@ -318,7 +349,8 @@ void InitObjectHookScripts() { LoadHookScript("hs_useanimobj", HOOK_USEANIMOBJ); LoadHookScript("hs_descriptionobj", HOOK_DESCRIPTIONOBJ); LoadHookScript("hs_setlighting", HOOK_SETLIGHTING); - LoadHookScript("hs_stdprocedure", HOOK_STDPROCEDURE); + LoadHookScript("hs_stdprocedure", HOOK_STDPROCEDURE); // combo hook + LoadHookScript("hs_stdprocedure", HOOK_STDPROCEDURE_END); } } diff --git a/sfall/Modules/HookScripts/ObjectHs.h b/sfall/Modules/HookScripts/ObjectHs.h index f14084be..832f00df 100644 --- a/sfall/Modules/HookScripts/ObjectHs.h +++ b/sfall/Modules/HookScripts/ObjectHs.h @@ -10,4 +10,5 @@ namespace sfall void Inject_DescriptionObjHook(); void Inject_SetLightingHook(); void Inject_ScriptProcedureHook(); + void Inject_ScriptProcedureHook2(); }