DFhackCExport command_result df_flows (Core * c, vector <string> & parameters) { uint32_t x_max,y_max,z_max; DFHack::designations40d designations; DFHack::Maps *Maps; c->Suspend(); Maps = c->getMaps(); // init the map if(!Maps->Start()) { c->con.printerr("Can't init map.\n"); c->Resume(); return CR_FAILURE; } DFHack::t_blockflags bflags; Maps->getSize(x_max,y_max,z_max); // walk the map, count flowing tiles, magma, water uint32_t flow1=0, flow2=0, flowboth=0, water=0, magma=0; c->con.print("Counting flows and liquids ...\n"); 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++) { if(Maps->getBlock(x,y,z)) { Maps->ReadBlockFlags(x, y, z, bflags); Maps->ReadDesignations(x, y, z, &designations); if (bflags.bits.liquid_1) flow1++; if (bflags.bits.liquid_2) flow2++; if (bflags.bits.liquid_1 && bflags.bits.liquid_2) flowboth++; for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++) { if (designations[i][j].bits.liquid_type == DFHack::liquid_magma) magma++; if (designations[i][j].bits.liquid_type == DFHack::liquid_water) water++; } } } } } c->con.print("Blocks with liquid_1=true: %d\n" "Blocks with liquid_2=true: %d\n" "Blocks with both: %d\n" "Water tiles: %d\n" "Magma tiles: %d\n" ,flow1, flow2, flowboth, water, magma ); c->Resume(); return CR_OK; }
int main (int numargs, const char ** args) { map<string, string> buildCommands; buildCommands["building_stockpilest"]=""; buildCommands["building_zonest"]=""; buildCommands["building_construction_blueprintst"]=""; buildCommands["building_wagonst"]=""; buildCommands["building_armor_standst"]="a"; buildCommands["building_bedst"]="b"; buildCommands["building_seatst"]="c"; buildCommands["building_burial_receptaclest"]="n"; buildCommands["building_doorst"]="d"; buildCommands["building_floodgatest"]="x"; buildCommands["building_floor_hatchst"]="H"; buildCommands["building_wall_gratest"]="W"; buildCommands["building_floor_gratest"]="G"; buildCommands["building_vertical_barsst"]="B"; buildCommands["building_floor_barsst"]="alt-b"; buildCommands["building_cabinetst"]="f"; buildCommands["building_containerst"]="h"; buildCommands["building_shopst"]=""; buildCommands["building_workshopst"]=""; buildCommands["building_alchemists_laboratoryst"]="wa"; buildCommands["building_carpenters_workshopst"]="wc"; buildCommands["building_farmers_workshopst"]="ww"; buildCommands["building_masons_workshopst"]="wm"; buildCommands["building_craftdwarfs_workshopst"]="wr"; buildCommands["building_jewelers_workshopst"]="wj"; buildCommands["building_metalsmiths_workshopst"]="wf"; buildCommands["building_magma_forgest"]=""; buildCommands["building_bowyers_workshopst"]="wb"; buildCommands["building_mechanics_workshopst"]="wt"; buildCommands["building_siege_workshopst"]="ws"; buildCommands["building_butchers_shopst"]="wU"; buildCommands["building_leather_worksst"]="we"; buildCommands["building_tanners_shopst"]="wn"; buildCommands["building_clothiers_shopst"]="wk"; buildCommands["building_fisheryst"]="wh"; buildCommands["building_stillst"]="wl"; buildCommands["building_loomst"]="wo"; buildCommands["building_quernst"]="wq"; buildCommands["building_kennelsst"]="k"; buildCommands["building_kitchenst"]="wz"; buildCommands["building_asheryst"]="wy"; buildCommands["building_dyers_shopst"]="wd"; buildCommands["building_millstonest"]="wM"; buildCommands["building_farm_plotst"]="p"; buildCommands["building_weapon_rackst"]="r"; buildCommands["building_statuest"]="s"; buildCommands["building_tablest"]="t"; buildCommands["building_paved_roadst"]="o"; buildCommands["building_bridgest"]="g"; buildCommands["building_wellst"]="l"; buildCommands["building_siege enginest"]="i"; buildCommands["building_catapultst"]="ic"; buildCommands["building_ballistast"]="ib"; buildCommands["building_furnacest"]=""; buildCommands["building_wood_furnacest"]="ew"; buildCommands["building_smelterst"]="es"; buildCommands["building_glass_furnacest"]="ek"; buildCommands["building_kilnst"]="ek"; buildCommands["building_magma_smelterst"]="es"; buildCommands["building_magma_glass_furnacest"]="ek"; buildCommands["building_magma_kilnst"]="ek"; buildCommands["building_glass_windowst"]="y"; buildCommands["building_gem_windowst"]="Y"; buildCommands["building_tradedepotst"]="D"; buildCommands["building_mechanismst"]=""; buildCommands["building_leverst"]="Tl"; buildCommands["building_pressure_platest"]="Tp"; buildCommands["building_cage_trapst"]="Tc"; buildCommands["building_stonefall_trapst"]="Ts"; buildCommands["building_weapon_trapst"]="Tw"; buildCommands["building_spikest"]=""; buildCommands["building_animal_trapst"]="m"; buildCommands["building_screw_pumpst"]="Ms"; buildCommands["building_water_wheelst"]="Mw"; buildCommands["building_windmillst"]="Mm"; buildCommands["building_gear_assemblyst"]="Mg"; buildCommands["building_horizontal_axlest"]="Mh"; buildCommands["building_vertical_axlest"]="Mv"; buildCommands["building_supportst"]="S"; buildCommands["building_cagest"]="j"; buildCommands["building_archery_targetst"]="A"; buildCommands["building_restraintst"]="v"; DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); try { DF->Attach(); } catch (std::exception& e) { std::cerr << e.what() << std::endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } DFHack::Gui *Gui = DF->getGui(); DFHack::VersionInfo* mem = DF->getMemoryInfo(); DFHack::Process * p = DF->getProcess(); OffsetGroup * OG_Maps = mem->getGroup("Maps"); OffsetGroup * OG_MapBlock = OG_Maps->getGroup("block"); OffsetGroup * OG_LocalFt = OG_Maps->getGroup("features")->getGroup("local"); uint32_t designations = OG_MapBlock->getOffset("designation"); uint32_t block_feature1 = OG_MapBlock->getOffset("feature_local"); uint32_t block_feature2 = OG_MapBlock->getOffset("feature_global"); uint32_t region_x_offset = OG_Maps->getAddress("region_x"); uint32_t region_y_offset = OG_Maps->getAddress("region_y"); uint32_t region_z_offset = OG_Maps->getAddress("region_z"); uint32_t feature1_start_ptr = OG_LocalFt->getAddress("start_ptr"); int32_t regionX, regionY, regionZ; // read position of the region inside DF world p->readDWord (region_x_offset, (uint32_t &)regionX); p->readDWord (region_y_offset, (uint32_t &)regionY); p->readDWord (region_z_offset, (uint32_t &)regionZ); while(1){ int32_t cx1,cy1,cz1; cx1 = -30000; while(cx1 == -30000) { DF->ForceResume(); cout << "Set cursor at first position, then press any key"; cin.ignore(); DF->Suspend(); Gui->getCursorCoords(cx1,cy1,cz1); } uint32_t tx1,ty1,tz1; tx1 = cx1/16; ty1 = cy1/16; tz1 = cz1; int32_t cx2,cy2,cz2; cx2 = -30000; while(cx2 == -30000) { DF->Resume(); cout << "Set cursor at second position, then press any key"; cin.ignore(); DF->Suspend(); Gui->getCursorCoords(cx2,cy2,cz2); } uint32_t tx2,ty2,tz2; tx2 = cx2/16; ty2 = cy2/16; tz2 = cz2; sort(tx1,tx2); sort(ty1,ty2); sort(tz1,tz2); sort(cx1,cx2); sort(cy1,cy2); sort(cz1,cz2); vector <vector<vector<string> > >dig(cz2-cz1+1,vector<vector<string> >(cy2-cy1+1,vector<string>(cx2-cx1+1))); vector <vector<vector<string> > >build(cz2-cz1+1,vector<vector<string> >(cy2-cy1+1,vector<string>(cx2-cx1+1))); mapblock40d block; DFHack::Maps *Maps = DF->getMaps(); Maps->Start(); for(uint32_t y = ty1;y<=ty2;y++) { for(uint32_t x = tx1;x<=tx2;x++) { for(uint32_t z = tz1;z<=tz2;z++) { if(Maps->isValidBlock(x,y,z)) { if(Maps->ReadBlock40d(x,y,z,&block)) { int ystart,yend,xstart,xend; ystart=xstart=0; yend=xend=15; if(y == ty2) { yend = cy2 % 16; } if(y == ty1) { ystart = cy1 % 16; } if(x == tx2) { xend = cx2 % 16; } if(x == tx1) { xstart = cx1 % 16; } int zidx = z-tz1; for(int yy = ystart; yy <= yend;yy++) { int yidx = yy+(16*(y-ty1)-(cy1%16)); for(int xx = xstart; xx <= xend;xx++) { int xidx = xx+(16*(x-tx1)-(cx1%16)); int16_t tt = block.tiletypes[xx][yy]; DFHack::TileShape ts = DFHack::tileShape(tt); if(DFHack::isOpenTerrain(tt) || DFHack::isFloorTerrain(tt)) { dig[zidx][yidx][xidx] = "d"; } else if(DFHack::STAIR_DOWN == ts) { dig [zidx][yidx][xidx] = "j"; build [zidx][yidx][xidx] = "Cd"; } else if(DFHack::STAIR_UP == ts) { dig [zidx][yidx][xidx] = "u"; build [zidx][yidx][xidx] = "Cu"; } else if(DFHack::STAIR_UPDOWN == ts) { dig [zidx][yidx][xidx] = "i"; build [zidx][yidx][xidx] = "Cx"; } else if(DFHack::isRampTerrain(tt)) { dig [zidx][yidx][xidx] = "r"; build [zidx][yidx][xidx] = "Cr"; } else if(DFHack::isWallTerrain(tt)) { build [zidx][yidx][xidx] = "Cw"; } } yidx++; } } } } } } DFHack::Buildings * Bld = DF->getBuildings(); std::map <uint32_t, std::string> custom_workshop_types; uint32_t numBuildings; if(Bld->Start(numBuildings)) { Bld->ReadCustomWorkshopTypes(custom_workshop_types); for(uint32_t i = 0; i < numBuildings; i++) { DFHack::t_building temp; Bld->Read(i, temp); if(temp.type != 0xFFFFFFFF) // check if type isn't invalid { std::string typestr; mem->resolveClassIDToClassname(temp.type, typestr); if(temp.z == cz1 && cx1 <= temp.x1 && cx2 >= temp.x2 && cy1 <= temp.y1 && cy2 >= temp.y2) { string currStr = build[temp.z-cz1][temp.y1-cy1][temp.x1-cx1]; stringstream stream; string newStr = buildCommands[typestr]; if(temp.x1 != temp.x2) { stream << "(" << temp.x2-temp.x1+1 << "x" << temp.y2-temp.y1+1 << ")"; newStr += stream.str(); } build[temp.z-cz1][temp.y1-cy1][temp.x1-cx1] = newStr + currStr; } } } } // for testing purposes //ofstream outfile("test.txt"); // printVecOfVec(outfile, dig,'\t'); // outfile << endl; // printVecOfVec(outfile, build,'\t'); // outfile << endl; // outfile.close(); int32_t cx3,cy3,cz3,cx4,cy4,cz4; uint32_t tx3,ty3,tz3,tx4,ty4,tz4; char result; while(1){ cx3 = -30000; while(cx3 == -30000){ DF->Resume(); cout << "Set cursor at new position, then press any key:"; result = cin.get(); DF->Suspend(); Gui->getCursorCoords(cx3,cy3,cz3); } if(result == 'q'){ break; } cx4 = cx3+cx2-cx1; cy4 = cy3+cy2-cy1; cz4 = cz3+cz2-cz1; tx3=cx3/16; ty3=cy3/16; tz3=cz3; tx4=cx4/16; ty4=cy4/16; tz4=cz4; DFHack::WindowIO * Win = DF->getWindowIO(); designations40d designationBlock; for(uint32_t y = ty3;y<=ty4;y++) { for(uint32_t x = tx3;x<=tx4;x++) { for(uint32_t z = tz3;z<=tz4;z++) { Maps->Start(); Maps->ReadBlock40d(x,y,z,&block); Maps->ReadDesignations(x,y,z,&designationBlock); int ystart,yend,xstart,xend; ystart=xstart=0; yend=xend=15; if(y == ty4){ yend = cy4 % 16; } if(y == ty3){ ystart = cy3 % 16; } if(x == tx4){ xend = cx4 % 16; } if(x == tx3){ xstart = cx3 % 16; } int zidx = z-tz3; for(int yy = ystart; yy <= yend;yy++){ int yidx = yy+(16*(y-ty3)-(cy3%16)); for(int xx = xstart; xx <= xend;xx++){ int xidx = xx+(16*(x-tx3)-(cx3%16)); if(dig[zidx][yidx][xidx] != ""){ char test = dig[zidx][yidx][xidx].c_str()[0]; switch (test){ case 'd': designationBlock[xx][yy].bits.dig = DFHack::designation_default; break; case 'i': designationBlock[xx][yy].bits.dig = DFHack::designation_ud_stair; break; case 'u': designationBlock[xx][yy].bits.dig = DFHack::designation_u_stair; break; case 'j': designationBlock[xx][yy].bits.dig = DFHack::designation_d_stair; break; case 'r': designationBlock[xx][yy].bits.dig = DFHack::designation_ramp; break; } } } yidx++; } Maps->Start(); Maps->WriteDesignations(x,y,z,&designationBlock); } } } } } DF->Detach(); #ifndef LINUX_BUILD std::cout << "Done. Press any key to continue" << std::endl; cin.ignore(); #endif return 0; }
int main (void) { uint32_t x_max,y_max,z_max; DFHack::designations40d designations; DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF; try { DF = DFMgr.getSingleContext(); DF->Attach(); } catch (exception& e) { cerr << e.what() << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } DFHack::Maps *Maps =DF->getMaps(); DFHack::Gui *Gui =DF->getGui(); // walk the map, save the hide bits, reveal. cout << "Pausing..." << endl; // horrible hack to make sure the pause is really set // preblem here is that we could be 'arriving' at the wrong time and DF could be in the middle of a frame. // that could mean that revealing, even with suspending DF's thread, would mean unleashing hell *in the same frame* // this here hack sets the pause state, resumes DF, waits a second for it to enter the pause (I know, BS value.) and suspends. Gui->SetPauseState(true); DF->Resume(); waitmsec(1000); DF->Suspend(); // init the map if(!Maps->Start()) { cerr << "Can't init map." << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } cout << "Revealing, please wait..." << endl; Maps->getSize(x_max,y_max,z_max); vector <hideblock> hidesaved; 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++) { if(Maps->isValidBlock(x,y,z)) { hideblock hb; hb.x = x; hb.y = y; hb.z = z; // read block designations Maps->ReadDesignations(x,y,z, &designations); // change the hidden flag to 0 for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++) { hb.hiddens[i][j] = designations[i][j].bits.hidden; designations[i][j].bits.hidden = 0; } hidesaved.push_back(hb); // write the designations back Maps->WriteDesignations(x,y,z, &designations); } } } } // FIXME: force game pause here! DF->Detach(); cout << "Map revealed. The game has been paused for you." << endl; cout << "Unpausing can unleash the forces of hell!" << endl << endl; cout << "Press any key to unreveal." << endl; cout << "Close to keep the map revealed." << endl; cin.ignore(); cout << "Unrevealing... please wait." << endl; // FIXME: do some consistency checks here! DF->Attach(); Maps = DF->getMaps(); Maps->Start(); for(int i = 0; i < hidesaved.size();i++) { hideblock & hb = hidesaved[i]; Maps->ReadDesignations(hb.x,hb.y,hb.z, &designations); for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++) { designations[i][j].bits.hidden = hb.hiddens[i][j]; } Maps->WriteDesignations(hb.x,hb.y,hb.z, &designations); } #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; }