Skip to content

Commit

Permalink
Mgv7 spawn search: Cope with extreme custom terrain and biome 'dust'
Browse files Browse the repository at this point in the history
Previously, maximum spawn level was set to 'water_level + 16'. This would result
in spawn search failing if terrain had been customised to be much higher than
'water_level' at all points.

Also raise spawn level by 1 node to avoid spawning half-buried in a biome 'dust'
node such as 'default:snowblock'.
  • Loading branch information
paramat committed Jun 19, 2017
1 parent 8f2e60a commit ea4d407
Showing 1 changed file with 24 additions and 14 deletions.
38 changes: 24 additions & 14 deletions src/mapgen_v7.cpp
Expand Up @@ -202,39 +202,49 @@ void MapgenV7Params::writeParams(Settings *settings) const

int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
{
// Base terrain calculation
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);

// If enabled, check if inside a river
// If rivers are enabled, first check if in a river
if (spflags & MGV7_RIDGES) {
float width = 0.2;
float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
if (fabs(uwatern) <= width)
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
}

// If mountains are disabled, terrain level is base terrain level
// Avoids spawn on non-existant mountain terrain
// Terrain noise 'offset' is the average level of that terrain.
// At least 50% of terrain will be below the higher of base and alt terrain
// 'offset's.
// Raising the maximum spawn level above 'water_level + 16' is necessary
// for when terrain 'offset's are set much higher than water_level.
s16 max_spawn_y = MYMAX(MYMAX(noise_terrain_alt->np.offset,
noise_terrain_base->np.offset),
water_level + 16);
// Base terrain calculation
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);

// If mountains are disabled, terrain level is base terrain level.
// Avoids mid-air spawn where mountain terrain would have been.
if (!(spflags & MGV7_MOUNTAINS)) {
if (y <= water_level || y > water_level + 16)
if (y <= water_level || y > max_spawn_y)
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
else
return y;
// + 1 to not be half-buried in a potential node-deep biome 'dust'
return y + 1;
}

// Mountain terrain calculation
int iters = 128;
while (iters--) {
// Search upwards for first node without mountain terrain
int iters = 256;
while (iters > 0 && y <= max_spawn_y) {
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { // If air above
if (y <= water_level || y > water_level + 16)
if (y <= water_level || y > max_spawn_y)
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
else
return y;
return y + 1;
}
y++;
iters--;
}

// Unsuitable spawn point, no mountain surface found
// Unsuitable spawn point
return MAX_MAP_GENERATION_LIMIT;
}

Expand Down

0 comments on commit ea4d407

Please sign in to comment.