From 3d2d1cdf2a89c507d923ab6aa139d5fc02160271 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Fri, 1 May 2020 07:38:35 +0800 Subject: [PATCH] Added combat rating check to "Snipe" distance preference fix --- artifacts/ddraw.ini | 2 +- sfall/Modules/AI.cpp | 29 +++++++++++++++++++---------- sfall/Modules/AI.h | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index eb03833b..5f68b62b 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -134,7 +134,7 @@ AllowDShowSound=0 ;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg ;Set to 2 to overwrite all occurances of the music path -OverrideMusicDir=2 +OverrideMusicDir=1 ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX [Input] diff --git a/sfall/Modules/AI.cpp b/sfall/Modules/AI.cpp index d3d5bee4..9389fb2d 100644 --- a/sfall/Modules/AI.cpp +++ b/sfall/Modules/AI.cpp @@ -42,20 +42,13 @@ fo::GameObject* AI::sf_check_critters_in_lof(fo::GameObject* object, DWORD check return object; } -fo::GameObject* __fastcall AI::CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) { +// Returns the friendly critter that is in the line of fire +fo::GameObject* AI::CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) { fo::GameObject* object = nullptr; fo::func::make_straight_path_func(attacker, attacker->tile, target->tile, 0, (DWORD*)&object, 32, (void*)fo::funcoffs::obj_shoot_blocking_at_); return sf_check_critters_in_lof(object, target->tile, attacker->critter.teamNum); // 0 if there are no friendly critters } -static long __fastcall RollFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) { - if (AI::CheckFriendlyFire(target, attacker)) { - long dice = fo::func::roll_random(1, 10); - return (fo::func::stat_level(attacker, fo::STAT_iq) >= dice); // 1 - is friendly - } - return 0; -} - static void __declspec(naked) ai_try_attack_hook_FleeFix() { __asm { or byte ptr [esi + combatState], 8; // set new 'ReTarget' flag @@ -300,6 +293,14 @@ static void __declspec(naked) cai_perform_distance_prefs_hack() { lea edx, [edx + ecx - 1]; cmp edx, 5; // minimum threshold distance jge skipMove; // distance >= 5? + // check combat rating + mov eax, esi; + call fo::funcoffs::combatai_rating_; + mov edx, eax; // source rating + mov eax, edi; + call fo::funcoffs::combatai_rating_; + cmp eax, edx; // target vs source rating + jl skipMove; // target rating is low moveAway: mov ebx, 10; // move away max distance retn; @@ -311,6 +312,14 @@ skipMove: //////////////////////////////////////////////////////////////////////////////// +static long __fastcall RollFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) { + if (AI::CheckFriendlyFire(target, attacker)) { + long dice = fo::func::roll_random(1, 10); + return (fo::func::stat_level(attacker, fo::STAT_iq) >= dice); // 1 - is friendly + } + return 0; +} + static void __declspec(naked) combat_safety_invalidate_weapon_func_hook_check() { static const DWORD safety_invalidate_weapon_burst_friendly = 0x4216C9; __asm { @@ -322,7 +331,7 @@ static void __declspec(naked) combat_safety_invalidate_weapon_func_hook_check() popadc; jmp fo::funcoffs::combat_ctd_init_; friendly: - lea esp, [esp + 8 + 3*4]; + lea esp, [esp + 8 + 3 * 4]; jmp safety_invalidate_weapon_burst_friendly; // "Friendly was in the way!" } } diff --git a/sfall/Modules/AI.h b/sfall/Modules/AI.h index 5b1aac93..330be1aa 100644 --- a/sfall/Modules/AI.h +++ b/sfall/Modules/AI.h @@ -31,7 +31,7 @@ public: void init(); static fo::GameObject* sf_check_critters_in_lof(fo::GameObject* object, DWORD checkTile, DWORD team); - static fo::GameObject* __fastcall CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker); + static fo::GameObject* CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker); // TODO: use subscription instead static void __stdcall AICombatStart();