mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Rewrite generate notification mechanism
Add support for notify-on-decoration Clean up mapgen constructors Clean up mapgen.cpp code style somewhat Remove trailing whitespace from some files
This commit is contained in:
parent
2b119e1e19
commit
5062b99cb0
19 changed files with 436 additions and 329 deletions
|
@ -49,19 +49,12 @@ FlagDesc flagdesc_mapgen_v7[] = {
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
|
||||
this->generating = false;
|
||||
this->id = mapgenid;
|
||||
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||
: Mapgen(mapgenid, params, emerge)
|
||||
{
|
||||
this->emerge = emerge;
|
||||
this->bmgr = emerge->biomemgr;
|
||||
|
||||
this->seed = (int)params->seed;
|
||||
this->water_level = params->water_level;
|
||||
this->flags = params->flags;
|
||||
this->gennotify = emerge->gennotify;
|
||||
|
||||
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
|
||||
|
||||
//// amount of elements to skip for the next index
|
||||
//// for noise/height/biome maps (not vmanip)
|
||||
this->ystride = csize.X;
|
||||
|
@ -119,7 +112,7 @@ MapgenV7::~MapgenV7() {
|
|||
|
||||
delete noise_heat;
|
||||
delete noise_humidity;
|
||||
|
||||
|
||||
delete[] ridge_heightmap;
|
||||
delete[] heightmap;
|
||||
delete[] biomemap;
|
||||
|
@ -177,7 +170,7 @@ void MapgenV7Params::writeParams(Settings *settings) {
|
|||
int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
|
||||
// Base terrain calculation
|
||||
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
|
||||
|
||||
|
||||
// Ridge/river terrain calculation
|
||||
float width = 0.3;
|
||||
float uwatern = NoisePerlin2DNoTxfm(noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
||||
|
@ -185,14 +178,14 @@ int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
|
|||
// if inside a river, simply guess
|
||||
if (uwatern >= -width && uwatern <= width)
|
||||
return water_level - 10;
|
||||
|
||||
|
||||
// Mountain terrain calculation
|
||||
int iters = 128; // don't even bother iterating more than 128 times..
|
||||
while (iters--) {
|
||||
//current point would have been air
|
||||
if (!getMountainTerrainAtPoint(p.X, y, p.Y))
|
||||
return y;
|
||||
|
||||
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -209,12 +202,12 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
|||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
|
||||
|
||||
this->generating = true;
|
||||
this->vm = data->vmanip;
|
||||
this->vm = data->vmanip;
|
||||
this->ndef = data->nodedef;
|
||||
//TimeTaker t("makeChunk");
|
||||
|
||||
|
||||
v3s16 blockpos_min = data->blockpos_min;
|
||||
v3s16 blockpos_max = data->blockpos_max;
|
||||
node_min = blockpos_min * MAP_BLOCKSIZE;
|
||||
|
@ -223,19 +216,19 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
|||
full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
|
||||
|
||||
blockseed = emerge->getBlockSeed(full_node_min); //////use getBlockSeed2()!
|
||||
|
||||
|
||||
// Make some noise
|
||||
calculateNoise();
|
||||
|
||||
|
||||
// Generate base terrain, mountains, and ridges with initial heightmaps
|
||||
s16 stone_surface_max_y = generateTerrain();
|
||||
|
||||
|
||||
updateHeightmap(node_min, node_max);
|
||||
|
||||
|
||||
// Calculate biomes
|
||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
||||
noise_humidity->result, heightmap, biomemap);
|
||||
|
||||
|
||||
// Actually place the biome-specific nodes and what not
|
||||
generateBiomes();
|
||||
|
||||
|
@ -255,17 +248,17 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
|||
|
||||
// Sprinkle some dust on top after everything else was generated
|
||||
dustTopNodes();
|
||||
|
||||
|
||||
//printf("makeChunk: %dms\n", t.stop());
|
||||
|
||||
|
||||
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
||||
|
||||
|
||||
if (flags & MG_LIGHT)
|
||||
calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||
//setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||
// node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
|
||||
|
||||
|
||||
this->generating = false;
|
||||
}
|
||||
|
||||
|
@ -275,24 +268,24 @@ void MapgenV7::calculateNoise() {
|
|||
int x = node_min.X;
|
||||
int y = node_min.Y;
|
||||
int z = node_min.Z;
|
||||
|
||||
|
||||
noise_height_select->perlinMap2D(x, z);
|
||||
noise_height_select->transformNoiseMap();
|
||||
|
||||
|
||||
noise_terrain_persist->perlinMap2D(x, z);
|
||||
noise_terrain_persist->transformNoiseMap();
|
||||
float *persistmap = noise_terrain_persist->result;
|
||||
for (int i = 0; i != csize.X * csize.Z; i++)
|
||||
persistmap[i] = rangelim(persistmap[i], 0.4, 0.9);
|
||||
|
||||
|
||||
noise_terrain_base->perlinMap2DModulated(x, z, persistmap);
|
||||
noise_terrain_base->transformNoiseMap();
|
||||
|
||||
|
||||
noise_terrain_alt->perlinMap2DModulated(x, z, persistmap);
|
||||
noise_terrain_alt->transformNoiseMap();
|
||||
|
||||
|
||||
noise_filler_depth->perlinMap2D(x, z);
|
||||
|
||||
|
||||
if (spflags & MGV7_MOUNTAINS) {
|
||||
noise_mountain->perlinMap3D(x, y, z);
|
||||
noise_mount_height->perlinMap2D(x, z);
|
||||
|
@ -303,10 +296,10 @@ void MapgenV7::calculateNoise() {
|
|||
noise_ridge->perlinMap3D(x, y, z);
|
||||
noise_ridge_uwater->perlinMap2D(x, z);
|
||||
}
|
||||
|
||||
|
||||
noise_heat->perlinMap2D(x, z);
|
||||
noise_humidity->perlinMap2D(x, z);
|
||||
|
||||
|
||||
//printf("calculateNoise: %dus\n", t.stop());
|
||||
}
|
||||
|
||||
|
@ -315,7 +308,7 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
|
|||
float heat = NoisePerlin2D(bmgr->np_heat, p.X, p.Z, seed);
|
||||
float humidity = NoisePerlin2D(bmgr->np_humidity, p.X, p.Z, seed);
|
||||
s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Z);
|
||||
|
||||
|
||||
return bmgr->getBiome(heat, humidity, groundlevel);
|
||||
}
|
||||
|
||||
|
@ -323,7 +316,7 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
|
|||
float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
|
||||
float hselect = NoisePerlin2D(noise_height_select->np, x, z, seed);
|
||||
hselect = rangelim(hselect, 0.0, 1.0);
|
||||
|
||||
|
||||
float persist = NoisePerlin2D(noise_terrain_persist->np, x, z, seed);
|
||||
persist = rangelim(persist, 0.4, 0.9);
|
||||
|
||||
|
@ -335,7 +328,7 @@ float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
|
|||
|
||||
if (height_alt > height_base)
|
||||
return height_alt;
|
||||
|
||||
|
||||
return (height_base * hselect) + (height_alt * (1.0 - hselect));
|
||||
}
|
||||
|
||||
|
@ -344,7 +337,7 @@ float MapgenV7::baseTerrainLevelFromMap(int index) {
|
|||
float hselect = rangelim(noise_height_select->result[index], 0.0, 1.0);
|
||||
float height_base = noise_terrain_base->result[index];
|
||||
float height_alt = noise_terrain_alt->result[index];
|
||||
|
||||
|
||||
if (height_alt > height_base)
|
||||
return height_alt;
|
||||
|
||||
|
@ -373,7 +366,7 @@ void MapgenV7::carveRivers() {
|
|||
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
|
||||
MapNode n_stone(c_stone);
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
int river_depth = 4;
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
|
@ -385,16 +378,16 @@ void MapgenV7::carveRivers() {
|
|||
float height = terrain_river * (1 - abs(terrain_mod)) *
|
||||
noise_terrain_river->np->scale;
|
||||
height = log(height * height); //log(h^3) is pretty interesting for terrain
|
||||
|
||||
|
||||
s16 y = heightmap[index];
|
||||
if (height < 1.0 && y > river_depth &&
|
||||
y - river_depth >= node_min.Y && y <= node_max.Y) {
|
||||
|
||||
|
||||
for (s16 ry = y; ry != y - river_depth; ry--) {
|
||||
u32 vi = vm->m_area.index(x, ry, z);
|
||||
vm->m_data[vi] = n_air;
|
||||
}
|
||||
|
||||
|
||||
u32 vi = vm->m_area.index(x, y - river_depth, z);
|
||||
vm->m_data[vi] = n_water_source;
|
||||
}
|
||||
|
@ -411,7 +404,7 @@ int MapgenV7::generateTerrain() {
|
|||
|
||||
if (spflags & MGV7_RIDGES)
|
||||
generateRidgeTerrain();
|
||||
|
||||
|
||||
return ymax;
|
||||
}
|
||||
|
||||
|
@ -420,23 +413,23 @@ int MapgenV7::generateBaseTerrain() {
|
|||
MapNode n_air(CONTENT_AIR);
|
||||
MapNode n_stone(c_stone);
|
||||
MapNode n_water(c_water_source);
|
||||
|
||||
|
||||
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
float surface_height = baseTerrainLevelFromMap(index);
|
||||
s16 surface_y = (s16)surface_height;
|
||||
|
||||
heightmap[index] = surface_y;
|
||||
|
||||
heightmap[index] = surface_y;
|
||||
ridge_heightmap[index] = surface_y;
|
||||
|
||||
|
||||
if (surface_y > stone_surface_max_y)
|
||||
stone_surface_max_y = surface_y;
|
||||
|
||||
u32 i = vm->m_area.index(x, node_min.Y, z);
|
||||
u32 i = vm->m_area.index(x, node_min.Y, z);
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||
if (y <= surface_y)
|
||||
|
@ -449,7 +442,7 @@ int MapgenV7::generateBaseTerrain() {
|
|||
vm->m_area.add_y(em, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return stone_surface_max_y;
|
||||
}
|
||||
|
||||
|
@ -457,10 +450,10 @@ int MapgenV7::generateBaseTerrain() {
|
|||
void MapgenV7::generateMountainTerrain() {
|
||||
if (node_max.Y <= water_level)
|
||||
return;
|
||||
|
||||
|
||||
MapNode n_stone(c_stone);
|
||||
u32 j = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||
|
@ -469,7 +462,7 @@ void MapgenV7::generateMountainTerrain() {
|
|||
|
||||
if (getMountainTerrainFromMap(j, index, y))
|
||||
vm->m_data[vi] = n_stone;
|
||||
|
||||
|
||||
vi++;
|
||||
j++;
|
||||
}
|
||||
|
@ -481,36 +474,36 @@ void MapgenV7::generateRidgeTerrain() {
|
|||
MapNode n_water(c_water_source);
|
||||
MapNode n_air(CONTENT_AIR);
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) {
|
||||
int j = (z - node_min.Z) * csize.X + (x - node_min.X);
|
||||
|
||||
|
||||
if (heightmap[j] < water_level - 4)
|
||||
continue;
|
||||
|
||||
|
||||
float widthn = (noise_terrain_persist->result[j] - 0.6) / 0.1;
|
||||
//widthn = rangelim(widthn, -0.05, 0.5);
|
||||
|
||||
|
||||
float width = 0.3; // TODO: figure out acceptable perlin noise values
|
||||
float uwatern = noise_ridge_uwater->result[j] * 2;
|
||||
if (uwatern < -width || uwatern > width)
|
||||
continue;
|
||||
|
||||
|
||||
float height_mod = (float)(y + 17) / 2.5;
|
||||
float width_mod = (width - fabs(uwatern));
|
||||
float nridge = noise_ridge->result[index] * (float)y / 7.0;
|
||||
|
||||
if (y < water_level)
|
||||
nridge = -fabs(nridge) * 3.0 * widthn * 0.3;
|
||||
|
||||
|
||||
if (nridge + width_mod * height_mod < 0.6)
|
||||
continue;
|
||||
|
||||
|
||||
if (y < ridge_heightmap[j])
|
||||
ridge_heightmap[j] = y - 1;
|
||||
ridge_heightmap[j] = y - 1;
|
||||
|
||||
vm->m_data[vi] = (y > water_level) ? n_air : n_water;
|
||||
}
|
||||
|
@ -528,7 +521,7 @@ void MapgenV7::generateBiomes() {
|
|||
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||
|
@ -537,14 +530,14 @@ void MapgenV7::generateBiomes() {
|
|||
s16 y0_filler = biome->depth_top + dfiller;
|
||||
|
||||
s16 nplaced = 0;
|
||||
u32 i = vm->m_area.index(x, node_max.Y, z);
|
||||
u32 i = vm->m_area.index(x, node_max.Y, z);
|
||||
|
||||
content_t c_above = vm->m_data[i + em.X].getContent();
|
||||
bool have_air = c_above == CONTENT_AIR;
|
||||
|
||||
|
||||
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
||||
content_t c = vm->m_data[i].getContent();
|
||||
|
||||
|
||||
// It could be the case that the elevation is equal to the chunk
|
||||
// boundary, but the chunk above has not been generated yet
|
||||
if (y == node_max.Y && c_above == CONTENT_IGNORE &&
|
||||
|
@ -554,10 +547,10 @@ void MapgenV7::generateBiomes() {
|
|||
(x - node_min.X);
|
||||
have_air = !getMountainTerrainFromMap(j, index, y);
|
||||
}
|
||||
|
||||
|
||||
if (c == c_stone && have_air) {
|
||||
content_t c_below = vm->m_data[i - em.X].getContent();
|
||||
|
||||
|
||||
if (c_below != CONTENT_AIR) {
|
||||
if (nplaced < y0_top) {
|
||||
if(y < water_level)
|
||||
|
@ -593,7 +586,7 @@ void MapgenV7::generateBiomes() {
|
|||
have_air = true;
|
||||
nplaced = 0;
|
||||
}
|
||||
|
||||
|
||||
vm->m_area.add_y(em, i, -1);
|
||||
}
|
||||
}
|
||||
|
@ -603,14 +596,14 @@ void MapgenV7::generateBiomes() {
|
|||
void MapgenV7::dustTopNodes() {
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
if (water_level > node_max.Y)
|
||||
return;
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||
|
||||
|
||||
if (biome->c_dust == CONTENT_IGNORE)
|
||||
continue;
|
||||
|
||||
|
@ -622,17 +615,17 @@ void MapgenV7::dustTopNodes() {
|
|||
|
||||
vm->m_area.add_y(em, vi, -1);
|
||||
}
|
||||
|
||||
|
||||
content_t c = vm->m_data[vi].getContent();
|
||||
if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
|
||||
if (y < node_min.Y)
|
||||
continue;
|
||||
|
||||
|
||||
vm->m_data[vi] = MapNode(biome->c_dust_water);
|
||||
} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE) {
|
||||
if (y == node_max.Y)
|
||||
continue;
|
||||
|
||||
|
||||
vm->m_area.add_y(em, vi, 1);
|
||||
vm->m_data[vi] = MapNode(biome->c_dust);
|
||||
}
|
||||
|
@ -649,10 +642,10 @@ void MapgenV7::addTopNodes() {
|
|||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
||||
|
||||
|
||||
//////////////////// First, add top nodes below the ridge
|
||||
s16 y = ridge_heightmap[index];
|
||||
|
||||
|
||||
// This cutoff is good enough, but not perfect.
|
||||
// It will cut off potentially placed top nodes at chunk boundaries
|
||||
if (y < node_min.Y)
|
||||
|
@ -664,7 +657,7 @@ void MapgenV7::addTopNodes() {
|
|||
if (ndef->get(c).walkable)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// N.B. It is necessary to search downward since ridge_heightmap[i]
|
||||
// might not be the actual height, just the lowest part in the chunk
|
||||
// where a ridge had been carved
|
||||
|
@ -692,7 +685,7 @@ void MapgenV7::addTopNodes() {
|
|||
vm->m_data[i] = MapNode(c_dirt_with_grass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////// Now, add top nodes on top of the ridge
|
||||
y = heightmap[index];
|
||||
if (y > node_max.Y) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue