forked from Mirrorlandia_minetest/minetest
Mgv7 spawn search: Cope with extreme custom terrain and biome 'dust'
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'.
This commit is contained in:
parent
8f2e60a961
commit
ea4d407082
@ -202,10 +202,7 @@ void MapgenV7Params::writeParams(Settings *settings) const
|
|||||||
|
|
||||||
int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
|
int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
|
||||||
{
|
{
|
||||||
// Base terrain calculation
|
// If rivers are enabled, first check if in a river
|
||||||
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
|
|
||||||
|
|
||||||
// If enabled, check if inside a river
|
|
||||||
if (spflags & MGV7_RIDGES) {
|
if (spflags & MGV7_RIDGES) {
|
||||||
float width = 0.2;
|
float width = 0.2;
|
||||||
float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
||||||
@ -213,28 +210,41 @@ int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
|
|||||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||||
}
|
}
|
||||||
|
|
||||||
// If mountains are disabled, terrain level is base terrain level
|
// Terrain noise 'offset' is the average level of that terrain.
|
||||||
// Avoids spawn on non-existant mountain 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 (!(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
|
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||||
else
|
else
|
||||||
return y;
|
// + 1 to not be half-buried in a potential node-deep biome 'dust'
|
||||||
|
return y + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mountain terrain calculation
|
// Search upwards for first node without mountain terrain
|
||||||
int iters = 128;
|
int iters = 256;
|
||||||
while (iters--) {
|
while (iters > 0 && y <= max_spawn_y) {
|
||||||
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { // If air above
|
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
|
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||||
else
|
else
|
||||||
return y;
|
return y + 1;
|
||||||
}
|
}
|
||||||
y++;
|
y++;
|
||||||
|
iters--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsuitable spawn point, no mountain surface found
|
// Unsuitable spawn point
|
||||||
return MAX_MAP_GENERATION_LIMIT;
|
return MAX_MAP_GENERATION_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user