diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index c163da34..f1943d89 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -703,6 +703,9 @@ DontDeleteProtos=0 ;Set to 1 to give scripts direct access to Fallout's address space, and to make arbitrary calls into Fallout's code AllowUnsafeScripting=0 +;Set to 1 to force sfall to search for global scripts every time the game loads rather than only once on the first game start +AlwaysFindScripts=0 + ;Set to 1 to force sfall to inject all hooks code into the game, even if corresponding hook scripts don't exist InjectAllGameHooks=0 diff --git a/sfall/Modules/HookScripts.cpp b/sfall/Modules/HookScripts.cpp index 783f1f69..98917380 100644 --- a/sfall/Modules/HookScripts.cpp +++ b/sfall/Modules/HookScripts.cpp @@ -221,7 +221,7 @@ void LoadHookScripts() { initingHookScripts = 1; for (int i = 0; i < numHooks; i++) { if (hooks[i].size()) { - InitScriptProgram(hooks[i][0].prog);// zero hook is always hs_*.int script because Hook scripts are loaded BEFORE global scripts + InitScriptProgram(hooks[i][0].prog); // zero hook is always hs_*.int script because Hook scripts are loaded BEFORE global scripts } } isGlobalScriptLoading = 0; @@ -242,7 +242,8 @@ void HookScripts::init() { LoadGameHook::OnGameModeChange() += GameModeChangeHook; LoadGameHook::OnAfterGameStarted() += SourceUseSkillOnInit; - HookScripts::injectAllHooks = (isDebug && (GetConfigInt("Debugging", "InjectAllGameHooks", 0) != 0)); + HookScripts::injectAllHooks = isDebug && (GetPrivateProfileIntA("Debugging", "InjectAllGameHooks", 0, ::sfall::ddrawIni) != 0); + if (HookScripts::injectAllHooks) dlogr("Injecting all game hooks", DL_HOOK); } } diff --git a/sfall/Modules/MiscPatches.cpp b/sfall/Modules/MiscPatches.cpp index 1d73b0f9..3e6c41c6 100644 --- a/sfall/Modules/MiscPatches.cpp +++ b/sfall/Modules/MiscPatches.cpp @@ -475,7 +475,7 @@ static void __declspec(naked) win_debug_hook() { void DebugModePatch() { if (isDebug) { - DWORD dbgMode = GetPrivateProfileIntA("Debugging", "DebugMode", 0, ".\\ddraw.ini"); + DWORD dbgMode = GetPrivateProfileIntA("Debugging", "DebugMode", 0, ::sfall::ddrawIni); if (dbgMode) { dlog("Applying debugmode patch.", DL_INIT); //If the player is using an exe with the debug patch already applied, just skip this block without erroring @@ -792,7 +792,7 @@ void DialogueFix() { } void DontDeleteProtosPatch() { - if (isDebug && GetPrivateProfileIntA("Debugging", "DontDeleteProtos", 0, ".\\ddraw.ini")) { + if (isDebug && GetPrivateProfileIntA("Debugging", "DontDeleteProtos", 0, ::sfall::ddrawIni)) { dlog("Applying permanent protos patch.", DL_INIT); SafeWrite8(0x48007E, 0xEB); dlogr(" Done", DL_INIT); diff --git a/sfall/Modules/Perks.cpp b/sfall/Modules/Perks.cpp index d6ae6be2..74a28977 100644 --- a/sfall/Modules/Perks.cpp +++ b/sfall/Modules/Perks.cpp @@ -561,7 +561,7 @@ normalPerk: jl end; cmp edx, PERK_gain_luck_perk; jg end; - inc ds:[edx * 4 + (FO_VAR_pc_proto + 0x24 - (PERK_gain_strength_perk) * 4)]; // base_stat_srength + inc ds:[edx * 4 + (FO_VAR_pc_proto + 0x24 - PERK_gain_strength_perk * 4)]; // base_stat_srength end: retn; } diff --git a/sfall/Modules/ScriptExtender.cpp b/sfall/Modules/ScriptExtender.cpp index 08cc2ce7..7b571358 100644 --- a/sfall/Modules/ScriptExtender.cpp +++ b/sfall/Modules/ScriptExtender.cpp @@ -93,6 +93,7 @@ typedef std::pair<__int64, int> glob_pair; DWORD availableGlobalScriptTypes = 0; bool isGameLoading; +bool alwaysFindScripts; fo::ScriptInstance overrideScriptStruct; @@ -405,7 +406,7 @@ ScriptProgram* GetGlobalScriptProgram(fo::Program* scriptPtr) { } bool _stdcall IsGameScript(const char* filename) { - if ((filename[0] != 'g' || filename[1] != 'l') && (filename[0] != 'h' || filename[1] != 's')) return true; + if (strlen(filename) > 8) return false; // TODO: write better solution for (int i = 0; i < fo::var::maxScriptNum; i++) { if (strcmp(filename, fo::var::scriptListInfo[i].fileName) == 0) return true; @@ -435,6 +436,7 @@ static void LoadGlobalScriptsList() { } static void PrepareGlobalScriptsListByMask() { + globalScriptFilesList.clear(); for (auto& fileMask : globalScriptPathList) { char** filenames; auto basePath = fileMask.substr(0, fileMask.find_last_of("\\/") + 1); // path to scripts without mask @@ -457,7 +459,6 @@ static void PrepareGlobalScriptsListByMask() { } fo::func::db_free_file_list(&filenames, 0); } - globalScriptPathList.clear(); // clear path list, it is no longer needed } // this runs after the game was loaded/started @@ -466,9 +467,10 @@ static void LoadGlobalScripts() { isGameLoading = false; LoadHookScripts(); dlogr("Loading global scripts", DL_SCRIPT|DL_INIT); - if (!listIsPrepared) { // runs only once + if (!listIsPrepared) { // only once PrepareGlobalScriptsListByMask(); - listIsPrepared = true; + listIsPrepared = !alwaysFindScripts; + if (listIsPrepared) globalScriptPathList.clear(); // clear path list, it is no longer needed } LoadGlobalScriptsList(); dlogr("Finished loading global scripts", DL_SCRIPT|DL_INIT); @@ -687,6 +689,9 @@ void ScriptExtender::init() { dlogr("Arrays in backward-compatiblity mode.", DL_SCRIPT); } + alwaysFindScripts = isDebug && (GetPrivateProfileIntA("Debugging", "AlwaysFindScripts", 0, ::sfall::ddrawIni) != 0); + if (alwaysFindScripts) dlogr("Always searching for global scripts behavior enabled.", DL_SCRIPT); + MakeJump(0x4A390C, FindSidHack); MakeJump(0x4A5E34, ScrPtrHack); memset(&overrideScriptStruct, 0, sizeof(fo::ScriptInstance)); diff --git a/sfall/Modules/ScriptExtender.h b/sfall/Modules/ScriptExtender.h index e36e99ee..fe4ebdf2 100644 --- a/sfall/Modules/ScriptExtender.h +++ b/sfall/Modules/ScriptExtender.h @@ -91,5 +91,6 @@ static char regAnimCombatCheck = 1; extern DWORD isGlobalScriptLoading; extern DWORD availableGlobalScriptTypes; extern DWORD modifiedIni; +extern bool alwaysFindScripts; }