diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 4ca2e8fd..331109a1 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -121,7 +121,7 @@ WorldMapTerrainInfo=0 ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX [Sound] ;Sets the number of allowed simultaneous sound effects -;Set to 0 to leave the default unchanged (i.e. 4) +;Set to 0 to leave the default unchanged (i.e. 4). The maximum is 32 NumSoundBuffers=0 ;Set to 1 to allow attaching sound files to combat float messages diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index 88578d2d..b26f3e9d 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -1456,15 +1456,16 @@ end: static void __declspec(naked) combat_display_hack() { __asm { test [esi + flags], Flat; // ctd.mainTarget - jnz flatTarget; // Flat flag is set - mov ebx, 0x42536B; - je end; // This is a critter + jnz end; // Main target is flat (engine jump) + cmp eax, OBJ_TYPE_CRITTER << 24; // Is this a critter? + je end; // Yes (engine no jump) cmp dword ptr [ecx + scriptId], -1; // Does the target have a script? - jne end; // Yes -flatTarget: - mov ebx, 0x425413; +// jne hasScript; // Yes (engine no jump) + lahf; + xor ah, 0x40; // invert ZF (01000000b) + sahf; // if there is a script, do not jump (ZF is set) end: - jmp ebx; + retn; } } @@ -3009,7 +3010,7 @@ void BugFixes::init() // Fix for the displayed message when the attack randomly hits a target that is not a critter and has a script attached // Tweak: if the main target has Flat flag set, display the "You missed" message instead of the message of hitting another object - MakeJump(0x425365, combat_display_hack, 1); + MakeCall(0x42535F, combat_display_hack, 1); // Fix for damage_p_proc being called for misses if the target is not a critter MakeCall(0x424CD2, apply_damage_hack); diff --git a/sfall/Modules/Combat.cpp b/sfall/Modules/Combat.cpp index 93ea14f1..105490fc 100644 --- a/sfall/Modules/Combat.cpp +++ b/sfall/Modules/Combat.cpp @@ -35,7 +35,7 @@ namespace sfall static const DWORD bodypartAddr[] = { 0x425562, // combat_display_ 0x42A68F, 0x42A739, // ai_called_shot_ - 0x429E82, 0x429EC2, 0x429EFF, // ai_pick_hit_mode_ +// 0x429E82, 0x429EC2, 0x429EFF, // ai_pick_hit_mode_ 0x423231, 0x423268, // check_ranged_miss_ 0x4242D4, // attack_crit_failure_ // for combat_ctd_init_ func @@ -265,7 +265,7 @@ static long __fastcall CheckDisableBurst(fo::GameObject* critter) { return 0; } -static void __declspec(naked) ai_pick_hit_mode_hack() { +static void __declspec(naked) ai_pick_hit_mode_hack_noSecondary() { __asm { mov ebx, [eax + 0x94]; // cap->area_attack_mode push eax; @@ -450,6 +450,13 @@ static void BodypartHitReadConfig() { bodypartHit.Uncalled = static_cast(GetConfigInt("Misc", "BodyHit_Torso_Uncalled", 0)); } +static void __declspec(naked) ai_pick_hit_mode_hook_bodypart() { + __asm { + mov ebx, 8; // replace Body_Torso with Body_Uncalled + jmp fo::funcoffs::determine_to_hit_; + } +} + static void __declspec(naked) apply_damage_hack() { __asm { xor edx, edx; @@ -492,7 +499,7 @@ void Combat::init() { BlockCall(0x424796); // Actually disables all secondary attacks for the critter, regardless of whether the weapon has a burst attack - MakeCall(0x429E44, ai_pick_hit_mode_hack, 1); // NoBurst + MakeCall(0x429E44, ai_pick_hit_mode_hack_noSecondary, 1); // NoBurst if (GetConfigInt("Misc", "CheckWeaponAmmoCost", 0)) { MakeCall(0x4234B3, compute_spray_hack, 1); @@ -511,6 +518,7 @@ void Combat::init() { 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 + HookCalls(ai_pick_hit_mode_hook_bodypart, {0x429E8C, 0x429ECC, 0x429F09}); LoadGameHook::OnGameReset() += Combat_OnGameLoad; } diff --git a/sfall/Modules/Sound.cpp b/sfall/Modules/Sound.cpp index 6ba4b85e..903603ab 100644 --- a/sfall/Modules/Sound.cpp +++ b/sfall/Modules/Sound.cpp @@ -565,7 +565,8 @@ void Sound::init() { // Pause and resume sound playback when the game loses focus fo::func::set_focus_func(SoundLostFocus); - if (int allowDShowSound = GetConfigInt("Sound", "AllowDShowSound", 0) > 0) { + int allowDShowSound = GetConfigInt("Sound", "AllowDShowSound", 0); + if (allowDShowSound > 0) { MakeJump(0x4AD499, soundLoad_hack); HookCalls(gmovie_play_hook_stop, {0x44E80A, 0x445280}); // only play looping music if (allowDShowSound > 1) { @@ -574,7 +575,8 @@ void Sound::init() { CreateSndWnd(); } - if (int sBuff = GetConfigInt("Sound", "NumSoundBuffers", 0)) { + int sBuff = GetConfigInt("Sound", "NumSoundBuffers", 0); + if (sBuff > 0 && sBuff <= 32) { SafeWrite8(0x451129, (BYTE)sBuff); }