From 77b299aeba1045aadd591499191e4a0a68d116e5 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Wed, 22 Jul 2015 10:33:34 +0800 Subject: [PATCH] Added final version of 'NPC turns into a container' bug fix Also added related definitions in corresponding source files --- sfall/Bugs.cpp | 96 +++++++++++++++++++++++------------------ sfall/Define.h | 10 ++++- sfall/FalloutEngine.cpp | 3 ++ sfall/FalloutEngine.h | 3 ++ 4 files changed, 68 insertions(+), 44 deletions(-) diff --git a/sfall/Bugs.cpp b/sfall/Bugs.cpp index 75623c13..f4722ce6 100644 --- a/sfall/Bugs.cpp +++ b/sfall/Bugs.cpp @@ -597,62 +597,72 @@ end: static void __declspec(naked) set_new_results_hack() { __asm { - mov ecx, 0x424FC6 - test ah, 0x3 // DAM_KNOCKED_OUT or DAM_KNOCKED_DOWN - jz end // Conscious and standing - xor edx, edx - inc edx // type = knockout - test ah, 0x1 // DAM_KNOCKED_OUT - jnz knocked_out // Unconscious - mov eax, esi - call queue_find_ - test eax, eax // Has knockout in queue? - jnz end // Yes - mov ecx, 0x424FAD - xchg edx, eax - jmp ecx -knocked_out: + test ah, 0x1 // DAM_KNOCKED_OUT? + jz end // No mov dword ptr ds:[_critterClearObj], esi - mov eax, critterClearObjDrugs_ - xchg edx, eax - call queue_clear_type_ - mov ecx, 0x424F93 + mov edx, critterClearObjDrugs_ + xor eax, eax + inc eax // type = knockout + call queue_clear_type_ // Remove knockout from queue (if there is one) + retn end: - jmp ecx + pop eax // Destroying return address + mov eax, 0x424FC6 + jmp eax } } static void __declspec(naked) critter_wake_clear_hack() { __asm { - test dl, 0x80 // DAM_DEAD - jnz skip // This is a corpse - push eax - mov eax, esi - call isPartyMember_ - test eax, eax // This is a party member? - pop eax - jnz end // Yes + jne end // This is not a critter + mov dl, [esi+0x44] + test dl, 0x80 // DAM_DEAD? + jnz end // This is a corpse and dl, 0xFE // Unset DAM_KNOCKED_OUT or dl, 0x2 // Set DAM_KNOCKED_DOWN mov [esi+0x44], dl -skip: - pop eax // Destroying return address - mov eax, 1 +end: + xor eax, eax + inc eax pop esi pop ecx pop ebx -end: - retn + retn } } -static void __declspec(naked) critter_wake_clear_hack1() { +static void __declspec(naked) obj_load_func_hack() { __asm { - mov eax, 1 - pop esi - pop ecx - pop ebx - retn + mov edi, 0x488EF9 + test byte ptr [eax+0x25], 0x4 // Temp_ + jnz end + mov edi, [eax+0x64] + shr edi, 0x18 + cmp edi, ObjType_Critter + jne skip + test byte ptr [eax+0x44], 0x2 // DAM_KNOCKED_DOWN? + jz clear // No + pushad + xor ecx, ecx + inc ecx + xor ebx, ebx + xor edx, edx + xchg edx, eax + call queue_add_ + popad +clear: + and word ptr [eax+0x44], 0x7FFD // not (DAM_LOSE_TURN or DAM_KNOCKED_DOWN) +skip: + mov edi, 0x488F14 +end: + jmp edi + } +} + +static void __declspec(naked) partyMemberPrepLoadInstance_hack() { + __asm { + and word ptr [eax+0x44], 0x7FFD // not (DAM_LOSE_TURN or DAM_KNOCKED_DOWN) + jmp dude_stand_ } } @@ -796,10 +806,10 @@ void BugsInit() // Corrects "NPC turns into a container" if (GetPrivateProfileIntA("Misc", "NPCTurnsIntoContainerFix", 1, ini)) { dlog("Applying Fix for NPC turns into a container.", DL_INIT); - MakeCall(0x424F8E, &set_new_results_hack, true); - SafeWrite16(0x42E44F, 0x03EB); // jmps 0x42E454 - MakeCall(0x42E476, &critter_wake_clear_hack, false); - MakeCall(0x42E4BA, &critter_wake_clear_hack1, true); + MakeCall(0x424F8E, &set_new_results_hack, false); + MakeCall(0x42E46E, &critter_wake_clear_hack, true); + MakeCall(0x488EF3, &obj_load_func_hack, true); + HookCall(0x4949B2, &partyMemberPrepLoadInstance_hack); dlogr(" Done", DL_INIT); } } diff --git a/sfall/Define.h b/sfall/Define.h index 06e16ce7..e3fd00e2 100644 --- a/sfall/Define.h +++ b/sfall/Define.h @@ -256,6 +256,14 @@ #define item_type_misc_item (5) #define item_type_key_item (6) +#define ObjType_Item (0) +#define ObjType_Critter (1) +#define ObjType_Scenery (2) +#define ObjType_Wall (3) +#define ObjType_Tile (4) +#define ObjType_Misc (5) +#define ObjType_Intrface (6) + #define OBJFLAG_CAN_WEAR_ITEMS (0xf000000) #define OBJFLAG_HELD_IN_RIGHT (0x10000) @@ -273,4 +281,4 @@ #define ROLL_CRITICAL_FAILURE (0) #define ROLL_FAILURE (1) #define ROLL_SUCCESS (2) -#define ROLL_CRITICAL_SUCCESS (3) \ No newline at end of file +#define ROLL_CRITICAL_SUCCESS (3) diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index bbd115c3..97ca9b17 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -124,6 +124,7 @@ const DWORD DOSCmdLineDestroy_ = 0x4E3D3C; const DWORD DrawCard_ = 0x43AAEC; const DWORD DrawFolder_ = 0x43410C; const DWORD DrawInfoWin_ = 0x4365AC; +const DWORD dude_stand_ = 0x418378; const DWORD editor_design_ = 0x431DF8; const DWORD elapsed_time_ = 0x4C93E0; const DWORD elevator_end_ = 0x43F6D0; @@ -298,7 +299,9 @@ const DWORD proto_dude_update_gender_ = 0x49F984; const DWORD proto_ptr_ = 0x4A2108; // eax - PID, edx - int** - pointer to a pointer to a proto struct const DWORD pushLongStack_ = 0x46736C; const DWORD qsort_ = 0x4F05B6; +const DWORD queue_add_ = 0x4A258C; const DWORD queue_clear_type_ = 0x4A2790; +const DWORD queue_find_ = 0x4A26A8; const DWORD queue_find_first_ = 0x4A295C; const DWORD queue_find_next_ = 0x4A2994; const DWORD queue_remove_this_ = 0x4A264C; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 89f5ecef..4fe79a74 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -258,6 +258,7 @@ extern const DWORD DOSCmdLineDestroy_; extern const DWORD DrawCard_; extern const DWORD DrawFolder_; extern const DWORD DrawInfoWin_; +extern const DWORD dude_stand_; extern const DWORD editor_design_; extern const DWORD elapsed_time_; extern const DWORD elevator_end_; @@ -435,7 +436,9 @@ extern const DWORD proto_dude_update_gender_; extern const DWORD proto_ptr_; extern const DWORD pushLongStack_; extern const DWORD qsort_; +extern const DWORD queue_add_; extern const DWORD queue_clear_type_; +extern const DWORD queue_find_; extern const DWORD queue_find_first_; extern const DWORD queue_find_next_; extern const DWORD queue_remove_this_;