diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini
index 5b28a3b5..0fa6b689 100644
--- a/artifacts/ddraw.ini
+++ b/artifacts/ddraw.ini
@@ -665,7 +665,7 @@ InterfaceDontMoveOnTop=0
SpecialDeathGVAR=491
;Set to 1 to disable the special handling of map IDs 19 and 37 in the engine when entering the maps
-;Don't set this to anything other than 0 unless another mod you're using explicitly tells you to!
+;Note that enabling this option can break the map changes in Modoc and Vault 15
DisableSpecialMapIDs=0
;Set to 1 to display sfall built-in credits at the bottom of credits.txt contents instead of at the top
diff --git a/sfall/Bugs.cpp b/sfall/Bugs.cpp
index e2d0edab..dbc74a71 100644
--- a/sfall/Bugs.cpp
+++ b/sfall/Bugs.cpp
@@ -1397,7 +1397,7 @@ mapLeave:
static void __declspec(naked) obj_move_to_tile_hack_seen() {
__asm {
- cmp ds:[_loadingGame], 0; // loading save game
+ cmp ds:[_loadingGame], 0; // loading saved game
jnz fix;
// if (map_state <= 0 && mapEntranceTileNum != -1) then fix
cmp dword ptr ds:[_map_state], 0; // map number, -1 exit to worldmap
@@ -1986,6 +1986,24 @@ skip:
}
}
+static DWORD dudeScriptID;
+static void __declspec(naked) obj_load_dude_hook0() {
+ __asm {
+ mov eax, ds:[_obj_dude];
+ mov eax, [eax + 0x78];
+ mov dudeScriptID, eax;
+ retn;
+ }
+}
+
+static void __declspec(naked) obj_load_dude_hook1() {
+ __asm {
+ mov ebx, dudeScriptID;
+ mov [eax + 0x78], ebx;
+ retn;
+ }
+}
+
void BugsInit()
{
// fix vanilla negate operator on float values
@@ -2507,4 +2525,10 @@ void BugsInit()
HookCall(0x41C0FC, automap_pip_save_hook);
HookCall(0x499212, PrintAutoMapList); // PrintAMList_
HookCall(0x499013, PrintAutoMapList); // PrintAMelevList_
+
+ // Fix for a duplicate obj_dude script being created when loading a saved game
+ HookCall(0x48D63E, obj_load_dude_hook0);
+ HookCall(0x48D666, obj_load_dude_hook1);
+ BlockCall(0x48D675);
+ BlockCall(0x48D69D);
}
diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp
index ad1a4402..068a39f4 100644
--- a/sfall/FalloutEngine.cpp
+++ b/sfall/FalloutEngine.cpp
@@ -486,6 +486,7 @@ const DWORD mouse_hide_ = 0x4CA534;
const DWORD mouse_in_ = 0x4CA8C8;
const DWORD mouse_show_ = 0x4CA34C;
const DWORD move_inventory_ = 0x474708;
+const DWORD new_obj_id_ = 0x4A386C;
const DWORD NixHotLines_ = 0x4999C0;
const DWORD nrealloc_ = 0x4F1669;
const DWORD obj_ai_blocking_at_ = 0x48BA20;
diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h
index 1b38f12f..25fb878b 100644
--- a/sfall/FalloutEngine.h
+++ b/sfall/FalloutEngine.h
@@ -58,6 +58,7 @@
#define _critter_db_handle 0x58E94C
#define _critterClearObj 0x518438
#define _crnt_func 0x664508
+#define _cur_id 0x51C7D4
#define _curr_font_num 0x51E3B0
#define _curr_pc_stat 0x6681AC
#define _curr_stack 0x59E96C
@@ -699,6 +700,7 @@ extern const DWORD mouse_hide_;
extern const DWORD mouse_in_;
extern const DWORD mouse_show_;
extern const DWORD move_inventory_;
+extern const DWORD new_obj_id_;
extern const DWORD NixHotLines_;
extern const DWORD nrealloc_;
extern const DWORD obj_ai_blocking_at_;
diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp
index 2f4d2024..51914834 100644
--- a/sfall/ScriptExtender.cpp
+++ b/sfall/ScriptExtender.cpp
@@ -1268,6 +1268,18 @@ long SetObjectUniqueID(TGameObj* obj) {
return objUniqueID;
}
+static void __declspec(naked) new_obj_id_hook() {
+ __asm {
+ mov eax, 83535;
+ cmp dword ptr ds:[_cur_id], eax;
+ jle pickNewID;
+ retn;
+pickNewID: // skip PM range (18000 - 83535)
+ mov ds:[_cur_id], eax;
+ jmp new_obj_id_;
+ }
+}
+
void ScriptExtenderSetup() {
bool AllowUnsafeScripting = IsDebug
&& GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ".\\ddraw.ini") != 0;
@@ -1300,6 +1312,9 @@ void ScriptExtenderSetup() {
}
}
+ HookCall(0x4A38A5, new_obj_id_hook);
+ SafeWrite8(0x4A38B3, 0x90); // fix ID increment
+
arraysBehavior = GetPrivateProfileIntA("Misc", "arraysBehavior", 1, ini);
if (arraysBehavior > 0) {
arraysBehavior = 1; // only 1 and 0 allowed at this time
diff --git a/sfall/timer.cpp b/sfall/SpeedPatch.cpp
similarity index 100%
rename from sfall/timer.cpp
rename to sfall/SpeedPatch.cpp
diff --git a/sfall/timer.h b/sfall/SpeedPatch.h
similarity index 100%
rename from sfall/timer.h
rename to sfall/SpeedPatch.h
diff --git a/sfall/ddraw.vcxproj b/sfall/ddraw.vcxproj
index abd98c9d..5eda34f9 100644
--- a/sfall/ddraw.vcxproj
+++ b/sfall/ddraw.vcxproj
@@ -257,7 +257,7 @@
-
+
@@ -311,7 +311,7 @@
Create
-
+
diff --git a/sfall/ddraw.vcxproj.filters b/sfall/ddraw.vcxproj.filters
index dc4099d3..cb1cfb1b 100644
--- a/sfall/ddraw.vcxproj.filters
+++ b/sfall/ddraw.vcxproj.filters
@@ -90,7 +90,7 @@
Headers
-
+
Headers
@@ -282,7 +282,7 @@
Source
-
+
Source
diff --git a/sfall/main.cpp b/sfall/main.cpp
index f8b93e06..47c38250 100644
--- a/sfall/main.cpp
+++ b/sfall/main.cpp
@@ -56,10 +56,10 @@
#include "ScriptExtender.h"
#include "skills.h"
#include "sound.h"
+#include "SpeedPatch.h"
#include "stats.h"
#include "SuperSave.h"
#include "Tiles.h"
-#include "timer.h"
#include "version.h"
ddrawDll ddraw;
@@ -838,6 +838,7 @@ static void DllMain2() {
dlogr("Running BugsInit().", DL_INIT);
BugsInit();
+ dlogr("Running SpeedPatchInit().", DL_INIT);
SpeedPatchInit();
//if (GetPrivateProfileIntA("Input", "Enable", 0, ini)) {
@@ -877,7 +878,10 @@ static void DllMain2() {
dlogr(" Done", DL_INIT);
}
+ dlogr("Running AmmoModInit().", DL_INIT);
AmmoModInit();
+
+ dlogr("Running MoviesInit().", DL_INIT);
MoviesInit();
mapName[64] = 0;
@@ -1128,8 +1132,10 @@ static void DllMain2() {
dlogr(" Done", DL_INIT);
}
+ dlogr("Running FileSystemInit().", DL_INIT);
FileSystemInit();
+ dlogr("Running DebugEditorInit().", DL_INIT);
DebugEditorInit();
if (GetPrivateProfileIntA("Misc", "SingleCore", 1, ini)) {
@@ -1164,6 +1170,7 @@ static void DllMain2() {
dlogr(" Done", DL_INIT);
}
+ dlogr("Running CritInit().", DL_INIT);
CritInit();
//if (GetPrivateProfileIntA("Misc", "MultiPatches", 0, ini)) {
@@ -1215,12 +1222,6 @@ static void DllMain2() {
dlogr(" Done", DL_INIT);
}
- if (GetPrivateProfileIntA("Misc", "SkipOpeningMovies", 0, ini)) {
- dlog("Skipping opening movies.", DL_INIT);
- SafeWrite16(0x4809C7, 0x1CEB); // jmps 0x4809E5
- dlogr(" Done", DL_INIT);
- }
-
RetryCombatMinAP = GetPrivateProfileIntA("Misc", "NPCsTryToSpendExtraAP", 0, ini);
if (RetryCombatMinAP > 0) {
dlog("Applying retry combat patch.", DL_INIT);
@@ -1335,6 +1336,7 @@ static void DllMain2() {
dlogr("Patching out ereg call.", DL_INIT);
BlockCall(0x4425E6);
+ dlogr("Running AnimationsAtOnceInit().", DL_INIT);
AnimationsAtOnceInit();
if (tmp = GetPrivateProfileIntA("Sound", "OverrideMusicDir", 0, ini)) {
@@ -1436,8 +1438,11 @@ static void DllMain2() {
}
// phobos2077:
+ dlogr("Running ComputeSprayModInit().", DL_INIT);
ComputeSprayModInit();
+ dlogr("Running ExplosionInit().", DL_INIT);
ExplosionInit();
+ dlogr("Running BooksInit().", DL_INIT);
BooksInit();
DWORD addrs[2] = {0x45F9DE, 0x45FB33};
SimplePatch(addrs, 2, "Misc", "CombatPanelAnimDelay", 1000, 0, 65535);
diff --git a/sfall/movies.cpp b/sfall/movies.cpp
index 19b5822f..c8958d02 100644
--- a/sfall/movies.cpp
+++ b/sfall/movies.cpp
@@ -744,6 +744,14 @@ less:
}
}
+void SkipOpeningMoviesPatch() {
+ if (GetPrivateProfileIntA("Misc", "SkipOpeningMovies", 0, ini)) {
+ dlog("Skipping opening movies.", DL_INIT);
+ SafeWrite16(0x4809C7, 0x1CEB); // jmps 0x4809E5
+ dlogr(" Done", DL_INIT);
+ }
+}
+
void MoviesInit() {
dlog("Applying movie patch.", DL_INIT);
@@ -801,6 +809,9 @@ void MoviesInit() {
MakeJump(0x4A378B, Artimer1DaysCheckHack);
dlogr("Done", DL_INIT);
}
+
+ // Should be AFTER the PlayMovieHook setup above
+ SkipOpeningMoviesPatch();
}
void MoviesExit() {