Compare commits

...
Author SHA1 Message Date
Mike Klaas d53c6916a9 [Et tu] Add world map travel timing 2026-07-26 15:43:33 -07:00
4 changed files with 45 additions and 1 deletions
+4
View File
@@ -48,6 +48,10 @@ The following settings were moved into [`<DAT>/config/game.cfg`](files/ce.dat/co
| `Misc` | `ViewXPos` | `start` | `worldmap_view_x` |
| `Misc` | `ViewYPos` | `start` | `worldmap_view_y` |
| `Misc` | `StartGDialogFix` | `dialog` | `start_gdialog_fix` |
| `Misc` | `WorldMapFPSPatch` + `WorldMapDelay2` | `worldmap` | `travel_delay` |
Unlike sfall, `travel_delay` throttles only world-map travel simulation. Input,
rendering, and world-map scripts continue at the normal frame rate.
## Opcodes / Metarules
+2
View File
@@ -118,6 +118,8 @@ repair=293
[worldmap]
; Set to 1 to prevent using number keys to enter unvisited areas on a town map.
town_map_hotkeys_fix=1
; Milliseconds between world map travel updates (1-150). Set to 0 to update every rendered frame.
travel_delay=0
; Set to 1 to show travel markers on the world map, or 2 to show only when sneaking.
trail_markers=0
; Set to 1 to skip the encounter with Frank Horrigan.
+12
View File
@@ -1,5 +1,6 @@
#include "game_config_migration.h"
#include <algorithm>
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -262,6 +263,17 @@ static bool contentConfigMigrateFromSfall(Config* sfallConfig, const char* conte
}
bool migrated = false;
bool worldMapFpsPatch;
if (configGetBool(sfallConfig, kSfallMisc, "WorldMapFPSPatch", &worldMapFpsPatch)
&& worldMapFpsPatch) {
int travelDelay = 66;
configGetInt(sfallConfig, kSfallMisc, "WorldMapDelay2", &travelDelay);
travelDelay = std::clamp(travelDelay, 1, 150);
configSetInt(&migratedConfig, CONTENT_CONFIG_WORLDMAP_SECTION, "travel_delay", travelDelay);
migrated = true;
}
// Migrate start year/month/day only when explicitly set (not the sfall -1 sentinel).
auto migrateStartInt = [&](const char* sfallKey, const char* targetKey, int defaultValue) {
int value;
+27 -1
View File
@@ -541,6 +541,7 @@ static bool wmGameTimeIncrement(int ticksToAdd);
static int wmGrabTileWalkMask(int tileIdx);
static bool wmWorldPosInvalid(int x, int y);
static void wmPartyInitWalking(int x, int y);
static bool wmTravelTickDue(unsigned int now);
static void wmPartyWalkingStep();
static void wmInterfaceScrollTabsStart(int delta);
static void wmInterfaceScrollTabsStop();
@@ -943,6 +944,8 @@ static FrmImage _townFrmImage;
static bool wmFaded = false;
static int wmForceEncounterMapId = -1;
static unsigned int wmForceEncounterFlags = 0;
static int worldmapTravelDelay;
static unsigned int wmLastTravelTick;
static int worldmapTrailMarkers;
static inline bool cityIsValid(int city)
@@ -995,6 +998,8 @@ int wmWorldMap_init()
// SFALL
configGetBool(&gContentConfig, CONTENT_CONFIG_WORLDMAP_SECTION, "town_map_hotkeys_fix", &gTownMapHotkeysFix, true);
configGetInt(&gContentConfig, CONTENT_CONFIG_WORLDMAP_SECTION, "travel_delay", &worldmapTravelDelay, 0);
worldmapTravelDelay = std::clamp(worldmapTravelDelay, 0, 150);
configGetInt(&gContentConfig, CONTENT_CONFIG_WORLDMAP_SECTION, "trail_markers", &worldmapTrailMarkers, 0);
// CE: City size fids should be initialized during startup. They are used
@@ -3206,6 +3211,7 @@ static int wmWorldMapFunc(int a1)
unsigned int partyHealTime = 0;
int map = -1;
int rc = 0;
wmLastTravelTick = getTicks();
while (true) {
sharedFpsLimiter.mark();
@@ -3237,7 +3243,7 @@ static int wmWorldMapFunc(int a1)
int mouseEvent = mouseGetEvent();
if (wmGenData.isWalking) {
if (wmGenData.isWalking && wmTravelTickDue(now)) {
wmPartyWalkingStep();
if (wmGenData.isInCar) {
@@ -4546,6 +4552,7 @@ static void wmPartyInitWalking(int x, int y)
wmGenData.walkDestinationY = y;
wmGenData.currentAreaId = -1;
wmGenData.isWalking = true;
wmLastTravelTick = getTicks();
int dx = abs(x - wmGenData.worldPosX);
int dy = abs(y - wmGenData.worldPosY);
@@ -4585,6 +4592,25 @@ static void wmPartyInitWalking(int x, int y)
}
}
static bool wmTravelTickDue(unsigned int now)
{
if (worldmapTravelDelay == 0) {
return true;
}
if (getTicksBetween(now, wmLastTravelTick) < worldmapTravelDelay) {
return false;
}
wmLastTravelTick += worldmapTravelDelay;
if (getTicksBetween(now, wmLastTravelTick) >= worldmapTravelDelay) {
// Drop accumulated ticks after a stall instead of advancing in bursts.
wmLastTravelTick = now;
}
return true;
}
// 0x4C1F90 wmPartyWalkingStep
static void wmPartyWalkingStep()
{