diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index deabd4a3..a24af807 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -2,6 +2,10 @@ ;v4.3.3 [Main] +;Change to 1 if you want to use command line args to tell sfall to use another ini file +;This option is always enabled in 4.3.3/3.8.33 or later. The information is left for reference only +UseCommandLine=0 + ;Uncomment and point to a file to get alternate translations for some sfall messages ;This file can be placed in text\\ for sfall to get the translations depending on the game language ;TranslationsINI=sfall\Translations.ini @@ -276,7 +280,7 @@ UseFileSystemOverride=0 ;Original: patchXXX.dat > critter_patches > critter_dat > f2_res_patches > f2_res_dat > master_patches > master_dat ;Modified: master_patches > critter_patches > patchXXX.dat > critter_dat > f2_res_patches > f2_res_dat > master_dat ;This option is always enabled in 4.3/3.8.30 or later. The information is left for reference only -;DataLoadOrderPatch=1 +DataLoadOrderPatch=1 ;Set to 1 to load alternative dialog msg files from text\\dialog_female\ for female PC ;Set to 2 to also load subtitle files from text\\cuts_female\ for female PC diff --git a/sfall/FalloutEngine/Structs.h b/sfall/FalloutEngine/Structs.h index e397296c..e91076c1 100644 --- a/sfall/FalloutEngine/Structs.h +++ b/sfall/FalloutEngine/Structs.h @@ -1036,17 +1036,14 @@ struct DrugInfoList { struct FloatText { long flags; - void* unknown0; - long unknown1; - long unknown2; - long unknown3; - long unknown4; - long unknown5; - long unknown6; - long unknown7; - long unknown8; - long unknown9; - void* unknown10; + GameObject* owner; + long time; + long lines; + long x_off; + long y_off; + long tile_num; + sfall::Rectangle rect; + BYTE* buffer; }; struct SubTitleList { diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index bf0b81f3..34e8ca2d 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -3982,6 +3982,9 @@ void BugFixes::init() // Fix to prevent the main menu music from stopping when entering the load game screen BlockCall(0x480B25); + + // Fix incorrect value of the limit number of floating messages + SafeWrite8(0x4B039F, 20); // text_object_create_ (was 19) } } diff --git a/sfall/Modules/MiscPatches.cpp b/sfall/Modules/MiscPatches.cpp index 2f30a39e..32dea6e6 100644 --- a/sfall/Modules/MiscPatches.cpp +++ b/sfall/Modules/MiscPatches.cpp @@ -387,7 +387,7 @@ static void __fastcall RemoveAllFloatTextObjects() { long textCount = fo::var::text_object_index; if (textCount > 0) { for (long i = 0; i < textCount; i++) { - fo::func::mem_free(fo::var::text_object_list[i]->unknown10); + fo::func::mem_free(fo::var::text_object_list[i]->buffer); fo::func::mem_free(fo::var::text_object_list[i]); } fo::var::text_object_index = 0; @@ -414,6 +414,52 @@ static void __declspec(naked) map_check_state_hook() { } } +// Frees up space in the array to create a text object +static void __fastcall RemoveFloatTextObject(fo::GameObject* source) { + size_t index = 0; + size_t textCount = fo::var::text_object_index; + long minTime = fo::var::text_object_list[0]->time; + + for (size_t i = 1; i < textCount; i++) { + if (fo::var::text_object_list[i]->owner == source) { + index = i; + break; + } + if (fo::var::text_object_list[i]->time < minTime) { + minTime = fo::var::text_object_list[i]->time; + index = i; + } + } + fo::FloatText* tObj = fo::var::text_object_list[index]; + + fo::func::tile_coord(tObj->tile_num, &tObj->rect.x, &tObj->rect.y); + tObj->rect.y += tObj->y_off; + tObj->rect.x += tObj->x_off; + + fo::BoundRect rect; + rect.x = tObj->rect.x; + rect.y = tObj->rect.y; + rect.offx = tObj->rect.width + tObj->rect.x - 1; + rect.offy = tObj->rect.height + tObj->rect.y - 1; + + fo::func::mem_free(tObj->buffer); + fo::func::mem_free(tObj); + + // copy the last element of the array to the place of the removed one + if (--textCount > index) fo::var::text_object_list[index] = fo::var::text_object_list[textCount]; + fo::var::text_object_index--; + + fo::func::tile_refresh_rect(&rect, fo::var::map_elevation); +} + +static void __declspec(naked) text_object_create_hack() { + __asm { + mov ecx, eax; + push 0x4B03A6; // ret addr + jmp RemoveFloatTextObject; + } +} + static void __declspec(naked) obj_move_to_tile_hook_redraw() { __asm { mov MainLoopHook::displayWinUpdateState, 1; @@ -959,6 +1005,9 @@ void MiscPatches::init() { HookCall(0x48A94B, obj_move_to_tile_hook); HookCall(0x4836BB, map_check_state_hook); + // Remove an old floating message when creating a new one if the maximum number of floating messages has been reached + HookCall(0x4B03A1, text_object_create_hack); // jge hack + // Redraw the screen to update black edges of the map (HRP bug) // https://github.com/phobos2077/sfall/issues/282 HookCall(0x48A954, obj_move_to_tile_hook_redraw);