DFhackCExport command_result bflags (Core * c, vector <string> & parameters) { c->Suspend(); Gui * g = c-> getGui(); Maps* m = c->getMaps(); if(!m->Start()) { c->con.printerr("No map to probe\n"); return CR_FAILURE; } int32_t cx,cy,cz; g->getCursorCoords(cx,cy,cz); if(cx == -30000) { // get map size in blocks uint32_t sx,sy,sz; m->getSize(sx,sy,sz); std::map <uint8_t, df_block *> counts; // for each block for(size_t x = 0; x < sx; x++) for(size_t y = 0; y < sx; y++) for(size_t z = 0; z < sx; z++) { df_block * b = m->getBlock(x,y,z); if(!b) continue; auto iter = counts.find(b->flags.size); if(iter == counts.end()) { counts[b->flags.bits[0]] = b; } } for(auto iter = counts.begin(); iter != counts.end(); iter++) { c->con.print("%2x : 0x%x\n",iter->first, iter->second); } } else { df_block * b = m->getBlock(cx/16,cy/16,cz); if(b) { c->con << "Block flags:" << b->flags << std::endl; } else { c->con.printerr("No block here\n"); return CR_FAILURE; } } c->Resume(); return CR_OK; }
DFhackCExport command_result mapitems (Core * c, vector <string> & parameters) { c->Suspend(); vector <df_item *> vec_items; Gui * g = c-> getGui(); Maps* m = c->getMaps(); Items* it = c->getItems(); if(!m->Start()) { c->con.printerr("No map to probe\n"); return CR_FAILURE; } if(!it->Start() || !it->readItemVector(vec_items)) { c->con.printerr("Failed to get items\n"); return CR_FAILURE; } int32_t cx,cy,cz; g->getCursorCoords(cx,cy,cz); if(cx != -30000) { df_block * b = m->getBlock(cx/16,cy/16,cz); if(b) { c->con.print("Item IDs present in block:\n"); auto iter_b = b->items.begin(); while (iter_b != b->items.end()) { df_item * itmz = it->findItemByID(*iter_b); string s; itmz->getItemDescription(&s); c->con.print("%d = %s\n",*iter_b, s.c_str()); iter_b++; } c->con.print("Items under cursor:\n"); auto iter_it = vec_items.begin(); while (iter_it != vec_items.end()) { df_item * itm = *iter_it; if(itm->x == cx && itm->y == cy && itm->z == cz) { string s; itm->getItemDescription(&s,0); c->con.print("%d = %s\n",itm->id, s.c_str()); } iter_it ++; } } } c->Resume(); return CR_OK; }
DFhackCExport command_result digcircle (Core * c, vector <string> & parameters) { static bool filled = false; static circle_what what = circle_set; static e_designation type = designation_default; static int diameter = 0; auto saved_d = diameter; bool force_help = false; for(int i = 0; i < parameters.size();i++) { if(parameters[i] == "help" || parameters[i] == "?") { force_help = true; } else if(parameters[i] == "hollow") { filled = false; } else if(parameters[i] == "filled") { filled = true; } else if(parameters[i] == "set") { what = circle_set; } else if(parameters[i] == "unset") { what = circle_unset; } else if(parameters[i] == "invert") { what = circle_invert; } else if(parameters[i] == "dig") { type = designation_default; } else if(parameters[i] == "ramp") { type = designation_ramp; } else if(parameters[i] == "dstair") { type = designation_d_stair; } else if(parameters[i] == "ustair") { type = designation_u_stair; } else if(parameters[i] == "xstair") { type = designation_ud_stair; } else if(parameters[i] == "chan") { type = designation_channel; } else if (!from_string(diameter,parameters[i], std::dec)) { diameter = saved_d; } } if(diameter < 0) diameter = -diameter; if(force_help || diameter == 0) { c->con.print( "A command for easy designation of filled and hollow circles.\n" "\n" "Options:\n" " hollow = Set the circle to hollow (default)\n" " filled = Set the circle to filled\n" "\n" " set = set designation\n" " unset = unset current designation\n" " invert = invert current designation\n" "\n" " dig = normal digging\n" " ramp = ramp digging\n" " ustair = staircase up\n" " dstair = staircase down\n" " xstair = staircase up/down\n" " chan = dig channel\n" "\n" " # = diameter in tiles (default = 0)\n" "\n" "After you have set the options, the command called with no options\n" "repeats with the last selected parameters:\n" "'digcircle filled 3' = Dig a filled circle with radius = 3.\n" "'digcircle' = Do it again.\n" ); return CR_OK; } int32_t cx, cy, cz; c->Suspend(); Gui * gui = c->getGui(); Maps * maps = c->getMaps(); if(!maps->Start()) { c->Resume(); c->con.printerr("Can't init the map...\n"); return CR_FAILURE; } uint32_t x_max, y_max, z_max; maps->getSize(x_max,y_max,z_max); MapExtras::MapCache MCache (maps); if(!gui->getCursorCoords(cx,cy,cz) || cx == -30000) { c->Resume(); c->con.printerr("Can't get the cursor coords...\n"); return CR_FAILURE; } auto dig = [&](int32_t x, int32_t y, int32_t z) -> bool { DFCoord at (x,y,z); auto b = MCache.BlockAt(at/16); if(!b || !b->valid) return false; if(x == 0 || x == x_max * 16 - 1) { //c->con.print("not digging map border\n"); return false; } if(y == 0 || y == y_max * 16 - 1) { //c->con.print("not digging map border\n"); return false; } uint16_t tt = MCache.tiletypeAt(at); t_designation des = MCache.designationAt(at); // could be potentially used to locate hidden constructions? if(tileMaterial(tt) == CONSTRUCTED && !des.bits.hidden) return false; TileShape ts = tileShape(tt); if(ts == EMPTY) return false; if(!des.bits.hidden) { do { if(isWallTerrain(tt)) { std::cerr << "allowing tt" << tt << ", is wall\n"; break; } if(isFloorTerrain(tt) && (type == designation_d_stair || type == designation_channel) && ts != TREE_OK && ts != TREE_DEAD ) { std::cerr << "allowing tt" << tt << ", is floor\n"; break; } if(isStairTerrain(tt) && type == designation_channel ) break; return false; } while(0); } switch(what) { case circle_set: if(des.bits.dig == designation_no) { des.bits.dig = type; } break; case circle_unset: if (des.bits.dig != designation_no) { des.bits.dig = designation_no; } case circle_invert: if(des.bits.dig == designation_no) { des.bits.dig = type; } else { des.bits.dig = designation_no; } break; } std::cerr << "allowing tt" << tt << "\n"; MCache.setDesignationAt(at,des); return true; }; auto lineX = [&](int32_t y1, int32_t y2, int32_t x, int32_t z) -> bool { for(int32_t y = y1; y <= y2; y++) { dig(x,y,z); } return true; }; auto lineY = [&](int32_t x1, int32_t x2, int32_t y, int32_t z) -> bool { for(int32_t x = x1; x <= x2; x++) { dig(x,y,z); } return true; }; int r = diameter / 2; int iter; bool adjust; if(diameter % 2) { // paint center if(filled) { lineY(cx - r, cx + r, cy, cz); } else { dig(cx - r, cy, cz); dig(cx + r, cy, cz); } adjust = false; iter = 2; } else { adjust = true; iter = 1; } int lastwhole = r; for(; iter <= diameter - 1; iter +=2) { // top, bottom coords int top = cy - ((iter + 1) / 2) + adjust; int bottom = cy + ((iter + 1) / 2); // see where the current 'line' intersects the circle double val = std::sqrt(double(diameter*diameter - iter*iter)); // adjust for circles with odd diameter if(!adjust) val -= 1; // map the found value to the DF grid double whole; double fraction = std::modf(val / 2.0, & whole); if (fraction > 0.5) whole += 1.0; int right = cx + whole; int left = cx - whole + adjust; int diff = lastwhole - whole; // paint if(filled || iter == diameter - 1) { lineY(left, right, top , cz); lineY(left, right, bottom , cz); } else { dig(left, top, cz); dig(left, bottom, cz); dig(right, top, cz); dig(right, bottom, cz); } if(!filled && diff > 1) { int lright = cx + lastwhole; int lleft = cx - lastwhole + adjust; lineY(lleft + 1, left - 1, top + 1 , cz); lineY(right + 1, lright - 1, top + 1 , cz); lineY(lleft + 1, left - 1, bottom - 1 , cz); lineY(right + 1, lright - 1, bottom - 1 , cz); } lastwhole = whole; } MCache.WriteAll(); c->Resume(); return CR_OK; }
DFhackCExport command_result expdig (Core * c, vector <string> & parameters) { bool force_help = false; static explo_how how = EXPLO_NOTHING; static explo_what what = EXPLO_HIDDEN; for(int i = 0; i < parameters.size();i++) { if(parameters[i] == "help" || parameters[i] == "?") { force_help = true; } else if(parameters[i] == "all") { what = EXPLO_ALL; } else if(parameters[i] == "hidden") { what = EXPLO_HIDDEN; } else if(parameters[i] == "designated") { what = EXPLO_DESIGNATED; } else if(parameters[i] == "diag5") { how = EXPLO_DIAG5; } else if(parameters[i] == "clear") { how = EXPLO_CLEAR; } else if(parameters[i] == "ladder") { how = EXPLO_LADDER; } else if(parameters[i] == "cross") { how = EXPLO_CROSS; } } if(force_help || how == EXPLO_NOTHING) { c->con.print("This command can be used for exploratory mining.\n" "http://df.magmawiki.com/index.php/DF2010:Exploratory_mining\n" "\n" "There are two variables that can be set: pattern and filter.\n" "Patterns:\n" " diag5 = diagonals separated by 5 tiles\n" " ladder = A 'ladder' pattern\n" " clear = Just remove all dig designations\n" " cross = A cross, exactly in the middle of the map.\n" "Filters:\n" " all = designate whole z-level\n" " hidden = designate only hidden tiles of z-level (default)\n" " designated = Take current designation and apply pattern to it.\n" "\n" "After you have a pattern set, you can use 'expdig' to apply it:\n" "'expdig diag5 hidden' = set filter to hidden, pattern to diag5.\n" "'expdig' = apply the pattern with filter.\n" ); return CR_OK; } c->Suspend(); Gui * gui = c->getGui(); Maps * maps = c->getMaps(); uint32_t x_max, y_max, z_max; if(!maps->Start()) { c->Resume(); c->con.printerr("Can't init the map...\n"); return CR_FAILURE; } maps->getSize(x_max,y_max,z_max); int32_t xzzz,yzzz,z_level; if(!gui->getViewCoords(xzzz,yzzz,z_level)) { c->Resume(); c->con.printerr("Can't get view coords...\n"); return CR_FAILURE; } auto apply = [&](uint32_t bx, uint32_t by, digmask & dm) -> bool { df_block * bl = maps->getBlock(bx,by,z_level); if(!bl) return false; int x = 0,mx = 16; if(bx == 0) x = 1; if(bx == x_max - 1) mx = 15; for(; x < mx; x++) { int y = 0,my = 16; if(by == 0) y = 1; if(by == y_max - 1) my = 15; for(; y < my; y++) { naked_designation & des = bl->designation[x][y].bits; short unsigned int tt = bl->tiletype[x][y]; // could be potentially used to locate hidden constructions? if(tileMaterial(tt) == CONSTRUCTED && !des.hidden) continue; if(!isWallTerrain(tt) && !des.hidden) continue; if(how == EXPLO_CLEAR) { des.dig = designation_no; continue; } if(dm[y][x]) { if(what == EXPLO_ALL || des.dig == designation_default && what == EXPLO_DESIGNATED || des.hidden && what == EXPLO_HIDDEN) { des.dig = designation_default; } } else if(what == EXPLO_DESIGNATED) { des.dig = designation_no; } } } bl->flags.set(BLOCK_DESIGNATED); return true; }; if(how == EXPLO_DIAG5) { int which; for(uint32_t x = 0; x < x_max; x++) { for(int32_t y = 0 ; y < y_max; y++) { which = (4*x + y) % 5; apply(x,y_max - 1 - y,diag5[which]); } } } else if(how == EXPLO_LADDER) { int which; for(uint32_t x = 0; x < x_max; x++) { which = x % 3; for(int32_t y = 0 ; y < y_max; y++) { apply(x,y,ladder[which]); } } } else if(how == EXPLO_CROSS) { // middle + recentering for the image int xmid = x_max * 8 - 8; int ymid = y_max * 8 - 8; MapExtras::MapCache mx (maps); for(int x = 0; x < 16; x++) for(int y = 0; y < 16; y++) { DFCoord pos(xmid+x,ymid+y,z_level); short unsigned int tt = mx.tiletypeAt(pos); if(tt == 0) continue; t_designation des = mx.designationAt(pos); if(tileMaterial(tt) == CONSTRUCTED && !des.bits.hidden) continue; if(!isWallTerrain(tt) && !des.bits.hidden) continue; if(cross[y][x]) { des.bits.dig = designation_default; mx.setDesignationAt(pos,des); } } mx.WriteAll(); } else for(uint32_t x = 0; x < x_max; x++) for(int32_t y = 0 ; y < y_max; y++) apply(x,y,all_tiles); c->Resume(); return CR_OK; }