mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added a fix for AI weapon validation before attack
* the check was always based on the primary weapon hit mode instead of the selected attack mode.
This commit is contained in:
@@ -99,6 +99,18 @@ enum AnimCommand : long
|
|||||||
RB_END_ANIM = 0x200
|
RB_END_ANIM = 0x200
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BodyParts : long {
|
||||||
|
Head = 0,
|
||||||
|
LeftArm = 1,
|
||||||
|
RightArm = 2,
|
||||||
|
Torso = 3,
|
||||||
|
RightLeg = 4,
|
||||||
|
LeftLeg = 5,
|
||||||
|
Eyes = 6,
|
||||||
|
Groin = 7,
|
||||||
|
Uncalled = 8
|
||||||
|
};
|
||||||
|
|
||||||
enum CritterFlags : long
|
enum CritterFlags : long
|
||||||
{
|
{
|
||||||
Sneak = 0x01, // Can sneak ?
|
Sneak = 0x01, // Can sneak ?
|
||||||
|
|||||||
@@ -448,6 +448,13 @@ friendly:
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void __declspec(naked) ai_try_attack_hack_check_safe_weapon() {
|
||||||
|
__asm {
|
||||||
|
mov ebx, [esp + 0x364 - 0x38 + 4]; // hit mode
|
||||||
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void __fastcall CombatAttackHook(fo::GameObject* source, fo::GameObject* target) {
|
static void __fastcall CombatAttackHook(fo::GameObject* source, fo::GameObject* target) {
|
||||||
sources[target] = source; // who attacked the 'target' from the last time
|
sources[target] = source; // who attacked the 'target' from the last time
|
||||||
targets[source] = target; // who was attacked by the 'source' from the last time
|
targets[source] = target; // who was attacked by the 'source' from the last time
|
||||||
@@ -545,6 +552,9 @@ void AI::init() {
|
|||||||
// also patch combat_safety_invalidate_weapon_func_ for returning out_range argument in a negative value
|
// also patch combat_safety_invalidate_weapon_func_ for returning out_range argument in a negative value
|
||||||
SafeWrite8(0x421628, 0xD0); // sub edx, eax > sub eax, edx
|
SafeWrite8(0x421628, 0xD0); // sub edx, eax > sub eax, edx
|
||||||
SafeWrite16(0x42162A, 0xFF40); // lea eax, [edx+1] > lea eax, [eax-1]
|
SafeWrite16(0x42162A, 0xFF40); // lea eax, [edx+1] > lea eax, [eax-1]
|
||||||
|
|
||||||
|
// Check the safety of weapons based on the selected attack mode instead of always the primary weapon hit mode
|
||||||
|
MakeCall(0x42A8D9, ai_try_attack_hack_check_safe_weapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
fo::GameObject* __stdcall AI::AIGetLastAttacker(fo::GameObject* target) {
|
fo::GameObject* __stdcall AI::AIGetLastAttacker(fo::GameObject* target) {
|
||||||
|
|||||||
@@ -524,7 +524,7 @@ void Combat::init() {
|
|||||||
SafeWrite8(0x423830, CodeType::JumpShort); // compute_attack_
|
SafeWrite8(0x423830, CodeType::JumpShort); // compute_attack_
|
||||||
BlockCall(0x42303F); // block Body_Torso check (combat_attack_)
|
BlockCall(0x42303F); // block Body_Torso check (combat_attack_)
|
||||||
SafeWrite8(0x42A713, 7); // Body_Uncalled > Body_Groin (ai_called_shot_)
|
SafeWrite8(0x42A713, 7); // Body_Uncalled > Body_Groin (ai_called_shot_)
|
||||||
SafeWriteBatch<BYTE>(8, bodypartAddr); // replace Body_Torso with Body_Uncalled
|
SafeWriteBatch<BYTE>(fo::BodyParts::Uncalled, bodypartAddr); // replace Body_Torso with Body_Uncalled
|
||||||
HookCalls(ai_pick_hit_mode_hook_bodypart, {0x429E8C, 0x429ECC, 0x429F09});
|
HookCalls(ai_pick_hit_mode_hook_bodypart, {0x429E8C, 0x429ECC, 0x429F09});
|
||||||
|
|
||||||
LoadGameHook::OnGameReset() += Combat_OnGameLoad;
|
LoadGameHook::OnGameReset() += Combat_OnGameLoad;
|
||||||
|
|||||||
Reference in New Issue
Block a user