StockpileInfo(building_stockpilest *sp_) : sp(sp_) { MapExtras::MapCache mc; z = sp_->z; x1 = sp_->room.x; x2 = sp_->room.x + sp_->room.width; y1 = sp_->room.y; y2 = sp_->room.y + sp_->room.height; int e = 0; size = 0; free = 0; for (int y = y1; y < y2; y++) for (int x = x1; x < x2; x++) if (sp_->room.extents[e++] == 1) { size++; DFCoord cursor (x,y,z); uint32_t blockX = x / 16; uint32_t tileX = x % 16; uint32_t blockY = y / 16; uint32_t tileY = y % 16; MapExtras::Block * b = mc.BlockAt(cursor/16); if(b && b->is_valid()) { auto &block = *b->getRaw(); df::tile_occupancy &occ = block.occupancy[tileX][tileY]; if (!occ.bits.item) free++; } } }
command_result df_probe (color_ostream &out, vector <string> & parameters) { //bool showBlock, showDesig, showOccup, showTile, showMisc; /* if (!parseOptions(parameters, showBlock, showDesig, showOccup, showTile, showMisc)) { out.printerr("Unknown parameters!\n"); return CR_FAILURE; } */ CoreSuspender suspend; DFHack::Materials *Materials = Core::getInstance().getMaterials(); std::vector<t_matglossInorganic> inorganic; bool hasmats = Materials->CopyInorganicMaterials(inorganic); if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } MapExtras::MapCache mc; int32_t regionX, regionY, regionZ; Maps::getPosition(regionX,regionY,regionZ); int32_t cursorX, cursorY, cursorZ; Gui::getCursorCoords(cursorX,cursorY,cursorZ); if(cursorX == -30000) { out.printerr("No cursor; place cursor over tile to probe.\n"); return CR_FAILURE; } DFCoord cursor (cursorX,cursorY,cursorZ); uint32_t blockX = cursorX / 16; uint32_t tileX = cursorX % 16; uint32_t blockY = cursorY / 16; uint32_t tileY = cursorY % 16; MapExtras::Block * b = mc.BlockAt(cursor/16); if(!b || !b->is_valid()) { out.printerr("No data.\n"); return CR_OK; } auto &block = *b->getRaw(); out.print("block addr: 0x%x\n\n", &block); /* if (showBlock) { out.print("block flags:\n"); print_bits<uint32_t>(block.blockflags.whole,out); out.print("\n\n"); } */ df::tiletype tiletype = mc.tiletypeAt(cursor); df::tile_designation &des = block.designation[tileX][tileY]; df::tile_occupancy &occ = block.occupancy[tileX][tileY]; /* if(showDesig) { out.print("designation\n"); print_bits<uint32_t>(block.designation[tileX][tileY].whole, out); out.print("\n\n"); } if(showOccup) { out.print("occupancy\n"); print_bits<uint32_t>(block.occupancy[tileX][tileY].whole, out); out.print("\n\n"); } */ // tiletype out.print("tiletype: "); describeTile(out, tiletype); out.print("static: "); describeTile(out, mc.staticTiletypeAt(cursor)); out.print("base: "); describeTile(out, mc.baseTiletypeAt(cursor)); out.print("temperature1: %d U\n",mc.temperature1At(cursor)); out.print("temperature2: %d U\n",mc.temperature2At(cursor)); int offset = block.region_offset[des.bits.biome]; int bx = clip_range(block.region_pos.x + (offset % 3) - 1, 0, world->world_data->world_width-1); int by = clip_range(block.region_pos.y + (offset / 3) - 1, 0, world->world_data->world_height-1); auto biome = &world->world_data->region_map[bx][by]; int sav = biome->savagery; int evi = biome->evilness; int sindex = sav > 65 ? 2 : sav < 33 ? 0 : 1; int eindex = evi > 65 ? 2 : evi < 33 ? 0 : 1; int surr = sindex + eindex * 3; const char* surroundings[] = { "Serene", "Mirthful", "Joyous Wilds", "Calm", "Wilderness", "Untamed Wilds", "Sinister", "Haunted", "Terrifying" }; // biome, geolayer out << "biome: " << des.bits.biome << " (" << "region id=" << biome->region_id << ", " << surroundings[surr] << ", " << "savagery " << biome->savagery << ", " << "evilness " << biome->evilness << ")" << std::endl; out << "geolayer: " << des.bits.geolayer_index << std::endl; int16_t base_rock = mc.layerMaterialAt(cursor); if(base_rock != -1) { out << "Layer material: " << dec << base_rock; if(hasmats) out << " / " << inorganic[base_rock].id << " / " << inorganic[base_rock].name << endl; else out << endl; } int16_t vein_rock = mc.veinMaterialAt(cursor); if(vein_rock != -1) { out << "Vein material (final): " << dec << vein_rock; if(hasmats) out << " / " << inorganic[vein_rock].id << " / " << inorganic[vein_rock].name << endl; else out << endl; } MaterialInfo minfo(mc.baseMaterialAt(cursor)); if (minfo.isValid()) out << "Base material: " << minfo.getToken() << " / " << minfo.toString() << endl; minfo.decode(mc.staticMaterialAt(cursor)); if (minfo.isValid()) out << "Static material: " << minfo.getToken() << " / " << minfo.toString() << endl; // liquids if(des.bits.flow_size) { if(des.bits.liquid_type == tile_liquid::Magma) out <<"magma: "; else out <<"water: "; out << des.bits.flow_size << std::endl; } if(des.bits.flow_forbid) out << "flow forbid" << std::endl; if(des.bits.pile) out << "stockpile?" << std::endl; if(des.bits.rained) out << "rained?" << std::endl; if(des.bits.smooth) out << "smooth?" << std::endl; if(des.bits.water_salt) out << "salty" << endl; if(des.bits.water_stagnant) out << "stagnant" << endl; #define PRINT_FLAG( FIELD, BIT ) out.print("%-16s= %c\n", #BIT , ( FIELD.bits.BIT ? 'Y' : ' ' ) ) PRINT_FLAG( des, hidden ); PRINT_FLAG( des, light ); PRINT_FLAG( des, outside ); PRINT_FLAG( des, subterranean ); PRINT_FLAG( des, water_table ); PRINT_FLAG( des, rained ); PRINT_FLAG( occ, monster_lair); df::coord2d pc(blockX, blockY); t_feature local; t_feature global; Maps::ReadFeatures(&block,&local,&global); PRINT_FLAG( des, feature_local ); if(local.type != -1) { out.print("%-16s", ""); out.print(" %4d", block.local_feature); out.print(" (%2d)", local.type); out.print(" addr 0x%X ", local.origin); out.print(" %s\n", sa_feature(local.type)); } PRINT_FLAG( des, feature_global ); if(global.type != -1) { out.print("%-16s", ""); out.print(" %4d", block.global_feature); out.print(" (%2d)", global.type); out.print(" %s\n", sa_feature(global.type)); } #undef PRINT_FLAG out << "local feature idx: " << block.local_feature << endl; out << "global feature idx: " << block.global_feature << endl; out << std::endl; if(block.occupancy[tileX][tileY].bits.no_grow) out << "no grow" << endl; for(size_t e=0; e<block.block_events.size(); e++) { df::block_square_event * blev = block.block_events[e]; df::block_square_event_type blevtype = blev->getType(); switch(blevtype) { case df::block_square_event_type::grass: { df::block_square_event_grassst * gr_ev = (df::block_square_event_grassst *)blev; if(gr_ev->amount[tileX][tileY] > 0) { out << "amount of grass: " << (int)gr_ev->amount[tileX][tileY] << endl; } break; } case df::block_square_event_type::world_construction: { df::block_square_event_world_constructionst * co_ev = (df::block_square_event_world_constructionst*)blev; uint16_t bits = co_ev->tile_bitmask[tileY]; out << "construction bits: " << bits << endl; break; } default: //out << "unhandled block event type!" << endl; break; } } return CR_OK; }
bool gather_embark_tile_layer(int EmbX, int EmbY, int EmbZ, EmbarkTileLayer * tile, MapExtras::MapCache * MP) { for(int i = tile->mat_type_table_size(); i < 2304; i++) { //This is needed so we have a full array to work with, otherwise the size isn't updated correctly. tile->add_mat_type_table(AIR); tile->add_mat_subtype_table(0); } int num_valid_blocks = 0; for(int yy = 0; yy < 3; yy++) { for(int xx = 0; xx < 3; xx++) { DFCoord current_coord, upper_coord; current_coord.x = EmbX+xx; current_coord.y = EmbY+yy; current_coord.z = EmbZ; upper_coord = current_coord; upper_coord.z += 1; MapExtras::Block * b = MP->BlockAt(current_coord); MapExtras::Block * b_upper = MP->BlockAt(upper_coord); if(b && b->getRaw()) { for(int block_y=0; block_y<16; block_y++) { for(int block_x=0; block_x<16; block_x++) { df::coord2d block_coord; block_coord.x = block_x; block_coord.y = block_y; df::tiletype tile_type = b->tiletypeAt(block_coord); df::tiletype upper_tile = df::tiletype::Void; if(b_upper && b_upper->getRaw()) { upper_tile = b_upper->tiletypeAt(block_coord); } df::tile_designation designation = b->DesignationAt(block_coord); DFHack::t_matpair actual_mat; if(tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor && (tileMaterial(tile_type) != tiletype_material::FROZEN_LIQUID) && (tileMaterial(tile_type) != tiletype_material::BROOK)) { //if the upper tile is a floor, use that material instead. Unless it's ice. actual_mat = b_upper->staticMaterialAt(block_coord); } else { actual_mat = b->staticMaterialAt(block_coord); } if(((tileMaterial(tile_type) == tiletype_material::FROZEN_LIQUID) || (tileMaterial(tile_type) == tiletype_material::BROOK)) && (tileShapeBasic(tileShape(tile_type)) == tiletype_shape_basic::Floor)) { tile_type = tiletype::OpenSpace; } unsigned int array_index = coord_to_index_48(xx*16+block_x, yy*16+block_y); //make a new fake material at the given index if(tileMaterial(tile_type) == tiletype_material::FROZEN_LIQUID && !((tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor) && (tileMaterial(upper_tile) != tiletype_material::FROZEN_LIQUID))) { //Ice. tile->set_mat_type_table(array_index, BasicMaterial::LIQUID); //Ice is totally a liquid, shut up. tile->set_mat_subtype_table(array_index, LiquidType::ICE); num_valid_blocks++; } else if(designation.bits.flow_size && (tileShapeBasic(tileShape(upper_tile)) != tiletype_shape_basic::Floor)) { //Contains either water or lava. tile->set_mat_type_table(array_index, BasicMaterial::LIQUID); if(designation.bits.liquid_type) //Magma tile->set_mat_subtype_table(array_index, LiquidType::MAGMA); else //water tile->set_mat_subtype_table(array_index, LiquidType::WATER); num_valid_blocks++; } else if(((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Open) || (tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor)) && ((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Floor) || (tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor))) { //if the upper tile is a floor, we don't skip, otherwise we do. if(actual_mat.mat_type == builtin_mats::INORGANIC) { //inorganic tile->set_mat_type_table(array_index, BasicMaterial::INORGANIC); tile->set_mat_subtype_table(array_index, actual_mat.mat_index); } else if(actual_mat.mat_type == 419) { //Growing plants tile->set_mat_type_table(array_index, BasicMaterial::PLANT); tile->set_mat_subtype_table(array_index, actual_mat.mat_index); } else if(actual_mat.mat_type >= 420) { //Wooden constructions. Different from growing plants. tile->set_mat_type_table(array_index, BasicMaterial::WOOD); tile->set_mat_subtype_table(array_index, actual_mat.mat_index); } else { //Unknown and unsupported stuff. Will just be drawn as grey. tile->set_mat_type_table(array_index, BasicMaterial::OTHER); tile->set_mat_subtype_table(array_index, actual_mat.mat_type); } num_valid_blocks++; } else { tile->set_mat_type_table(array_index, BasicMaterial::AIR); } } } } } } return (num_valid_blocks >0); }