mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user