diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 762f4c12..08d73f76 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -351,6 +351,7 @@ #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_combat_free_move(value) sfall_func1("set_combat_free_move", value) #define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode) #define set_flags(obj, flags) sfall_func2("set_flags", obj, flags) #define set_iface_tag_text(tag, text, color) sfall_func3("set_iface_tag_text", tag, text, color) diff --git a/artifacts/scripting/hookscripts.md b/artifacts/scripting/hookscripts.md index 56bc6440..eb774f94 100644 --- a/artifacts/scripting/hookscripts.md +++ b/artifacts/scripting/hookscripts.md @@ -755,10 +755,12 @@ Runs before or after Fallout engine executes a standard procedure (handler) in a __NOTE:__ This hook will not be executed for `start`, `critter_p_proc`, `timed_event_p_proc`, and `map_update_p_proc` procedures. ``` -int arg0 - the number of the standard script handler (see define.h) +int arg0 - the number of the standard script handler (see *_proc in define.h) Obj arg1 - the object that owns this handler (self_obj) Obj arg2 - the object that called this handler (source_obj, can be 0) int arg3 - 1 after procedure execution (for HOOK_STDPROCEDURE_END), 0 otherwise +Obj arg4 - the object that is acted upon by this handler (target_obj, can be 0) +int arg5 - the parameter of this call (fixed_param), useful for combat_proc int ret0 - pass -1 to cancel the execution of the handler (only for HOOK_STDPROCEDURE) ``` diff --git a/artifacts/scripting/sfall function notes.md b/artifacts/scripting/sfall function notes.md index 0a5ddd78..836a27c7 100644 --- a/artifacts/scripting/sfall function notes.md +++ b/artifacts/scripting/sfall function notes.md @@ -1044,6 +1044,13 @@ sfall_funcX metarule functions - `centerMult/targetMult`: multiplier values are capped at divisor values - __NOTE:__ refer to the description of **ComputeSpray_\*** settings in ddraw.ini for details of the bullet distribution of burst attacks +---- +##### set_combat_free_move +`void sfall_func1("set_combat_free_move", int value)` + +- Allows changing "bonus move" points (yellow lights on the interface bar) that can only be used for movement, not attacking +- Can be called from `HOOK_STDPROCEDURE` with `combat_proc` event (will work on both NPCs and `dude_obj`) + **** _See other documentation files (arrays.md, hookscripts.md) for related functions reference._ diff --git a/sfall/Modules/HookScripts/ObjectHs.cpp b/sfall/Modules/HookScripts/ObjectHs.cpp index b2b99d8c..a8b22c81 100644 --- a/sfall/Modules/HookScripts/ObjectHs.cpp +++ b/sfall/Modules/HookScripts/ObjectHs.cpp @@ -253,11 +253,13 @@ skip: static DWORD __fastcall StdProcedureHook_Script(long numHandler, fo::ScriptInstance* script, DWORD procTable) { BeginHook(); - argCount = 4; + argCount = 6; args[0] = numHandler; args[1] = (DWORD)script->selfObject; args[2] = (DWORD)script->sourceObject; + args[4] = (DWORD)script->targetObject; + args[5] = script->fixedParam; if (procTable) { args[3] = 0; diff --git a/sfall/Modules/PartyControl.cpp b/sfall/Modules/PartyControl.cpp index 40d6cebd..e61d054f 100644 --- a/sfall/Modules/PartyControl.cpp +++ b/sfall/Modules/PartyControl.cpp @@ -299,6 +299,20 @@ static long __fastcall GetRealDudeTrait(fo::GameObject* source, long trait) { return fo::func::trait_level(trait); } +static void __declspec(naked) inven_pickup_hook() { + __asm { + pushadc; + mov ecx, eax; // item + call PartyControl::SwitchHandHook; + test eax, eax; + popadc; + jns skip; // eax > -1 + jmp fo::funcoffs::switch_hand_; +skip: + retn; + } +} + static void __declspec(naked) CombatWrapper_v2() { __asm { sub esp, 4; @@ -707,6 +721,8 @@ void PartyControl::init() { } MakeCall(0x45F47C, intface_toggle_items_hack); + const DWORD switchHandAddr[] = {0x4712E3, 0x47136D}; // left slot, right slot + HookCalls(inven_pickup_hook, switchHandAddr); // will be overwritten if HOOK_INVENTORYMOVE is injected NpcAutoLevelPatch(); diff --git a/sfall/Modules/Scripting/Handlers/Combat.cpp b/sfall/Modules/Scripting/Handlers/Combat.cpp index cff3617d..23077750 100644 --- a/sfall/Modules/Scripting/Handlers/Combat.cpp +++ b/sfall/Modules/Scripting/Handlers/Combat.cpp @@ -265,5 +265,15 @@ void mf_set_spray_settings(OpcodeContext& ctx) { BurstMods::SetComputeSpraySettings(centerMult, centerDiv, targetMult, targetDiv); } +void mf_set_combat_free_move(OpcodeContext& ctx) { + long value = ctx.arg(0).rawValue(); + if (value < 0) value = 0; + + *fo::ptr::combat_free_move = value; + if ((*fo::ptr::main_ctd).attacker == *fo::ptr::obj_dude) { + fo::func::intface_update_move_points((*fo::ptr::obj_dude)->critter.movePoints, *fo::ptr::combat_free_move); + } +} + } } diff --git a/sfall/Modules/Scripting/Handlers/Combat.h b/sfall/Modules/Scripting/Handlers/Combat.h index e3cbad0d..9ccee2a6 100644 --- a/sfall/Modules/Scripting/Handlers/Combat.h +++ b/sfall/Modules/Scripting/Handlers/Combat.h @@ -58,5 +58,7 @@ void mf_combat_data(OpcodeContext&); void mf_set_spray_settings(OpcodeContext&); +void mf_set_combat_free_move(OpcodeContext&); + } } diff --git a/sfall/Modules/Scripting/Handlers/Metarule.cpp b/sfall/Modules/Scripting/Handlers/Metarule.cpp index f76bf0ed..dda564f8 100644 --- a/sfall/Modules/Scripting/Handlers/Metarule.cpp +++ b/sfall/Modules/Scripting/Handlers/Metarule.cpp @@ -125,6 +125,7 @@ static const SfallMetarule metarules[] = { {"set_spray_settings", mf_set_spray_settings, 4, 4, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}}, {"set_can_rest_on_map", mf_set_rest_on_map, 3, 3, -1, {ARG_INT, ARG_INT, ARG_INT}}, {"set_car_intface_art", mf_set_car_intface_art, 1, 1, -1, {ARG_INT}}, + {"set_combat_free_move", mf_set_combat_free_move, 1, 1, -1, {ARG_INT}}, {"set_cursor_mode", mf_set_cursor_mode, 1, 1, -1, {ARG_INT}}, {"set_flags", mf_set_flags, 2, 2, -1, {ARG_OBJECT, ARG_INT}}, {"set_iface_tag_text", mf_set_iface_tag_text, 3, 3, -1, {ARG_INT, ARG_STRING, ARG_INT}},