-
-
Save therahedwig/20c1686de873c59774a9d789389569a5 to your computer and use it in GitHub Desktop.
world-map-to-svg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Generate an SVG worldmap for the active save. | |
--[====[ | |
world-map-to-svg | |
================ | |
This generates an interactive SVG for the current world, | |
using css and svg shape titles and svg views to create some | |
minor interactivity. | |
Will save as region-world-name-svg-map.svg in the DF play folder. | |
Open the resulting file in chrome or firefox. Hover over elements | |
to learn their name. Click on glowing elements to have them fill | |
the viewport. On the left hand there is a list of landmass names. | |
On the right hand a list of civilization names with the colors | |
pulled from DF. The names on both these lists can be clicked to | |
have their regions (and in the case of civs, claims) fill the viewport. | |
Files can be opened in inkscape. Most of the colors are stored as | |
Inkscape swatches, so you can 'easily' change them. The bigger issue | |
is that Inkscape might have trouble with the amount of objects in a big | |
df world. | |
]====] | |
function checkIfCoordindateInGrid(point_x, point_y, grid_x, grid_y) | |
for point, x in pairs (grid_x) do | |
if point_x == x then | |
if point_y == grid_y[point] then | |
return true | |
end | |
end | |
end | |
return false | |
end | |
function comparePoints(p1, p2) | |
return p1.x == p2.x and p1.y == p2.y | |
end | |
function grid_to_border(grid) | |
local linesList = {} | |
local sortedLines = {} | |
local coordinateList = {} | |
local subpaths = {} | |
for point, x in pairs (grid.x) do | |
print(point.." / "..#grid.x) | |
y = grid.y[point] | |
topLeft = {"x", "y"} | |
topLeft.x = x | |
topLeft.y = y | |
topRight = {"x", "y"} | |
topRight.x = x+1 | |
topRight.y = y | |
bottomLeft = {"x", "y"} | |
bottomLeft.x = x | |
bottomLeft.y = y+1 | |
bottomRight = {"x", "y"} | |
bottomRight.x = x+1 | |
bottomRight.y = y+1 | |
--print(x, y) | |
if checkIfCoordindateInGrid(x, y-1, grid.x, grid.y) == false then | |
local line = {"p1", "p2"} | |
line.p1 = topLeft | |
line.p2 = topRight | |
--print("top| "..line.p1.x..", "..line.p1.y..", "..line.p2.x..", "..line.p2.y) | |
table.insert(linesList, line) | |
end | |
if checkIfCoordindateInGrid(x+1, y, grid.x, grid.y) == false then | |
local line = {"p1", "p2"} | |
line.p1 = topRight | |
line.p2 = bottomRight | |
--print("rigt| "..line.p1.x..", "..line.p1.y..", "..line.p2.x..", "..line.p2.y) | |
table.insert(linesList, line) | |
end | |
if checkIfCoordindateInGrid(x, y+1, grid.x, grid.y) == false then | |
local line = {"p1", "p2"} | |
line.p1 = bottomRight | |
line.p2 = bottomLeft | |
--print("bttom| "..line.p1.x..", "..line.p1.y..", "..line.p2.x..", "..line.p2.y) | |
table.insert(linesList, line) | |
end | |
if checkIfCoordindateInGrid(x-1, y, grid.x, grid.y) == false then | |
local line = {"p1", "p2"} | |
line.p1 = bottomLeft | |
line.p2 = topLeft | |
--print("left| "..line.p1.x..", "..line.p1.y..", "..line.p2.x..", "..line.p2.y) | |
table.insert(linesList, line) | |
end | |
end | |
print("Total border lines "..#linesList) | |
local sortedLines = {} | |
local debugstring = "" | |
for no, line_n in pairs(linesList) do | |
local sorted = false | |
for i, l in pairs(sortedLines) do | |
if comparePoints(line_n.p1, l.p2) then | |
table.insert(sortedLines, i+1, line_n) | |
sorted = true | |
break | |
end | |
end | |
if sorted == false then | |
table.insert(sortedLines, line_n) | |
end | |
debugstring = debugstring.."| "..line_n.p1.x..", "..line_n.p1.y..", "..line_n.p2.x..", "..line_n.p2.y | |
end | |
--print("DEBUG "..debugstring) | |
coordinateList = {} | |
while(#sortedLines > 0) do | |
if (#coordinateList==0) then | |
table.insert(coordinateList, sortedLines[1].p1) | |
table.insert(coordinateList, sortedLines[1].p2) | |
table.remove(sortedLines, 1) | |
else | |
local lastPoint = coordinateList[#coordinateList] | |
for n, line_j in pairs(sortedLines) do | |
if comparePoints(lastPoint, line_j.p1) then | |
if lastPoint.x+1 == line_j.p2.x then | |
table.insert(coordinateList, line_j.p2) | |
table.remove(sortedLines, n) | |
break | |
elseif lastPoint.y+1 == line_j.p2.y then | |
table.insert(coordinateList, line_j.p2) | |
table.remove(sortedLines, n) | |
break | |
elseif lastPoint.x-1 == line_j.p2.x then | |
table.insert(coordinateList, line_j.p2) | |
table.remove(sortedLines, n) | |
break | |
elseif lastPoint.y-1 == line_j.p2.y then | |
table.insert(coordinateList, line_j.p2) | |
table.remove(sortedLines, n) | |
break | |
end | |
elseif comparePoints(lastPoint, line_j.p2) then | |
if lastPoint.x+1 == line_j.p1.x then | |
table.insert(coordinateList, line_j.p1) | |
table.remove(sortedLines, n) | |
break | |
elseif lastPoint.y+1 == line_j.p1.y then | |
table.insert(coordinateList, line_j.p1) | |
table.remove(sortedLines, n) | |
break | |
elseif lastPoint.x-1 == line_j.p1.x then | |
table.insert(coordinateList, line_j.p1) | |
table.remove(sortedLines, n) | |
break | |
elseif lastPoint.y-1 == line_j.p1.y then | |
table.insert(coordinateList, line_j.p1) | |
table.remove(sortedLines, n) | |
break | |
end | |
end | |
end | |
if comparePoints(lastPoint, coordinateList[#coordinateList]) then | |
table.insert(subpaths, coordinateList) | |
coordinateList = {} | |
end | |
end | |
print(#sortedLines) | |
end | |
if #coordinateList > 0 then | |
table.insert(subpaths, coordinateList) | |
end | |
print("total subpaths", #subpaths) | |
return subpaths | |
end | |
function remove_spaces(name) | |
if name ~= "" then | |
--[[ | |
spaces = string.find(name, ' ', 1, true) | |
while spaces ~= nil do | |
name = string.sub(name,1, spaces-1)..'-'..string.sub(name,spaces+1) | |
spaces = string.find(name, ' ', 1, true) | |
end | |
]] | |
name = string.gsub(name," ","-") | |
else | |
name = "unnamed" | |
end | |
return name | |
end | |
function write_double(double) | |
if type(double) ~= "number" then | |
print("Not a number!", type(double), double) | |
return "" | |
end | |
return string.gsub(""..double,",",".") | |
end | |
function write_color_swatch(id, fillString, listOfStrings) | |
listOfStrings[#listOfStrings+1] = "<linearGradient osb:paint=\"solid\" id=\""..id.."\">\n" | |
listOfStrings[#listOfStrings+1] = "\t<stop style=\"stop-color:"..fillString..";stop-opacity:1;\" />\n" | |
listOfStrings[#listOfStrings+1] = "</linearGradient>\n" | |
return listOfStrings | |
end | |
function write_rect(id, x, y, width, height, styleString, strings) | |
local rectangle = {} | |
table.insert(rectangle, "<rect") | |
if id ~= "" and type(id) == "string" then | |
table.insert(rectangle, string.format("id=\"%s\"", string.lower(remove_spaces(id)))) | |
end | |
if type(x) == "number" then | |
table.insert(rectangle, string.format("x=\"%s\"", write_double(x))) | |
end | |
if type(y) == "number" then | |
table.insert(rectangle, string.format("y=\"%s\"", write_double(y))) | |
end | |
if type(width) == "number" then | |
table.insert(rectangle, string.format("width=\"%s\"", write_double(width))) | |
end | |
if type(height) == "number" then | |
table.insert(rectangle, string.format("height=\"%s\"", write_double(height))) | |
end | |
if styleString ~= "" and type(styleString) == "string" then | |
table.insert(rectangle, string.format("style=\"%s\"", styleString)) | |
end | |
table.insert(rectangle, "/>") | |
table.insert(strings, table.concat(rectangle, " ")) | |
end | |
function write_text(id, class, x, y, styleString, textString, strings) | |
local text = {} | |
table.insert(text, "<text") | |
if id ~= "" and type(id) == "string" then | |
table.insert(text, string.format("id=\"%s\"", string.lower(remove_spaces(id)))) | |
end | |
if class ~= "" and type(class) == "string" then | |
table.insert(text, string.format("class=\"%s\"", class)) | |
end | |
if type(x) == "number" then | |
table.insert(text, string.format("x=\"%s\"", write_double(x))) | |
end | |
if type(y) == "number" then | |
table.insert(text, string.format("y=\"%s\"", write_double(y))) | |
end | |
if styleString ~= "" and type(styleString) == "string" then | |
table.insert(text, string.format("style=\"%s\"", styleString)) | |
end | |
table.insert(text, ">") | |
table.insert(text, textString) | |
table.insert(text, "</text>") | |
table.insert(strings, table.concat(text, " ")) | |
end | |
function write_path(id, class, path, styleString, title, strings) | |
local pathShape = {} | |
table.insert(pathShape, "<path") | |
if id ~= "" and type(id) == "string" then | |
table.insert(pathShape, string.format("id=\"%s\"", string.lower(remove_spaces(id)))) | |
end | |
if class ~= "" and type(class) == "string" then | |
table.insert(pathShape, string.format("class=\"%s\"", class)) | |
end | |
if path ~= "" and type(path) == "string" then | |
table.insert(pathShape, string.format("d=\"%s\"", path)) | |
end | |
if styleString ~= "" and type(styleString) == "string" then | |
table.insert(pathShape, string.format("style=\"%s\"", styleString)) | |
end | |
if title ~= "" and type(title) == "string" then | |
table.insert(pathShape, string.format("><title>%s</title></path>", title)) | |
else | |
table.insert(pathShape, "/>") | |
end | |
table.insert(strings, table.concat(pathShape, " ")) | |
end | |
function write_group(id, class, transform, styleString, listOfShapes, strings) | |
local group = {} | |
table.insert(group, "<g") | |
if id ~= "" and type(id) == "string" then | |
table.insert(group, string.format("id=\"%s\"", string.lower(remove_spaces(id)))) | |
end | |
if class ~= "" and type(class) == "string" then | |
table.insert(group, string.format("class=\"%s\"", class)) | |
end | |
if transform ~= "" and type(transform) == "string" then | |
table.insert(group, string.format("transform=\"%s\"", transform)) | |
end | |
if styleString ~= "" and type(styleString) == "string" then | |
table.insert(group, string.format("style=\"%s\"", styleString)) | |
end | |
table.insert(group, ">\n") | |
table.insert(group, table.concat(listOfShapes, "\n\t")) | |
table.insert(group, "\n</g>") | |
table.insert(strings, table.concat(group, " ")) | |
end | |
function write_link(id, link, styleString, listOfShapes, strings) | |
local group = {} | |
table.insert(group, "<a") | |
if id ~= "" and type(id) == "string" then | |
table.insert(group, string.format("id=\"%s\"", string.lower(remove_spaces(id)))) | |
end | |
if link ~= "" and type(link) == "string" then | |
table.insert(group, string.format("xlink:href=\"%s\"", "#"..link)) | |
end | |
if styleString ~= "" and type(styleString) == "string" then | |
table.insert(group, string.format("style=\"%s\"", styleString)) | |
end | |
table.insert(group, ">\n") | |
table.insert(group, table.concat(listOfShapes, "\n\t")) | |
table.insert(group, "\n</a>") | |
table.insert(strings, table.concat(group, " ")) | |
end | |
function write_view(id, x, y, width, height, strings) | |
local view = {} | |
table.insert(view, "<view") | |
if id ~= "" and type(id) == "string" then | |
table.insert(view, string.format("id=\"%s\"", string.lower(remove_spaces(id)))) | |
end | |
if type(x) == "number" and type(y) == "number" and type(width) == "number" and type(height) == "number" then | |
table.insert(view, string.format("viewBox=\"%s %s %s %s\"", write_double(x), write_double(y), write_double(width), write_double(height))) | |
end | |
table.insert(view, "/>\n") | |
table.insert(strings, table.concat(view, " ")) | |
end | |
worldRegionMultiplier = 16 | |
saveDir = df.global.world.cur_savegame.save_dir | |
worldName = dfhack.TranslateName(df.global.world.world_data.name) | |
print("Getting map for "..worldName) | |
documentName = saveDir.."-"..remove_spaces(dfhack.TranslateName(df.global.world.world_data.name, true, true))..'-svg-map'..'.svg' | |
local log = io.open(documentName, 'w') | |
width = df.global.world.world_data.world_width | |
height = df.global.world.world_data.world_height | |
log:write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>') | |
namespace = 'xmlns:svg="http://www.w3.org/2000/svg"\n xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink"' | |
namespace = namespace.." xmlns:osb=\"http://www.openswatchbook.org/uri/2009/osb\"\n" | |
log:write(string.format("<svg %s viewBox=\"%s %s %s %s\" >\n", namespace, (0-10)*worldRegionMultiplier, 0, (width+20)*worldRegionMultiplier, (height+10)*worldRegionMultiplier)) | |
local worldStrings = {} | |
write_text("world-name", nil, (width*worldRegionMultiplier)/2, (height+4)*worldRegionMultiplier, "font-size:50pt; text-anchor:middle;", worldName, worldStrings) | |
write_text("world-name-translated", nil, (width*worldRegionMultiplier)/2, (height+7)*worldRegionMultiplier, "font-size:15pt; text-anchor:middle;", dfhack.TranslateName(df.global.world.world_data.name, true, true), worldStrings) | |
write_text("dfversion", nil, (width*worldRegionMultiplier)/2, (height+9)*worldRegionMultiplier, "font-size:15pt; text-anchor:middle;", string.format("A Dwarf Fortress %s World" , df.global.world.worldgen.version), worldStrings) | |
for _, string in pairs(worldStrings) do | |
log:write(string) | |
end | |
log:write("<defs>") | |
colorList = {} | |
listOfStrings = {} | |
colorList["Swamp"] = "url(#biome-temperate-freshwater-swamp)" | |
colorList["SWAMP_TEMPERATE_FRESHWATER"] = "url(#biome-temperate-freshwater-swamp)" | |
colorList["MARSH_TEMPERATE_FRESHWATER"] = "url(#biome-temperate-freshwater-marsh)" | |
colorList["SWAMP_TEMPERATE_SALTWATER"] = "url(#biome-temperate-saltwater-swamp)" | |
colorList["MARSH_TEMPERATE_SALTWATER"] = "url(#biome-temperate-saltwater-marsh)" | |
colorList["SWAMP_TROPICAL_FRESHWATER"] = "url(#biome-temperate-freshwater-swamp)" | |
colorList["MARSH_TROPICAL_FRESHWATER"] = "url(#biome-temperate-freshwater-marsh)" | |
colorList["SWAMP_TROPICAL_SALTWATER"] = "url(#biome-temperate-saltwater-swamp)" | |
colorList["MARSH_TROPICAL_SALTWATER"] = "url(#biome-temperate-saltwater-marsh)" | |
colorList["SWAMP_MANGROVE"] = "url(#biome-mangrove-swamp)" | |
write_color_swatch("biome-temperate-saltwater-marsh", "rgb(84, 131, 96)", listOfStrings) | |
write_color_swatch("biome-temperate-freshwater-marsh", "rgb(95, 147, 108)", listOfStrings) | |
write_color_swatch("biome-temperate-saltwater-swamp", "rgb(86, 129, 116)", listOfStrings) | |
write_color_swatch("biome-temperate-freshwater-swamp", "rgb(87, 147, 127)", listOfStrings) | |
write_color_swatch("biome-mangrove-swamp", "rgb(78, 115, 108)", listOfStrings) | |
write_color_swatch("biome-tropical-saltwater-marsh", "rgb(92, 125, 134)", listOfStrings) | |
write_color_swatch("biome-tropical-freshwater-marsh", "rgb(119, 163, 110)", listOfStrings) | |
write_color_swatch("biome-tropical-saltwater-swamp", "rgb(64, 192, 64)", listOfStrings) | |
write_color_swatch("biome-tropical-freshwater-swamp", "rgb(96, 192, 64)", listOfStrings) | |
colorList["Desert"] = "url(#biome-desert-sand)" | |
colorList["DESERT_SAND"] = "url(#biome-desert-sand-yellow)" | |
colorList["DESERT_SAND_YELLOW"] = "url(#biome-desert-sand-yellow)" | |
colorList["DESERT_SAND_RED"] = "url(#biome-desert-sand-red)" | |
colorList["DESERT_SAND_WHITE"] = "url(#biome-desert-sand-white)" | |
colorList["DESERT_SAND_BLACK"] = "url(#biome-desert-sand-black)" | |
colorList["DESERT_SAND_TAN"] = "url(#biome-desert-sand-tan)" | |
colorList["DESERT_ROCK"] = "url(#biome-desert-rock)" | |
colorList["DESERT_BADLAND"] = "url(#biome-desert-badlands)" | |
write_color_swatch("biome-desert-sand-yellow", "#eadd5a", listOfStrings) | |
write_color_swatch("biome-desert-sand-red", "#cc7362", listOfStrings) | |
write_color_swatch("biome-desert-sand-white", "#c0c0c0", listOfStrings) | |
write_color_swatch("biome-desert-sand-black", "#606060", listOfStrings) | |
write_color_swatch("biome-desert-sand-tan", "#d2b48c", listOfStrings) | |
write_color_swatch("biome-desert-rock", "#d0ac6d", listOfStrings) | |
write_color_swatch("biome-desert-badlands", "#c66038", listOfStrings) | |
colorList["Jungle"] = "url(#biome-forest-temperate-broadleaf)" | |
colorList["FOREST_TAIGA"] = "url(#biome-forest-taiga)" | |
colorList["FOREST_TEMPERATE_CONIFER"] = "url(#biome-forest-temperate-conifer)" | |
colorList["FOREST_TEMPERATE_BROADLEAF"] = "url(#biome-forest-temperate-broadleaf)" | |
colorList["FOREST_TROPICAL_CONIFER"] = "url(#biome-forest-tropical-conifer)" | |
colorList["FOREST_TROPICAL_DRY_BROADLEAF"] = "url(#biome-forest-tropical-dry-broadleaf)" | |
colorList["FOREST_TROPICAL_MOIST_BROADLEAF"] = "url(#biome-forest-tropical-moist-broadleaf)" | |
write_color_swatch("biome-forest-taiga", "rgb(74, 104, 94)", listOfStrings) | |
write_color_swatch("biome-forest-temperate-conifer", "rgb(34, 99, 85)", listOfStrings) | |
write_color_swatch("biome-forest-temperate-broadleaf", "rgb(0, 127, 66)", listOfStrings) | |
write_color_swatch("biome-forest-tropical-conifer", "rgb(0, 96, 53)", listOfStrings) | |
write_color_swatch("biome-forest-tropical-dry-broadleaf", "rgb(27, 146, 35)", listOfStrings) | |
write_color_swatch("biome-forest-tropical-moist-broadleaf", "rgb(31, 165, 41)", listOfStrings) | |
colorList["Mountains"] = "url(#biome-mountains)" | |
colorList["MOUNTAIN"] = "url(#biome-mountains)" | |
colorList["MOUNTAIN_MID"] = "url(#biome-mountains-mid)" | |
colorList["MOUNTAIN_HIGH"] = "url(#biome-mountains-high)" | |
write_color_swatch("biome-mountains", "#808080", listOfStrings) | |
write_color_swatch("biome-mountains-mid", "#a0a0a0", listOfStrings) | |
write_color_swatch("biome-mountains-high", "#c0c0c0", listOfStrings) | |
colorList["Ocean"] = "url(#biome-temperate-ocean)" | |
colorList["OCEAN_TEMPERATE"] = "url(#biome-temperate-ocean)" | |
colorList["OCEAN_TROPICAL"] = "url(#biome-tropical-ocean)" | |
colorList["OCEAN_ARTIC"] = "url(#biome-artic-ocean_1)" | |
write_color_swatch("biome-temperate-ocean", "#206f95", listOfStrings) | |
write_color_swatch("biome-tropical-ocean", "#39b1ea", listOfStrings) | |
write_color_swatch("biome-artic-ocean_2", "#0d3d49", listOfStrings) | |
write_color_swatch("biome-artic-ocean_1", "#a5ceda", listOfStrings) | |
colorList["Glacier"] = "url(#biome-glacier)" | |
write_color_swatch("biome-glacier", "#a5ceda", listOfStrings) | |
colorList["Steppe"] = "url(#biome-grassland-temperate)" | |
colorList["Hills"] = "url(#biome-hills)" | |
write_color_swatch("biome-hills", "#d8bc89", listOfStrings) | |
colorList["GRASSLAND_TEMPERATE"] = "url(#biome-grassland-temperate)" | |
colorList["SAVANNA_TEMPERATE"] = "url(#biome-savanna-temperate)" | |
colorList["SHRUBLAND_TEMPERATE"] = "url(#biome-shrubland-temperate)" | |
colorList["GRASSLAND_TROPICAL"] = "url(#biome-grassland-tropical)" | |
colorList["SAVANNA_TROPICAL"] = "url(#biome-savanna-tropical)" | |
colorList["SHRUBLAND_TROPICAL"] = "url(#biome-shrubland-tropical)" | |
write_color_swatch("biome-grassland-tropical", "rgb(163, 157, 72)", listOfStrings) | |
write_color_swatch("biome-shrubland-tropical", "rgb(158, 166, 47)", listOfStrings) | |
write_color_swatch("biome-savanna-tropical", "rgb(153, 173, 0)", listOfStrings) | |
write_color_swatch("biome-grassland-temperate", "rgb(124, 128, 90)", listOfStrings) | |
write_color_swatch("biome-shrubland-temperate", "rgb(105, 141, 94)", listOfStrings) | |
write_color_swatch("biome-savanna-temperate", "rgb(84, 151, 96)", listOfStrings) | |
colorList["Tundra"] = "url(#biome-tundra)" | |
write_color_swatch("biome-tundra", "rgb(85, 117, 113)", listOfStrings) | |
write_color_swatch("neutral-fg", "grey", listOfStrings) | |
write_color_swatch("neutral-bg", "black", listOfStrings) | |
colorList["Lake"] = "url(#biome-lake-temperate-freshwater)" | |
colorList["LAKE_TEMPERATE_FRESHWATER"] = "url(#biome-lake-temperate-freshwater)" | |
colorList["LAKE_TEMPERATE_BRAKISH"] = "url(#biome-lake-temperate-brackish)" | |
colorList["LAKE_TEMPERATE_SALTWATER"] = "url(#biome-lake-temperate-saltwater)" | |
colorList["LAKE_TEMPERATE_TROPICAL"] = "url(#biome-lake-temperate-freshwater)" | |
colorList["LAKE_TEMPERATE_TROPICAL"] = "url(#biome-lake-temperate-brackish)" | |
colorList["LAKE_TEMPERATE_TROPICAL"] = "url(#biome-lake-temperate-saltwater)" | |
write_color_swatch("biome-lake-tropical-saltwater", "#29b2ec", listOfStrings) | |
write_color_swatch("biome-lake-tropical-brackish", "#29c6e7", listOfStrings) | |
write_color_swatch("biome-lake-tropical-freshwater", "#2fdef1", listOfStrings) | |
write_color_swatch("biome-lake-temperate-saltwater", "#217693", listOfStrings) | |
write_color_swatch("biome-lake-temperate-brackish", "#2d9cb0", listOfStrings) | |
write_color_swatch("biome-lake-temperate-freshwater", "#298bac", listOfStrings) | |
write_color_swatch("river-major", "#0070ff", listOfStrings) | |
write_color_swatch("river-mid", "#0086e8", listOfStrings) | |
write_color_swatch("river-minor", "#00c1f5", listOfStrings) | |
write_color_swatch("river-stream", "#00e0ff", listOfStrings) | |
write_color_swatch("river-brook", "#00ffff", listOfStrings) | |
--Proly not gonna use these, but gotta keep track of them anyhow... | |
write_color_swatch("mud-tropical", "#a9925a", listOfStrings) | |
write_color_swatch("mud-temperate", "#8e6f57", listOfStrings) | |
write_color_swatch("mud-artic", "#574844", listOfStrings) | |
write_color_swatch("construction-road", "#8e6f57", listOfStrings) | |
write_color_swatch("construction-road-bars", "#c0c0c0", listOfStrings) | |
write_color_swatch("construction-road-smallgem", "#FF80FF", listOfStrings) | |
write_color_swatch("construction-road-blocks", "#808080", listOfStrings) | |
write_color_swatch("construction-road-rough", "#404040", listOfStrings) | |
write_color_swatch("construction-road-boulder", "#404040", listOfStrings) | |
write_color_swatch("construction-road-wood", "#a9925a", listOfStrings) | |
write_color_swatch("construction-bridge", "#808080", listOfStrings) | |
write_color_swatch("construction-tunnel", "#202020", listOfStrings) | |
write_color_swatch("construction-wall", "#808080", listOfStrings) | |
write_color_swatch("residence", "rgb(0, 255, 255)", listOfStrings) | |
write_color_swatch("capital", "rgb(255, 0, 255)", listOfStrings) | |
write_color_swatch("fortress", "rgb(0, 255, 180)", listOfStrings) | |
write_color_swatch("local_market", "rgb(0, 255, 0)", listOfStrings) | |
write_color_swatch("trade_partner", "rgb(255, 255, 0)", listOfStrings) | |
write_color_swatch("monument", "rgb(192, 0, 255)", listOfStrings) | |
write_color_swatch("primary_criminal_gang", "rgb(255, 192, 0)", listOfStrings) | |
write_color_swatch("criminal_gang", "rgb(255, 140, 0)", listOfStrings) | |
write_color_swatch("invasion_marked", "rgb(255, 0, 0)", listOfStrings) | |
write_color_swatch("land_for_holding", "rgb(80, 0, 80)", listOfStrings) | |
write_color_swatch("land_holder_residence", "rgb(120, 0, 120)", listOfStrings) | |
write_color_swatch("central_holding_land", "rgb(190, 0, 190)", listOfStrings) | |
write_color_swatch("reclaim", "rgb(0, 100, 100)", listOfStrings) | |
write_color_swatch("occupation_failed", "rgb(80, 0, 0)", listOfStrings) | |
log:write(string.format("<marker id=\"%s\" viewbox=\"%s\" refX=\"%s\" refY=\"%s\" markerWidth=\"%s\" markerHeight=\"%s\" orient=\"%s\">\n", "entity-link", "-10 -10 20 20", 5, 5, 10, 10, "auto-start-reverse")) | |
log:write("\t<circle cx=\"5\" cy=\"5\" r=\"2.5\" stroke=\"white\" />\n") | |
log:write("</marker>\n") | |
log:write("<style type=\"text/css\">\n") | |
--log:write("<![CDATA[\n") | |
log:write(string.format(".region {\n\tstroke:%s;\n\tstroke-width:%s;\n\tstroke-opacity:0.5;\n}\n", | |
"#000000", write_double(0.1*worldRegionMultiplier))) | |
log:write(string.format(".ocean {\n\tstroke:%s;\n\tstroke-width:%s;\n}\n", | |
"#88ddFF", write_double(0.5*worldRegionMultiplier))) | |
log:write(string.format(".region:hover {\n\tstroke-width:%s;\n}\n", | |
write_double(0.5*worldRegionMultiplier))) | |
log:write(string.format(".neutral:hover{\n\tstroke:%s;\n}\n", | |
"#c0c0c0")) | |
log:write(string.format(".good:hover{\n\tstroke:%s;\n}\n", | |
"#80ffff")) | |
log:write(string.format(".evil:hover{\n\tstroke:%s;\n}\n", | |
"#ff80ff")) | |
log:write(string.format(".river{\n\tstroke:%s;\n}\n", | |
"url(#river-mid)")) | |
log:write(string.format(".stream{\n\tstroke:%s;\n}\n", | |
"url(#river-stream)")) | |
log:write(string.format(".brook{\n\tstroke:%s;\n}\n", | |
"url(#river-brook)")) | |
log:write(string.format(".major{\n\tstroke:%s;\n}\n", | |
"url(#river-major)")) | |
log:write(string.format(".minor{\n\tstroke:%s;\n}\n", | |
"url(#river-minor)")) | |
log:write(string.format(".river:hover{\n\tstroke:%s;\n}\n", | |
"#aaffff")) | |
log:write(string.format(".road { \n\tfill: none; \n\tstroke-width: %s; \n\tstroke: %s;}", write_double(0.1*worldRegionMultiplier), "url(#construction-road)")) | |
log:write(string.format(".road-bars {\n\tstroke: %s;}", "url(#construction-road-bars)")) | |
log:write(string.format(".road-smallgem {\n\tstroke: %s;}", "url(#construction-road-smallgem)")) | |
log:write(string.format(".road-blocks {\n\tstroke: %s;}", "url(#construction-road-blocks)")) | |
log:write(string.format(".road-rough {\n\tstroke: %s;}", "url(#construction-road-rough)")) | |
log:write(string.format(".road-boulder {\n\tstroke: %s;}", "url(#construction-road-boulder)")) | |
log:write(string.format(".road-wood {\n\tstroke: %s;}", "url(#construction-road-wood)")) | |
log:write(string.format(".road:hover{\n\tstroke:%s;\n}\n", "#ffffff")) | |
log:write(string.format(".tunnel { \n\tfill: none; \n\tstroke-width: %s; \n\tstroke: %s;\n\tstroke-dasharray:%s, %s;}\n", | |
write_double(0.1*worldRegionMultiplier), "url(#construction-tunnel)", write_double(0.2*worldRegionMultiplier), write_double(0.2*worldRegionMultiplier))) | |
log:write(string.format(".tunnel:hover{\n\tstroke:%s;\n}\n", | |
"#404040")) | |
log:write(string.format(".wall{ \n\tfill: none; \n\tstroke-width: %s; \n\tstroke: %s;}", write_double(0.1*worldRegionMultiplier), "url(#construction-wall)")) | |
log:write(string.format(".wall:hover{\n\tstroke:%s;\n}\n", | |
"#ffffff")) | |
log:write(string.format(".text-legend{font-size:%spt; text-decoration:none}", write_double(0.5*worldRegionMultiplier))) | |
log:write(".text-legend:hover{text-decoration:underline}\n") | |
log:write(string.format(".entity-site-link{ \n\tvisibility: hidden; \n\tstroke-width: %s;}\n", write_double(0.1*worldRegionMultiplier), "url(#construction-wall)")) | |
log:write(".site{ \n\tvisibility: visible;}\n") | |
log:write(string.format(".entity-site-link:hover{\n\tvisibility:%s;\n}\n", | |
"visible")) | |
--log:write("]]>\n") | |
log:write("</style>\n") | |
civ_list = {} | |
local civoffset = 0 | |
for no, entity in pairs(df.global.world.entities.all) do | |
if entity.type == 0 then | |
local name = dfhack.TranslateName(entity.name, true, true) | |
if name == "" then | |
name = dfhack.TranslateName(entity.name) | |
end | |
if name ~= "" then | |
civoffset = civoffset+1 | |
local id = no.."-"..remove_spaces(name) | |
local fgcolor = df.global.world.raws.descriptors.colors[entity.resources.foreground_color[0]] | |
local bgcolor = df.global.world.raws.descriptors.colors[entity.resources.background_color[0]] | |
local colorString = "rgb("..math.floor(fgcolor.red*255)..", "..math.floor(fgcolor.green*255)..", "..math.floor(fgcolor.blue*255)..")" | |
write_color_swatch(id.."-fg", colorString, listOfStrings) | |
colorString = "rgb("..math.floor(bgcolor.red*255)..", "..math.floor(bgcolor.green*255)..", "..math.floor(bgcolor.blue*255)..")" | |
write_color_swatch(id.."-bg", colorString, listOfStrings) | |
print("getting civ colors "..id.." fore: "..fgcolor.name.." back: "..bgcolor.name) | |
local civdef = {} | |
write_rect(nil, nil, nil, worldRegionMultiplier, worldRegionMultiplier, "fill:url(#"..id.."-bg)" , civdef) | |
write_rect(nil, nil, 0.3*worldRegionMultiplier, worldRegionMultiplier, 0.3*worldRegionMultiplier, "fill:url(#"..id.."-fg)" , civdef) | |
local textShape = {} | |
write_text(nil, "text-legend", 1.5*worldRegionMultiplier, 0.6*worldRegionMultiplier, "text-anchor:start;", name, textShape) | |
table.insert(textShape, "<title>"..name.."</title>") | |
write_link(nil, string.lower(remove_spaces(no.."-"..name.."-view")), nil, textShape, civdef) | |
write_group(no.."-"..name.."-legend", nil, string.format("translate( %s , %s)", write_double((width+1)*worldRegionMultiplier), write_double(civoffset*worldRegionMultiplier)), nil, civdef, civ_list) | |
end | |
end | |
end | |
for _, string in pairs(listOfStrings) do | |
log:write(string) | |
end | |
log:write("</defs>") | |
landMassStrings = {} | |
for no, landmass in pairs(df.global.world.world_data.landmasses) do | |
local landmass_name = dfhack.TranslateName(landmass.name, true, true) | |
local id = string.lower(remove_spaces(no.."-"..landmass_name)) | |
write_view(id.."-view", (landmass.min_x-1)*worldRegionMultiplier, (landmass.min_y-1)*worldRegionMultiplier, | |
(landmass.max_x+3-landmass.min_x)*worldRegionMultiplier | |
, (landmass.max_y+3-landmass.min_y)*worldRegionMultiplier, landMassStrings) | |
local textShape = {} | |
write_text(nil, "text-legend", (0-1.5)*worldRegionMultiplier, (no+1+0.6)*worldRegionMultiplier, | |
"text-anchor:end;", | |
landmass_name, textShape) | |
table.insert(textShape, "<title>"..landmass_name.."</title>") | |
write_link(nil, id.."-view", nil, textShape, landMassStrings) | |
end | |
listOfStrings = {} | |
write_group("civ_legend",nil, nil, nil, civ_list, listOfStrings) | |
write_group("landmasses",nil, nil, nil, landMassStrings, listOfStrings) | |
for _, string in pairs(listOfStrings) do | |
log:write(string) | |
end | |
landmasses = {} | |
for no, region in pairs(df.global.world.world_data.regions) do | |
local region_name = "" | |
local regionStrings = {} | |
local landmass_name = "" | |
local biomeamount = 0 | |
local biometype = df.world_region_type[region.type] | |
if (region.name) then | |
region_name = dfhack.TranslateName(region.name, true, true) | |
end | |
print("bounding.. "..region_name) | |
local bordercoords = grid_to_border(region.region_coords) | |
print("done") | |
for biome, amount in pairs(region.biome_tile_counts) do | |
if amount>biomeamount then | |
biomeamount = amount | |
biometype = biome | |
end | |
end | |
if df.world_region_type[region.type] ~= "Ocean" then | |
for _, landmass in pairs(df.global.world.world_data.landmasses) do | |
if region.min_x >= landmass.min_x and region.max_x <= landmass.max_x and | |
region.min_y >= landmass.min_y and region.max_y <= landmass.max_y then | |
landmass_name = dfhack.TranslateName(landmass.name, true, true) | |
end | |
end | |
end | |
print(biometype) | |
local colorFill = colorList[biometype] | |
if colorFill == nil then | |
colorFill = colorList[df.world_region_type[region.type]] | |
end | |
local regionString = df.world_region_type[region.type] | |
if df.world_region_type[region.type] == "Jungle" then | |
regionString = "Forest" | |
end | |
local path = "" | |
local max_x = 0 | |
local max_y = 0 | |
local min_x = width | |
local min_y = width | |
for i, subpath in pairs(bordercoords) do | |
path = path.." M " | |
for p, point in pairs(subpath) do | |
if p ~= 1 then | |
path = path.." L " | |
end | |
path = path..write_double(point.x*worldRegionMultiplier).." "..write_double(point.y*worldRegionMultiplier) | |
max_x = math.max(point.x, max_x) | |
max_y = math.max(point.y, max_y) | |
min_x = math.min(point.x, min_x) | |
min_y = math.min(point.y, min_y) | |
end | |
path = path.." z" | |
end | |
local Other_Biomes = {} | |
-- ported from https://github.com/ragundo/exportmaps/blob/master/cpp/df_utils/biome_type.cpp#L105 and | |
-- https://github.com/PatrikLundell/scripts/blob/own_scripts/biomemanipulator.lua | |
for point, world_coord_x in pairs (region.region_coords.x) do | |
local biomename = biometype | |
local world_coord_y = region.region_coords.y[point] | |
local region_tile = dfhack.maps.getRegionBiome(world_coord_x, world_coord_y) | |
if (df.world_region_type[region.type] == "Ocean") then | |
if (region_tile.temperature < (0)) then | |
biomename = "OCEAN_ARTIC" | |
elseif (region_tile.temperature >= (75)) then | |
biomename = "OCEAN_TROPICAL" | |
else | |
biomename = "OCEAN_TEMPERATE" | |
end | |
end | |
if (df.world_region_type[region.type]=="Swamp") then | |
if region_tile.salinity >= 66 then | |
biomename = string.gsub(biometype,"FRESHWATER","SALTWATER") | |
if region_tile.temperature >= (75) and | |
region_tile.vegetation>=33 and | |
region_tile.drainage<10 then | |
print("SWAMP_MANGROVE") | |
biomename = "SWAMP_MANGROVE" | |
end | |
else | |
biomename = string.gsub(biometype,"SALTWATER","FRESHWATER") | |
end | |
end | |
if (df.world_region_type[region.type]=="Hills" or df.world_region_type[region.type]=="Steppe") then | |
if region_tile.vegetation < 20 then | |
biomename = "GRASSLAND" | |
elseif region_tile.vegetation >= 20 and region_tile.vegetation < 65 then | |
biomename = "SAVANNA" | |
else | |
biomename = "SHRUBLAND" | |
end | |
if string.find(biometype, "TROPICAL") then | |
biomename = biomename.."_TROPICAL" | |
else | |
biomename = biomename.."_TEMPERATE" | |
end | |
end | |
if (df.world_region_type[region.type]=="Jungle") then | |
local forest_type = "FOREST" | |
-- border above 180, below 184 | |
if string.find(biometype, "TROPICAL") then | |
forest_type = forest_type.."_TROPICAL" | |
if (region_tile.rainfall < 75) then | |
forest_type = forest_type.."_CONIFER" | |
else | |
if string.find(biometype, "DRY") then | |
forest_type = forest_type.."_DRY_BROADLEAF" | |
else | |
forest_type = forest_type.."_MOIST_BROADLEAF" | |
end | |
end | |
else | |
forest_type = forest_type.."_TEMPERATE" | |
if ((region_tile.rainfall < 75) or (region_tile.temperature < 65)) then | |
if (region_tile.temperature >= 10) then | |
forest_type = forest_type.."_CONIFER" | |
else | |
forest_type = "FOREST_TAIGA" | |
end | |
else | |
forest_type = forest_type.."_BROADLEAF" | |
end | |
end | |
biomename = forest_type | |
end | |
if (df.world_region_type[region.type]=="Desert") then | |
biomename = "DESERT" | |
-- border above 180, below 184 | |
if region_tile.drainage < 33 then | |
geolayer = df.global.world.world_data.geo_biomes[region_tile.geo_index].layers[0] | |
if geolayer.type == 6 then | |
material = df.global.world.raws.inorganics[geolayer.mat_index] | |
biomename = biomename.."_"..material.id | |
else | |
biomename = biomename.."_SAND" | |
end | |
elseif region_tile.drainage < 33 then | |
biomename = biomename.."_ROCK" | |
else | |
biomename = biomename.."_BADLAND" | |
end | |
end | |
if (df.world_region_type[region.type]=="Mountains") then | |
local mountain_type = "" | |
-- border above 180, below 184 | |
if region_tile.elevation >= 183 then | |
mountain_type = "_MID" | |
end | |
if region_tile.elevation > 215 then | |
mountain_type = "_HIGH" | |
end | |
biomename = "MOUNTAIN"..mountain_type | |
end | |
if (Other_Biomes[biomename]==nil) then | |
Other_Biomes[biomename] = {"x", "y"} | |
Other_Biomes[biomename]["x"] = {} | |
Other_Biomes[biomename]["y"] = {} | |
end | |
table.insert(Other_Biomes[biomename]["x"], world_coord_x) | |
table.insert(Other_Biomes[biomename]["y"], world_coord_y) | |
end | |
local className = "neutral" | |
if region.evil then | |
className = "evil" | |
regionString = "Evil "..regionString | |
end | |
if region.good then | |
className = "good" | |
regionString = "Good "..regionString | |
end | |
local regionInfo = {} | |
table.insert(regionInfo, region_name) | |
table.insert(regionInfo, regionString) | |
if (landmass_name ~= "") then | |
table.insert(regionInfo, landmass_name) | |
end | |
local linkStrings = {} | |
className = "region "..string.lower(df.world_region_type[region.type]).." "..className | |
write_path(nil, nil, path, string.format("fill: %s; stroke:none;", colorFill), nil, linkStrings) | |
for biomeName, biome in pairs(Other_Biomes) do | |
if biometype~= biomeName then | |
print("bounding.. "..region_name.." "..biomeName) | |
local bordercoords = grid_to_border(biome) | |
print("done") | |
local biomePath = "" | |
for i, subpath in pairs(bordercoords) do | |
biomePath = biomePath.." M " | |
for p, point in pairs(subpath) do | |
if p ~= 1 then | |
biomePath = biomePath.." L " | |
end | |
biomePath = biomePath..write_double(point.x*worldRegionMultiplier).." "..write_double(point.y*worldRegionMultiplier) | |
end | |
biomePath = biomePath.." z" | |
end | |
write_path(nil, nil, biomePath, string.format("fill: %s; stroke:none;", colorList[biomeName]), nil, linkStrings) | |
end | |
end | |
write_path(nil, nil, path, string.format("fill: %s;", "none"), nil, linkStrings) | |
write_link(nil, string.lower(remove_spaces(no.."-"..region_name.."-view")), nil, linkStrings, regionStrings) | |
table.insert(regionStrings, string.format("<title>%s</title>", table.concat(regionInfo, ", "))) | |
write_view(no.."-"..region_name.."-view", | |
(min_x-1)*worldRegionMultiplier, | |
(min_y-1)*worldRegionMultiplier, | |
(max_x+2-min_x)*worldRegionMultiplier, | |
(max_y+2-min_y)*worldRegionMultiplier, | |
regionStrings) | |
if (landmass_name == "") then | |
landmass_name = "Unsorted" | |
if df.world_region_type[region.type] == "Ocean" then | |
landmass_name = "Water" | |
end | |
end | |
local landmass = landmasses[landmass_name] | |
if landmass == nil then | |
landmass = {} | |
end | |
write_group(no.."-"..region_name, className, nil, nil, regionStrings, landmass) | |
landmasses[landmass_name] = landmass | |
end | |
log:write("<g id=\"regions\">") | |
--Draw oceans first. | |
if landmasses["Water"] ~= nil then | |
landmass = landmasses["Water"] | |
log:write("\t<g id=\"Water\">") | |
for _,strings in pairs(landmass) do | |
log:write("\t\t"..strings) | |
end | |
log:write("\t</g>") | |
end | |
for landmass_name, landmass in pairs(landmasses) do | |
if landmass_name ~= "Water" then | |
log:write("\t<g id=\""..landmass_name.."\">") | |
for _,strings in pairs(landmass) do | |
log:write("\t\t"..strings) | |
end | |
log:write("\t</g>") | |
end | |
end | |
log:write("</g>") | |
log:write("<g id=\"rivers\">") | |
for no, river in pairs(df.global.world.world_data.rivers) do | |
local river_name = "" | |
local path = "" | |
if (river.name) then | |
river_name = dfhack.TranslateName(river.name, true, true) | |
end | |
local max_x = 0 | |
local max_y = 0 | |
local min_x = width | |
local min_y = width | |
for point, x in pairs (river.path.x) do | |
if (path == "") then | |
path = string.format("M %s %s", write_double((x+0.5)*worldRegionMultiplier), | |
write_double((river.path.y[point]+0.5)*worldRegionMultiplier)) | |
else | |
path = string.format("%s L %s %s", path, write_double((x+0.5)*worldRegionMultiplier), | |
write_double((river.path.y[point]+0.5)*worldRegionMultiplier)) | |
end | |
max_x = math.max(x, max_x) | |
max_y = math.max(river.path.y[point], max_y) | |
min_x = math.min(x, min_x) | |
min_y = math.min(river.path.y[point], min_y) | |
end | |
path = string.format("%s L %s %s", path, write_double((river.end_pos.x+0.5)*worldRegionMultiplier), | |
write_double((river.end_pos.y+0.5)*worldRegionMultiplier)) | |
max_x = math.max(river.end_pos.x, max_x) | |
max_y = math.max(river.end_pos.y, max_y) | |
min_x = math.min(river.end_pos.x, min_x) | |
min_y = math.min(river.end_pos.y, min_y) | |
stroke_width = river.flow[0] | |
for _, flow in pairs(river.flow) do | |
if flow > stroke_width then | |
stroke_width = flow | |
end | |
end | |
river_type = "Stream" | |
if stroke_width >= 5000 then | |
river_type = "Minor River" | |
end | |
if stroke_width >= 10000 then | |
river_type = "River" | |
end | |
if stroke_width > 20000 then | |
river_type = "Major River" | |
end | |
stroke_width = math.floor(stroke_width / 40000 * 46) + 1 | |
print(stroke_width) | |
stroke_width = math.max(math.min(stroke_width*0.5, 15), 1) | |
listOfStrings = {} | |
write_view(no.."-"..river_name.."-view", | |
(min_x-0.5)*worldRegionMultiplier, | |
(min_y-0.5)*worldRegionMultiplier, | |
(max_x-min_x+2.5)*worldRegionMultiplier, | |
(max_y-min_y+2.5)*worldRegionMultiplier, | |
listOfStrings) | |
write_path(no.."-"..river_name, "river "..string.lower(river_type), path, string.format("stroke-width: %s; fill: %s; ", write_double(stroke_width), "none"), river_name..", "..river_type, listOfStrings) | |
linkStrings = {} | |
write_link(nil,string.lower(remove_spaces(no.."-"..river_name.."-view")), nil, listOfStrings, linkStrings) | |
for _, string in pairs(linkStrings) do | |
log:write("\t"..string.."\n") | |
end | |
end | |
log:write("</g>") | |
log:write("<g id=\"mountain_peaks\">") | |
for no, peak in pairs(df.global.world.world_data.mountain_peaks) do | |
local peak_name = "" | |
if (peak.name) then | |
peak_name = dfhack.TranslateName(peak.name, true, true) | |
end | |
local fgcolor = "black" | |
local bgcolor = "grey" | |
local typeName = "Mountain Peak" | |
if peak.flags.is_volcano then | |
bgcolor = "red" | |
typeName = "Volcano" | |
end | |
listOfStrings = {} | |
write_text(nil, nil, 0.5*worldRegionMultiplier, worldRegionMultiplier, "font-size:"..write_double(0.1*worldRegionMultiplier)..";text-anchor:middle;stroke:"..fgcolor..";stroke-width:"..write_double(0.1*worldRegionMultiplier)..";fill:"..bgcolor..";paint-order:stroke markers fill", "^", listOfStrings) | |
table.insert(listOfStrings, "<title>"..peak_name..", "..typeName) | |
table.insert(listOfStrings, peak.height.." tiles high</title>") | |
log:write("<g id=\""..no.."-"..remove_spaces(peak_name).."\" transform=\"translate("..write_double(peak.pos.x*worldRegionMultiplier).." , "..write_double(peak.pos.y*worldRegionMultiplier)..")\" >\n") | |
for _, string in pairs(listOfStrings) do | |
log:write("\t"..string.."\n") | |
end | |
log:write("</g>\n") | |
end | |
log:write("</g>") | |
log:write("<g id=\"world_constructions\">") | |
for no, construction in pairs(df.global.world.world_data.constructions.list) do | |
local path = "" | |
local bridgeRect = {} | |
local construction_name = "" | |
local typeName = "road" | |
local matName = "" | |
local dashes = "" | |
if (construction.name) then | |
construction_name = dfhack.TranslateName(construction.name, true, true) | |
end | |
local max_x = 0 | |
local max_y = 0 | |
local min_x = width | |
local min_y = width | |
if (#construction.square_pos.x > 1) then | |
for point, x in pairs (construction.square_pos.x) do | |
if (path == "") then | |
path = string.format("M %s %s", write_double((x+0.5)*worldRegionMultiplier), | |
write_double((construction.square_pos.y[point]+0.5)*worldRegionMultiplier)) | |
else | |
path = string.format("%s L %s %s", path, write_double((x+0.5)*worldRegionMultiplier), | |
write_double((construction.square_pos.y[point]+0.5)*worldRegionMultiplier)) | |
end | |
max_x = math.max(x, max_x) | |
max_y = math.max(construction.square_pos.y[point], max_y) | |
min_x = math.min(x, min_x) | |
min_y = math.min(construction.square_pos.y[point], min_y) | |
end | |
else | |
write_rect(nil, construction.square_pos.x[0]*worldRegionMultiplier, construction.square_pos.y[0]*worldRegionMultiplier, worldRegionMultiplier, worldRegionMultiplier, nil, bridgeRect) | |
end | |
if (construction._type==df.world_construction_roadst) then | |
print(construction.square_obj[0].item_type) | |
if construction.square_obj[0].item_type == 0 then | |
matName = "-bars" | |
end | |
if construction.square_obj[0].item_type == 1 then | |
matName = "-smallgem" | |
end | |
if construction.square_obj[0].item_type == 2 then | |
matName = "-blocks" | |
end | |
if construction.square_obj[0].item_type == 3 then | |
matName = "-rough" | |
end | |
if construction.square_obj[0].item_type == 4 then | |
matName = "-boulder" | |
end | |
if construction.square_obj[0].item_type == 5 then | |
matName = "-wood" | |
end | |
end | |
if (construction._type==df.world_construction_bridgest) then | |
typeName = "bridge" | |
end | |
if (construction._type==df.world_construction_tunnelst) then | |
typeName = "tunnel" | |
end | |
if (construction._type==df.world_construction_wallst) then | |
typeName = "wall" | |
end | |
if (path ~= "") then | |
listOfStrings = {} | |
write_path(no.."-"..remove_spaces(construction_name), typeName.." "..typeName..matName, path, nil, construction_name..", "..typeName, listOfStrings) | |
write_view(no.."-"..construction_name.."-view", | |
(min_x-0.5)*worldRegionMultiplier, | |
(min_y-0.5)*worldRegionMultiplier, | |
(max_x-min_x+2.5)*worldRegionMultiplier, | |
(max_y-min_y+2.5)*worldRegionMultiplier, | |
listOfStrings) | |
local linkStrings= {} | |
write_link(nil,string.lower(remove_spaces(no.."-"..construction_name.."-view")), nil, listOfStrings, linkStrings) | |
for _, string in pairs(linkStrings) do | |
log:write("\t"..string.."\n") | |
end | |
else | |
log:write("<g id=\""..no.."-"..remove_spaces(construction_name).."\" style=\"fill:url(#construction-"..typeName.."); opacity:0.1;\" >\n") | |
log:write(bridgeRect[1]) | |
log:write("\t<title>"..construction_name..", "..typeName.."\n") | |
log:write("</title>\n") | |
log:write("</g>\n") | |
end | |
end | |
log:write("</g>") | |
--links = {} | |
totalSiteStrings = {} | |
for no, site in pairs(df.global.world.world_data.sites) do | |
entities = df.global.world.entities.all | |
local site_name = "" | |
local typeName = "" | |
local symbol = "*" | |
local civilisation = "none" | |
local government = "no government" | |
local population = "unknown" | |
local fgcolor = "url(#neutral-fg)" | |
local bgcolor = "url(#neutral-bg)" | |
local site_width = math.max(site.global_max_x-site.global_min_x, 2) | |
local site_height = math.max(site.global_max_y-site.global_min_y, 2) | |
if (site.name) then | |
site_name = dfhack.TranslateName(site.name, true, true) | |
end | |
if (site_name == "") then | |
site_name = dfhack.TranslateName(site.name) | |
end | |
if (site.type~=nil) then | |
if (df.world_site_type[site.type]~=nil) then | |
typeName = df.world_site_type[site.type] | |
end | |
if typeName == "Cave" or typeName == "Lair" or typeName == "LairShrine" then | |
symbol = "•" | |
end | |
if (site.subtype_info~=nil) then | |
if (site.subtype_info.fortress_type>-1) then | |
typeName = string.lower(df.fortress_type[site.subtype_info.fortress_type]) | |
if (typeName == "tower") then | |
symbol = "I" | |
elseif (typeName == "monastery" or typeName == "castle") then | |
symbol = "○" | |
elseif (typeName == "fort") then | |
symbol = "◙" | |
else | |
print(siteName, "unknown fort type", typeName, site.subtype_info.fortress_type) | |
end | |
end | |
if (site.subtype_info.monument_type>-1) then | |
typeName = string.lower(df.monument_type[site.subtype_info.monument_type]) | |
if (typeName == "vault") then | |
symbol= "■" | |
elseif (typeName == "tomb") then | |
symbol = "0" | |
else | |
print(siteName, "unknown monument type", typeName, site.subtype_info.monument_type) | |
end | |
end | |
if (site.subtype_info.lair_type>-1) then | |
typeName = string.lower(df.lair_type[site.subtype_info.lair_type]) | |
if (typeName == "simple_mound") then | |
symbol = "•" | |
elseif(typeName == "simple_burrow") then | |
symbol = "•" | |
elseif(typeName == "labyrinth") then | |
symbol = "#" | |
elseif(typeName == "shrine") then | |
symbol = "Å" | |
elseif (typeName == "wilderness_location") then | |
symbol = "•" | |
else | |
print(siteName, "unknown lair type", typeName, site.subtype_info.lair_type) | |
end | |
typeName = string.gsub(typeName, "_", " ") | |
end | |
end | |
if typeName == "MountainHalls" then | |
symbol = "Ω" | |
if site.is_mountain_halls>0 then | |
typeName = "Mountain Halls" | |
else | |
if site.is_fortress>0 then | |
typeName = "Mountain Fortress" | |
else | |
typeName = "Hillocks" | |
end | |
end | |
if(site.cur_owner_id==-1) then | |
symbol = "μ" | |
end | |
end | |
if typeName == "PlayerFortress" then | |
symbol = "Ω" | |
if(site.cur_owner_id==-1) then | |
symbol = "μ" | |
end | |
end | |
if typeName == "DarkFortress" then | |
symbol = "º" | |
typeName = "Dark Pits" | |
if(site.flags.Town == true) then | |
symbol = "Π" | |
typeName = "Dark Fortress" | |
end | |
if(site.cur_owner_id==-1) then | |
symbol = "μ" | |
end | |
end | |
if typeName == "Town" then | |
symbol = "=" | |
if(site.flags.Town == true) then | |
symbol = "+" | |
else | |
typeName = "Hamlet" | |
end | |
if(site.cur_owner_id==-1) then | |
symbol = "μ" | |
end | |
end | |
if typeName == "ImportantLocation" then | |
symbol = "!" | |
end | |
if typeName == "ForestRetreat" then | |
symbol = "î" | |
if(site.flags.Town == true) then | |
symbol = "¶" | |
end | |
if(site.cur_owner_id==-1) then | |
symbol = "μ" | |
end | |
end | |
end | |
if (site.civ_id>0) then | |
if site.civ_id <= #entities then | |
civilisation = dfhack.TranslateName(entities[site.civ_id].name, true, true) | |
if (civilisation == "") then | |
civilisation = dfhack.TranslateName(entities[site.civ_id].name) | |
end | |
if entities[site.civ_id].type == 0 then | |
fgcolor = "url(#"..site.civ_id.."-"..remove_spaces(civilisation).."-fg)" | |
bgcolor = "url(#"..site.civ_id.."-"..remove_spaces(civilisation).."-bg)" | |
else | |
local fgcoloro = df.global.world.raws.descriptors.colors[entities[site.civ_id].resources.foreground_color[0]] | |
local bgcoloro = df.global.world.raws.descriptors.colors[entities[site.civ_id].resources.background_color[0]] | |
fgcolor = "rgb("..math.floor(fgcoloro.red*255)..", "..math.floor(fgcoloro.green*255)..", "..math.floor(fgcoloro.blue*255)..")" | |
bgcolor = "rgb("..math.floor(bgcoloro.red*255)..", "..math.floor(bgcoloro.green*255)..", "..math.floor(bgcoloro.blue*255)..")" | |
end | |
end | |
if civilisation == nil then | |
civilisation = "Something is seriously wrong with the civ definitions here..."..site.civ_id | |
end | |
end | |
if (site.cur_owner_id>0) then | |
government = dfhack.TranslateName(entities[site.cur_owner_id].name, true, true) | |
if (government == "") then | |
government = dfhack.TranslateName(entities[site.cur_owner_id].name) | |
end | |
fgcolor = "" | |
for _, link in pairs(entities[site.cur_owner_id].entity_links) do | |
if (link.type==0) then | |
if entities[link.target].type == 0 then | |
civilisation = dfhack.TranslateName(entities[link.target].name, true, true) | |
if (civilisation == "") then | |
civilisation = dfhack.TranslateName(entities[link.target].name) | |
end | |
fgcolor = "url(#"..link.target.."-"..remove_spaces(civilisation).."-fg)" | |
bgcolor = "url(#"..link.target.."-"..remove_spaces(civilisation).."-bg)" | |
else | |
local fgcoloro = df.global.world.raws.descriptors.colors[entities[link.target].resources.foreground_color[0]] | |
local bgcoloro = df.global.world.raws.descriptors.colors[entities[link.target].resources.background_color[0]] | |
fgcolor = "rgb("..math.floor(fgcoloro.red*255)..", "..math.floor(fgcoloro.green*255)..", "..math.floor(fgcoloro.blue*255)..")" | |
bgcolor = "rgb("..math.floor(bgcoloro.red*255)..", "..math.floor(bgcoloro.green*255)..", "..math.floor(bgcoloro.blue*255)..")" | |
end | |
end | |
end | |
if fgcolor == "" then | |
local fgcoloro = df.global.world.raws.descriptors.colors[entities[site.cur_owner_id].resources.foreground_color[0]] | |
local bgcoloro = df.global.world.raws.descriptors.colors[entities[site.cur_owner_id].resources.background_color[0]] | |
fgcolor = "rgb("..math.floor(fgcoloro.red*255)..", "..math.floor(fgcoloro.green*255)..", "..math.floor(fgcoloro.blue*255)..")" | |
bgcolor = "rgb("..math.floor(bgcoloro.red*255)..", "..math.floor(bgcoloro.green*255)..", "..math.floor(bgcoloro.blue*255)..")" | |
end | |
else | |
if symbol == "μ" then | |
fgcolor = "url(#neutral-fg)" | |
bgcolor = "url(#neutral-bg)" | |
end | |
end | |
population = site.resident_count | |
if typeName == "Town" or typeName == "Hamlet" then | |
if site.flags.Town==true then | |
if population>1000 then | |
symbol = "*" | |
end | |
if population>2000 then | |
symbol = "#" | |
end | |
if population>5000 then | |
symbol = "☼" | |
end | |
else | |
if population>50 then | |
symbol = "æ" | |
end | |
end | |
end | |
siteStrings = {} | |
local path = "" | |
write_rect(nil, nil, nil, site_width, site_height, string.format("fill:#ffffff;fill-opacity:0.3;stroke:%s;stroke-width:%s; visibility:visible", bgcolor, write_double(0.1*worldRegionMultiplier)), siteStrings) | |
local dashes = string.format("%s, %s;", write_double(0.2*worldRegionMultiplier), write_double(0.2*worldRegionMultiplier)) | |
write_rect(nil, nil, nil, site_width, site_height, string.format("fill:none;stroke:%s;stroke-width:%s; stroke-dasharray:%s; visibility:visible", fgcolor, write_double(0.1*worldRegionMultiplier), dashes), siteStrings) | |
for _, link in pairs(site.entity_links) do | |
path = "" | |
entity = entities[link.entity_id] | |
local residence_name = "" | |
--find residence or location | |
for _, reslink in pairs(entity.site_links) do | |
if (reslink.flags["residence"] or reslink.flags["capital"]) and reslink.target ~= no+1 then | |
if reslink.target > -1 and reslink.target < #df.global.world.world_data.sites then | |
target_site = df.global.world.world_data.sites[reslink.target-1] | |
residence_name = dfhack.TranslateName(target_site.name, true, true) | |
local coord_x = ((target_site.global_max_x-target_site.global_min_x)*0.5)+target_site.global_min_x | |
coord_x = coord_x-site.global_min_x | |
local coord_y = ((target_site.global_max_y-target_site.global_min_y)*0.5)+target_site.global_min_y | |
coord_y = coord_y-site.global_min_y | |
path = string.format("M %s %s", write_double(coord_x), write_double(coord_y)) | |
end | |
end | |
end | |
for fname, fb in pairs(link.flags) do | |
if (fb and path~="") then | |
path2 = path..string.format(" L %s %s", write_double((site_width*0.5)), write_double((site_height*0.5))) | |
local link_title = dfhack.TranslateName(entity.name, true, true)..", "..df.historical_entity_type[entity.type] | |
link_title = link_title.."\n"..residence_name..", "..fname | |
write_path(nil, nil, path2, string.format("stroke:%s;stroke-opacity: %s; marker-start:url(#entity-link)", "url(#"..fname..")", write_double(link.link_strength*0.005)), link_title, siteStrings) | |
end | |
end | |
end | |
local title = site_name..", "..typeName.."\n" | |
if civilisation ~= "none" then | |
title = title.."Civilization:\t\t"..civilisation.."\n" | |
end | |
if government ~= "no government" then | |
title = title.."Government:\t"..government.."\n" | |
end | |
if population ~= 0 then | |
title = title.."Population:\t\t"..population.."\n" | |
end | |
table.insert(siteStrings, "<title>"..title.."</title>") | |
local style = string.format("font-size:%spx;text-anchor:middle;stroke:%s;stroke-width:%s;fill:%s;paint-order:stroke markers fill; visibility:visible", math.min(site_width, site_height), fgcolor, write_double(0.1*worldRegionMultiplier), bgcolor ) | |
write_text(nil, nil, 0.5*site_width, site_height, style, symbol, siteStrings) | |
write_group(no.."-"..site_name, "entity-site-link", string.format("translate( %s, %s)", site.global_min_x, site.global_min_y), nil, siteStrings, totalSiteStrings) | |
end | |
log:write("<g id=\"sites\">\n") | |
for _, string in pairs(totalSiteStrings) do | |
log:write(string) | |
end | |
log:write("</g>") | |
log:write("<g id=\"entity_claims\" visibility=\"hidden\">") | |
listOfStrings = {} | |
for no, entity in pairs(df.global.world.entities.all) do | |
if (#entity.claims.border.x) > 0 then | |
local entity_name = dfhack.TranslateName(entity.name, true, true) | |
if (entity_name == "") then | |
entity_name = dfhack.TranslateName(entity.name) | |
end | |
local typeName = df.historical_entity_type[entity.type] | |
local fgcolor = "url(#"..no.."-"..remove_spaces(entity_name).."-fg)" | |
local bgcolor = "url(#"..no.."-"..remove_spaces(entity_name).."-bg)" | |
print("bounding.. "..entity_name.." border") | |
local bordercoords = grid_to_border(entity.claims.border) | |
print("done") | |
local path = "" | |
local max_x = 0 | |
local max_y = 0 | |
local min_x = width | |
local min_y = width | |
for i, subpath in pairs(bordercoords) do | |
path = path.." M " | |
for p, point in pairs(subpath) do | |
if p ~= 1 then | |
path = path.." L " | |
end | |
path = path..write_double(point.x*worldRegionMultiplier).." "..write_double(point.y*worldRegionMultiplier) | |
max_x = math.max(point.x, max_x) | |
max_y = math.max(point.y, max_y) | |
min_x = math.min(point.x, min_x) | |
min_y = math.min(point.y, min_y) | |
end | |
path = path.." z" | |
end | |
local borderPath = {} | |
write_path(nil, nil, path, "stroke:"..fgcolor.."; fill:"..bgcolor.."; opacity:0.5; stroke-width:1;", nil, borderPath) | |
table.insert(borderPath, "<title>"..entity_name..", "..typeName.."") | |
table.insert(borderPath, "</title>\n") | |
write_view(no.."-"..entity_name.."-view", | |
min_x*worldRegionMultiplier, | |
min_y*worldRegionMultiplier, | |
(max_x-min_x)*worldRegionMultiplier, | |
(max_y-min_y)*worldRegionMultiplier, | |
borderPath) | |
write_group(no.."-"..entity_name, nil, nil, nil, borderPath, listOfStrings) | |
end | |
end | |
for _, string in pairs(listOfStrings) do | |
log:write(string) | |
end | |
log:write("</g>") | |
log:write("</svg>\n") | |
log:close() | |
print("Succesfully saved data to "..documentName) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment