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.
This commit is contained in:
NovaRain
2019-09-09 14:46:54 +08:00
parent 4975177c34
commit 4afde14f04
5 changed files with 91 additions and 73 deletions
+5
View File
@@ -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
+25
View File
@@ -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<long>(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<DWORD>(0x424FA7, "Misc", "KnockoutTime", 35, 35, 100);
BodypartHitReadConfig();
LoadGameHook::OnBeforeGameStart() += BodypartHitChances; // set on start & load
+2 -2
View File
@@ -249,8 +249,8 @@ 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);
SafeWrite16(0x4A3052, 0x9090);
SafeWrite16(0x4A3093, 0x9090);
dlogr(" Done", DL_INIT);
}
}
+12 -68
View File
@@ -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<DWORD>(0x424FA7, "Misc", "KnockoutTime", 35, 35, 100);
// Increase the max text width of the information card in the character screen
SafeWriteBatch<BYTE>(144, {0x43ACD5, 0x43DD37}); // 136, 133
CombatProcFix();
F1EngineBehaviorPatch();
DialogueFix();
AdditionalWeaponAnimsPatch();
MultiPatchesPatch();
@@ -866,7 +811,6 @@ void MiscPatches::init() {
OverrideMusicDirPatch();
NpcStage6Fix();
FashShotTraitFix();
BoostScriptDialogLimitPatch();
MotionScannerFlagsPatch();
EncounterTableSizePatch();
+46 -2
View File
@@ -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();