diff --git a/sfall/CheckAddress.cpp b/sfall/CheckAddress.cpp index 62e6a16f..278194bb 100644 --- a/sfall/CheckAddress.cpp +++ b/sfall/CheckAddress.cpp @@ -9,10 +9,14 @@ namespace sfall std::multimap writeAddress; -static std::vector excludeAddr = { +static std::vector excludeWarning = { 0x44E949, 0x44E94A, 0x44E937, 0x4F5F40, 0x4CB850, // from movies.cpp }; +static std::vector excludeConflict = { + 0x42A0F8, // bugfixes.cpp +}; + struct HackPair { long addr; long len; @@ -135,8 +139,10 @@ void PrintAddrList() { if (diff == 0) { dlog_f("0x%x L:%d [Overwriting]\n", DL_MAIN, el.addr, el.len); } else if (diff < pl) { - dlog_f("0x%x L:%d [Conflict] with 0x%x L:%d\n", DL_MAIN, el.addr, el.len, pa, pl); - MessageBoxA(0, "Conflict detected!", "", MB_TASKMODAL); + if (std::find(excludeConflict.cbegin(), excludeConflict.cend(), el.addr) == excludeConflict.cend()) { + dlog_f("0x%x L:%d [Conflict] with 0x%x L:%d\n", DL_MAIN, el.addr, el.len, pa, pl); + MessageBoxA(0, "Conflict detected!", "", MB_TASKMODAL); + } } else if (level >= 11 && diff == pl) { dlog_f("0x%x L:%d [Warning] Hacking near:0x%x\n", DL_MAIN, el.addr, el.len, pa); } else if (level >= 12) { @@ -149,7 +155,7 @@ void PrintAddrList() { void CheckConflict(DWORD addr, long len) { if (writeAddress.find(addr) != writeAddress.cend()) { - if (std::find(excludeAddr.cbegin(), excludeAddr.cend(), addr) != excludeAddr.cend()) return; + if (std::find(excludeWarning.cbegin(), excludeWarning.cend(), addr) != excludeWarning.cend()) return; char buf[64]; sprintf_s(buf, "Memory overwriting at address 0x%x", addr); MessageBoxA(0, buf, "", MB_TASKMODAL); diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index 28ecb0bc..48e59f70 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -1237,42 +1237,6 @@ end: } } -static void __declspec(naked) wmTeleportToArea_hack() { - static const DWORD wmTeleportToArea_Ret = 0x4C5A77; - __asm { - xor ecx, ecx; - cmp ebx, ds:[FO_VAR_WorldMapCurrArea]; - je end; - mov ds:[FO_VAR_WorldMapCurrArea], ebx; - sub eax, edx; - add eax, ds:[FO_VAR_wmAreaInfoList]; - cmp dword ptr [eax + 0x34], 1; // wmAreaInfoList.size - mov edx, [eax + 0x30]; // wmAreaInfoList.world_posy - mov eax, [eax + 0x2C]; // wmAreaInfoList.world_posx - jg largeLoc; - je mediumLoc; -//smallLoc: - sub eax, 5; - lea edx, [edx - 5]; -mediumLoc: - sub eax, 10 - lea edx, [edx - 10]; - // check negative values - test eax, eax; - cmovl eax, ecx; - test edx, edx; - cmovl edx, ecx; -largeLoc: - mov ds:[FO_VAR_world_ypos], edx; - mov ds:[FO_VAR_world_xpos], eax; -end: - mov ds:[FO_VAR_target_xpos], ecx; - mov ds:[FO_VAR_target_ypos], ecx; - mov ds:[FO_VAR_In_WorldMap], ecx; - jmp wmTeleportToArea_Ret; - } -} - static void __declspec(naked) db_get_file_list_hack() { __asm { push edi @@ -2337,6 +2301,42 @@ static void __declspec(naked) action_climb_ladder_hack() { } } +static void __declspec(naked) wmTeleportToArea_hack() { + static const DWORD wmTeleportToArea_Ret = 0x4C5A77; + __asm { + xor ecx, ecx; + cmp ebx, ds:[FO_VAR_WorldMapCurrArea]; + je end; + mov ds:[FO_VAR_WorldMapCurrArea], ebx; + sub eax, edx; + add eax, ds:[FO_VAR_wmAreaInfoList]; + cmp dword ptr [eax + 0x34], 1; // wmAreaInfoList.size + mov edx, [eax + 0x30]; // wmAreaInfoList.world_posy + mov eax, [eax + 0x2C]; // wmAreaInfoList.world_posx + jg largeLoc; + je mediumLoc; +//smallLoc: + sub eax, 5; + lea edx, [edx - 5]; +mediumLoc: + sub eax, 10 + lea edx, [edx - 10]; + // check negative values + test eax, eax; + cmovl eax, ecx; + test edx, edx; + cmovl edx, ecx; +largeLoc: + mov ds:[FO_VAR_world_ypos], edx; + mov ds:[FO_VAR_world_xpos], eax; +end: + mov ds:[FO_VAR_target_xpos], ecx; + mov ds:[FO_VAR_target_ypos], ecx; + mov ds:[FO_VAR_In_WorldMap], ecx; + jmp wmTeleportToArea_Ret; + } +} + static void __declspec(naked) wmAreaMarkVisitedState_hack() { static const DWORD wmAreaMarkVisitedState_Ret = 0x4C46A2; //static const DWORD wmAreaMarkVisitedState_Error = 0x4C4698; @@ -3010,13 +3010,6 @@ void BugFixes::init() // Fix for checking the horizontal position on the y-axis instead of x when setting coordinates on the world map SafeWrite8(0x4C4743, 0xC6); // cmp esi, eax - // Partial fix for incorrect positioning after exiting small/medium locations (e.g. Ghost Farm) - //if (GetConfigInt("Misc", "SmallLocExitFix", 1)) { - dlog("Applying fix for incorrect positioning after exiting small/medium locations.", DL_INIT); - MakeJump(0x4C5A41, wmTeleportToArea_hack); - dlogr(" Done", DL_INIT); - //} - //if (GetConfigInt("Misc", "PrintToFileFix", 1)) { dlog("Applying print to file fix.", DL_INIT); MakeCall(0x4C67D4, db_get_file_list_hack); @@ -3332,6 +3325,13 @@ void BugFixes::init() MakeCall(0x411FD6, action_use_an_item_on_object_hack); MakeCall(0x411DF7, action_climb_ladder_hack); // bug caused by anim_move_to_tile_ fix + // Partial fix for incorrect positioning after exiting small/medium locations (e.g. Ghost Farm) + //if (GetConfigInt("Misc", "SmallLocExitFix", 1)) { + dlog("Applying fix for incorrect positioning after exiting small/medium locations.", DL_INIT); + MakeJump(0x4C5A41, wmTeleportToArea_hack); + dlogr(" Done", DL_INIT); + //} + // Fix for Scout perk being taken into account when setting the visibility of locations with mark_area_known function // also fix the incorrect coordinates for small/medium location circles that the engine uses to highlight their sub-tiles // and fix visited tiles on the world map being darkened again when a location is added next to them @@ -3417,7 +3417,19 @@ void BugFixes::init() 0x74, 0x1A, // jz 0x426D83 0x90 }; - SafeWriteBytes(0x426D5C, codeData, 14); + SafeWriteBytes(0x426D5C, codeData, 14); // combat_is_shot_blocked_ + + // Fix for NPC stuck in an animation loop in combat when trying to move close to a multihex critter + // this prevents moving to the multihex critter when the critters are close together + BYTE codeData1[] = { + 0x89, 0xF0, // mov eax, esi + 0x89, 0xFA, // mov edx, edi + 0xE8, 0x00, 0x00, 0x0, 0x0, // call obj_dist_ + 0x83, 0xF8, 0x01, // cmp eax, 1 + 0x0F, 0x8E, 0xAB, 0x0, 0x0, 0x0, // jle 0x42A1B1 (exit) + }; + SafeWriteBytes(0x42A0F4, codeData1, 18); // ai_move_steps_closer_ + HookCall(0x42A0F8, (void*)fo::funcoffs::obj_dist_); } } diff --git a/sfall/Modules/MiscPatches.cpp b/sfall/Modules/MiscPatches.cpp index 54341a15..d4384547 100644 --- a/sfall/Modules/MiscPatches.cpp +++ b/sfall/Modules/MiscPatches.cpp @@ -103,7 +103,7 @@ static void __declspec(naked) intface_item_reload_hook() { mov eax, dword ptr ds:[FO_VAR_obj_dude]; call fo::funcoffs::register_clear_; xor edx, edx; // ANIM_stand - xor ebx, ebx; // no delay + xor ebx, ebx; // delay (unused) lea eax, [edx + 1]; // RB_UNRESERVED call fo::funcoffs::register_begin_; mov eax, dword ptr ds:[FO_VAR_obj_dude];