diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 6d89f1d50..1cde42970 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -217,12 +217,16 @@ static void clean_ramps(MapExtras::MapCache &map, const DFCoord &pos) { clean_ramp(map, DFCoord(pos.x, pos.y+1, pos.z)); } -// returns material type of walls at the given position, or -1 if not a wall -static int16_t get_wall_mat(MapExtras::MapCache &map, const DFCoord &pos) { +// returns material type of prospective boulders generated by the wall tile at +// the given position, or -1 if not a boulderable wall +static int16_t get_boulder_mat(MapExtras::MapCache &map, const DFCoord &pos) { df::tiletype tt = map.tiletypeAt(pos); df::tiletype_shape shape = tileShape(tt); + df::tiletype_material tmat = tileMaterial(tt); - if (shape != df::tiletype_shape::WALL) + if (shape != df::tiletype_shape::WALL + || (tmat != df::tiletype_material::STONE + && tmat != df::tiletype_material::MINERAL)) return -1; t_matpair matpair; @@ -235,7 +239,7 @@ static int16_t get_wall_mat(MapExtras::MapCache &map, const DFCoord &pos) { static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, const DFCoord &pos, df::tile_dig_designation designation, - int16_t *wall_mat) { + int16_t *boulder_mat) { df::tiletype tt = map.tiletypeAt(pos); // TODO: handle tree trunks, roots, and surface tiles @@ -243,7 +247,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, if (!isGroundMaterial(tile_mat)) return false; - *wall_mat = get_wall_mat(map, pos); + *boulder_mat = get_boulder_mat(map, pos); df::tiletype target_type = df::tiletype::Void; switch(designation) { @@ -265,7 +269,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, DFCoord pos_below(pos.x, pos.y, pos.z-1); if (map.ensureBlockAt(pos_below) && dig_tile(out, map, pos_below, - df::tile_dig_designation::Ramp, wall_mat)) { + df::tile_dig_designation::Ramp, boulder_mat)) { clean_ramps(map, pos_below); // if we successfully dug out the ramp below, that took care // of the ramp top here @@ -297,7 +301,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, if (can_dig_ramp(tt)) { target_type = findSimilarTileType(tt, df::tiletype_shape::RAMP); DFCoord pos_above(pos.x, pos.y, pos.z+1); - wall_mat[1] = get_wall_mat(map, pos_above); + boulder_mat[1] = get_boulder_mat(map, pos_above); if (target_type != tt && map.ensureBlockAt(pos_above)) { // set tile type directly instead of calling dig_shape // because we need to use *this* tile's material, not the @@ -327,12 +331,60 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, return true; } +// connects adjacent smooth walls to our new smooth wall +static bool adjust_smooth_wall_dir(MapExtras::MapCache &map, + const DFCoord &pos, + TileDirection adjacent_tdir) { + df::tiletype tt = map.tiletypeAt(pos); + if (tileSpecial(tt) != df::tiletype_special::SMOOTH + || tileShape(tt) != df::tiletype_shape::WALL) + return false; + + TileDirection tdir = tileDirection(tt); + tdir.whole |= adjacent_tdir.whole; + + tt = findTileType(tileShape(tt), tileMaterial(tt), tileVariant(tt), + tileSpecial(tt), tdir); + if (tt == df::tiletype::Void) + return false; + + map.setTiletypeAt(pos, tt); + return true; +} + +// assumes that if the game let you designate a tile for smoothing, it must be +// valid to do so. static bool smooth_tile(color_ostream &out, MapExtras::MapCache &map, const DFCoord &pos) { - // TODO - return false; + df::tiletype tt = map.tiletypeAt(pos); + + TileDirection tdir; + if (tileShape(tt) == df::tiletype_shape::WALL) { + if (adjust_smooth_wall_dir(map, DFCoord(pos.x, pos.y-1, pos.z), + TileDirection(1, 1, 0, 0))) + tdir.north = tdir.south = 1; + if (adjust_smooth_wall_dir(map, DFCoord(pos.x, pos.y+1, pos.z), + TileDirection(1, 1, 0, 0))) + tdir.north = tdir.south = 1; + if (adjust_smooth_wall_dir(map, DFCoord(pos.x-1, pos.y, pos.z), + TileDirection(0, 0, 1, 1))) + tdir.east = tdir.west = 1; + if (adjust_smooth_wall_dir(map, DFCoord(pos.x+1, pos.y, pos.z), + TileDirection(0, 0, 1, 1))) + tdir.east = tdir.west = 1; + } + + tt = findTileType(tileShape(tt), tileMaterial(tt), tileVariant(tt), + df::tiletype_special::SMOOTH, tdir); + if (tt == df::tiletype::Void) + return false; + + map.setTiletypeAt(pos, tt); + return true; } +// assumes that if the game let you designate a tile for track carving, it must +// be valid to do so. static bool carve_tile(MapExtras::MapCache &map, const DFCoord &pos, df::tile_occupancy &to) { df::tiletype tt = map.tiletypeAt(pos); @@ -397,19 +449,19 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, df::tile_designation td = map.designationAt(pos); df::tile_occupancy to = map.occupancyAt(pos); if (td.bits.dig != df::tile_dig_designation::No) { - int16_t wall_mat[2]; - memset(wall_mat, -1, sizeof(wall_mat)); - if (dig_tile(out, map, pos, td.bits.dig, wall_mat)) { + int16_t boulder_mat[2]; + memset(boulder_mat, -1, sizeof(boulder_mat)); + if (dig_tile(out, map, pos, td.bits.dig, boulder_mat)) { td = map.designationAt(pos); td.bits.dig = df::tile_dig_designation::No; map.setDesignationAt(pos, td); dug_coords.push_back(pos); for (size_t i = 0; i < 2; ++i) { - if (wall_mat[i] < 0) + if (boulder_mat[i] < 0) continue; if (produces_boulder(options, rng, map.BlockAtTile(pos)->veinTypeAt(pos))) { - boulder_coords[wall_mat[i]].push_back(pos); + boulder_coords[boulder_mat[i]].push_back(pos); } } }