From 1f1d6eb6f08343e7510e89dae83050ec98fddd0a Mon Sep 17 00:00:00 2001 From: NovaRain Date: Fri, 3 Apr 2020 12:20:27 +0800 Subject: [PATCH] Some code correction in BugFixes Minor edits to documents. --- artifacts/ddraw.ini | 2 +- artifacts/scripting/arrays.txt | 2 +- sfall/BugFixes.cpp | 46 ++++++++++++++++++---------------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index be460d5e..58480c31 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -655,7 +655,7 @@ DontTurnOffSneakIfYouRun=0 UseWalkDistance=3 ;Changes the displayed message when you recover from the negative effects of radiation exposure -;The value is the message number in misc.msg (Default is 3003, the 'You feel better' line) +;The value is the message number in misc.msg (Default is 3003: 'You feel better') RadEffectsRemovalMsg=3003 ;Set to 1 to display messages about radiation for the active geiger counter diff --git a/artifacts/scripting/arrays.txt b/artifacts/scripting/arrays.txt index faa896f9..44f2b7a3 100644 --- a/artifacts/scripting/arrays.txt +++ b/artifacts/scripting/arrays.txt @@ -155,7 +155,7 @@ Example: - creates permanent array (but not "saved") - if size is >= 0, creates list with given size - if size == -1, creates map (associative array) -- if size == -1 and flags == 2, creates a "lookup" map in which the values of existing keys are read-only and can't be updated. +- if size == -1 and flags == 2, creates a "lookup" map (associative array) in which the values of existing keys are read-only and can't be updated. This type of array allows you to store a zero (0) key value - NOTE: in earlier versions (up to 4.1.3/3.8.13) the second argument is not used, just use 0 - returns arrayID (valid until array is deleted) diff --git a/sfall/BugFixes.cpp b/sfall/BugFixes.cpp index 71b6335a..89a199a1 100644 --- a/sfall/BugFixes.cpp +++ b/sfall/BugFixes.cpp @@ -185,24 +185,23 @@ static void __declspec(naked) PipStatus_hook() { // corrects saving script blocks (to *.sav file) by properly accounting for actual number of scripts to be saved static void __declspec(naked) scr_write_ScriptNode_hook() { __asm { - mov ecx, 16 - cmp dword ptr [esp+0xEC+4], ecx // number_of_scripts - jg skip - mov ecx, dword ptr [esp+0xEC+4] - cmp ecx, 0 - jg skip - xor eax, eax - retn -skip: - sub dword ptr [esp+0xEC+4], ecx // number_of_scripts - push dword ptr [ebp+0xE00] // num - mov dword ptr [ebp+0xE00], ecx // num - xor ecx, ecx - xchg dword ptr [ebp+0xE04], ecx // NextBlock - call scr_write_ScriptNode_ - xchg dword ptr [ebp+0xE04], ecx // NextBlock - pop dword ptr [ebp+0xE00] // num - retn + mov ecx, 16; // maximum number of scripts in block + cmp dword ptr [esp + 0xEC + 4], ecx; // number_of_scripts (total scripts) + jg writeBlock; + mov ecx, dword ptr [esp + 0xEC + 4]; + test ecx, ecx; + jg writeBlock; // > 0 + xor eax, eax; + retn; // don't save the current ScriptBlock +writeBlock: + sub dword ptr [esp + 0xEC + 4], ecx; // number_of_scripts (reduce number [e.g. 24-16=8] or set it to 0) + xchg dword ptr [ebp + 0xE00], ecx; // ScriptBlocks.num (keep and set correct value: 16 or previous value of number_of_scripts) + xor esi, esi; + xchg dword ptr [ebp + 0xE04], esi; // ScriptBlocks.NextBlock (keep pointer and set it to 0) + call scr_write_ScriptNode_; + mov dword ptr [ebp + 0xE04], esi; // restore ScriptBlocks.NextBlock + mov dword ptr [ebp + 0xE00], ecx; // restore ScriptBlocks.num + retn; } } @@ -1024,7 +1023,7 @@ end: static const DWORD obj_load_func_Ret = 0x488F14; static void __declspec(naked) obj_load_func_hack() { __asm { - test byte ptr [eax + 0x25], 0x4; // Temp_ + test word ptr [eax + 0x24], 0x400; // ObjectFlag Temp (engine code) jz fix; retn; fix: @@ -1032,6 +1031,8 @@ fix: and edi, 0x0F000000; cmp edi, OBJ_TYPE_CRITTER << 24; jne skip; + test byte ptr [eax + 0x44], DAM_DEAD; + jnz skip; // is dead test byte ptr [eax + 0x44], DAM_KNOCKED_OUT; jnz clear; // Yes test byte ptr [eax + 0x44], DAM_KNOCKED_DOWN; @@ -1494,9 +1495,9 @@ static void __declspec(naked) ResetPlayer_hook() { static void __declspec(naked) obj_move_to_tile_hack() { static const DWORD obj_move_to_tile_Ret = 0x48A74E; __asm { - cmp ds:[_loadingGame], 0; + cmp ds:[_loadingGame], 0; // prevents leaving the map right after loading a saved game if last time the player died on another map jnz skip; - cmp dword ptr ds:[_map_state], 0; // map number, -1 exit to worldmap (probably redundant) + cmp dword ptr ds:[_map_state], 0; // map number, -1 exit to worldmap jz mapLeave; skip: add esp, 4; @@ -2691,6 +2692,7 @@ void BugFixesInit() dlogr(" Done", DL_INIT); // Fix for "Too Many Items" bug + // http://fforum.kochegarov.com/index.php?showtopic=29288&view=findpost&p=332242 //if (GetConfigInt("Misc", "TooManyItemsBugFix", 1)) { dlog("Applying preventive patch for \"Too Many Items\" bug.", DL_INIT); HookCall(0x4A596A, scr_write_ScriptNode_hook); @@ -3013,7 +3015,7 @@ void BugFixesInit() // Fix for critters killed in combat by scripting still being able to move in their combat turn if the distance parameter // in their AI packages is set to stay_close/charge, or NPCsTryToSpendExtraAP is enabled - HookCall(0x42A1A8, ai_move_steps_closer_hook); // 0x42B24D + HookCall(0x42A1A8, ai_move_steps_closer_hook); // old 0x42B24D // Fix instant death critical dlog("Applying instant death fix.", DL_INIT);