mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Implemented drawing red dots while traveling on the world map
(from rotators/Fo1in2#3 by ghost22238)
This commit is contained in:
+4
-1
@@ -1,5 +1,5 @@
|
||||
;sfall configuration settings
|
||||
;v4.2.2
|
||||
;v4.2.3
|
||||
|
||||
[Main]
|
||||
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
||||
@@ -119,6 +119,9 @@ ExpandWorldMap=0
|
||||
;The minimum supported version of High Resolution Patch is 4.1.8
|
||||
ActionPointsBar=0
|
||||
|
||||
;Set to 1 to enable drawing a dotted line when moving around on the world map (similar to Fallout 1)
|
||||
WorldTravelMarkers=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Input]
|
||||
;Set to 1 to enable the mouse scroll wheel to scroll through the inventory, barter, and loot screens
|
||||
|
||||
@@ -239,6 +239,7 @@
|
||||
#define FO_VAR_wd_obj 0x59E98C
|
||||
#define FO_VAR_window 0x6ADE58
|
||||
#define FO_VAR_wmAreaInfoList 0x51DDF8
|
||||
#define FO_VAR_wmBkWinBuf 0x51DE24
|
||||
#define FO_VAR_wmLastRndTime 0x51DEA0
|
||||
#define FO_VAR_wmMaxMapNum 0x51DE10
|
||||
#define FO_VAR_wmMaxTileNum 0x51DDF0
|
||||
|
||||
@@ -212,8 +212,8 @@ VAR_(wmMaxTileNum, DWORD)
|
||||
VAR_(wmNumHorizontalTiles, DWORD)
|
||||
VAR_(wmViewportRightScrlLimit, DWORD)
|
||||
VAR_(wmViewportBottomtScrlLimit, DWORD)
|
||||
VAR_(wmWorldOffsetX, DWORD)
|
||||
VAR_(wmWorldOffsetY, DWORD)
|
||||
VAR_(wmWorldOffsetX, long)
|
||||
VAR_(wmWorldOffsetY, long)
|
||||
VAR_(world_xpos, DWORD)
|
||||
VAR_(world_ypos, DWORD)
|
||||
VAR_(WorldMapCurrArea, DWORD)
|
||||
|
||||
@@ -186,6 +186,8 @@ static void __declspec(naked) wmInterfaceInit_text_font_hook() {
|
||||
static DWORD wmTownMapSubButtonIds[WMAP_TOWN_BUTTONS + 1]; // replace _wmTownMapSubButtonIds (index 0 - unused element)
|
||||
static int worldmapInterface;
|
||||
static long wmapWinWidth = 640;
|
||||
static long wmapViewPortWidth = 450;
|
||||
static long wmapViewPortHeight = 443;
|
||||
|
||||
// Window width
|
||||
static const DWORD wmWinWidth[] = {
|
||||
@@ -400,9 +402,11 @@ static void WorldmapViewportPatch() {
|
||||
0x4C4157, 0x4C415F, // wmInterfaceDrawSubTileList_
|
||||
});
|
||||
// right limit of the viewport (450)
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_WIDTH - (640 - 450), wmViewportEndRight); // 890 - 190 = 700 + 22 = 722
|
||||
wmapViewPortWidth = WMAP_WIN_WIDTH - (640 - 450); // 890 - 190 = 700 + 22 = 722
|
||||
SafeWriteBatch<DWORD>(wmapViewPortWidth, wmViewportEndRight);
|
||||
// bottom limit of the viewport (443)
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_HEIGHT - (480 - 443), wmViewportEndBottom); // 720 - 37 = 683 + 21 = 704
|
||||
wmapViewPortHeight = WMAP_WIN_HEIGHT - (480 - 443); // 720 - 37 = 683 + 21 = 704
|
||||
SafeWriteBatch<DWORD>(wmapViewPortHeight, wmViewportEndBottom);
|
||||
|
||||
// Night/Day frm (wmRefreshInterfaceDial_)
|
||||
SafeWrite32(0x4C577F, WMAP_WIN_WIDTH - (640 - 532)); // X offset (532)
|
||||
@@ -455,6 +459,84 @@ static void WorldmapViewportPatch() {
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
struct DotPosition {
|
||||
long x;
|
||||
long y;
|
||||
};
|
||||
static std::vector<DotPosition> dots;
|
||||
|
||||
static long spaceLen = 2;
|
||||
static long dotLen = 1;
|
||||
static long dot_xpos = 0;
|
||||
static long dot_ypos = 0;
|
||||
|
||||
static void AddNewDot() {
|
||||
dot_xpos = fo::var::world_xpos;
|
||||
dot_ypos = fo::var::world_ypos;
|
||||
|
||||
if (dotLen <= 0 && spaceLen) {
|
||||
spaceLen--;
|
||||
if (!spaceLen) dotLen = 1; // set dot length
|
||||
return;
|
||||
}
|
||||
dotLen--;
|
||||
|
||||
DotPosition dot;
|
||||
dot.x = dot_xpos;
|
||||
dot.y = dot_ypos;
|
||||
dots.push_back(std::move(dot));
|
||||
|
||||
spaceLen = 2;
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmInterfaceRefresh_hook() {
|
||||
long x_offset, y_offset;
|
||||
__asm {
|
||||
pushad;
|
||||
mov ebp, esp; // prolog
|
||||
sub esp, __LOCAL_SIZE;
|
||||
}
|
||||
|
||||
if ((fo::var::target_xpos || fo::var::target_ypos) && (dot_xpos != fo::var::world_xpos || dot_ypos != fo::var::world_ypos)) {
|
||||
AddNewDot();
|
||||
}
|
||||
x_offset = 22 - fo::var::wmWorldOffsetX;
|
||||
y_offset = 21 - fo::var::wmWorldOffsetY;
|
||||
|
||||
for (const auto &dot : dots) { // redraws all dots
|
||||
if (dot.x < fo::var::wmWorldOffsetX || dot.y < fo::var::wmWorldOffsetY) continue; // the pixel is out of viewport
|
||||
if (dot.x > fo::var::wmWorldOffsetX + wmapViewPortWidth || dot.y > fo::var::wmWorldOffsetY + wmapViewPortHeight) continue;
|
||||
|
||||
long wmPixelX = (dot.x + x_offset);
|
||||
long wmPixelY = (dot.y + y_offset);
|
||||
|
||||
wmPixelY *= wmapWinWidth;
|
||||
|
||||
BYTE* wmWinBuf = *(BYTE**)FO_VAR_wmBkWinBuf;
|
||||
BYTE* wmWinBuf_xy = (wmPixelY + wmPixelX) + wmWinBuf;
|
||||
|
||||
// put pixel to interface window buffer
|
||||
if (wmWinBuf_xy > wmWinBuf) *wmWinBuf_xy = 133; // index color in palette: R = 252, G = 0, B = 0
|
||||
|
||||
// TODO: fix dots for car travel
|
||||
}
|
||||
|
||||
__asm {
|
||||
mov esp, ebp; // epilog
|
||||
popad;
|
||||
jmp fo::funcoffs::wmInterfaceDrawSubTileList_;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmInterfaceRefresh_hook_stop() {
|
||||
if (!fo::var::target_xpos && !fo::var::target_ypos) {
|
||||
dots.clear();
|
||||
dotLen = 1;
|
||||
spaceLen = 2;
|
||||
}
|
||||
__asm jmp fo::funcoffs::wmDrawCursorStopped_;
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmInterfaceRefreshCarFuel_hack_empty() {
|
||||
__asm {
|
||||
mov byte ptr [eax - 1], 13;
|
||||
@@ -481,6 +563,8 @@ static void __declspec(naked) wmInterfaceRefreshCarFuel_hack() {
|
||||
}
|
||||
|
||||
static void WorldMapInterfacePatch() {
|
||||
BlockCall(0x4C2380); // Remove disabling palette animations (can be used as a place to call a hack function in wmInterfaceInit_)
|
||||
|
||||
if (GetConfigInt("Misc", "WorldMapFontPatch", 0)) {
|
||||
dlog("Applying world map font patch.", DL_INIT);
|
||||
HookCall(0x4C2343, wmInterfaceInit_text_font_hook);
|
||||
@@ -514,6 +598,16 @@ static void WorldMapInterfacePatch() {
|
||||
LoadGameHook::OnAfterGameInit() += WorldmapViewportPatch; // Note: must be applied after WorldMapSlots patch
|
||||
}
|
||||
}
|
||||
|
||||
if (GetConfigInt("Interface", "WorldTravelMarkers", 0)) {
|
||||
HookCall(0x4C3BE6, wmInterfaceRefresh_hook); // when calling wmInterfaceDrawSubTileList_
|
||||
HookCall(0x4C3C7E, wmInterfaceRefresh_hook_stop);
|
||||
dots.reserve(512);
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
dots.clear();
|
||||
};
|
||||
}
|
||||
|
||||
// Car fuel gauge graphics patch
|
||||
MakeCall(0x4C528A, wmInterfaceRefreshCarFuel_hack_empty);
|
||||
MakeCall(0x4C529E, wmInterfaceRefreshCarFuel_hack);
|
||||
|
||||
@@ -664,7 +664,7 @@ void MiscPatches::init() {
|
||||
}
|
||||
|
||||
// Increase the max text width of the information card in the character screen
|
||||
SafeWriteBatch<BYTE>(144, {0x43ACD5, 0x43DD37}); // 136, 133
|
||||
SafeWriteBatch<BYTE>(145, {0x43ACD5, 0x43DD37}); // 136, 133
|
||||
|
||||
F1EngineBehaviorPatch();
|
||||
DialogueFix();
|
||||
|
||||
@@ -410,7 +410,7 @@ void WorldmapFpsPatch() {
|
||||
if (GetConfigInt("Misc", "WorldMapEncounterFix", 0)) {
|
||||
dlog("Applying world map encounter patch.", DL_INIT);
|
||||
WorldMapEncounterRate = GetConfigInt("Misc", "WorldMapEncounterRate", 5);
|
||||
SafeWrite32(0x4C232D, 0x01EBC031); // xor eax, eax; jmps 0x4C2332 (wmInterfaceInit_)
|
||||
SafeWrite32(0x4C232D, 0xB8); // mov eax, 0; (wmInterfaceInit_)
|
||||
HookCall(0x4BFEE0, wmWorldMapFunc_hook);
|
||||
MakeCall(0x4C0667, wmRndEncounterOccurred_hack);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
Reference in New Issue
Block a user