fix: mountain smoothing logic
Signed-off-by: szdytom <szdytom@qq.com>
This commit is contained in:
parent
e7b9fd856f
commit
45836dc897
@ -210,6 +210,11 @@ private:
|
||||
*/
|
||||
void smoothen_mountains(TileMap &tilemap, std::uint32_t step_i);
|
||||
|
||||
void smoothen_mountains_tile(
|
||||
const TileMap &tilemap, TilePos pos, std::uint32_t step_i,
|
||||
std::vector<std::pair<TilePos, Tile>> &replacements
|
||||
);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a mountain smoothing pass
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "generation.h"
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <ranges>
|
||||
#include <set>
|
||||
|
||||
namespace istd {
|
||||
@ -156,8 +157,9 @@ std::uint32_t SmoothenMountainsPass::bfs_component_size(
|
||||
return size;
|
||||
}
|
||||
|
||||
void SmoothenMountainsPass::smoothen_mountains(
|
||||
TileMap &tilemap, std::uint32_t step_i
|
||||
void SmoothenMountainsPass::smoothen_mountains_tile(
|
||||
const TileMap &tilemap, TilePos pos, std::uint32_t step_i,
|
||||
std::vector<std::pair<TilePos, Tile>> &replacements
|
||||
) {
|
||||
struct CAConf {
|
||||
int neighbor_count;
|
||||
@ -175,19 +177,12 @@ void SmoothenMountainsPass::smoothen_mountains(
|
||||
{4, 16, 0 }
|
||||
};
|
||||
|
||||
for (std::uint8_t chunk_x = 0; chunk_x < tilemap.get_size(); ++chunk_x) {
|
||||
for (std::uint8_t chunk_y = 0; chunk_y < tilemap.get_size();
|
||||
++chunk_y) {
|
||||
for (std::uint8_t local_x = 0; local_x < Chunk::size; ++local_x) {
|
||||
for (std::uint8_t local_y = 0; local_y < Chunk::size;
|
||||
++local_y) {
|
||||
TilePos pos{chunk_x, chunk_y, local_x, local_y};
|
||||
auto [global_x, global_y] = pos.to_global();
|
||||
auto neighbors = tilemap.get_neighbors(pos);
|
||||
|
||||
// Ignore if adjacent to the boundary
|
||||
if (neighbors.size() < 4) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
// Count neighboring mountains
|
||||
@ -200,21 +195,52 @@ void SmoothenMountainsPass::smoothen_mountains(
|
||||
}
|
||||
|
||||
// Get the configuration for this count
|
||||
const CAConf &conf
|
||||
= cellularAutomataConfigurations[mountain_count];
|
||||
int rd = noise_.noise(global_x, global_y, step_i) & 0xF;
|
||||
const CAConf &conf = cellularAutomataConfigurations[mountain_count];
|
||||
auto sample = noise_.noise(global_x, global_y, step_i);
|
||||
auto rd = sample & 0xF;
|
||||
auto sel = sample >> 4;
|
||||
|
||||
Tile &tile = tilemap.get_tile(pos);
|
||||
if (tile.base == BaseTileType::Mountain
|
||||
&& conf.remove_chance > rd) {
|
||||
demountainize(tilemap, {pos});
|
||||
} else if (tile.base != BaseTileType::Mountain
|
||||
&& conf.fill_chance > rd) {
|
||||
Tile tile = tilemap.get_tile(pos);
|
||||
if (tile.base == BaseTileType::Mountain && conf.remove_chance > rd) {
|
||||
auto filterer = [&tilemap](const TilePos &p) {
|
||||
auto neighbor_tile = tilemap.get_tile(p);
|
||||
return neighbor_tile.base != BaseTileType::Mountain;
|
||||
};
|
||||
auto non_mountain_neighbors = neighbors | std::views::filter(filterer)
|
||||
| std::ranges::to<std::vector>();
|
||||
|
||||
if (!non_mountain_neighbors.empty()) {
|
||||
auto n = non_mountain_neighbors.size();
|
||||
auto replacement = non_mountain_neighbors[sel % n];
|
||||
tile.base = tilemap.get_tile(replacement).base;
|
||||
replacements.emplace_back(pos, tile);
|
||||
}
|
||||
} else if (tile.base != BaseTileType::Mountain && conf.fill_chance > rd) {
|
||||
tile.base = BaseTileType::Mountain;
|
||||
replacements.emplace_back(pos, tile);
|
||||
}
|
||||
}
|
||||
|
||||
void SmoothenMountainsPass::smoothen_mountains(
|
||||
TileMap &tilemap, std::uint32_t step_i
|
||||
) {
|
||||
std::vector<std::pair<TilePos, Tile>> replacements;
|
||||
|
||||
for (std::uint8_t chunk_x = 0; chunk_x < tilemap.get_size(); ++chunk_x) {
|
||||
for (std::uint8_t chunk_y = 0; chunk_y < tilemap.get_size();
|
||||
++chunk_y) {
|
||||
for (std::uint8_t local_x = 0; local_x < Chunk::size; ++local_x) {
|
||||
for (std::uint8_t local_y = 0; local_y < Chunk::size;
|
||||
++local_y) {
|
||||
TilePos pos{chunk_x, chunk_y, local_x, local_y};
|
||||
smoothen_mountains_tile(tilemap, pos, step_i, replacements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &[pos, new_tile] : replacements) {
|
||||
tilemap.set_tile(pos, new_tile);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user