-- Export everything from legends mode --[[=begin exportlegends ============= Controls legends mode to export data - especially useful to set-and-forget large worlds, or when you want a map of every site when there are several hundred. 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: :info: Exports the world/gen info, the legends XML, and a custom XML with more information :sites: Exports all available site maps :maps: Exports all seventeen detailed maps :all: Equivalent to calling all of the above, in that order =end]] gui = require 'gui' local args = {...} local vs = dfhack.gui.getCurViewscreen() local i = 1 local MAPS = { "Standard biome+site map", "Elevations including lake and ocean floors", "Elevations respecting water level", "Biome", "Hydrosphere", "Temperature", "Rainfall", "Drainage", "Savagery", "Volcanism", "Current vegetation", "Evil", "Salinity", "Structures/fields/roads/etc.", "Trade", "Nobility and Holdings", "Diplomacy", } function getItemSubTypeName(itemType, subType) if (dfhack.items.getSubtypeCount(itemType)) <= 0 then return tostring(-1) end local subtypename = dfhack.items.getSubtypeDef(itemType, subType) if (subtypename == nil) then return tostring(-1) else return tostring(subtypename.name):lower() end end function findEntity(id) for k,v in ipairs(df.global.world.entities.all) do if (v.id == id) then return v end end return nil end function table.contains(table, element) for _, value in pairs(table) do if value == element then return true end end return false end function table.containskey(table, key) for value, _ in pairs(table) do if value == key then return true end end return false end --create an extra legends xml with extra data, by Mason11987 for World Viewer 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 filename = df.global.world.cur_savegame.save_dir.."-"..date_str.."-legends_plus.xml" local file = io.open(filename, 'w') if not file then qerror("could not open file: " .. filename) end file:write("\n") file:write("\n") file:write(""..dfhack.df2utf(dfhack.TranslateName(df.global.world.world_data.name)).."\n") file:write(""..dfhack.df2utf(dfhack.TranslateName(df.global.world.world_data.name,1)).."\n") file:write("\n") for regionK, regionV in ipairs(df.global.world.world_data.regions) do file:write("\t\n") file:write("\t\t"..regionV.index.."\n") file:write("\t\t") for xK, xVal in ipairs(regionV.region_coords.x) do file:write(xVal..","..regionV.region_coords.y[xK].."|") end file:write("\n") file:write("\t\n") end file:write("\n") file:write("\n") for regionK, regionV in ipairs(df.global.world.world_data.underground_regions) do file:write("\t\n") file:write("\t\t"..regionV.index.."\n") file:write("\t\t") for xK, xVal in ipairs(regionV.region_coords.x) do file:write(xVal..","..regionV.region_coords.y[xK].."|") end file:write("\n") file:write("\t\n") end file:write("\n") file:write("\n") for siteK, siteV in ipairs(df.global.world.world_data.sites) do if (#siteV.buildings > 0) then file:write("\t\n") for k,v in pairs(siteV) do if (k == "id") then file:write("\t\t<"..k..">"..tostring(v).."\n") elseif (k == "buildings") then file:write("\t\t\n") for buildingK, buildingV in ipairs(siteV.buildings) do file:write("\t\t\t\n") file:write("\t\t\t\t"..buildingV.id.."\n") file:write("\t\t\t\t"..df.abstract_building_type[buildingV:getType()]:lower().."\n") if (df.abstract_building_type[buildingV:getType()]:lower() ~= "underworld_spire") then file:write("\t\t\t\t"..dfhack.df2utf(dfhack.TranslateName(buildingV.name, 1)).."\n") file:write("\t\t\t\t"..dfhack.df2utf(dfhack.TranslateName(buildingV.name)).."\n") end file:write("\t\t\t\n") end file:write("\t\t\n") end end file:write("\t\n") end end file:write("\n") file:write("\n") for wcK, wcV in ipairs(df.global.world.world_data.constructions.list) do file:write("\t\n") file:write("\t\t"..wcV.id.."\n") file:write("\t\t"..dfhack.df2utf(dfhack.TranslateName(wcV.name,1)).."\n") file:write("\t\t"..(df.world_construction_type[wcV:getType()]):lower().."\n") file:write("\t\t") for xK, xVal in ipairs(wcV.square_pos.x) do file:write(xVal..","..wcV.square_pos.y[xK].."|") end file:write("\n") file:write("\t\n") end file:write("\n") file:write("\n") for artifactK, artifactV in ipairs(df.global.world.artifacts.all) do file:write("\t\n") file:write("\t\t"..artifactV.id.."\n") if (artifactV.item:getType() ~= -1) then file:write("\t\t"..tostring(df.item_type[artifactV.item:getType()]):lower().."\n") if (artifactV.item:getSubtype() ~= -1) then file:write("\t\t"..artifactV.item.subtype.name.."\n") end end if (table.containskey(artifactV.item,"description")) then file:write("\t\t"..dfhack.df2utf(artifactV.item.description:lower()).."\n") end if (artifactV.item:getMaterial() ~= -1 and artifactV.item:getMaterialIndex() ~= -1) then file:write("\t\t"..dfhack.matinfo.toString(dfhack.matinfo.decode(artifactV.item:getMaterial(), artifactV.item:getMaterialIndex())).."\n") end file:write("\t\n") end file:write("\n") file:write("\n\n") file:write("\n") for entityPopK, entityPopV in ipairs(df.global.world.entity_populations) do file:write("\t\n") file:write("\t\t"..entityPopV.id.."\n") for raceK, raceV in ipairs(entityPopV.races) do local raceName = (df.global.world.raws.creatures.all[raceV].creature_id):lower() file:write("\t\t"..raceName..":"..entityPopV.counts[raceK].."\n") end file:write("\t\t"..entityPopV.civ_id.."\n") file:write("\t\n") end file:write("\n") file:write("\n") for entityK, entityV in ipairs(df.global.world.entities.all) do file:write("\t\n") file:write("\t\t"..entityV.id.."\n") if entityV.race >= 0 then file:write("\t\t"..(df.global.world.raws.creatures.all[entityV.race].creature_id):lower().."\n") end file:write("\t\t"..(df.historical_entity_type[entityV.type]):lower().."\n") if entityV.type == df.historical_entity_type.Religion then -- Get worshipped figure if (entityV.unknown1b ~= nil and entityV.unknown1b.worship ~= nil and #entityV.unknown1b.worship == 1) then file:write("\t\t"..entityV.unknown1b.worship[0].."\n") else print(entityV.unknown1b, entityV.unknown1b.worship, #entityV.unknown1b.worship) end end for id, link in pairs(entityV.entity_links) do file:write("\t\t\n") for k, v in pairs(link) do if (k == "type") then file:write("\t\t\t<"..k..">"..tostring(df.entity_entity_link_type[v]).."\n") else file:write("\t\t\t<"..k..">"..v.."\n") end end file:write("\t\t\n") end for id, link in ipairs(entityV.children) do file:write("\t\t"..link.."\n") end file:write("\t\n") end file:write("\n") file:write("\n") for formK, formV in ipairs(df.global.world.poetic_forms.all) do for k,v in pairs(formV) do print(k,v) end file:write("\t\n") file:write("\t\t"..formV.id.."\n") file:write("\t\t"..dfhack.df2utf(dfhack.TranslateName(formV.name,1)).."\n") file:write("\t\n") end file:write("\n") file:write("\n") for formK, formV in ipairs(df.global.world.poetic_forms.all) do file:write("\t\n") file:write("\t\t"..formV.id.."\n") file:write("\t\t"..dfhack.df2utf(dfhack.TranslateName(formV.name,1)).."\n") file:write("\t\n") end file:write("\n") file:write("\n") for formK, formV in ipairs(df.global.world.dance_forms.all) do file:write("\t\n") file:write("\t\t"..formV.id.."\n") file:write("\t\t"..dfhack.df2utf(dfhack.TranslateName(formV.name,1)).."\n") file:write("\t\n") end file:write("\n") file:write("\n") for wcK, wcV in ipairs(df.global.world.written_contents.all) do file:write("\t\n") file:write("\t\t"..wcV.id.."\n") file:write("\t\t"..wcV.title.."\n") file:write("\t\t"..wcV.page_start.."\n") file:write("\t\t"..wcV.page_end.."\n") for refK, refV in pairs(wcV.refs) do file:write("\t\t\n") file:write("\t\t\t"..df.general_ref_type[refV:getType()].."\n") if refV:getType() == 64 then file:write("\t\t\t"..refV.anon_1.."\n") -- written content elseif refV:getType() == 0 then file:write("\t\t\t"..refV.artifact_id.."\n") -- artifact elseif refV:getType() == 42 then file:write("\t\t\t"..refV.entity_id.."\n") -- entity elseif refV:getType() == 49 then file:write("\t\t\t"..refV.event_id.."\n") -- event elseif refV:getType() == 51 then file:write("\t\t\t"..refV.site_id.."\n") -- site elseif refV:getType() == 52 then file:write("\t\t\t"..refV.region_id.."\n") -- region elseif refV:getType() == 54 then file:write("\t\t\t"..refV.hist_figure_id.."\n") -- hist figure elseif refV:getType() == 65 then file:write("\t\t\t"..refV.poetic_form_id.."\n") -- poetic form elseif refV:getType() == 66 then file:write("\t\t\t"..refV.musical_form_id.."\n") -- musical form elseif refV:getType() == 67 then file:write("\t\t\t"..refV.dance_form_id.."\n") -- dance form elseif refV:getType() == 47 then -- TODO interaction elseif refV:getType() == 60 then -- TODO scholar knowledge elseif refV:getType() == 62 then -- TODO value level elseif refV:getType() == 63 then -- TODO language else print("unknown reference",refV:getType(),df.general_ref_type[refV:getType()]) --for k,v in pairs(refV) do print(k,v) end end file:write("\t\t\n") end file:write("\t\t"..(df.written_content_type[wcV.type] or wcV.type).."\n") for styleK, styleV in pairs(wcV.styles) do file:write("\t\t