implement tile smoothing

develop
myk002 2021-06-05 06:49:51 -07:00
parent d7f417051d
commit 6bc2a2bdad
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
1 changed files with 66 additions and 14 deletions

@ -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
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<DFCoord> &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);
}
}
}