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; }
command_result df_probe (Core * c, vector <string> & parameters) { //bool showBlock, showDesig, showOccup, showTile, showMisc; Console & con = c->con; /* if (!parseOptions(parameters, showBlock, showDesig, showOccup, showTile, showMisc)) { con.printerr("Unknown parameters!\n"); return CR_FAILURE; } */ CoreSuspender suspend(c); DFHack::Gui *Gui = c->getGui(); DFHack::Materials *Materials = c->getMaterials(); DFHack::VersionInfo* mem = c->vinfo; std::vector<t_matglossInorganic> inorganic; bool hasmats = Materials->CopyInorganicMaterials(inorganic); if (!Maps::IsValid()) { c->con.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) { con.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->valid) { con.printerr("No data.\n"); return CR_OK; } mapblock40d & block = b->raw; con.print("block addr: 0x%x\n\n", block.origin); /* if (showBlock) { con.print("block flags:\n"); print_bits<uint32_t>(block.blockflags.whole,con); con.print("\n\n"); } */ df::tiletype tiletype = mc.tiletypeAt(cursor); df::tile_designation &des = block.designation[tileX][tileY]; /* if(showDesig) { con.print("designation\n"); print_bits<uint32_t>(block.designation[tileX][tileY].whole, con); con.print("\n\n"); } if(showOccup) { con.print("occupancy\n"); print_bits<uint32_t>(block.occupancy[tileX][tileY].whole, con); con.print("\n\n"); } */ // tiletype con.print("tiletype: %d", tiletype); if(tileName(tiletype)) con.print(" = %s",tileName(tiletype)); con.print("\n"); df::tiletype_shape shape = tileShape(tiletype); df::tiletype_material material = tileMaterial(tiletype); df::tiletype_special special = tileSpecial(tiletype); df::tiletype_variant variant = tileVariant(tiletype); con.print("%-10s: %4d %s\n","Class" ,shape, ENUM_KEY_STR(tiletype_shape, shape)); con.print("%-10s: %4d %s\n","Material" , material, ENUM_KEY_STR(tiletype_material, material)); con.print("%-10s: %4d %s\n","Special" , special, ENUM_KEY_STR(tiletype_special, special)); con.print("%-10s: %4d %s\n" ,"Variant" , variant, ENUM_KEY_STR(tiletype_variant, variant)); con.print("%-10s: %s\n" ,"Direction", tileDirection(tiletype).getStr()); con.print("\n"); con.print("temperature1: %d U\n",mc.temperature1At(cursor)); con.print("temperature2: %d U\n",mc.temperature2At(cursor)); // biome, geolayer con << "biome: " << des.bits.biome << std::endl; con << "geolayer: " << des.bits.geolayer_index << std::endl; int16_t base_rock = mc.baseMaterialAt(cursor); if(base_rock != -1) { con << "Layer material: " << dec << base_rock; if(hasmats) con << " / " << inorganic[base_rock].id << " / " << inorganic[base_rock].name << endl; else con << endl; } int16_t vein_rock = mc.veinMaterialAt(cursor); if(vein_rock != -1) { con << "Vein material (final): " << dec << vein_rock; if(hasmats) con << " / " << inorganic[vein_rock].id << " / " << inorganic[vein_rock].name << endl; else con << endl; } // liquids if(des.bits.flow_size) { if(des.bits.liquid_type == tile_liquid::Magma) con <<"magma: "; else con <<"water: "; con << des.bits.flow_size << std::endl; } if(des.bits.flow_forbid) con << "flow forbid" << std::endl; if(des.bits.pile) con << "stockpile?" << std::endl; if(des.bits.rained) con << "rained?" << std::endl; if(des.bits.smooth) con << "smooth?" << std::endl; if(des.bits.water_salt) con << "salty" << endl; if(des.bits.water_stagnant) con << "stagnant" << endl; #define PRINT_FLAG( X ) con.print("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) ) PRINT_FLAG( bits.hidden ); PRINT_FLAG( bits.light ); PRINT_FLAG( bits.outside ); PRINT_FLAG( bits.subterranean ); PRINT_FLAG( bits.water_table ); PRINT_FLAG( bits.rained ); df::coord2d pc(blockX, blockY); t_feature local; t_feature global; Maps::ReadFeatures(&(b->raw),&local,&global); PRINT_FLAG( bits.feature_local ); if(local.type != -1) { con.print("%-16s", ""); con.print(" %4d", block.local_feature); con.print(" (%2d)", local.type); con.print(" addr 0x%X ", local.origin); con.print(" %s\n", sa_feature(local.type)); } PRINT_FLAG( bits.feature_global ); if(global.type != -1) { con.print("%-16s", ""); con.print(" %4d", block.global_feature); con.print(" (%2d)", global.type); con.print(" %s\n", sa_feature(global.type)); } #undef PRINT_FLAG con << "local feature idx: " << block.local_feature << endl; con << "global feature idx: " << block.global_feature << endl; con << "mystery: " << block.mystery << endl; con << std::endl; return CR_OK; }