diff --git a/sfall/Modules/Animations.cpp b/sfall/Modules/Animations.cpp index 978c897a..4c6fed5d 100644 --- a/sfall/Modules/Animations.cpp +++ b/sfall/Modules/Animations.cpp @@ -532,6 +532,37 @@ static void __stdcall combat_begin_anim_stop_hook() { fo::func::object_anim_compact(); } +static __declspec(naked) void obj_read_obj_hack() { + using namespace fo; + using namespace Fields; + __asm { + shr eax, 24; + test eax, eax; // OBJ_TYPE_ITEM + jz skip; + cmp eax, OBJ_TYPE_CRITTER; + jne skip; + mov edx, [esi + artFid]; + mov ebx, edx; + and ebx, 0xFF0000; + shr ebx, 16; + cmp ebx, ANIM_fall_back; + jl skip; + cmp ebx, ANIM_fall_front_blood; + jg skip; + mov ecx, ANIM_burned_to_nothing; + cmp ebx, ANIM_fire_dance; + cmove ebx, ecx; + add ebx, 28; // single-frame death animations + shl ebx, 16; + and edx, 0x0F00FFFF; // clear rotaion and anim code + or edx, ebx; // set new anim code (also unset ZF) + mov [esi + artFid], edx; + mov dword ptr [esi + currFrame], 0; // for single frame +skip: + retn; + } +} + static void ApplyAnimationsAtOncePatches(signed char aniMax) { //allocate memory to store larger animation struct arrays sf_anim_set.resize(aniMax + 1); // include a dummy @@ -645,6 +676,10 @@ void Animations::init() { // Prevent the "forever" type of animation on objects from stopping when entering combat // also allow death animations to finish HookCall(0x421A48, combat_begin_anim_stop_hook); + + // Replace death animations on critters with single-frame variants on map load + // also fix critters stuck in the middle of death animations after returning to the map + MakeCall(0x488CBA, obj_read_obj_hack); } //void Animations::exit() { diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index e3734a41..19a695f1 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -2402,7 +2402,7 @@ static __declspec(naked) void partyFixMultipleMembers_hack() { sar eax, 24; cmp eax, OBJ_TYPE_CRITTER; jne skip; - test [esi + damageFlags], DAM_DEAD; + test byte ptr [esi + damageFlags], DAM_DEAD; cmovnz edx, esi; skip: retn; @@ -4104,9 +4104,9 @@ void BugFixes::init() { HookCall(0x429A2B, ai_search_inven_weap_hook0); // for melee/unarmed weapons HookCall(0x4299EC, ai_search_inven_weap_hook1); // for the solar scorcher - // Fix for critters not being healed over time when entering the map if 'dead_bodies_age=No' is set in maps.txt + // Fix for critters not being healed over time when entering a map with 'dead_bodies_age=No' set in maps.txt // also fix the zero initialization of a local variable to correct time for removing corpses and blood - dlogr("Applying fix for the self-healing of critters when entering the map.", DL_FIX); + dlogr("Applying fix for the self-healing of critters when entering a map.", DL_FIX); MakeCall(0x483356, map_age_dead_critters_hack); SafeWrite32(0x4832A0, 0x9090C189); // mov ecx, eax (keep dead_bodies_age flag) SafeWrite32(0x4832A4, 0x0C245489); // mov [esp + var_30], edx