diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 1255afa1..64c9eab0 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/Bugs.cpp b/sfall/Bugs.cpp index 75c5ff07..9f16923c 100644 --- a/sfall/Bugs.cpp +++ b/sfall/Bugs.cpp @@ -12,10 +12,17 @@ static DWORD weightOnBody = 0; static char textBuf[355]; +static const DWORD ScriptTargetAddr[] = { + 0x456554, // op_pickup_obj_ + 0x456600, // op_drop_obj_ + 0x456A6D, // op_use_obj_ + 0x456AA4, // op_use_obj_ +}; + 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() { @@ -1737,6 +1744,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 + 0x64]; // 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 + 0x64]; // source + shr edx, 24; + retn; +fail: + add esp, 4; + mov edx, 0x456ABA; // exit func + jmp edx; + } +} + void BugsInit() { @@ -2207,4 +2242,14 @@ void BugsInit() 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 + for (int i = 0; i < sizeof(ScriptTargetAddr) / 4; i++) { + SafeWrite8(ScriptTargetAddr[i], 0x34); // script.target > script.self + } }