From 52db1af01014df532884075564e34b44cb0bf2f1 Mon Sep 17 00:00:00 2001 From: Alistair-Afton Date: Wed, 16 Sep 2026 01:30:31 +0200 Subject: [PATCH] questport, reveal-adv-map: fix for current viewscreen_adventure_logst The quest log's cursor, player position, and map bounds moved into the map_display compound, so both scripts crashed reading the removed top-level fields. Also fixes two latent porting bugs in questport: travel-mode movement needs A_MOVE_* keys rather than CURSOR_*, and `not travel_not_moved` on a numeric flag is always false in Lua, which left the relocate-existing-army branch unreachable. Fixes DFHack/dfhack#5894 --- changelog.txt | 2 ++ docs/questport.rst | 5 +++-- questport.lua | 19 +++++++++++++------ reveal-adv-map.lua | 15 ++++++++------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/changelog.txt b/changelog.txt index 1ed30ae501..36f8fa590e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,6 +33,8 @@ Template for new versions: ## New Features ## Fixes +- `questport`: fix crash on current DF versions and make the teleport actually move the player in fast travel +- `reveal-adv-map`: fix live quest log map update when revealing or hiding the map - `bodyswap`: fix "invalid argument count" when the target unit has no nemesis record - `fix/loyaltycascade`: guard against citizens that are not historical figures and emit a warning. - `gui/siegemanager`: fix nil index if there are no siege engines on the map diff --git a/docs/questport.rst b/docs/questport.rst index 6d937895e5..1af0cc583a 100644 --- a/docs/questport.rst +++ b/docs/questport.rst @@ -3,12 +3,13 @@ questport .. dfhack-tool:: :summary: Teleport to your quest log map cursor. - :tags: unavailable + :tags: adventure armok map If you open the quest log map and move the cursor to your target location, you can run this command to teleport straight there. This can be done both within and outside of fast travel mode, and it is possible to ``questport`` in -situations where fast travel is normally prohibited. +situations where fast travel is normally prohibited. The quest log map must be +zoomed out to the world map when running this command. It is not possible to ``questport`` into inaccessible locations like ocean and mountain tiles. diff --git a/questport.lua b/questport.lua index d43702860c..cdf43e1e4b 100644 --- a/questport.lua +++ b/questport.lua @@ -7,7 +7,7 @@ local function processTravelNoArmy(advmode, advScreen, target_x, target_y) gui.simulateInput(advScreen.child, 'LEAVESCREEN') -- close map gui.simulateInput(advScreen.child, 'LEAVESCREEN') -- close log advmode.site_level_zoom = 1 -- zoom in to shrink the following travel movement, reducing the risk of failure - gui.simulateInput(advScreen, 'CURSOR_DOWN') -- the player army is only created once the player moves in travel mode; ensure that this movement occurs as the player will otherwise find themselves at their original location if they end travel mode immediately + gui.simulateInput(advScreen, 'A_MOVE_S') -- the player army is only created once the player moves in travel mode; ensure that this movement occurs as the player will otherwise find themselves at their original location if they end travel mode immediately -- note: the above movement may be blocked by an impassable tile (especially if trying to teleport into a mountain range); it would be more ideal to create and move the player army directly instead end @@ -20,9 +20,14 @@ local advScreen = dfhack.gui.getViewscreenByType(df.viewscreen_dungeonmodest, 0) local questMap = dfhack.gui.getViewscreenByType(df.viewscreen_adventure_logst, 0) or qerror("You must first select your destination on the quest log map!") -local target_x = questMap.cursor.x -local target_y = questMap.cursor.y -if questMap.player_region.x == target_x and questMap.player_region.y == target_y then +local mapDisplay = questMap.map_display +if mapDisplay.midmap ~= 0 or mapDisplay.localmap ~= 0 then + qerror("Please zoom the quest log map out to the world map!") +end + +local target_x = mapDisplay.cursor.x +local target_y = mapDisplay.cursor.y +if mapDisplay.cur_loc.x == target_x and mapDisplay.cur_loc.y == target_y then qerror("You already seem to be at the target location!") end @@ -38,8 +43,8 @@ if advmode.menu == df.ui_advmode_menu.Default then processTravelNoArmy(advmode, advScreen, target_x, target_y) elseif advmode.menu == df.ui_advmode_menu.Travel then - if not advmode.travel_not_moved then -- player is already moving in fast travel mode; just relocate the player army - local army = df.army.find(advmode.player_army_id) + local army = df.army.find(advmode.player_army_id) + if advmode.travel_not_moved == 0 and army then -- player is already moving in fast travel mode; just relocate the player army army.pos.x = target_x army.pos.y = target_y gui.simulateInput(advScreen.child, 'LEAVESCREEN') -- close map @@ -47,4 +52,6 @@ elseif advmode.menu == df.ui_advmode_menu.Travel then else -- player has opened travel mode but hasn't moved yet, so the player army hasn't been created processTravelNoArmy(advmode, advScreen, target_x, target_y) end +else + qerror("Please close the open menu before questporting!") end diff --git a/reveal-adv-map.lua b/reveal-adv-map.lua index e99cae9dc8..50cbf2394d 100644 --- a/reveal-adv-map.lua +++ b/reveal-adv-map.lua @@ -12,15 +12,16 @@ function revealAdvMap(hide) -- update the quest log configuration if it is already open (restricts map cursor movement): local view = dfhack.gui.getDFViewscreen(true) if view._type == df.viewscreen_adventure_logst then - local player = view.player_region + local mapDisplay = view.map_display + local player = mapDisplay.cur_loc if hide then - view.cursor.x = player.x - view.cursor.y = player.y + mapDisplay.cursor.x = player.x + mapDisplay.cursor.y = player.y end - view.min_discovered.x = (hide and player.x) or 0 - view.min_discovered.y = (hide and player.y) or 0 - view.max_discovered.x = (hide and player.x) or world.world_width - 1 - view.max_discovered.y = (hide and player.y) or world.world_height - 1 + mapDisplay.min.x = (hide and player.x) or 0 + mapDisplay.min.y = (hide and player.y) or 0 + mapDisplay.max.x = (hide and player.x) or world.world_width - 1 + mapDisplay.max.y = (hide and player.y) or world.world_height - 1 end end