From a17471b624f4fbc10f3a5c5265e6bf22c1057de1 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 24 Sep 2019 11:52:50 +0800 Subject: [PATCH] Some minor changes: * Improved the display of the car fuel gauge on the world map interface. * Expanded set_critter_stat function to allow changing STAT_unused and STAT_dmg_* stats for the player, and STAT_unused for other critters. * Changed AllowUnsafeScripting to not require sfall debugging mode. * Changed NPCStage6Fix to be enabled by default. * Added a new value to AIBestWeaponFix to change the priority multiplier for having weapon perk to 3x. * Added RP's extra weapon anim codes to vanilla PMs in npcarmor.ini. Updated version number. --- artifacts/config_files/npcarmor.ini | 8 +++--- artifacts/ddraw.ini | 27 ++++++++++--------- sfall/Modules/BugFixes.cpp | 9 ++++--- sfall/Modules/Interface.cpp | 16 ++++++++--- sfall/Modules/MiscPatches.cpp | 2 +- sfall/Modules/Scripting/Opcodes.cpp | 2 +- sfall/Modules/Stats.cpp | 41 +++++++++++++++++++++++++++-- sfall/version.h | 4 +-- 8 files changed, 80 insertions(+), 29 deletions(-) diff --git a/artifacts/config_files/npcarmor.ini b/artifacts/config_files/npcarmor.ini index 65572995..90b20b7c 100644 --- a/artifacts/config_files/npcarmor.ini +++ b/artifacts/config_files/npcarmor.ini @@ -31,7 +31,7 @@ Robe=16777218 ; Sulik [1] PID=16777313 -WeaponAnims=1,3,4,6 +WeaponAnims=1,3,4,6,14 Default=16777280 Leather=16777325 Power=16777324 @@ -42,7 +42,7 @@ Combat=16777322 ; Vic [2] PID=16777278 -WeaponAnims=1,5,7 +WeaponAnims=1,5,7,13,14 Default=16777307 Jacket=16777329 Combat=16777330 @@ -53,7 +53,7 @@ Leather=16777333 ; Cassidy [3] PID=16777305 -WeaponAnims=4,5,7 +WeaponAnims=4,5,7,13 Default=16777354 Leather=16777260 Power=16777328 @@ -64,7 +64,7 @@ Combat=16777326 ; Myron [4] PID=16777376 -WeaponAnims=1,5 +WeaponAnims=1,5,14 Default=16777304 Leather= Power=16777349 diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index ca0b6827..013b8696 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -1,5 +1,5 @@ ;sfall configuration settings -;v4.2 +;v4.2.1 [Main] ;Change to 1 if you want to use command line args to tell sfall to use another ini file. @@ -186,7 +186,7 @@ FastMoveFromContainer=0 ;A key to press to open a debug game editor ;Set to 0 to disable, or a DX scancode otherwise -;Requires sfall debugging mode to be enabled and FalloutClient.exe from the modders pack +;Requires sfall debugging mode and FalloutClient.exe from the modders pack DebugEditorKey=0 ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX @@ -412,8 +412,9 @@ SkipOpeningMovies=0 ;Set to 0 to disable NPCsTryToSpendExtraAP=0 -;Set to 1 to fix NPCs not checking weapon perks properly when searching for the best weapon -;Note that enabling this option can significantly affect the weapon choice of some NPCs in combat +;Set to 1 to fix NPCs not checking weapon perks properly when choosing the best weapon in combat +;Set to 2 to change the priority multiplier for having weapon perk to 3x (the original is 5x) +;Note that enabling this option can significantly affect the weapon of choice for some NPCs AIBestWeaponFix=0 ;Set to 1 to fix NPCs not taking chem_primary_desire in AI.txt as drug use preference when using drugs in their inventory @@ -646,7 +647,7 @@ StackEmptyWeapons=0 ;If the amount of ammo boxes in the inventory is less than or equal to the reserve, only one box will be used ReloadReserve=-1 -;Set to 1 to change the counter in the 'Move Items' window to start with maximum number except in the barter screen +;Set to 1 to change the counter in the 'Move Items' window to start with maximum number, except in the barter screen ItemCounterDefaultMax=0 ;Set to 1 to leave the music playing in dialogue with talking heads @@ -748,8 +749,8 @@ GlobalScriptPaths=scripts\gl*.int,scripts\sfall\gl*.int Enable=0 ;Fallout 2 Debug Patch -;Set to 1 to send debug output to the screen, 2 to a debug.log file, or 3 to both the screen and a debug.log file -;Does not require enabling sfall debugging mode +;Set to 1 to send debug output to the screen, 2 to a debug.log file, or 3 to both the screen and debug.log +;Does not require sfall debugging mode ;While you don't need to create an environment variable, you do still need to set the appropriate lines in fallout2.cfg: ;------- ;[debug] @@ -765,19 +766,18 @@ Enable=0 DebugMode=0 ;Set to 1 to hide error messages in debug output when a null value is passed to the function as an object -;Requires DebugMode to be enabled HideObjIsNullMsg=0 ;Change to 1 to skip the compatibility mode check SkipCompatModeCheck=0 ;Set to 1 to skip the executable file size check -;Does not require enabling sfall debugging mode +;Does not require sfall debugging mode SkipSizeCheck=0 ;If you're testing changes to the Fallout exe, you can override the CRC that sfall looks for here ;You can use several hex values, separated by commas -;Does not require enabling sfall debugging mode +;Does not require sfall debugging mode ;ExtraCRC=0x00000000,0x00000000 ;Set to 1 to stop Fallout from deleting non read-only protos at startup @@ -785,14 +785,15 @@ SkipSizeCheck=0 DontDeleteProtos=0 ;Set to 1 to give scripts direct access to Fallout's address space, and to make arbitrary calls into Fallout's code +;Does not require sfall debugging mode 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 +;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 critters to display combat float messages ;Requires AllowSoundForFloats to be enabled Test_ForceFloats=0 diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index 2fd96a3c..4511b2f6 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -2693,11 +2693,14 @@ void BugFixes::init() } // Fix for AI not checking weapon perks properly when searching for the best weapon - if (GetConfigInt("Misc", "AIBestWeaponFix", 0)) { + int bestWeaponPerkFix = GetConfigInt("Misc", "AIBestWeaponFix", 0); + if (bestWeaponPerkFix > 0) { dlog("Applying AI best weapon choice fix.", DL_INIT); HookCall(0x42954B, ai_best_weapon_hook); - // also change the modifier for having weapon perk to 3x (was 5x) - SafeWriteBatch(0x55, {0x42955E, 0x4296E7}); + // also change the priority multiplier for having weapon perk to 3x (the original is 5x) + if (bestWeaponPerkFix > 1) { + SafeWriteBatch(0x55, {0x42955E, 0x4296E7}); + } dlogr(" Done", DL_INIT); } diff --git a/sfall/Modules/Interface.cpp b/sfall/Modules/Interface.cpp index 86b9b894..c36e2a30 100644 --- a/sfall/Modules/Interface.cpp +++ b/sfall/Modules/Interface.cpp @@ -84,7 +84,7 @@ static void ActionPointsBarPatch() { if (hrpVersionValid && !_stricmp((const char*)HRPAddressOffset(0x39358), "HR_IFACE_%i.frm")) { SafeWriteStr(HRPAddressOffset(0x39363), "E.frm"); // patching HRP } else { - dlog(" Incorrect HRP version!", DL_INIT); + dlogr(" Incorrect HRP version!", DL_INIT); return; } LoadGameHook::OnAfterGameInit() += APBarRectPatch; @@ -412,7 +412,13 @@ static void WorldmapViewportPatch() { static void __declspec(naked) wmInterfaceRefreshCarFuel_hack_empty() { __asm { - mov byte ptr [eax - 1], 14; + mov byte ptr [eax - 1], 13; + mov byte ptr [eax + 1], 13; + add eax, wmapWinWidth; + dec ebx; + mov byte ptr [eax], 14; + mov byte ptr [eax - 1], 15; + mov byte ptr [eax + 1], 15; add eax, wmapWinWidth; retn; } @@ -421,8 +427,10 @@ static void __declspec(naked) wmInterfaceRefreshCarFuel_hack_empty() { static void __declspec(naked) wmInterfaceRefreshCarFuel_hack() { __asm { mov byte ptr [eax - 1], 196; + mov byte ptr [eax + 1], 196; add eax, wmapWinWidth; - mov byte ptr [eax - 1], 14; + mov byte ptr [eax - 1], 200; + mov byte ptr [eax + 1], 200; retn; } } @@ -464,6 +472,8 @@ static void WorldMapInterfacePatch() { // Car fuel gauge graphics patch MakeCall(0x4C528A, wmInterfaceRefreshCarFuel_hack_empty); MakeCall(0x4C529E, wmInterfaceRefreshCarFuel_hack); + SafeWrite8(0x4C52A8, 197); + SafeWrite8(0x4C5289, 12); } void Interface::init() { diff --git a/sfall/Modules/MiscPatches.cpp b/sfall/Modules/MiscPatches.cpp index b5535f77..8ac6662a 100644 --- a/sfall/Modules/MiscPatches.cpp +++ b/sfall/Modules/MiscPatches.cpp @@ -513,7 +513,7 @@ void CorpseLineOfFireFix() { } void NpcStage6Fix() { - if (GetConfigInt("Misc", "NPCStage6Fix", 0)) { + if (GetConfigInt("Misc", "NPCStage6Fix", 1)) { dlog("Applying NPC Stage 6 Fix.", DL_INIT); MakeJump(0x493CE9, NPCStage6Fix1); SafeWrite8(0x494063, 6); // loop should look for a potential 6th stage diff --git a/sfall/Modules/Scripting/Opcodes.cpp b/sfall/Modules/Scripting/Opcodes.cpp index b2da066c..edb15565 100644 --- a/sfall/Modules/Scripting/Opcodes.cpp +++ b/sfall/Modules/Scripting/Opcodes.cpp @@ -260,7 +260,7 @@ void InitNewOpcodes() { SafeWrite32(0x46CE6C, (DWORD)opcodes); // call that actually jumps to the opcode SafeWrite32(0x46E390, (DWORD)opcodes); // mov that writes to the opcode - if (isDebug && (GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ::sfall::ddrawIni) != 0)) { + if (GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ::sfall::ddrawIni)) { dlogr(" Unsafe opcodes enabled.", DL_SCRIPT); opcodes[0x1cf] = op_write_byte; opcodes[0x1d0] = op_write_short; diff --git a/sfall/Modules/Stats.cpp b/sfall/Modules/Stats.cpp index 49fc22ec..6a60b36d 100644 --- a/sfall/Modules/Stats.cpp +++ b/sfall/Modules/Stats.cpp @@ -238,7 +238,40 @@ static void __declspec(naked) stat_recalc_derived_hack() { } } -///////////////////// CRITTERS STATS ///////////////////// +static const DWORD StatSetBaseRet = 0x4AF559; +static void __declspec(naked) stat_set_base_hack_allow() { + using namespace fo; + __asm { + cmp ecx, STAT_unused; + je allow; + cmp ecx, STAT_dmg_thresh; + jl notAllow; + cmp ecx, STAT_dmg_resist_explosion; + jg notAllow; +allow: + pop eax; // destroy return address + jmp StatSetBaseRet; +notAllow: + mov eax, -1; // overwritten engine code + retn; + } +} + +static const DWORD SetCritterStatRet = 0x455D8A; +static void __declspec(naked) op_set_critter_stat_hack() { + using namespace fo; + __asm { + cmp dword ptr [esp + 0x2C - 0x28 + 4], STAT_unused; + je allow; + mov ebx, 3; // overwritten engine code + retn; +allow: + add esp, 4; // destroy return address + jmp SetCritterStatRet; + } +} + +//////////////////////////////// CRITTERS STATS //////////////////////////////// static long isNotPartyMemberPid; static struct { @@ -549,7 +582,7 @@ void StatsProtoReset() { protoMem.clear(); isNotPartyMemberPid = 0; } -/////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// void StatsReset() { for (int i = 0; i < fo::STAT_max_stat; i++) { @@ -584,6 +617,10 @@ void Stats::init() { MakeCall(0x4AF09C, CalcApToAcBonus, 3); // stat_level_ + // Allow set_critter_stat function to change STAT_unused and STAT_dmg_* stats for the player + MakeCall(0x4AF54E, stat_set_base_hack_allow); + MakeCall(0x455D65, op_set_critter_stat_hack); // STAT_unused for other critters + auto xpTableList = GetConfigList("Misc", "XPTable", "", 2048); size_t numLevels = xpTableList.size(); if (numLevels > 0) { diff --git a/sfall/version.h b/sfall/version.h index 623cf8b3..e48dc61a 100644 --- a/sfall/version.h +++ b/sfall/version.h @@ -24,7 +24,7 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 2 -#define VERSION_BUILD 0 +#define VERSION_BUILD 1 #define VERSION_REV 0 -#define VERSION_STRING "4.2" +#define VERSION_STRING "4.2.1"