diff --git a/sfall/FalloutEngine/Enums.h b/sfall/FalloutEngine/Enums.h index 4c6f3da1..a3883410 100644 --- a/sfall/FalloutEngine/Enums.h +++ b/sfall/FalloutEngine/Enums.h @@ -99,6 +99,18 @@ enum AnimCommand : long 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 { Sneak = 0x01, // Can sneak ? diff --git a/sfall/Modules/AI.cpp b/sfall/Modules/AI.cpp index a91be457..caa65626 100644 --- a/sfall/Modules/AI.cpp +++ b/sfall/Modules/AI.cpp @@ -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) { sources[target] = source; // who attacked the 'target' 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 SafeWrite8(0x421628, 0xD0); // sub edx, eax > sub eax, edx 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) { diff --git a/sfall/Modules/Combat.cpp b/sfall/Modules/Combat.cpp index ecc87847..667f717b 100644 --- a/sfall/Modules/Combat.cpp +++ b/sfall/Modules/Combat.cpp @@ -524,7 +524,7 @@ void Combat::init() { SafeWrite8(0x423830, CodeType::JumpShort); // compute_attack_ BlockCall(0x42303F); // block Body_Torso check (combat_attack_) SafeWrite8(0x42A713, 7); // Body_Uncalled > Body_Groin (ai_called_shot_) - SafeWriteBatch(8, bodypartAddr); // replace Body_Torso with Body_Uncalled + SafeWriteBatch(fo::BodyParts::Uncalled, bodypartAddr); // replace Body_Torso with Body_Uncalled HookCalls(ai_pick_hit_mode_hook_bodypart, {0x429E8C, 0x429ECC, 0x429F09}); LoadGameHook::OnGameReset() += Combat_OnGameLoad;