Fixed cur_town function on new game start (#366)

This commit is contained in:
NovaRain
2021-04-13 12:08:45 +08:00
parent df45450394
commit fbd997e8bc
2 changed files with 50 additions and 13 deletions
+1
View File
@@ -288,6 +288,7 @@
#define FO_VAR_wmBkWinBuf 0x51DE24
#define FO_VAR_wmEncounterIconShow 0x672E48
#define FO_VAR_wmLastRndTime 0x51DEA0
#define FO_VAR_wmMaxAreaNum 0x51DDFC
#define FO_VAR_wmMaxMapNum 0x51DE10
#define FO_VAR_wmMaxTileNum 0x51DDF0
#define FO_VAR_wmMsgFile 0x672FB0
+49 -13
View File
@@ -329,6 +329,30 @@ skip:
}
}
static bool customPosition = false;
static void __declspec(naked) main_load_new_hook() {
__asm {
call fo::funcoffs::map_load_;
push -1;
mov edx, esp;
mov eax, dword ptr ds:[FO_VAR_map_number];
call fo::funcoffs::wmMatchAreaContainingMapIdx_;
pop eax; // area ID
cmp customPosition, 0;
jnz skip;
jmp fo::funcoffs::wmTeleportToArea_;
skip:
test eax, eax;
js end;
cmp eax, dword ptr ds:[FO_VAR_wmMaxAreaNum];
jge end;
mov dword ptr ds:[FO_VAR_WorldMapCurrArea], eax;
end:
retn;
}
}
static void RestRestore() {
if (!restMode) return;
restMode = false;
@@ -462,34 +486,46 @@ static void StartingStatePatches() {
dlogr(" Done", DL_INIT);
}
date = IniReader::GetConfigInt("Misc", "StartXPos", -1);
if (date != -1) {
long xPos = IniReader::GetConfigInt("Misc", "StartXPos", -1);
if (xPos != -1) {
if (xPos < 0) xPos = 0;
dlog("Applying starting x position patch.", DL_INIT);
SafeWrite32(0x4BC990, date);
SafeWrite32(0x4BCC08, date);
SafeWrite32(0x4BC990, xPos);
SafeWrite32(0x4BCC08, xPos);
dlogr(" Done", DL_INIT);
customPosition = true;
}
date = IniReader::GetConfigInt("Misc", "StartYPos", -1);
if (date != -1) {
long yPos = IniReader::GetConfigInt("Misc", "StartYPos", -1);
if (yPos != -1) {
if (yPos < 0) yPos = 0;
dlog("Applying starting y position patch.", DL_INIT);
SafeWrite32(0x4BC995, date);
SafeWrite32(0x4BCC0D, date);
SafeWrite32(0x4BC995, yPos);
SafeWrite32(0x4BCC0D, yPos);
dlogr(" Done", DL_INIT);
customPosition = true;
}
ViewportX = IniReader::GetConfigInt("Misc", "ViewXPos", -1);
if (ViewportX != -1) {
// Fix the starting position of the player's marker on the world map when starting a new game
// also initialize the value of the current area for METARULE_CURRENT_TOWN metarule function
HookCall(0x480DC0, main_load_new_hook);
xPos = IniReader::GetConfigInt("Misc", "ViewXPos", -1);
if (xPos != -1) {
if (xPos < 0) xPos = 0;
ViewportX = xPos;
dlog("Applying starting x view patch.", DL_INIT);
SafeWrite32(FO_VAR_wmWorldOffsetX, ViewportX);
dlogr(" Done", DL_INIT);
}
ViewportY = IniReader::GetConfigInt("Misc", "ViewYPos", -1);
if (ViewportY != -1) {
yPos = IniReader::GetConfigInt("Misc", "ViewYPos", -1);
if (yPos != -1) {
if (yPos < 0) yPos = 0;
ViewportY = yPos;
dlog("Applying starting y view patch.", DL_INIT);
SafeWrite32(FO_VAR_wmWorldOffsetY, ViewportY);
dlogr(" Done", DL_INIT);
}
if (ViewportX != -1 || ViewportY != -1) HookCall(0x4BCF07, ViewportHook); // game_reset_
if (xPos != -1 || yPos != -1) HookCall(0x4BCF07, ViewportHook); // game_reset_
}
static void PipBoyAutomapsPatch() {