Fixed ai_retrieve_object_ engine function not returning the requested object when there are different objects with the same ID (from Mr.Stalin)

Added info about map_*_p_proc procedures to the global script section in notes.txt (#197)
This commit is contained in:
NovaRain
2018-09-23 08:13:35 +08:00
parent bbe789d013
commit 27f2d57ebd
2 changed files with 39 additions and 2 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
---------- GLOBAL SCRIPTS -----------
-------------------------------------
As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object. (i.e. using self_obj without using set_self first will crash the script.) To use a global script, the script must have a name which begins with 'gl' and contains a procedure called 'start'. This procedure will be executed once when the player loads a saved game or starts a new game. If you wish the script to be executed repeatedly, call set_global_script_repeat on this first run using the number of frames between each run as the argument. (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.)
As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object. (i.e. using self_obj without using set_self first will crash the script.) To use a global script, the script must have a name which begins with 'gl' and contains a procedure called 'start', 'map_enter_p_proc', 'map_exit_p_proc', or 'map_update_p_proc'. The start procedure will be executed once when the player loads a saved game or starts a new game. The map_*_p_proc procedures will be executed once when the player enters/leaves a map via exit grids or the world map, or rests/waits on a map. If you wish the script to be executed repeatedly, call set_global_script_repeat on this first run using the number of frames between each run as the argument. (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.)
Global scripts have multiple modes, which can be set using the set_global_script_type function. In the default mode (i.e. mode 0) their execution is linked to the local map game loop, so the script will not run in dialogs or on the world map. In mode 1 their execution is linked to the player input, and so they will run whenever the mouse cursor is visible on screen, including the world map, character dialogs etc. In mode 2, execution is linked to the world map loop, so the script will only be executed on the world map and not on the local map or in any dialog windows. Mode 3 is a combination of modes 0 and 2, so scripts will be executed on both local maps and the world map, but not in dialog windows. Using mode 1 requires the input wrapper to be enabled. Use available_global_script_types to check what is available.
+38 -1
View File
@@ -1434,6 +1434,36 @@ fix:
}
}
static BYTE retrievePtr = 0;
static void __declspec(naked) ai_retrieve_object_hook() {
__asm {
mov retrievePtr, 1;
mov edx, ebx; // object ptr
call fo::funcoffs::inven_find_id_; // check prt (fix behavior)
mov retrievePtr, 0;
test eax, eax;
jz tryFindId;
retn;
tryFindId:
mov eax, ecx; // source
mov edx, [ebx]; // obj.id
jmp fo::funcoffs::inven_find_id_; // vanilla behavior
}
}
static void __declspec(naked) inven_find_id_hack() {
__asm {
mov ebx, [edi + ebx]; // inv.item
test retrievePtr, 0xFF;
jnz fix;
cmp ecx, [ebx]; // obj.id == obj.id
retn;
fix:
cmp ecx, ebx; // object ptr == object ptr
retn;
}
}
void BugFixes::init()
{
@@ -1812,7 +1842,7 @@ void BugFixes::init()
dlogr(" Done", DL_INIT);
}
// Fix for critters not checking weapon perks properly when searching for the best weapon
// Fix for AI not checking weapon perks properly when searching for the best weapon
if (GetConfigInt("Misc", "AIBestWeaponFix", 0)) {
dlog("Applying AI best weapon choice fix.", DL_INIT);
HookCall(0x42954B, ai_best_weapon_hook);
@@ -1827,6 +1857,13 @@ void BugFixes::init()
// Fix for the underline position in the inventory display window when the item name is longer than one line
MakeCall(0x472F5F, inven_obj_examine_func_hack);
SafeWrite8(0x472F64, 0x90);
// Fix for ai_retrieve_object_ engine function not returning the requested object when there are different objects
// with the same ID
dlog("Applying ai_retrieve_object engine function fix.", DL_INIT);
HookCall(0x429D7B, ai_retrieve_object_hook);
MakeCall(0x472708, inven_find_id_hack);
dlogr(" Done", DL_INIT);
}
}