From 4afde14f049c58d206cc269d9d9d3c735bf6b001 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Mon, 9 Sep 2019 14:46:54 +0800 Subject: [PATCH] Added F1EngineBehavior option to change some of F2 engine funcs to F1 * disables playing the final movie/credits after the endgame slideshow. * disables halving the weight for power armor items. Moved FastShotFix and Ray's combat_p_proc fix from MiscPatches to other modules. --- artifacts/ddraw.ini | 5 +++ sfall/Modules/Combat.cpp | 25 +++++++++++ sfall/Modules/Criticals.cpp | 6 +-- sfall/Modules/MiscPatches.cpp | 80 ++++++----------------------------- sfall/Modules/Perks.cpp | 48 ++++++++++++++++++++- 5 files changed, 91 insertions(+), 73 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index c6a94a7b..feaa540b 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -191,6 +191,11 @@ DebugEditorKey=0 ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX [Misc] +;Changes some of Fallout 2 engine features to Fallout 1 behavior: +;- disables playing the final movie/credits after the endgame slideshow +;- disables halving the weight for power armor items +F1EngineBehavior=0 + ;Time limit in years. Must be between -3 and 13 ;Set to 0 if you want to die the instant you leave arroyo ;Set to -1 to remove the time limit, and automatically reset the date back to 2241 each time you would have reached it diff --git a/sfall/Modules/Combat.cpp b/sfall/Modules/Combat.cpp index 0f8a7857..3f965dda 100644 --- a/sfall/Modules/Combat.cpp +++ b/sfall/Modules/Combat.cpp @@ -21,6 +21,7 @@ #include "..\main.h" #include "..\FalloutEngine\Fallout2.h" +#include "..\SimplePatch.h" #include "HookScripts.h" #include "LoadGameHook.h" #include "Objects.h" @@ -448,6 +449,26 @@ static void BodypartHitReadConfig() { bodypartHit.Uncalled = static_cast(GetConfigInt("Misc", "BodyHit_Torso_Uncalled", 0)); } +static void __declspec(naked) apply_damage_hack() { + __asm { + xor edx, edx; + inc edx; // COMBAT_SUBTYPE_WEAPON_USED + test [esi + 0x15], dl; // ctd.flags2Source & DAM_HIT_ + jz end; // no hit + inc edx; // COMBAT_SUBTYPE_HIT_SUCCEEDED +end: + retn; + } +} + +static void CombatProcFix() { + //Ray's combat_p_proc fix + dlog("Applying Ray's combat_p_proc patch.", DL_INIT); + MakeCall(0x424DD9, apply_damage_hack); + SafeWrite16(0x424DC6, 0x9090); + dlogr(" Done", DL_INIT); +} + static void Combat_OnGameLoad() { baseHitChance.SetDefault(); mTargets.clear(); @@ -460,6 +481,8 @@ static void Combat_OnGameLoad() { } void Combat::init() { + CombatProcFix(); + MakeCall(0x424B76, compute_damage_hack, 2); // KnockbackMod MakeJump(0x4136D3, compute_dmg_damage_hack); // for op_critter_dmg @@ -476,6 +499,8 @@ void Combat::init() { HookCall(0x42A95D, ai_try_attack_hook); // jz func } + SimplePatch(0x424FA7, "Misc", "KnockoutTime", 35, 35, 100); + BodypartHitReadConfig(); LoadGameHook::OnBeforeGameStart() += BodypartHitChances; // set on start & load diff --git a/sfall/Modules/Criticals.cpp b/sfall/Modules/Criticals.cpp index 2d1b59fd..14579e3b 100644 --- a/sfall/Modules/Criticals.cpp +++ b/sfall/Modules/Criticals.cpp @@ -248,9 +248,9 @@ static void CriticalTableOverride() { static void RemoveCriticalTimeLimitsPatch() { if (GetConfigInt("Misc", "RemoveCriticalTimelimits", 0)) { dlog("Removing critical time limits.", DL_INIT); - SafeWrite8(0x424118, 0xEB); // jump to 0x424131 - SafeWrite8(0x4A3053, 0x0); - SafeWrite8(0x4A3094, 0x0); + SafeWrite8(0x424118, 0xEB); // jump to 0x424131 + SafeWrite16(0x4A3052, 0x9090); + SafeWrite16(0x4A3093, 0x9090); dlogr(" Done", DL_INIT); } } diff --git a/sfall/Modules/MiscPatches.cpp b/sfall/Modules/MiscPatches.cpp index d089b976..a43b5aef 100644 --- a/sfall/Modules/MiscPatches.cpp +++ b/sfall/Modules/MiscPatches.cpp @@ -47,10 +47,6 @@ static const DWORD PutAwayWeapon[] = { 0x472996, // invenWieldFunc_ }; -static const DWORD FastShotFixF1[] = { - 0x478BB8, 0x478BC7, 0x478BD6, 0x478BEA, 0x478BF9, 0x478C08, 0x478C2F, -}; - static const DWORD script_dialog_msgs[] = { 0x4A50C2, 0x4A5169, 0x4A52FA, 0x4A5302, 0x4A6B86, 0x4A6BE0, 0x4A6C37, }; @@ -59,18 +55,6 @@ static const DWORD walkDistanceAddr[] = { 0x411FF0, 0x4121C4, 0x412475, 0x412906, }; -static void __declspec(naked) apply_damage_hack() { - __asm { - xor edx, edx; - inc edx; // COMBAT_SUBTYPE_WEAPON_USED - test [esi + 0x15], dl; // ctd.flags2Source & DAM_HIT_ - jz end; // no hit - inc edx; // COMBAT_SUBTYPE_HIT_SUCCEEDED -end: - retn; - } -} - static void __declspec(naked) WeaponAnimHook() { __asm { cmp edx, 11; @@ -158,26 +142,6 @@ end: } } -static const DWORD FastShotTraitFixEnd1 = 0x478E7F; -static const DWORD FastShotTraitFixEnd2 = 0x478E7B; -static void __declspec(naked) FastShotTraitFix() { - __asm { - test eax, eax; // does player have Fast Shot trait? - je ajmp; // skip ahead if no - mov edx, ecx; // argument for item_w_range_: hit_mode - mov eax, ebx; // argument for item_w_range_: pointer to source_obj (always dude_obj due to code path) - call fo::funcoffs::item_w_range_; // get weapon's range - cmp eax, 0x2; // is weapon range less than or equal 2 (i.e. melee/unarmed attack)? - jle ajmp; // skip ahead if yes - xor eax, eax; // otherwise, disallow called shot attempt - jmp bjmp; -ajmp: - jmp FastShotTraitFixEnd1; // continue processing called shot attempt -bjmp: - jmp FastShotTraitFixEnd2; // clean up and exit function item_w_called_shot - } -} - static void __declspec(naked) ReloadHook() { __asm { push eax; @@ -469,24 +433,6 @@ void ScienceOnCrittersPatch() { } } -void FashShotTraitFix() { - switch (GetConfigInt("Misc", "FastShotFix", 1)) { - case 1: - dlog("Applying Fast Shot Trait Fix.", DL_INIT); - MakeJump(0x478E75, FastShotTraitFix); - dlogr(" Done", DL_INIT); - break; - case 2: - dlog("Applying Fast Shot Trait Fix. (Fallout 1 version)", DL_INIT); - SafeWrite8(0x478CA0, 0x0); - for (int i = 0; i < sizeof(FastShotFixF1) / 4; i++) { - HookCall(FastShotFixF1[i], (void*)0x478C7D); - } - dlogr(" Done", DL_INIT); - break; - } -} - void BoostScriptDialogLimitPatch() { if (GetConfigInt("Misc", "BoostScriptDialogLimit", 0)) { const int scriptDialogCount = 10000; @@ -540,14 +486,6 @@ void DontTurnOffSneakIfYouRunPatch() { } } -void CombatProcFix() { - //Ray's combat_p_proc fix - dlog("Applying Ray's combat_p_proc patch.", DL_INIT); - MakeCall(0x424DD9, apply_damage_hack); - SafeWrite8(0x424DC7, 0x0); - dlogr(" Done", DL_INIT); -} - void MultiPatchesPatch() { //if (GetConfigInt("Misc", "MultiPatches", 0)) { dlog("Applying load multiple patches patch.", DL_INIT); @@ -592,7 +530,7 @@ void MotionScannerFlagsPatch() { if (flags & 1) MakeJump(0x41BBE9, ScannerAutomapHook); if (flags & 2) { // automap_ - SafeWrite8(0x41BC25, 0x0); + SafeWrite16(0x41BC24, 0x9090); BlockCall(0x41BC3C); // item_m_use_charged_item_ SafeWrite8(0x4794B3, 0x5E); // jbe short 0x479512 @@ -774,6 +712,15 @@ void UseWalkDistancePatch() { } } +void F1EngineBehaviorPatch() { + if (GetConfigInt("Misc", "F1EngineBehavior", 0)) { + dlog("Applying Fallout 1 engine behavior patch.", DL_INIT); + BlockCall(0x4A4343); // disable playing the final movie/credits after the endgame slideshow + SafeWrite8(0x477C71, 0xEB); // disable halving the weight for power armor items + dlogr(" Done", DL_INIT); + } +} + void MiscPatches::init() { mapName[64] = 0; if (GetConfigString("Misc", "StartingMap", "", mapName, 64)) { @@ -814,7 +761,7 @@ void MiscPatches::init() { if (GetConfigInt("Misc", "OverrideArtCacheSize", 0)) { dlog("Applying override art cache size patch.", DL_INIT); - SafeWrite8(0x41886A, 0x0); + SafeWrite32(0x418867, 0x90909090); SafeWrite32(0x418872, 256); dlogr(" Done", DL_INIT); } @@ -842,12 +789,10 @@ void MiscPatches::init() { dlogr(" Done", DL_INIT); } - SimplePatch(0x424FA7, "Misc", "KnockoutTime", 35, 35, 100); - // Increase the max text width of the information card in the character screen SafeWriteBatch(144, {0x43ACD5, 0x43DD37}); // 136, 133 - CombatProcFix(); + F1EngineBehaviorPatch(); DialogueFix(); AdditionalWeaponAnimsPatch(); MultiPatchesPatch(); @@ -866,7 +811,6 @@ void MiscPatches::init() { OverrideMusicDirPatch(); NpcStage6Fix(); - FashShotTraitFix(); BoostScriptDialogLimitPatch(); MotionScannerFlagsPatch(); EncounterTableSizePatch(); diff --git a/sfall/Modules/Perks.cpp b/sfall/Modules/Perks.cpp index 22824400..758234b9 100644 --- a/sfall/Modules/Perks.cpp +++ b/sfall/Modules/Perks.cpp @@ -1212,6 +1212,48 @@ static __declspec(naked) void TraitInitWrapper() { } } +static const DWORD FastShotTraitFixEnd1 = 0x478E7F; +static const DWORD FastShotTraitFixEnd2 = 0x478E7B; +static void __declspec(naked) item_w_called_shot_hack() { + __asm { + test eax, eax; // does player have Fast Shot trait? + je ajmp; // skip ahead if no + mov edx, ecx; // argument for item_w_range_: hit_mode + mov eax, ebx; // argument for item_w_range_: pointer to source_obj (always dude_obj due to code path) + call fo::funcoffs::item_w_range_; // get weapon's range + cmp eax, 0x2; // is weapon range less than or equal 2 (i.e. melee/unarmed attack)? + jle ajmp; // skip ahead if yes + xor eax, eax; // otherwise, disallow called shot attempt + jmp bjmp; +ajmp: + jmp FastShotTraitFixEnd1; // continue processing called shot attempt +bjmp: + jmp FastShotTraitFixEnd2; // clean up and exit function item_w_called_shot + } +} + +static const DWORD FastShotFixF1[] = { + 0x478BB8, 0x478BC7, 0x478BD6, 0x478BEA, 0x478BF9, 0x478C08, 0x478C2F, +}; + +static void FastShotTraitFix() { + switch (GetConfigInt("Misc", "FastShotFix", 1)) { + case 1: + dlog("Applying Fast Shot Trait Fix.", DL_INIT); + MakeJump(0x478E75, item_w_called_shot_hack); + goto done; + case 2: + dlog("Applying Fast Shot Trait Fix. (Fallout 1 version)", DL_INIT); + SafeWrite16(0x478C9F, 0x9090); + for (int i = 0; i < sizeof(FastShotFixF1) / 4; i++) { + HookCall(FastShotFixF1[i], (void*)0x478C7D); + } + done: + dlogr(" Done", DL_INIT); + break; + } +} + /////////////////////////////////////////////////////////////////////////////// void _stdcall SetPerkValue(int id, int value, DWORD offset) { @@ -1248,10 +1290,10 @@ void PerksReset() { } // Reset some settable game values back to the defaults + // Perk level mod + SafeWrite32(0x496880, 0x019078); // Pyromaniac bonus SafeWrite8(0x424AB6, 5); - // Perk level mod - SafeWrite32(0x496880, 0x00019078); // Restore 'Heave Ho' modify fix if (perkHeaveHoModFix) { SafeWrite8(0x478AC4, 0xBA); @@ -1400,6 +1442,8 @@ void PerksAcceptCharScreen() { } void Perks::init() { + FastShotTraitFix(); + for (int i = STAT_st; i <= STAT_lu; i++) SafeWrite8(GainStatPerks[i][0], (BYTE)GainStatPerks[i][1]); PerkEngineInit();