Skip to content

Commit

Permalink
MgV5/6/7: Generate dungeons above water level
Browse files Browse the repository at this point in the history
Use/add stone_surface_max_y to speed-optimise/guide dungeon generation
MgV7: Don't let mountain terrain chop dungeons at mapchunk borders
Make mountain terrain update stone_surface_max_y for caves in mountains
  • Loading branch information
paramat authored and kwolekr committed Jan 1, 2015
1 parent 938a3f2 commit 7452d53
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 15 deletions.
5 changes: 1 addition & 4 deletions src/dungeongen.cpp
Expand Up @@ -70,10 +70,7 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams) {

void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) {
//TimeTaker t("gen dungeons");
int approx_groundlevel = 10 + mg->water_level;

if ((nmin.Y + nmax.Y) / 2 >= approx_groundlevel ||
NoisePerlin3D(&dp.np_rarity, nmin.X, nmin.Y, nmin.Z, mg->seed) < 0.2)
if (NoisePerlin3D(&dp.np_rarity, nmin.X, nmin.Y, nmin.Z, mg->seed) < 0.2)
return;

this->blockseed = bseed;
Expand Down
12 changes: 9 additions & 3 deletions src/mapgen_v5.cpp
Expand Up @@ -252,7 +252,8 @@ void MapgenV5::makeChunk(BlockMakeData *data)
calculateNoise();

// Generate base terrain
generateBaseTerrain();
s16 stone_surface_max_y = generateBaseTerrain();

updateHeightmap(node_min, node_max);

// Generate underground dirt, sand, gravel and lava blobs
Expand All @@ -268,7 +269,7 @@ void MapgenV5::makeChunk(BlockMakeData *data)
generateBiomes();

// Generate dungeons and desert temples
if (flags & MG_DUNGEONS) {
if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
DungeonGen dgen(this, NULL);
dgen.generate(blockseed, full_node_min, full_node_max);
}
Expand Down Expand Up @@ -342,10 +343,11 @@ void MapgenV5::calculateNoise()


// Make base ground level
void MapgenV5::generateBaseTerrain()
int MapgenV5::generateBaseTerrain()
{
u32 index = 0;
u32 index2d = 0;
int stone_surface_max_y = -MAP_GENERATION_LIMIT;

for(s16 z=node_min.Z; z<=node_max.Z; z++) {
for(s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
Expand All @@ -372,12 +374,16 @@ void MapgenV5::generateBaseTerrain()
vm->m_data[i] = MapNode(CONTENT_AIR);
} else {
vm->m_data[i] = MapNode(c_stone);
if (y > stone_surface_max_y)
stone_surface_max_y = y;
}
}
index2d = index2d - ystride;
}
index2d = index2d + ystride;
}

return stone_surface_max_y;
}


Expand Down
2 changes: 1 addition & 1 deletion src/mapgen_v5.h
Expand Up @@ -94,7 +94,7 @@ class MapgenV5 : public Mapgen {
virtual void makeChunk(BlockMakeData *data);
int getGroundLevelAtPoint(v2s16 p);
void calculateNoise();
void generateBaseTerrain();
int generateBaseTerrain();
void generateBlobs();
void generateBiomes();
void dustTopNodes();
Expand Down
2 changes: 1 addition & 1 deletion src/mapgen_v6.cpp
Expand Up @@ -500,7 +500,7 @@ void MapgenV6::makeChunk(BlockMakeData *data)
}

// Add dungeons
if (flags & MG_DUNGEONS) {
if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
DungeonParams dp;

dp.np_rarity = nparams_dungeon_rarity;
Expand Down
17 changes: 12 additions & 5 deletions src/mapgen_v7.cpp
Expand Up @@ -241,7 +241,7 @@ void MapgenV7::makeChunk(BlockMakeData *data)
if (flags & MG_CAVES)
generateCaves(stone_surface_max_y);

if (flags & MG_DUNGEONS) {
if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
DungeonGen dgen(this, NULL);
dgen.generate(blockseed, full_node_min, full_node_max);
}
Expand Down Expand Up @@ -405,7 +405,7 @@ int MapgenV7::generateTerrain()
int ymax = generateBaseTerrain();

if (spflags & MGV7_MOUNTAINS)
generateMountainTerrain();
ymax = generateMountainTerrain(ymax);

if (spflags & MGV7_RIDGES)
generateRidgeTerrain();
Expand Down Expand Up @@ -453,10 +453,10 @@ int MapgenV7::generateBaseTerrain()
}


void MapgenV7::generateMountainTerrain()
int MapgenV7::generateMountainTerrain(int ymax)
{
if (node_max.Y <= water_level)
return;
return ymax;

MapNode n_stone(c_stone);
u32 j = 0;
Expand All @@ -466,14 +466,21 @@ void MapgenV7::generateMountainTerrain()
u32 vi = vm->m_area.index(node_min.X, y, z);
for (s16 x = node_min.X; x <= node_max.X; x++) {
int index = (z - node_min.Z) * csize.X + (x - node_min.X);
content_t c = vm->m_data[vi].getContent();

if (getMountainTerrainFromMap(j, index, y))
if (getMountainTerrainFromMap(j, index, y)
&& (c == CONTENT_AIR || c == c_water_source)) {
vm->m_data[vi] = n_stone;
if (y > ymax)
ymax = y;
}

vi++;
j++;
}
}

return ymax;
}


Expand Down
2 changes: 1 addition & 1 deletion src/mapgen_v7.h
Expand Up @@ -107,7 +107,7 @@ class MapgenV7 : public Mapgen {

virtual int generateTerrain();
int generateBaseTerrain();
void generateMountainTerrain();
int generateMountainTerrain(int ymax);
void generateRidgeTerrain();

void generateBiomes();
Expand Down

2 comments on commit 7452d53

@HybridDog
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

screenshot_2619996150
dungeons already appeared above sea level before

@paramat
Copy link
Contributor Author

@paramat paramat commented on 7452d53 Jan 2, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, my commit message is imprecise because i shortened it. Before now, dungeons were only generated in and below surface mapchunks (the mapchunk containing sea level). They were generated out to the mapblock shell around a mpachunk, so up to a maximum of y = 47 + 16, but no higher.

Please sign in to comment.