Added a tweak to replace death anims on critters with "_sf" variants on map load

(also fix critters stuck in the middle of death anims after returning
to the map, #584)
This commit is contained in:
NovaRain
2025-03-10 10:02:18 +08:00
parent 3a29db5f90
commit 3fde11c7d9
2 changed files with 38 additions and 3 deletions
+35
View File
@@ -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() {
+3 -3
View File
@@ -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