int main (void) { int32_t x,y,z,tx,ty; //DFHack::designations40d designations; DFHack::tiletypes40d tiles; //DFHack::t_temperatures temp1,temp2; uint32_t x_max,y_max,z_max; int32_t oldT, newT; int count, dirty; //Brush defaults DFHack::TileShape BrushClass = DFHack::WALL; DFHack::TileMaterial BrushMat = DFHack::tilematerial_invalid; int BrushType = -1; DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF; DFHack::Maps * Maps; DFHack::Gui * Gui; try { DF=DFMgr.getSingleContext(); DF->Attach(); Maps = DF->getMaps(); Maps->Start(); Maps->getSize(x_max,y_max,z_max); Gui = DF->getGui(); } catch (exception& e) { cerr << e.what() << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } bool end = false; cout << "Welcome to the Tile Drawing tool.\nType 'help' or ? for a list of available commands, 'q' to quit" << endl; string mode = "wall"; string command = ""; while(!end) { DF->Resume(); cout << endl << ":"; getline(cin, command); int ch = command[0]; if(command.length()<=0) ch=0; if( ((int)command.find("help")) >=0 ) ch='?'; //under windows, find was casting unsigned! switch(ch) { case '?': cout << "Modes:" << endl << "O - draw Open Space" << endl << "M - draw material only (shape unchanged)" << endl << "m number - use Material value entered" << endl << "r - use Rock/stone material" << endl << "l - use Soil material" << endl << "v - use Vein material" << endl << "H - draw tile shape only (material unchanged)" << endl << "h number - draw Tile Shape value entered" << endl << "w - draw Wall tiles" << endl << "f - draw Floor tiles" << endl << "t number - draw exact tile type entered" << endl << "Commands:" << endl << "p - print tile shapes and materials, and current brush" << endl << "P - print all tile types" << endl << "q - quit" << endl << "help OR ? - print this list of commands" << endl << "d - being drawing" << endl << endl << "Usage:\nChoose a mode (default is walls), then enter 'd' to being drawing.\nMove the cursor in DF wherever you want to draw.\nPress any key to pause drawing." << endl; break; case 'p': //Classes printf("\nTile Type Classes:\n"); for(int i=0;i<DFHack::tileshape_count;++i) { printf("%4i ; %s\n", i, DFHack::TileShapeString[i] ,0 ); } //Materials printf("\nTile Type Materials:\n"); for(int i=0;i<DFHack::tilematerial_count;++i) { printf("%4i ; %s\n", i, DFHack::TileMaterialString[i] ,0 ); } //fall through... case 10: case 13: case 0: //Print current cursor & brush settings. cout << "\nCurrent Brush:\n"; cout << "tile = "; if(BrushClass<0) cout<<"(not drawing)"; else cout<<DFHack::TileShapeString[BrushClass]; cout << endl; cout << "mat = "; if(BrushMat<0) cout<<"(not drawing)"; else cout<<DFHack::TileMaterialString[BrushMat]; cout << endl; cout << "type = "; if(BrushType<0){ cout<<"(not drawing)"; }else{ printtiletype(BrushType); } break; case 'P': cout << "\nAll Valid Tile Types:\n"; for(int i=0;i<TILE_TYPE_ARRAY_LENGTH;++i) { if( DFHack::tileTypeTable[i].name ) printtiletype(i); } case 'w': BrushType=-1; BrushClass = DFHack::WALL; cout << "Tile brush shape set to Wall." << endl; break; case 'f': BrushType=-1; BrushClass = DFHack::FLOOR; cout << "Tile brush shape set to Floor." << endl; break; case 'h': BrushType=-1; BrushClass = (DFHack::TileShape)atol( command.c_str()+1 ); cout << "Tile brush shape set to " << BrushClass << endl; break; case 'M': BrushClass = DFHack::tileshape_invalid; cout << "Tile brush will not draw tile shape." << endl; break; case 'r': BrushType=-1; BrushMat = DFHack::STONE; cout << "Tile brush material set to Rock." << endl; break; case 'l': BrushType=-1; BrushMat = DFHack::SOIL; cout << "Tile brush material set to Soil." << endl; break; case 'v': BrushType=-1; BrushMat = DFHack::VEIN; cout << "Tile brush material set to Vein." << endl; break; case 'm': BrushType=-1; BrushMat = (DFHack::TileMaterial)atol( command.c_str()+1 ); cout << "Tile brush material set to " << BrushMat << endl; break; case 'H': BrushMat = DFHack::tilematerial_invalid; cout << "Tile brush will not draw material." << endl; break; case 'O': BrushType=-1; BrushClass = DFHack::EMPTY; BrushMat = DFHack::AIR; cout << "Tile brush will draw Open Space." << endl; break; case 't': BrushClass = DFHack::tileshape_invalid ; BrushMat = DFHack::tilematerial_invalid; BrushType = atol( command.c_str()+1 ); cout << "Tile brush type set to:" << endl; printtiletype(BrushType); break; case 'q': end = true; cout << "Bye!" << endl; break; case 'd': { count=0; cout << "Beginning to draw at cursor." << endl << "Press any key to stop drawing." << endl; //DF->Suspend(); kbhit(); //throw away, just to be sure. for(;;) { if(!Maps->Start()) { cout << "Can't see any DF map loaded." << endl; break; } if(!Gui->getCursorCoords(x,y,z)) { cout << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl; break; } //cout << "cursor coords: " << x << "/" << y << "/" << z << endl; tx=x%16; ty=y%16; if(!Maps->isValidBlock(x/16,y/16,z)) { cout << "Invalid block." << endl; break; } //Read the tiles. dirty=0; Maps->ReadTileTypes((x/16),(y/16),z, &tiles); oldT = tiles[tx][ty]; newT = -1; if( 0<BrushType ){ //Explicit tile type set. Trust the user. newT = BrushType; }else if( 0==BrushMat && 0==BrushClass ){ //Special case, Empty Air. newT = 32; }else if( BrushMat>=0 && BrushClass>=0 && ( BrushClass != DFHack::tileTypeTable[oldT].shape || BrushMat != DFHack::tileTypeTable[oldT].material) ){ //Set tile material and class newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tileTypeTable[oldT].variant , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); if(newT<0) newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tilevariant_invalid, DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); if(newT<0) newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , (uint32_t)0 ); }else if( BrushMat<0 && BrushClass>=0 && BrushClass != DFHack::tileTypeTable[oldT].shape ){ //Set current tile class only, as accurately as can be expected newT = DFHack::findSimilarTileType(oldT,BrushClass); }else if( BrushClass<0 && BrushMat>=0 && BrushMat != DFHack::tileTypeTable[oldT].material ){ //Set current tile material only newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tileTypeTable[oldT].variant , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); if(newT<0) newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); if(newT<0) newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , (uint32_t)0 ); } //If no change, skip it (couldn't find a good tile type, or already what we want) if ( newT > 0 && oldT != newT ){ //Set new tile type tiles[tx][ty] = newT; dirty=-1; } //If anything was changed, write it all. if (dirty) { //Maps->WriteDesignations(x/16,y/16,z/16, &designations); Maps->WriteTileTypes(x/16,y/16,z, &tiles); printf("(%4d,%4d,%4d)",x,y,z); ++count; } Maps->Finish(); Sleep(10); if( kbhit() ) break; } cin.clear(); cout << endl << count << " tiles were drawn." << endl << "Drawing halted. Entering command mode." << endl; } continue; break; default: cout << "Unknown command: " << command << endl; } } DF->Detach(); #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }
DFhackCExport command_result tubefill(DFHack::Core * c, std::vector<std::string> & params) { uint32_t x_max,y_max,z_max; DFHack::designations40d designations; DFHack::tiletypes40d tiles; int32_t oldT, newT; uint64_t count = 0; int dirty=0; for(int i = 0; i < params.size();i++) { if(params[i] == "help" || params[i] == "?") { c->con.print("Replenishes mined out adamantine and hollow adamantine tubes.\n" "May cause !!FUN!!\n" ); return CR_OK; } } c->Suspend(); DFHack::Maps *Mapz = c->getMaps(); // init the map if (!Mapz->Start()) { c->con.printerr("Can't init map.\n"); c->Resume(); return CR_FAILURE; } Mapz->getSize(x_max,y_max,z_max); if(!Mapz->StartFeatures()) { c->con.printerr("Can't get map features.\n"); c->Resume(); return CR_FAILURE; } // walk the map for (uint32_t x = 0; x< x_max;x++) { for (uint32_t y = 0; y< y_max;y++) { for (uint32_t z = 0; z< z_max;z++) { DFHack::t_feature * locf = 0; DFHack::t_feature * glof = 0; if (Mapz->ReadFeatures(x,y,z,&locf,&glof)) { // we're looking for addy tubes if(!locf) continue; if(locf->type != DFHack::feature_Adamantine_Tube) continue; dirty=0; Mapz->ReadDesignations(x,y,z, &designations); Mapz->ReadTileTypes(x,y,z, &tiles); for (uint32_t ty=0;ty<16;++ty) { for (uint32_t tx=0;tx<16;++tx) { if(!designations[tx][ty].bits.feature_local) continue; oldT = tiles[tx][ty]; if ( DFHack::tileShape(oldT) != DFHack::WALL ) { //Current tile is not a wall. //Set current tile, as accurately as can be expected //newT = DFHack::findSimilarTileType(oldT,DFHack::WALL); newT = DFHack::findTileType( DFHack::WALL, DFHack::FEATSTONE, DFHack::tilevariant_invalid, DFHack::TILE_NORMAL, DFHack::TileDirection() ); //If no change, skip it (couldn't find a good tile type) if ( oldT == newT) continue; //Set new tile type, clear designation tiles[tx][ty] = newT; dirty=1; ++count; } } } //If anything was changed, write it all. if (dirty) { Mapz->WriteTileTypes(x,y,z, &tiles); } } } } } c->Resume(); c->con.print("Found and changed %d tiles.\n", count); return CR_OK; }
int main (void) { bool temporary_terminal = TemporaryTerminal(); uint32_t x_max,y_max,z_max; DFHack::designations40d designations; DFHack::tiletypes40d tiles; int32_t oldT, newT; uint64_t count = 0; int dirty=0; DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); //Init try { DF->Attach(); } catch (exception& e) { cerr << e.what() << endl; if(temporary_terminal) cin.ignore(); return 1; } DFHack::Maps *Mapz = DF->getMaps(); // init the map if (!Mapz->Start()) { cerr << "Can't init map." << endl; if(temporary_terminal) cin.ignore(); return 1; } Mapz->getSize(x_max,y_max,z_max); if(!Mapz->StartFeatures()) { cerr << "Can't get features." << endl; if(temporary_terminal) cin.ignore(); return 1; } // walk the map for (uint32_t x = 0; x< x_max;x++) { for (uint32_t y = 0; y< y_max;y++) { for (uint32_t z = 0; z< z_max;z++) { DFHack::t_feature * locf = 0; DFHack::t_feature * glof = 0; if (Mapz->ReadFeatures(x,y,z,&locf,&glof)) { // we're looking for addy tubes if(!locf) continue; if(locf->type != DFHack::feature_Adamantine_Tube) continue; dirty=0; Mapz->ReadDesignations(x,y,z, &designations); Mapz->ReadTileTypes(x,y,z, &tiles); for (uint32_t ty=0;ty<16;++ty) { for (uint32_t tx=0;tx<16;++tx) { if(!designations[tx][ty].bits.feature_local) continue; oldT = tiles[tx][ty]; if ( DFHack::tileShape(oldT) != DFHack::WALL ) { //Current tile is not a wall. //Set current tile, as accurately as can be expected //newT = DFHack::findSimilarTileType(oldT,DFHack::WALL); newT = DFHack::findTileType( DFHack::WALL, DFHack::FEATSTONE, DFHack::tilevariant_invalid, DFHack::TILE_NORMAL, DFHack::TileDirection() ); //If no change, skip it (couldn't find a good tile type) if ( oldT == newT) continue; //Set new tile type, clear designation tiles[tx][ty] = newT; dirty=1; ++count; } } } //If anything was changed, write it all. if (dirty) { Mapz->WriteTileTypes(x,y,z, &tiles); } } } } } DF->Detach(); cout << "Found and changed " << count << " tiles." << endl; if(temporary_terminal) { cout << "Done. Press any key to continue" << endl; cin.ignore(); } return 0; }