From 0e0ca799f1252be13c10b8f8af68aa7554a15a54 Mon Sep 17 00:00:00 2001 From: phobos2077 Date: Sun, 25 Oct 2015 21:40:03 +0700 Subject: [PATCH] Added HOOK_INVENWIELD hook, called when NPC's wielding or unwielding weapons or armor. --- sfall/FalloutEngine.cpp | 3 ++ sfall/FalloutEngine.h | 3 ++ sfall/HookScripts.cpp | 105 +++++++++++++++++++++++++++++++++++++++- sfall/HookScripts.h | 55 +++++++++++---------- 4 files changed, 140 insertions(+), 26 deletions(-) diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 97ca9b17..e0a463e6 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -82,6 +82,7 @@ const DWORD combat_input_ = 0x4227F4; const DWORD combat_should_end_ = 0x422C60; const DWORD combat_turn_ = 0x42299C; const DWORD compute_damage_ = 0x4247B8; +const DWORD correctFidForRemovedItem_ = 0x45409C; const DWORD credits_ = 0x42C860; const DWORD credits_get_next_line_ = 0x42CE6C; const DWORD critter_body_type_ = 0x42DDC4; @@ -171,6 +172,8 @@ const DWORD intface_update_hit_points_ = 0x45EBD8; const DWORD intface_update_items_ = 0x45EFEC; const DWORD intface_update_move_points_ = 0x45EE0C; const DWORD intface_use_item_ = 0x45F5EC; +const DWORD invenUnwieldFunc_ = 0x472A64; +const DWORD invenWieldFunc_ = 0x472768; const DWORD inven_display_msg_ = 0x472D24; const DWORD inven_left_hand_ = 0x471BBC; const DWORD inven_pid_is_carried_ptr_ = 0x471CA0; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 4fe79a74..9c83f5a9 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -216,6 +216,7 @@ extern const DWORD combat_input_; extern const DWORD combat_should_end_; extern const DWORD combat_turn_; extern const DWORD compute_damage_; +extern const DWORD correctFidForRemovedItem_; // (int critter@, int oldArmor@, int removeSlotsFlags@) extern const DWORD credits_; extern const DWORD credits_get_next_line_; extern const DWORD critter_body_type_; @@ -305,6 +306,8 @@ extern const DWORD intface_update_hit_points_; extern const DWORD intface_update_items_; extern const DWORD intface_update_move_points_; extern const DWORD intface_use_item_; +extern const DWORD invenUnwieldFunc_; // (int critter@, int slot@, int a3@) - int result (-1 on error, 0 on success) +extern const DWORD invenWieldFunc_; // (int who@, int item@, int a3@, int slot@) - int result (-1 on error, 0 on success) extern const DWORD inven_display_msg_; extern const DWORD inven_left_hand_; extern const DWORD inven_pid_is_carried_ptr_; diff --git a/sfall/HookScripts.cpp b/sfall/HookScripts.cpp index 03f72a2e..02945a9e 100644 --- a/sfall/HookScripts.cpp +++ b/sfall/HookScripts.cpp @@ -21,6 +21,7 @@ #include #include +#include "Define.h" #include "FalloutEngine.h" #include "HookScripts.h" #include "Inventory.h" @@ -30,7 +31,7 @@ #define MAXDEPTH (8) -static const int numHooks = 25; +static const int numHooks = HOOK_COUNT; struct sHookScript { sScriptProgram prog; @@ -937,6 +938,99 @@ skipcall: } } +static void _declspec(naked) invenWieldFunc_Hook() { + __asm { + hookbegin(4); + mov args[0], eax; // critter + mov args[4], edx; // item + mov args[8], ebx; // slot + mov args[12], 1; // wield flag + pushad; + cmp ebx, 1; // right hand slot? + je skip; + mov eax, edx; + call item_get_type_; + cmp eax, item_type_armor; + jz skip; + mov args[8], 2; // INVEN_TYPE_LEFT_HAND +skip: + push HOOK_INVENWIELD; + call RunHookScript; + popad; + cmp cRet, 1; + jl defaulthandler; + cmp rets[0], -1; + je defaulthandler; + jmp end +defaulthandler: + call invenWieldFunc_ +end: + hookend; + retn; + } +} + +// called when unwielding weapons +static void _declspec(naked) invenUnwieldFunc_Hook() { + __asm { + hookbegin(4); + mov args[0], eax; // critter + mov args[4], 0; // item + mov args[8], edx; // slot + mov args[12], 0; // wield flag + cmp edx, 0; // left hand slot? + jne notlefthand; + mov args[8], 2; // left hand +notlefthand: + pushad; + push HOOK_INVENWIELD; + call RunHookScript; + popad; + cmp cRet, 1; + jl defaulthandler; + cmp rets[0], -1; + je defaulthandler; + jmp end +defaulthandler: + call invenUnwieldFunc_; +end: + hookend; + retn; + } +} + +static void _declspec(naked) correctFidForRemovedItem_Hook() { + __asm { + hookbegin(4); + mov args[0], eax; // critter + mov args[4], edx; // item + mov args[8], 0; // slot + mov args[12], 0 // wield flag (armor by default) + test ebx, 0x02000000; // right hand slot? + jz notrighthand; + mov args[8], 1; // right hand +notrighthand: + test ebx, 0x01000000; // left hand slot? + jz notlefthand; + mov args[8], 2; // left hand +notlefthand: + pushad; + push HOOK_INVENWIELD; + call RunHookScript; + popad; + cmp cRet, 1; + jl defaulthandler; + cmp rets[0], -1; + je defaulthandler; + jmp end +defaulthandler: + call correctFidForRemovedItem_; +end: + hookend; + retn; + } +} + static const DWORD DropAmmoIntoWeaponHack_back = 0x47658D; // proceed with reloading static const DWORD DropAmmoIntoWeaponHack_return = 0x476643; static void _declspec(naked) DropAmmoIntoWeaponHack() { @@ -1166,6 +1260,15 @@ static void HookScriptInit2() { //HookCall(0x471351, &DropAmmoIntoWeaponHook); MakeCall(0x476588, &DropAmmoIntoWeaponHack, true); + LoadHookScript("invenwield", HOOK_INVENWIELD); + HookCall(0x47275E, &invenWieldFunc_Hook); + HookCall(0x495FDF, &invenWieldFunc_Hook); + HookCall(0x45967D, &invenUnwieldFunc_Hook); + HookCall(0x472A5A, &invenUnwieldFunc_Hook); + HookCall(0x495F0B, &invenUnwieldFunc_Hook); + HookCall(0x45680C, &correctFidForRemovedItem_Hook); + HookCall(0x45C4EA, &correctFidForRemovedItem_Hook); + dlogr("Completed hook script init", DL_HOOK|DL_INIT); } diff --git a/sfall/HookScripts.h b/sfall/HookScripts.h index 7006c0ba..f8efd255 100644 --- a/sfall/HookScripts.h +++ b/sfall/HookScripts.h @@ -18,31 +18,36 @@ #pragma once -#define HOOK_TOHIT (0) -#define HOOK_AFTERHITROLL (1) -#define HOOK_CALCAPCOST (2) -#define HOOK_DEATHANIM1 (3) -#define HOOK_DEATHANIM2 (4) -#define HOOK_COMBATDAMAGE (5) -#define HOOK_ONDEATH (6) -#define HOOK_FINDTARGET (7) -#define HOOK_USEOBJON (8) -#define HOOK_REMOVEINVENOBJ (9) -#define HOOK_BARTERPRICE (10) -#define HOOK_MOVECOST (11) -#define HOOK_HEXMOVEBLOCKING (12) -#define HOOK_HEXAIBLOCKING (13) -#define HOOK_HEXSHOOTBLOCKING (14) -#define HOOK_HEXSIGHTBLOCKING (15) -#define HOOK_ITEMDAMAGE (16) -#define HOOK_AMMOCOST (17) -#define HOOK_USEOBJ (18) -#define HOOK_KEYPRESS (19) -#define HOOK_MOUSECLICK (20) -#define HOOK_USESKILL (21) -#define HOOK_STEAL (22) -#define HOOK_WITHINPERCEPTION (23) -#define HOOK_INVENTORYMOVE (24) +enum HookType +{ + HOOK_TOHIT = 0, + HOOK_AFTERHITROLL = 1, + HOOK_CALCAPCOST = 2, + HOOK_DEATHANIM1 = 3, + HOOK_DEATHANIM2 = 4, + HOOK_COMBATDAMAGE = 5, + HOOK_ONDEATH = 6, + HOOK_FINDTARGET = 7, + HOOK_USEOBJON = 8, + HOOK_REMOVEINVENOBJ = 9, + HOOK_BARTERPRICE = 10, + HOOK_MOVECOST = 11, + HOOK_HEXMOVEBLOCKING = 12, + HOOK_HEXAIBLOCKING = 13, + HOOK_HEXSHOOTBLOCKING = 14, + HOOK_HEXSIGHTBLOCKING = 15, + HOOK_ITEMDAMAGE = 16, + HOOK_AMMOCOST = 17, + HOOK_USEOBJ = 18, + HOOK_KEYPRESS = 19, + HOOK_MOUSECLICK = 20, + HOOK_USESKILL = 21, + HOOK_STEAL = 22, + HOOK_WITHINPERCEPTION = 23, + HOOK_INVENTORYMOVE = 24, + HOOK_INVENWIELD = 25, + HOOK_COUNT +}; DWORD _stdcall GetHSArgCount(); DWORD _stdcall GetHSArg();