diff --git a/library/depends/protobuf/CMakeLists.txt b/library/depends/protobuf/CMakeLists.txt index 85c5a7be1..46711b418 100644 --- a/library/depends/protobuf/CMakeLists.txt +++ b/library/depends/protobuf/CMakeLists.txt @@ -199,6 +199,7 @@ google/protobuf/compiler/zip_writer.cc LIST(APPEND LIBPROTOBUF_FULL_SRCS ${LIBPROTOBUF_LITE_SRCS}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) +INCLUDE_DIRECTORIES(${dfhack_SOURCE_DIR}/library/depends/zlib) ADD_LIBRARY(protobuf-lite ${LIBPROTOBUF_LITE_SRCS} ${LIBPROTOBUF_LITE_HDRS}) ADD_LIBRARY(protobuf ${LIBPROTOBUF_FULL_SRCS} ${LIBPROTOBUF_FULL_HDRS}) diff --git a/library/depends/protobuf/config.h.in b/library/depends/protobuf/config.h.in index b636642a5..7da01520a 100644 --- a/library/depends/protobuf/config.h.in +++ b/library/depends/protobuf/config.h.in @@ -9,4 +9,4 @@ /* define if you want to use zlib. See readme.txt for additional * requirements. */ -// #define HAVE_ZLIB 1 +#define HAVE_ZLIB 1 diff --git a/library/xml b/library/xml index 03b768f11..64a7aeb6a 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 03b768f1158e675f2a4937ce857f2cd5acb58103 +Subproject commit 64a7aeb6a87b7b5067ace8f6a869b7b4fe6561a4 diff --git a/plugins/df2mc b/plugins/df2mc index 23fbb78ed..c114ec5f9 160000 --- a/plugins/df2mc +++ b/plugins/df2mc @@ -1 +1 @@ -Subproject commit 23fbb78edaff35a62887803e178a24f9148ffc84 +Subproject commit c114ec5f995aec69631187212254309464f82775 diff --git a/plugins/mapexport/CMakeLists.txt b/plugins/mapexport/CMakeLists.txt index 68422f5bb..d3ff25857 100644 --- a/plugins/mapexport/CMakeLists.txt +++ b/plugins/mapexport/CMakeLists.txt @@ -1,8 +1,13 @@ PROJECT(mapexport) -include_directories ( +INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ${dfhack_SOURCE_DIR}/library/depends/protobuf/ + ${dfhack_SOURCE_DIR}/library/depends/zlib/ +) + +LINK_DIRECTORIES( + ${dfhack_SOURCE_DIR}/library/depends/zlib/ ) #The protobuf sources we generate will require these headers @@ -22,7 +27,9 @@ mapexport.cpp SET(PROJECT_PROTOS ${CMAKE_CURRENT_SOURCE_DIR}/proto/Tile.proto +${CMAKE_CURRENT_SOURCE_DIR}/proto/Plant.proto ${CMAKE_CURRENT_SOURCE_DIR}/proto/Block.proto +${CMAKE_CURRENT_SOURCE_DIR}/proto/Material.proto ${CMAKE_CURRENT_SOURCE_DIR}/proto/Map.proto ) @@ -43,4 +50,8 @@ COMMAND protoc-bin -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/ --cpp_out=${CMAKE_CURRE DEPENDS protoc-bin ${PROJECT_PROTOS} ) -DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf) +IF(WIN32) + DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf zlib) +ELSE() + DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf z) +ENDIF() diff --git a/plugins/mapexport/mapexport.cpp b/plugins/mapexport/mapexport.cpp index 033398274..23b5695c8 100644 --- a/plugins/mapexport/mapexport.cpp +++ b/plugins/mapexport/mapexport.cpp @@ -6,13 +6,22 @@ using namespace DFHack; #include +#include +#include +#include +using namespace google::protobuf::io; #include "DataDefs.h" #include "df/world.h" +#include "modules/Constructions.h" #include "proto/Map.pb.h" +#include "proto/Block.pb.h" -using namespace DFHack::Simple; +using namespace DFHack; +using df::global::world; + +typedef std::vector PlantList; DFhackCExport command_result mapexport (Core * c, std::vector & parameters); @@ -37,25 +46,29 @@ DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result mapexport (Core * c, std::vector & parameters) { + bool showHidden = false; + + int filenameParameter = 1; + for(size_t i = 0; i < parameters.size();i++) { if(parameters[i] == "help" || parameters[i] == "?") { c->con.print("Exports the currently visible map to a file.\n" - "Usage: mapexport \n" + "Usage: mapexport [options] \n" + "Example: mapexport all embark.dfmap\n" + "Options:\n" + " all - Export the entire map, not just what's revealed." ); return CR_OK; } + if (parameters[i] == "all") + { + showHidden = true; + filenameParameter++; + } } - std::string filename; - if (parameters.size() < 1) - { - c->con.printerr("Please supply a filename.\n"); - return CR_OK; - } - filename = parameters[0]; - bool showHidden = true; uint32_t x_max=0, y_max=0, z_max=0; c->Suspend(); @@ -65,29 +78,83 @@ DFhackCExport command_result mapexport (Core * c, std::vector & pa c->Resume(); return CR_FAILURE; } + + if (parameters.size() < filenameParameter) + { + c->con.printerr("Please supply a filename.\n"); + c->Resume(); + return CR_FAILURE; + } + + std::string filename = parameters[filenameParameter-1]; + if (filename.rfind(".dfmap") == std::string::npos) filename += ".dfmap"; + c->con << "Writing to " << filename << "..." << std::endl; + + std::ofstream output_file(filename, std::ios::out | std::ios::trunc | std::ios::binary); + if (!output_file.is_open()) + { + c->con.printerr("Couldn't open the output file.\n"); + c->Resume(); + return CR_FAILURE; + } + ZeroCopyOutputStream *raw_output = new OstreamOutputStream(&output_file); + GzipOutputStream *zip_output = new GzipOutputStream(raw_output); + CodedOutputStream *coded_output = new CodedOutputStream(zip_output); + + coded_output->WriteLittleEndian32(0x50414DDF); //Write our file header + Maps::getSize(x_max, y_max, z_max); MapExtras::MapCache map; DFHack::Materials *mats = c->getMaterials(); - if (!Vegetation::isValid()) - { - c->con.printerr("Unable to read vegetation; plants won't be listed!\n" ); - } + c->con << "Writing map info..." << std::endl; dfproto::Map protomap; protomap.set_x_size(x_max); protomap.set_y_size(y_max); protomap.set_z_size(z_max); + c->con << "Writing material dictionary..." << std::endl; + + for (size_t i = 0; i < world->raws.inorganics.size(); i++) + { + dfproto::Material *protomaterial = protomap.add_inorganic_material(); + protomaterial->set_type(i); + protomaterial->set_name(world->raws.inorganics[i]->id); + } + + for (size_t i = 0; i < world->raws.plants.all.size(); i++) + { + dfproto::Material *protomaterial = protomap.add_organic_material(); + protomaterial->set_type(i); + protomaterial->set_name(world->raws.plants.all[i]->id); + } + + std::map > constructionMaterials; + if (Constructions::isValid()) + { + for (uint32_t i = 0; i < Constructions::getCount(); i++) + { + df::construction *construction = Constructions::getConstruction(i); + constructionMaterials[construction->pos] = std::make_pair(construction->mat_index, construction->mat_type); + } + } + + coded_output->WriteVarint32(protomap.ByteSize()); + protomap.SerializeToCodedStream(coded_output); + DFHack::t_feature blockFeatureGlobal; DFHack::t_feature blockFeatureLocal; + c->con.print("Writing map block information"); + 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++) { + if (b_x == 0 && b_y == 0 && z % 10 == 0) c->con.print("."); // Get the map block df::coord2d blockCoord(b_x, b_y); MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z)); @@ -96,10 +163,10 @@ DFhackCExport command_result mapexport (Core * c, std::vector & pa continue; } - dfproto::Block *protoblock = protomap.add_block(); - protoblock->set_x(b_x); - protoblock->set_y(b_y); - protoblock->set_z(z); + dfproto::Block protoblock; + protoblock.set_x(b_x); + protoblock.set_y(b_y); + protoblock.set_z(z); { // Find features uint32_t index = b->raw.global_feature; @@ -128,52 +195,96 @@ DFhackCExport command_result mapexport (Core * c, std::vector & pa continue; } - dfproto::Tile *prototile = protoblock->add_tile(); + dfproto::Tile *prototile = protoblock.add_tile(); prototile->set_x(x); prototile->set_y(y); // Check for liquid if (des.bits.flow_size) { - //if (des.bits.liquid_type == df::tile_liquid::Magma) - - //else + prototile->set_liquid_type((dfproto::Tile::LiquidType)des.bits.liquid_type); + prototile->set_flow_size(des.bits.flow_size); } uint16_t type = b->TileTypeAt(coord); const DFHack::TileRow *info = DFHack::getTileRow(type); prototile->set_type((dfproto::Tile::TileType)info->shape); - /*switch (info->shape) - { - case DFHack::WALL: - prototile->set_type(dfproto::Tile::WALL); + + prototile->set_material_type((dfproto::Tile::MaterialType)info->material); + + df::coord map_pos = df::coord(b_x*16+x,b_y*16+y,z); + + switch (info->material) + { + case DFHack::SOIL: + case DFHack::STONE: + prototile->set_material_index(0); + prototile->set_material(b->baseMaterialAt(coord)); + break; + case DFHack::VEIN: + prototile->set_material_index(0); + prototile->set_material(b->veinMaterialAt(coord)); + break; + case DFHack::FEATSTONE: + if (blockFeatureLocal.type != -1 && des.bits.feature_local) + { + if (blockFeatureLocal.type == df::feature_type::deep_special_tube + && blockFeatureLocal.main_material == 0) // stone + { + prototile->set_material_index(0); + prototile->set_material(blockFeatureLocal.sub_material); + } + if (blockFeatureGlobal.type != -1 && des.bits.feature_global + && blockFeatureGlobal.type == df::feature_type::feature_underworld_from_layer + && blockFeatureGlobal.main_material == 0) // stone + { + prototile->set_material_index(0); + prototile->set_material(blockFeatureGlobal.sub_material); + } + } break; - default: + case DFHack::CONSTRUCTED: + if (constructionMaterials.find(map_pos) != constructionMaterials.end()) + { + prototile->set_material_index(constructionMaterials[map_pos].first); + prototile->set_material(constructionMaterials[map_pos].second); + } break; - }*/ + } } } - } // block x + PlantList *plants; + if (Maps::ReadVegetation(b_x, b_y, z, plants)) + { + for (PlantList::const_iterator it = plants->begin(); it != plants->end(); it++) + { + dfproto::Plant *protoplant = protoblock.add_plant(); + const df::plant & plant = *(*it); + df::coord2d loc(plant.pos.x, plant.pos.y); + loc = loc % 16; + if (showHidden || !b->DesignationAt(loc).bits.hidden) + { + protoplant->set_is_shrub(plant.flags.bits.is_shrub); + protoplant->set_material(plant.material); + } + } + } + + coded_output->WriteVarint32(protoblock.ByteSize()); + protoblock.SerializeToCodedStream(coded_output); + } // block x // Clean uneeded memory map.trash(); } // block y } // z - 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"); + delete coded_output; + delete zip_output; + delete raw_output; + + mats->Finish(); + c->con.print("\nMap succesfully exported!\n"); c->Resume(); return CR_OK; } diff --git a/plugins/mapexport/proto/Block.proto b/plugins/mapexport/proto/Block.proto index 7a73d33b1..1540ce52c 100644 --- a/plugins/mapexport/proto/Block.proto +++ b/plugins/mapexport/proto/Block.proto @@ -1,7 +1,8 @@ package dfproto; -//option optimize_for = LITE_RUNTIME; +option optimize_for = LITE_RUNTIME; import "Tile.proto"; +import "Plant.proto"; message Block { @@ -9,4 +10,5 @@ message Block required uint32 y = 2; required uint32 z = 3; repeated Tile tile = 4; -} + repeated Plant plant = 5; +} \ No newline at end of file diff --git a/plugins/mapexport/proto/Map.proto b/plugins/mapexport/proto/Map.proto index 8801dafa4..bf3e7bd23 100644 --- a/plugins/mapexport/proto/Map.proto +++ b/plugins/mapexport/proto/Map.proto @@ -1,12 +1,13 @@ package dfproto; -//option optimize_for = LITE_RUNTIME; +option optimize_for = LITE_RUNTIME; -import "Block.proto"; +import "Material.proto"; message Map { required uint32 x_size = 1; required uint32 y_size = 2; required uint32 z_size = 3; - repeated Block block = 4; -} + repeated Material inorganic_material = 4; + repeated Material organic_material = 5; +} \ No newline at end of file diff --git a/plugins/mapexport/proto/Material.proto b/plugins/mapexport/proto/Material.proto new file mode 100644 index 000000000..af8ebcd46 --- /dev/null +++ b/plugins/mapexport/proto/Material.proto @@ -0,0 +1,8 @@ +package dfproto; +option optimize_for = LITE_RUNTIME; + +message Material +{ + required uint32 type = 1; + required string name = 2; +} \ No newline at end of file diff --git a/plugins/mapexport/proto/Plant.proto b/plugins/mapexport/proto/Plant.proto new file mode 100644 index 000000000..74500d170 --- /dev/null +++ b/plugins/mapexport/proto/Plant.proto @@ -0,0 +1,10 @@ +package dfproto; +option optimize_for = LITE_RUNTIME; + +message Plant +{ + required uint32 x = 1; + required uint32 y = 2; + required bool is_shrub = 3; + optional uint32 material = 4; +} \ No newline at end of file diff --git a/plugins/mapexport/proto/Tile.proto b/plugins/mapexport/proto/Tile.proto index ecf8c2e5e..51ffcc0e7 100644 --- a/plugins/mapexport/proto/Tile.proto +++ b/plugins/mapexport/proto/Tile.proto @@ -1,38 +1,67 @@ package dfproto; -//option optimize_for = LITE_RUNTIME; +option optimize_for = LITE_RUNTIME; message Tile { + enum TileType + { + EMPTY = 0; + WALL = 1; + PILLAR = 2; + BROOK_BED = 3; + FORTIFICATION = 4; + STAIR_UP = 5; + STAIR_DOWN = 6; + STAIR_UPDOWN = 7; + RAMP = 8; + RAMP_TOP = 9; + FLOOR = 10; + BROOK_TOP = 11; + RIVER_BED = 12; + POOL = 13; + TREE_DEAD = 14; + TREE_OK = 15; + SAPLING_DEAD = 16; + SAPLING_OK = 17; + SHRUB_DEAD = 18; + SHRUB_OK = 19; + BOULDER = 20; + PEBLLES = 21; + ENDLESS_PIT = 22; + } + enum LiquidType + { + WATER = 0; + MAGMA = 1; + } + enum MaterialType + { + AIR = 0; + SOIL = 1; + STONE = 2; + FEATSTONE = 3; + OBSIDIAN = 4; + VEIN = 5; + ICE = 6; + GRASS = 7; + GRASS2 = 8; + GRASS_DEAD = 9; + GRASS_DRY = 10; + DRIFTWOOD = 11; + HFS = 12; + MAGMA_TYPE = 13; + CAMPFIRE = 14; + FIRE = 15; + ASHES = 16; + CONSTRUCTED = 17; + CYAN_GLOW = 18; + } required uint32 x = 1; required uint32 y = 2; - - enum TileType - { - EMPTY = 0; - WALL = 1; - PILLAR = 2; - BROOK_BED = 3; - FORTIFICATION = 4; - STAIR_UP = 5; - STAIR_DOWN = 6; - STAIR_UPDOWN = 7; - RAMP = 8; - RAMP_TOP = 9; - FLOOR = 10; - BROOK_TOP = 11; - RIVER_BED = 12; - POOL = 13; - TREE_DEAD = 14; - TREE_OK = 15; - SAPLING_DEAD = 16; - SAPLING_OK = 17; - SHRUB_DEAD = 18; - SHRUB_OK = 19; - BOULDER = 20; - PEBLLES = 21; - ENDLESS_PIT = 22; - } - required TileType type = 3; - - optional uint32 material = 4; + required TileType type = 3; + optional MaterialType material_type = 4; + optional uint32 material_index = 5; + optional uint32 material = 6; + optional LiquidType liquid_type = 7; + optional uint32 flow_size = 8; } diff --git a/plugins/stonesense b/plugins/stonesense index f824e83b5..92627e39c 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit f824e83b5c4f4dfc1bbe60681d8dc6ed88f3f4f9 +Subproject commit 92627e39cb3502812cd5a131716d3d1da8ef625a