2012-01-19 23:15:51 -07:00
|
|
|
#include "Core.h"
|
2012-01-20 15:51:51 -07:00
|
|
|
#include "Console.h"
|
|
|
|
#include "Export.h"
|
|
|
|
#include "PluginManager.h"
|
|
|
|
#include "modules/MapCache.h"
|
|
|
|
using namespace DFHack;
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include "DataDefs.h"
|
|
|
|
#include "df/world.h"
|
2012-01-20 12:21:29 -07:00
|
|
|
|
|
|
|
#include "proto/Map.pb.h"
|
2012-01-19 23:15:51 -07:00
|
|
|
|
|
|
|
DFhackCExport command_result mapexport (Core * c, std::vector <std::string> & parameters);
|
|
|
|
|
|
|
|
DFhackCExport const char * plugin_name ( void )
|
|
|
|
{
|
|
|
|
return "mapexport";
|
|
|
|
}
|
|
|
|
|
|
|
|
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
|
|
|
|
{
|
2012-01-20 10:17:08 -07:00
|
|
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
2012-01-19 23:15:51 -07:00
|
|
|
commands.clear();
|
2012-01-20 15:51:51 -07:00
|
|
|
commands.push_back(PluginCommand("mapexport", "Exports the current map to a file.", mapexport, true));
|
2012-01-19 23:15:51 -07:00
|
|
|
return CR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
DFhackCExport command_result plugin_shutdown ( Core * c )
|
|
|
|
{
|
2012-01-20 10:17:08 -07:00
|
|
|
google::protobuf::ShutdownProtobufLibrary();
|
2012-01-19 23:15:51 -07:00
|
|
|
return CR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
DFhackCExport command_result mapexport (Core * c, std::vector <std::string> & parameters)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < parameters.size();i++)
|
|
|
|
{
|
|
|
|
if(parameters[i] == "help" || parameters[i] == "?")
|
|
|
|
{
|
2012-01-20 15:51:51 -07:00
|
|
|
c->con.print("Exports the currently visible map to a file.\n"
|
|
|
|
"Usage: mapexport <filename>\n"
|
|
|
|
);
|
2012-01-19 23:15:51 -07:00
|
|
|
return CR_OK;
|
|
|
|
}
|
|
|
|
}
|
2012-01-20 17:21:50 -07:00
|
|
|
std::string filename;
|
|
|
|
if (parameters.size() < 1)
|
|
|
|
{
|
|
|
|
c->con.printerr("Please supply a filename.\n");
|
|
|
|
return CR_OK;
|
|
|
|
}
|
|
|
|
filename = parameters[0];
|
2012-01-19 23:15:51 -07:00
|
|
|
|
2012-01-20 15:51:51 -07:00
|
|
|
bool showHidden = true;
|
|
|
|
|
|
|
|
uint32_t x_max=0, y_max=0, z_max=0;
|
2012-01-19 23:15:51 -07:00
|
|
|
c->Suspend();
|
2012-01-20 15:51:51 -07:00
|
|
|
if (!Maps::IsValid())
|
|
|
|
{
|
|
|
|
c->con.printerr("Map is not available!\n");
|
|
|
|
c->Resume();
|
|
|
|
return CR_FAILURE;
|
|
|
|
}
|
|
|
|
Maps::getSize(x_max, y_max, z_max);
|
|
|
|
MapExtras::MapCache map;
|
|
|
|
DFHack::Materials *mats = c->getMaterials();
|
|
|
|
|
|
|
|
DFHack::Vegetation *veg = c->getVegetation();
|
|
|
|
if (veg->Start())
|
|
|
|
{
|
|
|
|
c->con.printerr("Unable to read vegetation; plants won't be listed!\n" );
|
|
|
|
}
|
|
|
|
|
2012-01-20 17:21:50 -07:00
|
|
|
dfproto::Map protomap;
|
|
|
|
protomap.set_x_size(x_max);
|
|
|
|
protomap.set_y_size(y_max);
|
|
|
|
protomap.set_z_size(z_max);
|
2012-01-20 15:51:51 -07:00
|
|
|
|
|
|
|
DFHack::t_feature blockFeatureGlobal;
|
|
|
|
DFHack::t_feature blockFeatureLocal;
|
|
|
|
|
|
|
|
for(uint32_t z = 0; z < z_max; z++)
|
|
|
|
{
|
|
|
|
for(uint32_t b_y = 0; b_y < y_max; b_y++)
|
|
|
|
{
|
|
|
|
for(uint32_t b_x = 0; b_x < x_max; b_x++)
|
|
|
|
{
|
|
|
|
// Get the map block
|
|
|
|
df::coord2d blockCoord(b_x, b_y);
|
|
|
|
MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z));
|
|
|
|
if (!b || !b->valid)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-01-20 17:21:50 -07:00
|
|
|
dfproto::Block *protoblock = protomap.add_block();
|
|
|
|
protoblock->set_x(b_x);
|
|
|
|
protoblock->set_y(b_y);
|
|
|
|
protoblock->set_z(z);
|
2012-01-20 15:51:51 -07:00
|
|
|
|
|
|
|
{ // Find features
|
|
|
|
uint32_t index = b->raw.global_feature;
|
|
|
|
if (index != -1)
|
|
|
|
Maps::GetGlobalFeature(blockFeatureGlobal, index);
|
|
|
|
|
|
|
|
index = b->raw.local_feature;
|
|
|
|
if (index != -1)
|
|
|
|
Maps::GetLocalFeature(blockFeatureLocal, blockCoord, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
int global_z = df::global::world->map.region_z + z;
|
|
|
|
|
|
|
|
// Iterate over all the tiles in the block
|
|
|
|
for(uint32_t y = 0; y < 16; y++)
|
|
|
|
{
|
|
|
|
for(uint32_t x = 0; x < 16; x++)
|
|
|
|
{
|
|
|
|
df::coord2d coord(x, y);
|
|
|
|
df::tile_designation des = b->DesignationAt(coord);
|
|
|
|
df::tile_occupancy occ = b->OccupancyAt(coord);
|
|
|
|
|
|
|
|
// Skip hidden tiles
|
|
|
|
if (!showHidden && des.bits.hidden)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-01-20 17:21:50 -07:00
|
|
|
dfproto::Tile *prototile = protoblock->add_tile();
|
|
|
|
prototile->set_x(x);
|
|
|
|
prototile->set_y(y);
|
2012-01-20 15:51:51 -07:00
|
|
|
|
|
|
|
// Check for liquid
|
|
|
|
if (des.bits.flow_size)
|
|
|
|
{
|
|
|
|
//if (des.bits.liquid_type == df::tile_liquid::Magma)
|
|
|
|
|
|
|
|
//else
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t type = b->TileTypeAt(coord);
|
|
|
|
const DFHack::TileRow *info = DFHack::getTileRow(type);
|
2012-01-20 17:21:50 -07:00
|
|
|
prototile->set_type((dfproto::Tile::TileType)info->shape);
|
2012-01-20 15:51:51 -07:00
|
|
|
/*switch (info->shape)
|
|
|
|
{
|
|
|
|
case DFHack::WALL:
|
|
|
|
prototile->set_type(dfproto::Tile::WALL);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // block x
|
|
|
|
|
|
|
|
// Clean uneeded memory
|
|
|
|
map.trash();
|
|
|
|
} // block y
|
|
|
|
} // z
|
|
|
|
|
2012-01-20 17:21:50 -07:00
|
|
|
std::ofstream output(filename, std::ios::out | std::ios::trunc | std::ios::binary);
|
|
|
|
if (!output.is_open())
|
|
|
|
{
|
|
|
|
c->con.printerr("Couldn't open the output file.\n");
|
|
|
|
c->Resume();
|
|
|
|
return CR_FAILURE;
|
|
|
|
}
|
|
|
|
if (!protomap.SerializeToOstream(&output))
|
|
|
|
{
|
|
|
|
c->con.printerr("Failed to save map file.\n");
|
|
|
|
c->Resume();
|
|
|
|
return CR_FAILURE;
|
|
|
|
}
|
|
|
|
c->con.print("Map succesfully exported.\n");
|
2012-01-19 23:15:51 -07:00
|
|
|
c->Resume();
|
|
|
|
return CR_OK;
|
|
|
|
}
|