mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added a new hook: HOOK_CANUSEWEAPON
Updated NPC armor appearance mod script.
This commit is contained in:
Binary file not shown.
@@ -9,7 +9,7 @@
|
|||||||
NOTE: this script requires compiler from sfall modderspack with -s option
|
NOTE: this script requires compiler from sfall modderspack with -s option
|
||||||
(short circuit evaluation)
|
(short circuit evaluation)
|
||||||
|
|
||||||
version 1.1
|
version 1.2
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#define FID_OBJ_CRITTER (0x01000000)
|
#define FID_OBJ_CRITTER (0x01000000)
|
||||||
|
|
||||||
procedure update_armor_apperance;
|
procedure update_armor_apperance;
|
||||||
|
procedure canuseweapon_handler;
|
||||||
|
|
||||||
variable
|
variable
|
||||||
modIni := "npcarmor.ini",
|
modIni := "npcarmor.ini",
|
||||||
@@ -203,6 +204,7 @@ procedure start begin
|
|||||||
register_hook_proc(HOOK_INVENWIELD, invenwield_handler);
|
register_hook_proc(HOOK_INVENWIELD, invenwield_handler);
|
||||||
register_hook_proc(HOOK_ADJUSTFID, adjustfid_handler);
|
register_hook_proc(HOOK_ADJUSTFID, adjustfid_handler);
|
||||||
register_hook_proc(HOOK_INVENTORYMOVE, inventorymove_handler);
|
register_hook_proc(HOOK_INVENTORYMOVE, inventorymove_handler);
|
||||||
|
register_hook_proc_spec(HOOK_CANUSEWEAPON, canuseweapon_handler);
|
||||||
|
|
||||||
debug_msg("NPC armor appearance mod: Done.");
|
debug_msg("NPC armor appearance mod: Done.");
|
||||||
end
|
end
|
||||||
@@ -220,3 +222,14 @@ procedure update_armor_apperance begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
procedure canuseweapon_handler begin
|
||||||
|
variable critter, canWield;
|
||||||
|
critter := get_sfall_arg;
|
||||||
|
if (critter) then begin
|
||||||
|
canWield := check_weapon_change(critter, get_sfall_arg, true);
|
||||||
|
//if (canWield != 0) then canWield := 1;
|
||||||
|
set_sfall_arg(3, canWield); // override result
|
||||||
|
set_sfall_return(canWield);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -73,6 +73,7 @@
|
|||||||
#define HOOK_ADJUSTRADS (45)
|
#define HOOK_ADJUSTRADS (45)
|
||||||
#define HOOK_ROLLCHECK (46)
|
#define HOOK_ROLLCHECK (46)
|
||||||
#define HOOK_BESTWEAPON (47)
|
#define HOOK_BESTWEAPON (47)
|
||||||
|
#define HOOK_CANUSEWEAPON (48)
|
||||||
|
|
||||||
//Valid arguments to list_begin
|
//Valid arguments to list_begin
|
||||||
#define LIST_CRITTERS (0)
|
#define LIST_CRITTERS (0)
|
||||||
|
|||||||
@@ -888,3 +888,19 @@ Critter arg4 - the target of the critter (can be 0)
|
|||||||
|
|
||||||
Item ret0 - overrides the chosen best weapon
|
Item ret0 - overrides the chosen best weapon
|
||||||
```
|
```
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
#### `HOOK_CANUSEWEAPON (hs_canuseweapon.int)`
|
||||||
|
|
||||||
|
Run when the AI checks whether it can use a weapon.
|
||||||
|
This mostly happens when NPCs try to find weapons in their inventory or on the map.
|
||||||
|
|
||||||
|
```
|
||||||
|
Critter arg0 - the critter doing the check
|
||||||
|
Item arg1 - the weapon being checked
|
||||||
|
int arg2 - attack type (see ATKTYPE_* constants)
|
||||||
|
int arg3 - original result of engine function: 1 - can use, 0 - can't use
|
||||||
|
|
||||||
|
int ret0 - overrides the result of engine function. Any non-zero value allows using the weapon
|
||||||
|
```
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
because the compiler builds the better/optimized code when calling the engine functions
|
because the compiler builds the better/optimized code when calling the engine functions
|
||||||
*/
|
*/
|
||||||
WRAP_WATCOM_FFUNC4(long, _word_wrap, const char*, text, int, maxWidth, DWORD*, buf, BYTE*, count)
|
WRAP_WATCOM_FFUNC4(long, _word_wrap, const char*, text, int, maxWidth, DWORD*, buf, BYTE*, count)
|
||||||
|
WRAP_WATCOM_FFUNC4(fo::GameObject*, ai_best_weapon, fo::GameObject*, source, fo::GameObject*, prevItem, fo::GameObject*, checkItem, fo::GameObject*, target)
|
||||||
|
WRAP_WATCOM_FFUNC3(bool, ai_can_use_weapon, fo::GameObject*, critter, fo::GameObject*, item, DWORD, hitMode)
|
||||||
WRAP_WATCOM_FFUNC3(long, ai_have_ammo, fo::GameObject*, critter, fo::GameObject*, item, fo::GameObject**, outAmmo)
|
WRAP_WATCOM_FFUNC3(long, ai_have_ammo, fo::GameObject*, critter, fo::GameObject*, item, fo::GameObject**, outAmmo)
|
||||||
WRAP_WATCOM_FFUNC3(long, ai_pick_hit_mode, fo::GameObject*, source, fo::GameObject*, item, fo::GameObject*, target)
|
WRAP_WATCOM_FFUNC3(long, ai_pick_hit_mode, fo::GameObject*, source, fo::GameObject*, item, fo::GameObject*, target)
|
||||||
WRAP_WATCOM_FFUNC3(fo::GameObject*, ai_search_inven_weap, fo::GameObject*, source, long, apCheck, fo::GameObject*, target)
|
WRAP_WATCOM_FFUNC3(fo::GameObject*, ai_search_inven_weap, fo::GameObject*, source, long, apCheck, fo::GameObject*, target)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* sfall
|
||||||
|
* Copyright (C) 2008-2021 The sfall team
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#include "..\main.h"
|
||||||
|
#include "..\FalloutEngine\Fallout2.h"
|
||||||
|
|
||||||
|
#include "..\Modules\HookScripts\CombatHs.h"
|
||||||
|
|
||||||
|
#include "combatAI.h"
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace sf = sfall;
|
||||||
|
|
||||||
|
// Implementation of ai_can_use_weapon_ engine function with the HOOK_CANUSEWEAPON hook
|
||||||
|
long CombatAI::ai_can_use_weapon(fo::GameObject* source, fo::GameObject* weapon, long hitMode) {
|
||||||
|
long result = fo::func::ai_can_use_weapon(source, weapon, hitMode);
|
||||||
|
return sf::CanUseWeaponHook_Invoke(result, source, weapon, hitMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CombatAI::init() { // TODO: add to main.cpp
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* sfall
|
||||||
|
* Copyright (C) 2008-2021 The sfall team
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
|
||||||
|
class CombatAI {
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
|
||||||
|
static long ai_can_use_weapon(fo::GameObject* source, fo::GameObject* weapon, long hitMode);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -109,6 +109,7 @@ static HooksInjectInfo injectHooks[] = {
|
|||||||
{HOOK_ADJUSTRADS, Inject_AdjustRadsHook, 1}, // always embedded for party control fix
|
{HOOK_ADJUSTRADS, Inject_AdjustRadsHook, 1}, // always embedded for party control fix
|
||||||
{HOOK_ROLLCHECK, Inject_RollCheckHook, 0},
|
{HOOK_ROLLCHECK, Inject_RollCheckHook, 0},
|
||||||
{HOOK_BESTWEAPON, Inject_BestWeaponHook, 0},
|
{HOOK_BESTWEAPON, Inject_BestWeaponHook, 0},
|
||||||
|
{HOOK_CANUSEWEAPON, Inject_CanUseWeaponHook, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
void HookScripts::InjectingHook(int hookId) {
|
void HookScripts::InjectingHook(int hookId) {
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ enum HookType
|
|||||||
HOOK_ADJUSTRADS = 45,
|
HOOK_ADJUSTRADS = 45,
|
||||||
HOOK_ROLLCHECK = 46,
|
HOOK_ROLLCHECK = 46,
|
||||||
HOOK_BESTWEAPON = 47,
|
HOOK_BESTWEAPON = 47,
|
||||||
|
HOOK_CANUSEWEAPON = 48,
|
||||||
HOOK_COUNT
|
HOOK_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -600,12 +600,12 @@ static fo::GameObject* __stdcall BestWeaponHook_Script(fo::GameObject* bestWeapo
|
|||||||
|
|
||||||
static void __declspec(naked) ai_search_inven_weap_hook() {
|
static void __declspec(naked) ai_search_inven_weap_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
push ecx;
|
push ecx; // target
|
||||||
push ebx;
|
push ebx; // weapon2 (secondary)
|
||||||
push edx;
|
push edx; // weapon1 (primary)
|
||||||
push eax;
|
push eax; // source
|
||||||
call fo::funcoffs::ai_best_weapon_;
|
call fo::funcoffs::ai_best_weapon_;
|
||||||
push eax;
|
push eax; // bestWeapon
|
||||||
call BestWeaponHook_Script;
|
call BestWeaponHook_Script;
|
||||||
retn;
|
retn;
|
||||||
}
|
}
|
||||||
@@ -619,6 +619,48 @@ fo::GameObject* BestWeaponHook_Invoke(fo::GameObject* bestWeapon, fo::GameObject
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static long __stdcall CanUseWeaponHook_Script(long result, fo::GameObject* source, fo::GameObject* weapon, long hitMode) {
|
||||||
|
BeginHook();
|
||||||
|
argCount = 4;
|
||||||
|
|
||||||
|
args[0] = (DWORD)source;
|
||||||
|
args[1] = (DWORD)weapon;
|
||||||
|
args[2] = hitMode;
|
||||||
|
args[3] = result;
|
||||||
|
|
||||||
|
RunHookScript(HOOK_CANUSEWEAPON);
|
||||||
|
|
||||||
|
if (cRet > 0) {
|
||||||
|
result = rets[0];
|
||||||
|
if (result != 0) result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndHook();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) CanUseWeaponHook() {
|
||||||
|
__asm {
|
||||||
|
push ecx;
|
||||||
|
push ebx; // hitMode
|
||||||
|
push edx; // weapon
|
||||||
|
push eax; // source
|
||||||
|
call fo::funcoffs::ai_can_use_weapon_;
|
||||||
|
push eax; // result
|
||||||
|
call CanUseWeaponHook_Script;
|
||||||
|
pop ecx;
|
||||||
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long CanUseWeaponHook_Invoke(long result, fo::GameObject* source, fo::GameObject* weapon, long hitMode) {
|
||||||
|
return (HookScripts::HookHasScript(HOOK_CANUSEWEAPON))
|
||||||
|
? CanUseWeaponHook_Script(result, source, weapon, hitMode)
|
||||||
|
: result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Inject_ToHitHook() {
|
void Inject_ToHitHook() {
|
||||||
HookCalls(ToHitHook, {
|
HookCalls(ToHitHook, {
|
||||||
0x421686, // combat_safety_invalidate_weapon_func_
|
0x421686, // combat_safety_invalidate_weapon_func_
|
||||||
@@ -709,6 +751,14 @@ void Inject_BestWeaponHook() {
|
|||||||
HookCall(0x429A59, ai_search_inven_weap_hook);
|
HookCall(0x429A59, ai_search_inven_weap_hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Inject_CanUseWeaponHook() {
|
||||||
|
HookCalls(CanUseWeaponHook, {
|
||||||
|
0x429A1B, // ai_search_inven_weap_
|
||||||
|
0x429CF2, // ai_search_environ_
|
||||||
|
0x429E1C // ai_pick_hit_mode_
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void InitCombatHookScripts() {
|
void InitCombatHookScripts() {
|
||||||
HookScripts::LoadHookScript("hs_tohit", HOOK_TOHIT);
|
HookScripts::LoadHookScript("hs_tohit", HOOK_TOHIT);
|
||||||
HookScripts::LoadHookScript("hs_afterhitroll", HOOK_AFTERHITROLL);
|
HookScripts::LoadHookScript("hs_afterhitroll", HOOK_AFTERHITROLL);
|
||||||
@@ -722,6 +772,7 @@ void InitCombatHookScripts() {
|
|||||||
HookScripts::LoadHookScript("hs_subcombatdmg", HOOK_SUBCOMBATDAMAGE);
|
HookScripts::LoadHookScript("hs_subcombatdmg", HOOK_SUBCOMBATDAMAGE);
|
||||||
HookScripts::LoadHookScript("hs_targetobject", HOOK_TARGETOBJECT);
|
HookScripts::LoadHookScript("hs_targetobject", HOOK_TARGETOBJECT);
|
||||||
HookScripts::LoadHookScript("hs_bestweapon", HOOK_BESTWEAPON);
|
HookScripts::LoadHookScript("hs_bestweapon", HOOK_BESTWEAPON);
|
||||||
|
HookScripts::LoadHookScript("hs_canuseweapon", HOOK_CANUSEWEAPON);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ void Inject_OnExplosionHook();
|
|||||||
void Inject_SubCombatDamageHook();
|
void Inject_SubCombatDamageHook();
|
||||||
void Inject_TargetObjectHook();
|
void Inject_TargetObjectHook();
|
||||||
void Inject_BestWeaponHook();
|
void Inject_BestWeaponHook();
|
||||||
|
void Inject_CanUseWeaponHook();
|
||||||
|
|
||||||
int __fastcall AmmoCostHook_Script(DWORD hookType, fo::GameObject* weapon, DWORD &rounds);
|
int __fastcall AmmoCostHook_Script(DWORD hookType, fo::GameObject* weapon, DWORD &rounds);
|
||||||
|
|
||||||
long CalcApCostHook_Invoke(fo::GameObject* source, long hitMode, long isCalled, long cost, fo::GameObject* weapon);
|
long CalcApCostHook_Invoke(fo::GameObject* source, long hitMode, long isCalled, long cost, fo::GameObject* weapon);
|
||||||
//void FindTargetHook_Invoke(fo::GameObject* targets[], fo::GameObject* attacker);
|
//void FindTargetHook_Invoke(fo::GameObject* targets[], fo::GameObject* attacker);
|
||||||
//fo::GameObject* BestWeaponHook_Invoke(fo::GameObject* bestWeapon, fo::GameObject* source, fo::GameObject* weapon1, fo::GameObject* weapon2, fo::GameObject* target);
|
//fo::GameObject* BestWeaponHook_Invoke(fo::GameObject* bestWeapon, fo::GameObject* source, fo::GameObject* weapon1, fo::GameObject* weapon2, fo::GameObject* target);
|
||||||
|
long CanUseWeaponHook_Invoke(long result, fo::GameObject* source, fo::GameObject* weapon, long hitMode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,6 +291,7 @@
|
|||||||
<ClInclude Include="FalloutEngine\Variables.h" />
|
<ClInclude Include="FalloutEngine\Variables.h" />
|
||||||
<ClInclude Include="FalloutEngine\Functions.h" />
|
<ClInclude Include="FalloutEngine\Functions.h" />
|
||||||
<ClInclude Include="FalloutEngine\Functions_def.h" />
|
<ClInclude Include="FalloutEngine\Functions_def.h" />
|
||||||
|
<ClInclude Include="Game\combatAI.h" />
|
||||||
<ClInclude Include="Game\inventory.h" />
|
<ClInclude Include="Game\inventory.h" />
|
||||||
<ClInclude Include="Game\items.h" />
|
<ClInclude Include="Game\items.h" />
|
||||||
<ClInclude Include="Game\objects.h" />
|
<ClInclude Include="Game\objects.h" />
|
||||||
@@ -402,6 +403,7 @@
|
|||||||
<ClCompile Include="FalloutEngine\FunctionOffsets.cpp" />
|
<ClCompile Include="FalloutEngine\FunctionOffsets.cpp" />
|
||||||
<ClCompile Include="FalloutEngine\Variables.cpp" />
|
<ClCompile Include="FalloutEngine\Variables.cpp" />
|
||||||
<ClCompile Include="FalloutEngine\Functions.cpp" />
|
<ClCompile Include="FalloutEngine\Functions.cpp" />
|
||||||
|
<ClCompile Include="Game\combatAI.cpp" />
|
||||||
<ClCompile Include="Game\inventory.cpp" />
|
<ClCompile Include="Game\inventory.cpp" />
|
||||||
<ClCompile Include="Game\items.cpp" />
|
<ClCompile Include="Game\items.cpp" />
|
||||||
<ClCompile Include="Game\objects.cpp" />
|
<ClCompile Include="Game\objects.cpp" />
|
||||||
|
|||||||
@@ -343,6 +343,9 @@
|
|||||||
<Filter>Game</Filter>
|
<Filter>Game</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Translate.h" />
|
<ClInclude Include="Translate.h" />
|
||||||
|
<ClInclude Include="Game\combatAI.h">
|
||||||
|
<Filter>Game</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
@@ -636,6 +639,9 @@
|
|||||||
<Filter>Game</Filter>
|
<Filter>Game</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Translate.cpp" />
|
<ClCompile Include="Translate.cpp" />
|
||||||
|
<ClCompile Include="Game\combatAI.cpp">
|
||||||
|
<Filter>Game</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="version.rc" />
|
<ResourceCompile Include="version.rc" />
|
||||||
|
|||||||
Reference in New Issue
Block a user