Added combat rating check to "Snipe" distance preference fix

This commit is contained in:
NovaRain
2020-05-01 08:00:49 +08:00
parent 42347ac062
commit 3d2d1cdf2a
3 changed files with 21 additions and 12 deletions
+1 -1
View File
@@ -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]
+18 -9
View File
@@ -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 {
+1 -1
View File
@@ -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();