mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Code changes to the previous commit
Changed HOOK_CANUSEWEAPON to run for both the player and NPCs. Updated gl_npcarmor script.
This commit is contained in:
Binary file not shown.
@@ -65,7 +65,7 @@ procedure check_weapon_change(variable critter, variable weapon, variable isWiel
|
||||
weaponAnimList := npc["WeaponAnims"];
|
||||
if (weaponAnimList != 0) then begin
|
||||
foreach (i in string_split(weaponAnimList, ",")) begin
|
||||
if (newWeaponAnim == atoi(i)) then return -1; // can use (engine default)
|
||||
if (newWeaponAnim == atoi(i) and not(weapon_is_unusable(weapon))) then return -1; // can use (engine default)
|
||||
end
|
||||
end
|
||||
return 0; // can't use
|
||||
@@ -226,10 +226,10 @@ end
|
||||
procedure canuseweapon_handler begin
|
||||
variable critter, canWield;
|
||||
critter := get_sfall_arg;
|
||||
//if (critter) then begin
|
||||
if (critter != dude_obj) then begin
|
||||
canWield := check_weapon_change(critter, get_sfall_arg, true);
|
||||
// override result
|
||||
set_sfall_arg(3, canWield);
|
||||
set_sfall_return(canWield);
|
||||
//end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -289,9 +289,11 @@
|
||||
// checks if the specified PID number exists in the list of registered protos
|
||||
#define check_pid(pid) (get_proto_data(pid, 0) != -1)
|
||||
|
||||
// sets the status of a broken weapon that cannot be used in combat (the hand slot will not be available for use)
|
||||
#define set_broken_weapon_state_on(item) set_object_data(item, OBJ_DATA_MISC_FLAGS, get_object_data(item, OBJ_DATA_MISC_FLAGS) bwor 0x00000010)
|
||||
#define set_broken_weapon_state_off(item) set_object_data(item, OBJ_DATA_MISC_FLAGS, get_object_data(item, OBJ_DATA_MISC_FLAGS) bwand 0xFFFFFFEF)
|
||||
// sets the status of an unusable weapon that cannot be used in combat
|
||||
// use the HOOK_CANUSEWEAPON hook with weapon_is_unusable macro to override the engine value
|
||||
#define set_weapon_unusable(item) set_object_data(item, OBJ_DATA_MISC_FLAGS, get_object_data(item, OBJ_DATA_MISC_FLAGS) bwor 0x00000010)
|
||||
#define set_weapon_usable(item) set_object_data(item, OBJ_DATA_MISC_FLAGS, get_object_data(item, OBJ_DATA_MISC_FLAGS) bwand 0xFFFFFFEF)
|
||||
#define weapon_is_unusable(item) (get_object_data(item, OBJ_DATA_MISC_FLAGS) bwand 0x00000010)
|
||||
|
||||
|
||||
/* SFALL_FUNCX MACROS */
|
||||
|
||||
@@ -897,13 +897,14 @@ 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.
|
||||
Run when the AI checks whether it can use a weapon, or when the game checks whether the player can use a weapon.
|
||||
For AI, this mostly happens when NPCs try to find weapons in their inventory or on the map.
|
||||
For the player, this happens when the game redraws the interface bar.
|
||||
|
||||
```
|
||||
Critter arg0 - the critter doing the check
|
||||
Item arg1 - the weapon being checked
|
||||
int arg2 - attack type (see ATKTYPE_* constants)
|
||||
Item arg1 - the item being checked
|
||||
int arg2 - attack type (see ATKTYPE_* constants), or -1 for dude_obj
|
||||
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
|
||||
|
||||
@@ -616,6 +616,7 @@ FUNC(calculateColor_, 0x4C72B4)
|
||||
FUNC(calloc_, 0x4EAFEC)
|
||||
FUNC(can_see_, 0x412BEC)
|
||||
FUNC(can_talk_to_, 0x413420)
|
||||
FUNC(can_use_weapon_, 0x477F3C)
|
||||
FUNC(cget_, 0x4F2250)
|
||||
FUNC(cget_string_, 0x4F0EA1)
|
||||
FUNC(cgetw_, 0x4F2E5B)
|
||||
|
||||
@@ -626,17 +626,17 @@ static bool __stdcall CanUseWeaponHook_Script(bool result, fo::GameObject* sourc
|
||||
args[0] = (DWORD)source;
|
||||
args[1] = (DWORD)weapon;
|
||||
args[2] = hitMode;
|
||||
args[3] = 0 | result;
|
||||
args[3] = result;
|
||||
|
||||
RunHookScript(HOOK_CANUSEWEAPON);
|
||||
|
||||
if (cRet > 0) result = rets[0] ? true : false;
|
||||
if (cRet > 0) result = (rets[0]) ? true : false;
|
||||
|
||||
EndHook();
|
||||
return result; // only 0 and 1
|
||||
}
|
||||
|
||||
static void __declspec(naked) CanUseWeaponHook() {
|
||||
static void __declspec(naked) AICanUseWeaponHook() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push ebx; // hitMode
|
||||
@@ -645,7 +645,25 @@ static void __declspec(naked) CanUseWeaponHook() {
|
||||
call fo::funcoffs::ai_can_use_weapon_;
|
||||
push eax; // result
|
||||
call CanUseWeaponHook_Script;
|
||||
and eax, 1;
|
||||
//and eax, 1;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) CanUseWeaponHook() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push -1; // hitMode (indefinite)
|
||||
push eax; // weapon
|
||||
push ds:[FO_VAR_obj_dude]; // source
|
||||
call fo::funcoffs::can_use_weapon_; // 1 - can't use
|
||||
xor al, 1;
|
||||
push eax; // result
|
||||
call CanUseWeaponHook_Script;
|
||||
xor al, 1; // invert
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -750,11 +768,12 @@ void Inject_BestWeaponHook() {
|
||||
}
|
||||
|
||||
void Inject_CanUseWeaponHook() {
|
||||
HookCalls(CanUseWeaponHook, {
|
||||
HookCalls(AICanUseWeaponHook, {
|
||||
0x429A1B, // ai_search_inven_weap_
|
||||
0x429CF2, // ai_search_environ_
|
||||
0x429E1C // ai_pick_hit_mode_
|
||||
});
|
||||
HookCalls(CanUseWeaponHook, { 0x45F05E, 0x45F1C1, 0x45F203, 0x45F36A }); // intface_update_items_
|
||||
}
|
||||
|
||||
void InitCombatHookScripts() {
|
||||
|
||||
@@ -595,25 +595,6 @@ static void __declspec(naked) do_move_timer_hack() {
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) can_use_weapon_hook() {
|
||||
static const DWORD can_use_weapon_Ret = 0x477F9F;
|
||||
using namespace fo;
|
||||
using namespace fo::Fields;
|
||||
__asm {
|
||||
call fo::funcoffs::item_get_type_;
|
||||
cmp eax, item_type_weapon;
|
||||
je checkFlag;
|
||||
retn; // eax - type
|
||||
checkFlag:
|
||||
test dword ptr [edx + miscFlags], CantUse;
|
||||
jnz cantUse;
|
||||
retn; // eax - type
|
||||
cantUse:
|
||||
add esp, 4;
|
||||
jmp can_use_weapon_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
static int invenApCost, invenApCostDef;
|
||||
static char invenApQPReduction;
|
||||
|
||||
@@ -758,11 +739,6 @@ void Inventory::init() {
|
||||
// Note: the flag is not checked for the metarule(METARULE_INVEN_UNWIELD_WHO, x) function
|
||||
HookCall(0x45B0CE, op_inven_unwield_hook); // with fix to update interface slot after unwielding
|
||||
HookCall(0x45693C, op_wield_obj_critter_hook);
|
||||
|
||||
// Add an additional "Can't Use" flag to the misc flags of item objects (offset 0x0038)
|
||||
// Misc Flags:
|
||||
// 0x00000010 - Can't Use (makes the weapon object unusable in combat)
|
||||
HookCall(0x477F4C, can_use_weapon_hook);
|
||||
}
|
||||
|
||||
void Inventory::InvokeAdjustFid(long fid) {
|
||||
|
||||
@@ -60,6 +60,57 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) ai_can_use_weapon_hack() {
|
||||
using namespace fo;
|
||||
using namespace Fields;
|
||||
__asm {
|
||||
test dword ptr [esi + miscFlags], CantUse;
|
||||
jnz cantUse;
|
||||
mov eax, [edi + damageFlags];
|
||||
retn;
|
||||
cantUse:
|
||||
mov al, 0xFF;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) can_use_weapon_hook() {
|
||||
static const DWORD cant_use_weapon_Ret = 0x477F9F;
|
||||
using namespace fo;
|
||||
using namespace Fields;
|
||||
__asm {
|
||||
call fo::funcoffs::item_get_type_;
|
||||
cmp eax, item_type_weapon;
|
||||
je checkFlag;
|
||||
retn; // eax - type
|
||||
checkFlag:
|
||||
test dword ptr [edx + miscFlags], CantUse;
|
||||
jnz cantUse;
|
||||
retn; // eax - type
|
||||
cantUse:
|
||||
add esp, 4;
|
||||
jmp cant_use_weapon_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: in ai_try_attack_, the attacker will not be able to change unusable weapon, as it happens with crippled arms
|
||||
static void __declspec(naked) combat_check_bad_shot_hack() {
|
||||
static const DWORD combat_check_bad_shot_Ret = 0x42673A;
|
||||
using namespace fo;
|
||||
using namespace Fields;
|
||||
__asm {
|
||||
test dword ptr [ecx + miscFlags], CantUse;
|
||||
jnz cantUse;
|
||||
mov eax, [esi + damageFlags];
|
||||
test al, DAM_CRIP_ARM_LEFT;
|
||||
retn;
|
||||
cantUse:
|
||||
mov eax, 4; // result same as TargetDead
|
||||
add esp, 4;
|
||||
jmp combat_check_bad_shot_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall CombatBlock::SetBlockCombat(long toggle) {
|
||||
combatDisabled = toggle != 0;
|
||||
}
|
||||
@@ -67,6 +118,13 @@ void __stdcall CombatBlock::SetBlockCombat(long toggle) {
|
||||
void CombatBlock::init() {
|
||||
HookCall(0x45F626, intface_use_item_hook); // jnz hook
|
||||
HookCall(0x4432A6, game_handle_input_hook);
|
||||
|
||||
// Add an additional "Can't Use" flag to the misc flags of item objects (offset 0x0038)
|
||||
// Misc Flags:
|
||||
// 0x00000010 - Can't Use (makes the weapon object unusable in combat)
|
||||
HookCall(0x477F4C, can_use_weapon_hook);
|
||||
MakeCall(0x4298F4, ai_can_use_weapon_hack);
|
||||
MakeCall(0x426669, combat_check_bad_shot_hack);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user