diff --git a/changelog.txt b/changelog.txt
index a1bdf3bc6e..38c1e26c9c 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -30,6 +30,7 @@ that repo.
- `digfort`: documented that removing ramps, cutting trees, and gathering plants are indeed supported
- `exportlegends`: changed some flags to be represented by self-closing tags instead of true/false strings (e.g. ````) - note that this may require changes to other XML-parsing utilities
- `exportlegends`: changed some enum values from numbers to their string representations
+- `exportlegends`: added ability to save all files to a subfolder, named after the region folder and date by default
- `gui/advfort`: added support for specifying the entity used to determine available resources
- `gui/gm-editor`: added support for automatically following ref-targets when pressing the ``i`` key
- `modtools/moddable-gods`: added support for ``neuter`` gender
diff --git a/exportlegends.lua b/exportlegends.lua
index 8403d6e03f..4ab088537b 100644
--- a/exportlegends.lua
+++ b/exportlegends.lua
@@ -10,7 +10,11 @@ The 'info' option exports more data than is possible in vanilla, to a
:file:`region-date-legends_plus.xml` file developed to extend
:forums:`World Viewer <128932>` and other legends utilities.
-Options:
+Usage::
+
+ exportlegends OPTION [FOLDER_NAME]
+
+Valid values for ``OPTION`` are:
:info: Exports the world/gen info, the legends XML, and a custom XML with more information
:custom: Exports a custom XML with more information
@@ -18,15 +22,41 @@ Options:
:maps: Exports all seventeen detailed maps
:all: Equivalent to calling all of the above, in that order
+``FOLDER_NAME``, if specified, is the name of the folder where all the files
+will be saved. This defaults to the ``regionX-YYYYY-MM-DD`` format. A path is
+also allowed, although everything but the last folder has to exist. To export
+to the top-level DF folder, pass ``.`` for this argument.
+
+Examples:
+
+* Export all information to the ``regionX-YYYYY-MM-DD`` folder::
+
+ exportlegends all
+
+* Export all information to the ``region6`` folder::
+
+ exportlegends all region6
+
+* Export just the files included in ``info`` (above) to the ``regionX-YYYYY-MM-DD`` folder::
+
+ exportlegends info
+
+* Export just the custom XML file to the DF folder (no subfolder)::
+
+ exportlegends custom .
+
]====]
--luacheck-flags: strictsubtype
+-- General note: If you are looking for main function look at the buttom of this script file.
+
local gui = require 'gui'
local script = require 'gui.script'
local args = {...}
local vs = dfhack.gui.getCurViewscreen()
+-- List of all the detailed maps
local MAPS = {
"Standard biome+site map",
"Elevations including lake and ocean floors",
@@ -47,6 +77,31 @@ local MAPS = {
"Diplomacy",
}
+-- Get that date of the world as a string
+-- Format: "YYYYY-MM-DD"
+function get_world_date_str()
+ local month = dfhack.world.ReadCurrentMonth() + 1 --days and months are 1-indexed
+ local day = dfhack.world.ReadCurrentDay()
+ local year_str = string.format('%0'..math.max(5, string.len(''..df.global.cur_year))..'d', df.global.cur_year)
+ local date_str = year_str..string.format('-%02d-%02d', month, day)
+ return date_str
+end
+
+-- Go back to root folder so dfhack does not break, returns true if successfully
+function move_back_to_main_folder()
+ return dfhack.filesystem.chdir(dfhack.getDFPath())
+end
+
+-- Set default folder name
+local folder_name = df.global.world.cur_savegame.save_dir.."-"..get_world_date_str()
+-- Go to save folder, returns true if successfully
+function move_to_save_folder()
+ if move_back_to_main_folder() then
+ return dfhack.filesystem.chdir(folder_name)
+ end
+ return false
+end
+
function getItemSubTypeName(itemType, subType)
if (dfhack.items.getSubtypeCount(itemType)) <= 0 then
return tostring(-1)
@@ -122,17 +177,20 @@ function printifvalue (file, indentation, tag, value)
end
end
---create an extra legends xml with extra data, by Mason11987 for World Viewer
+-- Export additional legends data, legends_plus.xml
function export_more_legends_xml()
- local month = dfhack.world.ReadCurrentMonth() + 1 --days and months are 1-indexed
- local day = dfhack.world.ReadCurrentDay()
- local year_str = string.format('%0'..math.max(5, string.len(''..df.global.cur_year))..'d', df.global.cur_year)
- local date_str = year_str..string.format('-%02d-%02d', month, day)
local problem_elements = {}
- local filename = df.global.world.cur_savegame.save_dir.."-"..date_str.."-legends_plus.xml"
+ -- Move into the save folder
+ if not move_to_save_folder() then
+ qerror('Could not move into the save folder.')
+ end
+ local filename = df.global.world.cur_savegame.save_dir.."-"..get_world_date_str().."-legends_plus.xml"
local file = io.open(filename, 'w')
- if not file then qerror("could not open file: " .. filename) end
+ move_back_to_main_folder()
+ if not file then
+ qerror("could not open file: " .. filename)
+ end
file:write("\n")
file:write("\n")
@@ -1003,45 +1061,87 @@ function export_more_legends_xml()
end
end
--- export information and XML ('p, x')
+-- Export world information and legends.xml (keys: 'p and x')
function export_legends_info()
+ -- Move into the save folder
+ if not move_to_save_folder() then
+ qerror('Could not move into the save folder.')
+ end
print(' Exporting: World map/gen info')
gui.simulateInput(vs, 'LEGENDS_EXPORT_MAP')
print(' Exporting: Legends xml')
gui.simulateInput(vs, 'LEGENDS_EXPORT_XML')
+ move_back_to_main_folder() -- Move back out of the save folder
print(" Exporting: Extra legends_plus xml")
export_more_legends_xml()
end
+-- Export all the detailed maps like biome and elevation maps. (key: 'd')
function export_detailed_maps()
- script.start(function()
- for i = 1, #MAPS do
- local vs = dfhack.gui.getViewscreenByType(df.viewscreen_export_graphical_mapst, 0)
- if not vs then
- local legends_vs = dfhack.gui.getViewscreenByType(df.viewscreen_legendsst, 0)
- or qerror("Could not find legends screen")
- gui.simulateInput(legends_vs, 'LEGENDS_EXPORT_DETAILED_MAP')
- end
+ script.start(
+ function()
+ -- When script is finished run `move_back_to_main_folder()`
+ dfhack.with_finalize(
+ -- Function when script is finished
+ function()
+ -- This makes sure it will always go back to the main folder.
+ -- Even if an error occurs
+ move_back_to_main_folder()
+ -- Make sure this is always printed even when error occurs.
+ print(" Done exporting.")
+ end,
+ -- Run script
+ function()
+ -- Loop over all the detailed maps and export them.
+ for i = 1, #MAPS do
+ -- Select the detailed map section
+ local vs = dfhack.gui.getViewscreenByType(df.viewscreen_export_graphical_mapst, 0)
+ if not vs then
+ local legends_vs = dfhack.gui.getViewscreenByType(df.viewscreen_legendsst, 0)
+ if not legends_vs then
+ qerror("Could not find legends screen")
+ end
+
+ gui.simulateInput(legends_vs, 'LEGENDS_EXPORT_DETAILED_MAP')
+ end
- vs = dfhack.gui.getViewscreenByType(df.viewscreen_export_graphical_mapst, 0)
- or qerror("Could not find map export screen")
- vs.sel_type = i - 1
- print(' Exporting map: ' .. MAPS[i])
- gui.simulateInput(vs, 'SELECT')
- while dfhack.gui.getCurViewscreen() == vs do
- script.sleep(10, 'frames')
+ vs = dfhack.gui.getViewscreenByType(df.viewscreen_export_graphical_mapst, 0)
+ if not vs then
+ qerror("Could not find map export screen")
+ end
+
+ vs.sel_type = i - 1
+ -- Move into the save folder
+ if not move_to_save_folder() then
+ qerror('Could not move into the save folder.')
+ end
+ print(' Exporting map ' ..i.. '/' ..#MAPS..': '.. MAPS[i])
+ -- Select the map and start exporting
+ gui.simulateInput(vs, 'SELECT')
+ -- Wait for the map to finish exporting
+ while dfhack.gui.getCurViewscreen() == vs do
+ script.sleep(10, 'frames')
+ end
+ -- Move back out of the save folder
+ move_back_to_main_folder()
+ end
end
+ )
end
- end)
+ )
end
--- export site maps
+-- Export the maps of all the sites (cities, towns,...) (key: 'sites', 'p')
function export_site_maps()
local vs = dfhack.gui.getCurViewscreen()
if ((dfhack.gui.getCurFocus() ~= "legends" ) and (not table_contains(vs, "main_cursor"))) then -- Using open-legends
vs = vs.parent --luacheck: retype
end
if df.viewscreen_legendsst:is_instance(vs) then
+ -- Move into the save folder
+ if not move_to_save_folder() then
+ qerror('Could not move into the save folder.')
+ end
print(' Exporting: All possible site maps')
vs.main_cursor = 1
gui.simulateInput(vs, 'SELECT')
@@ -1050,12 +1150,40 @@ function export_site_maps()
gui.simulateInput(vs, 'STANDARDSCROLL_DOWN')
end
gui.simulateInput(vs, 'LEAVESCREEN')
+ move_back_to_main_folder() -- Move back out of the save folder
else
qerror('this command can only be used in Legends mode')
end
end
--- main()
+-- Check if a folder with this name could be created or already exists
+function create_folder(folder_name)
+ if folder_name == "-00000-01-01" then
+ qerror('"'..folder_name..'" is the default foldername, this folder will not be created as you are probably not in the legends screen.')
+ end
+ -- check if it is a file, not a folder
+ if dfhack.filesystem.isfile(folder_name) then
+ qerror(folder_name..' is a file, not a folder')
+ end
+ if dfhack.filesystem.exists(folder_name) then
+ return true
+ else
+ return dfhack.filesystem.mkdir(folder_name)
+ end
+end
+
+-- If folder_name is given as a argument use that
+if #args >= 2 then
+ folder_name = args[2]
+end
+-- Create folder to export all files into, if possible.
+if not create_folder(folder_name) then
+ -- no valid folder name or could not create folder
+ qerror('The foldername '..folder_name..' could not be created')
+end
+print("Writing all files in: "..folder_name)
+
+-- Main: Check if on legends screen and trigger the correct export.
if dfhack.gui.getCurFocus() == "legends" or dfhack.gui.getCurFocus() == "dfhack/lua/legends" then
-- either native legends mode, or using the open-legends.lua script
if args[1] == "all" then
@@ -1078,3 +1206,5 @@ elseif args[1] == "maps" and dfhack.gui.getCurFocus() == "export_graphical_map"
else
qerror('exportlegends must be run from the main legends view')
end
+
+print("Exported files can be found in the \""..folder_name.."\" folder.")