Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Template for new versions:
## Fixes

## Misc Improvements
gui/export-world-map: more precise bridge coordinates
gui/export-world-map: export of bridge and road materials


## Removed

Expand Down
1 change: 0 additions & 1 deletion gui/export-world-map.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ local SELECTED_ICON = dfhack.pen.parse{ch=string.char(251), fg=COLOR_LIGHTGREEN}
local DISABLED_ICON = dfhack.pen.parse{ch='x', fg=COLOR_RED}

function ExportMap:getChoices()
print("getChoices")
local choices = {}
for _, export in ipairs(exports) do
table.insert(choices, {
Expand Down
94 changes: 72 additions & 22 deletions internal/export-world-map/export-roads.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,93 @@
local json = require('json')
local util = reqscript('internal/export-world-map/util')

local function getConstructionAndGeometryType(construction)
if df.world_construction_roadst:is_instance(construction) then
local constructions = df.global.world.world_data.constructions

local function getConstructionAndGeometryType(construction, bridge_squares_by_id)
if construction:getType() == df.world_construction_type.ROAD then
local square = construction.square_obj[0] -- df populates square_obj for roads and tunnels (only)
local subtype = ""
if df.item_type[construction.square_obj[0]["item_type"]] == "BLOCKS" then
local material = ""

if df.item_type[square.item_type] == "BLOCKS" then
subtype = "paved"
else
material = dfhack.matinfo.decode(square):toString()
elseif df.item_type[square.item_type] == "NONE" then
subtype = "dirt"
end
return "road", "LineString", subtype
elseif df.world_construction_bridgest:is_instance(construction) then
return "bridge", "Point", ""
elseif df.world_construction_tunnelst:is_instance(construction) then
return "tunnel", "LineString", ""

return "road", "LineString", subtype, material
elseif construction:getType() == df.world_construction_type.BRIDGE then
local square = bridge_squares_by_id[construction.id] -- df does NOT populate square_obj for bridges
local subtype = ""
local material = ""

if df.item_type[square.item_type] == "WOOD" then
subtype = "wooden"
Comment thread
Nekkowe marked this conversation as resolved.
material = dfhack.matinfo.decode(square):toString()
elseif df.item_type[square.item_type] == "BLOCKS" then
subtype = "stone"
material = dfhack.matinfo.decode(square):toString()
end

return "bridge", "Point", subtype, material
elseif construction:getType() == df.world_construction_type.TUNNEL then
-- df assigns world construction squares to tunnels like it does to roads,
-- but tunnel squares have nothing besides positional data: no material info, no nothing.
return "tunnel", "LineString", "", ""
else
qerror("unknown construction type")
end
end

local function listBridgeSquaresById()
local squares = {}

local tile_array_width = constructions.width
local tile_array_height = constructions.height

for i = 0, (tile_array_width - 1) do
for j = 0, (tile_array_height - 1) do
for _, square in ipairs(constructions.map[i]:_displace(j).square) do
if square:getType() == df.world_construction_square_type.BRIDGE then
squares[square.construction_id] = square
end
end
end
end

return squares
end

local function gatherFeatures()
local features = {}
for _, construction in ipairs(df.global.world.world_data.constructions.list) do
local type, geometry_type, subtype = getConstructionAndGeometryType(construction)

local bridge_squares_by_id = listBridgeSquaresById()

for _, construction in ipairs(constructions.list) do
local type, geometry_type, subtype, material = getConstructionAndGeometryType(construction, bridge_squares_by_id)

local coordinates
if geometry_type == "Point" then
-- only world tile - not sure where to get region tile coordinates from
-- perhaps it gets them from neighbouring roads?
-- dwarf fortress doesn't populate square_obj for bridges, only for roads and tunnels.
-- but all world tiles are listed in df.global.world.world_data.constructions.map (not list),
-- a 2D array that has to be iterated over with _displace()
local region_x = construction.square_pos.y[0]
local region_y = construction.square_pos.y[0]
local midmap_x = bridge_squares_by_id[construction.id].embark_x[0]
local midmap_y = bridge_squares_by_id[construction.id].embark_y[0]

coordinates = {
construction.square_pos["x"][0]*768,
-(construction.square_pos["y"][0]*768)
region_x * 768 + midmap_x * 48 + 24,
-(region_y * 768 + midmap_y * 48 + 24)
}
else
coordinates = {}
for _,square_obj in ipairs(construction.square_obj) do
for i=0,#square_obj.embark_x-1 do
for _, square_obj in ipairs(construction.square_obj) do
for i = 0, #square_obj.embark_x - 1 do
Comment thread
Nekkowe marked this conversation as resolved.
table.insert(coordinates, {
square_obj.region_pos["x"]*768+square_obj.embark_x[i]*48+24,
-(square_obj.region_pos["y"]*768+square_obj.embark_y[i]*48+24)
square_obj.region_pos.x * 768 + square_obj.embark_x[i] * 48 + 24,
-(square_obj.region_pos.y * 768 + square_obj.embark_y[i] * 48 + 24)
})
end
end
Expand All @@ -49,10 +98,11 @@ local function gatherFeatures()
type = "Feature",
properties = {
id = construction.id,
name_df = dfhack.df2utf(dfhack.translation.translateName(construction["name"],false)),
name_en = dfhack.df2utf(dfhack.translation.translateName(construction["name"],true)),
name_df = dfhack.df2utf(dfhack.translation.translateName(construction.name, false)),
name_en = dfhack.df2utf(dfhack.translation.translateName(construction.name, true)),
construction_type = type,
construction_subtype = subtype,
construction_material = material,
},
geometry = {
type = geometry_type,
Expand All @@ -68,7 +118,7 @@ function export(by_world, by_date)
return function()
json.encode_file(
{ type = "FeatureCollection", features = gatherFeatures() },
util.getOutputFolder(by_world, by_date).."roads.geojson"
util.getOutputFolder(by_world, by_date) .. "roads.geojson"
)
end
end