I'm using Dfhack lua scripting to export the data to plain text and python to read the data.
Here's my lua script hope it helps.
function scene(unit)
-------------------------Map data---------------------
if unit==nil then
if df.global.gamemode==0 then
unit=dfhack.gui.getSelectedUnit()
else
unit=df.global.world.units.active[0] end
end
if unit==nil then
error("Unit not selected/valid")
end
z_t = 6 -- z coord cap
x_t = 20 -- x coord cap
y_t = 20 -- y coord cap
file = io.open("scene.dfv", "w")
count = 0
for z=unit.pos.z-(z_t/2), unit.pos.z+(z_t/2), 1 do
for y=unit.pos.y-y_t, unit.pos.y+y_t, 1 do
for x=unit.pos.x-x_t, unit.pos.x+x_t, 1 do
if dfhack.maps.getTileType(x,y,z) ~= 32 and dfhack.maps.getTileType(x,y,z) ~= nil then
count = count + 1
end
end
end
end
file:write(count)
file:write("\n")
for z=unit.pos.z-(z_t/2), unit.pos.z+(z_t/2), 1 do
for y=unit.pos.y-y_t, unit.pos.y+y_t, 1 do
for x=unit.pos.x-x_t, unit.pos.x+x_t, 1 do
if dfhack.maps.getTileType(x,y,z) ~= 32 and dfhack.maps.getTileType(x,y,z) ~= nil then
file:write(dfhack.maps.getTileType(x,y,z),",",x,",",y,",",z-100,",")
end
end
end
end
-------------------------Unit data---------------------
x_coord = unit.pos.x
y_coord = unit.pos.y
z_coord = unit.pos.z
current_year=df.global.cur_year
unit_count = 0
for i=#df.global.world.units.all-1,0,-1 do
if df.global.world.units.all.pos.x >= (x_coord-x_t) and df.global.world.units.all.pos.x <= (x_coord+x_t) and df.global.world.units.all.pos.y >= (y_coord-y_t) and df.global.world.units.all.pos.y <= (y_coord+y_t) and df.global.world.units.all.pos.z >= (z_coord-z_t) and df.global.world.units.all.pos.z <= (z_coord+z_t) then
unit_count = unit_count + 1
end
end
file:write("\n")
file:write(unit_count)
file:write("\n")
for i=#df.global.world.units.all-1,0,-1 do
if df.global.world.units.all.pos.x >= (x_coord-x_t) and df.global.world.units.all.pos.x <= (x_coord+x_t) and df.global.world.units.all.pos.y >= (y_coord-y_t) and df.global.world.units.all.pos.y <= (y_coord+y_t) and df.global.world.units.all.pos.z >= (z_coord-z_t) and df.global.world.units.all.pos.z <= (z_coord+z_t) then
unit=df.global.world.units.all
if unit.name.first_name == nil or unit.name.first_name == '' then
file:write("frob")
else
file:write(unit.name.first_name) -- First name
end
file:write(",")
file:write(current_year-unit.relations.birth_year) -- Age
file:write(",")
file:write(unit.race) -- Race
file:write(",")
file:write(unit.profession) -- Profession 1
file:write(",")
file:write(unit.profession2) -- Profession 2
file:write(",")
file:write(unit.sex) -- Gender 0 - female 1 - male
file:write(",")
file:write(unit.pos.x) -- Coordinate x
file:write(",")
file:write(unit.pos.y) -- Coordinate y
file:write(",")
file:write(unit.pos.z-100) -- Coordinate z
file:write(",")
file:write(#unit.body.body_plan.body_parts) -- Number of body parts
file:write("\n")
for i=#unit.body.body_plan.body_parts-1,0,-1 do
file:write(i+1)
file:write(",")
file:write(unit.body.body_plan.body_parts.token) -- See fingers and toes
file:write(",")
file:write(unit.body.body_plan.body_parts.category)
file:write(",")
file:write(unit.body.body_plan.body_parts.relsize)
file:write(",")
if unit.body.components.body_part_status.missing == true then -- i, unit.body.body_plan.body_parts[] == unit.body.components.body_part_status[]
file:write("True") -- severed boolean: see more
else
file:write("False") end -- severed boolean
file:write(",")
file:write(unit.body.body_plan.body_parts.number)
file:write("\n")
end
for j=#unit.body.wounds-1,0,-1 do
for k=#unit.body.wounds[j].parts-1,0,-1 do
file:write(unit.body.wounds[j].parts[k].body_part_id + 1)
file:write(",")
end
end
file:write("\n")
eqp_count = 0
for i=#unit.inventory-1,0,-1 do
for subt in pairs(unit.inventory.item) do
if subt == 'subtype' then
eqp_count = eqp_count + 1
end
end
end
file:write(eqp_count)
file:write("\n")
for i=#unit.inventory-1,0,-1 do
for subt in pairs(unit.inventory.item) do
if subt == 'subtype' then
if (string.find(unit.inventory.item.subtype.id,"(WEAPON)") or string.find(unit.inventory.item.subtype.id,"(SHIELD)") or string.find(unit.inventory.item.subtype.id,"(BUCKLER)") or string.find(unit.inventory.item.subtype.id,"(AMMO)") or string.find(unit.inventory.item.subtype.id,"(TOOL)")) == nil then
file:write(unit.inventory.item.subtype.id)
file:write(",")
file:write(unit.inventory.item.subtype.name)
file:write(",")
file:write(unit.body.body_plan.body_parts[unit.inventory.body_part_id].token)
file:write(",")
file:write(unit.inventory.item.quality)
file:write(",")
if unit.inventory.item.subtype.props.flags.METAL == true then
file:write('metal')
elseif unit.inventory.item.subtype.props.flags.BARRED == true then
file:write('barred')
elseif unit.inventory.item.subtype.props.flags.SCALED == true then
file:write('scaled')
elseif unit.inventory.item.subtype.props.flags.LEATHER == true then
file:write('leather')
else
file:write('unk')
end
file:write("\n")
else
file:write(unit.inventory.item.subtype.id)
file:write(",")
file:write(unit.inventory.item.subtype.name)
file:write(",")
file:write(unit.body.body_plan.body_parts[unit.inventory.body_part_id].token)
file:write(",")
file:write(unit.inventory.item.quality)
file:write(",")
file:write('metal')
file:write("\n")
end
end
end
end
end
end
file:close()
print("Done!")
if df.global.gamemode==0 then
print("Dwarf fortress export")
else
print("Adventure export") end
end
scene()