From 80afdae7ba2cdc34582bd2506d460057a8981e87 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Thu, 24 Jan 2019 23:47:27 +0800 Subject: [PATCH] Fixed pickup_obj/drop_obj/use_obj script functions (from Mr.Stalin) Fixed a crash when calling use_obj/use_obj_on_obj functions without using set_self in global scripts. --- artifacts/scripting/sfall function notes.txt | 2 +- sfall/Modules/BugFixes.cpp | 47 ++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 3d987ed8..857ba60d 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -165,7 +165,7 @@ array - array ID to be used with array-related functions (actually an integer) - self_obj will revert back to its original value after the next function call. - calling self_obj(0) will also revert self_obj to original value. It is recommended to call this after each use of set_self in normal scripts in order to avoid unforeseen side effects. - source_obj, target_obj, and similar functions will not work if preceded by "set_self" -- NOTE: for use_obj_on_obj vanilla function to work correctly, it is required to call set_self twice. +- NOTE: for use_obj/use_obj_on_obj vanilla functions to work correctly, it is required to call set_self twice. > void mod_skill_points_per_level(int x) - accepts a value of between -100 and 100, and modifies the number of skill points the player receives when they level up. diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index 3757af13..a2fc0b73 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -17,9 +17,9 @@ static DWORD weightOnBody = 0; static char textBuf[355]; void ResetBodyState() { - _asm mov critterBody, 0; - _asm mov sizeOnBody, 0; - _asm mov weightOnBody, 0; + __asm mov critterBody, 0; + __asm mov sizeOnBody, 0; + __asm mov weightOnBody, 0; } void GameInitialization() { @@ -1762,6 +1762,34 @@ static void __declspec(naked) op_attack_hook() { } } +static void __declspec(naked) op_use_obj_on_obj_hack() { + __asm { + test eax, eax; + jz fail; + mov edx, [eax + protoId]; // source + shr edx, 24; + retn; +fail: + add esp, 4; + mov edx, 0x45C3A3; // exit func + jmp edx; + } +} + +static void __declspec(naked) op_use_obj_hack() { + __asm { + test eax, eax; + jz fail; + mov edx, [eax + protoId]; // source + shr edx, 24; + retn; +fail: + add esp, 4; + mov edx, 0x456ABA; // exit func + jmp edx; + } +} + void BugFixes::init() { @@ -2243,6 +2271,19 @@ void BugFixes::init() SafeWrite8(0x456D98, 0x94); // setnz > setz (fix setting result flags) dlogr(" Done", DL_INIT); } + + // Fix crash when calling use_obj/use_obj_on_obj without using set_self in global scripts + MakeCall(0x45C376, op_use_obj_on_obj_hack, 1); + MakeCall(0x456A92, op_use_obj_hack, 1); + + // Fix pickup_obj/drop_obj/use_obj functions, change them to get pointer from script.self instead of script.target + // script.target contains an incorrect pointer, which may vary depending on the situations in the game + SafeWriteBatch(0x34, { // script.target > script.self + 0x456554, // op_pickup_obj_ + 0x456600, // op_drop_obj_ + 0x456A6D, // op_use_obj_ + 0x456AA4 // op_use_obj_ + }); } }