From 155c14f4e717f670f9f808ed534091797eb3b1e0 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 25 Aug 2019 10:25:30 +0800 Subject: [PATCH] Fixed player stuck at "climbing" frame after ladder climbing animation Removed the previous fix about player's direction. Minor code refactoring in AnimationsAtOnceLimit.cpp (from 4.x) --- sfall/AnimationsAtOnceLimit.cpp | 57 +++++++++++++++++++++++---------- sfall/DamageMod.cpp | 2 +- sfall/HookScripts.cpp | 2 +- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/sfall/AnimationsAtOnceLimit.cpp b/sfall/AnimationsAtOnceLimit.cpp index a4ae786b..3496e0f2 100644 --- a/sfall/AnimationsAtOnceLimit.cpp +++ b/sfall/AnimationsAtOnceLimit.cpp @@ -23,6 +23,7 @@ #include "LoadGameHook.h" static const int animRecordSize = 2656; +static const int sadSize = 3240; static int animationLimit = 32; @@ -149,19 +150,23 @@ static const DWORD sad_28[] = { 0x4173CE, 0x4174C1, 0x4175F1, 0x417730, }; +static DWORD __fastcall AnimCombatFix(DWORD* src, BYTE combatFlag) { + DWORD animAddr = animSetAddr; + + if (animationLimit > 32) { + animAddr += animRecordSize; // include a dummy + } + + if (combatFlag & 2) { // combat flag is set + __asm call combat_anim_finished_; + } + return animAddr; +} + static void __declspec(naked) anim_set_end_hack() { __asm { - mov edi, _anim_set; - cmp dword ptr animationLimit, 32; - jle skip; - mov edi, animSetAddr; - add edi, animRecordSize; // Include a dummy -skip: - test dl, 0x2; // Is the combat flag set? - jz end; // No - call combat_anim_finished_; -end: - mov [edi][esi], ebx; + call AnimCombatFix; + mov [eax][esi], ebx; xor dl, dl; // goto 0x415DF2; retn; } @@ -169,7 +174,7 @@ end: static DWORD __fastcall CheckSetSad(BYTE openFlag, DWORD valueMul) { bool result = false; - int offset = (3240 * valueMul) + 32; + int offset = (sadSize * valueMul) + 32; if (*(DWORD*)(sadAddr + offset) == -1000) { result = true; @@ -196,6 +201,24 @@ end: } } +static void __declspec(naked) action_climb_ladder_hook() { + __asm { + cmp word ptr [edi + 0x40], 0xFFFF; // DestTile + je skip; + cmp dword ptr [edi + 0x3C], 0; // DestMap + je reset; + push edx; + mov edx, ds:[_map_number]; + cmp dword ptr [edi + 0x3C], edx; + pop edx; + jne skip; +reset: + and al, ~0x4; // reset RB_DONTSTAND flag +skip: + jmp register_begin_; + } +} + void ApplyAnimationsAtOncePatches(signed char aniMax) { if (aniMax <= 32) return; @@ -203,10 +226,10 @@ void ApplyAnimationsAtOncePatches(signed char aniMax) { //allocate memory to store larger animation struct arrays anim_set = new BYTE[animRecordSize * (aniMax + 1)]; - sad = new BYTE[3240 * (aniMax + 1)]; + sad = new BYTE[sadSize * (aniMax + 1)]; - animSetAddr = (DWORD)anim_set; - sadAddr = (DWORD)sad; + animSetAddr = reinterpret_cast(anim_set); + sadAddr = reinterpret_cast(sad); //set general animation limit check (old 20) aniMax-12 -- +12 reserved for PC movement(4) + other critical animations(8)? SafeWrite8(0x413C07, aniMax - 12); @@ -361,8 +384,8 @@ void AnimationsAtOnceInit() { // Fix crash when the critter goes through a door with animation trigger MakeJump(0x41755E, object_move_hack); - // Fix player's direction after ladder climbing animation - SafeWrite16(0x49CA14, 0xB190); // mov cl, 26 (skip setting the direction) + // Fix for the player stuck at "climbing" frame after ladder climbing animation + HookCall(0x411E1F, action_climb_ladder_hook); } void AnimationsAtOnceExit() { diff --git a/sfall/DamageMod.cpp b/sfall/DamageMod.cpp index 244457db..77b701b1 100644 --- a/sfall/DamageMod.cpp +++ b/sfall/DamageMod.cpp @@ -423,7 +423,7 @@ static void __declspec(naked) DisplayBonusHtHDmg2_hack() { shl eax, 1; add eax, 1; push eax; // min dmg + bonus - mov ecx, dword ptr[esp + 0x98 + 0x4]; + mov ecx, dword ptr [esp + 0x98 + 0x4]; push ecx; // message push 0x509EDC; // '%s %d-%d' lea eax, [esp + 0x0C + 0x4]; diff --git a/sfall/HookScripts.cpp b/sfall/HookScripts.cpp index 805a2021..0e0ac65b 100644 --- a/sfall/HookScripts.cpp +++ b/sfall/HookScripts.cpp @@ -959,7 +959,7 @@ static void __declspec(naked) PerceptionRangeSeeHook() { cmp eax, 2; jne nevermind; // normal return dec eax; - mov dword ptr[esp + 0x2C - 0x1C + 4], eax; // set 1, skip blocking check + mov dword ptr [esp + 0x2C - 0x1C + 4], eax; // set 1, skip blocking check dec eax; nevermind: retn;