aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorparamat <paramat@users.noreply.github.com>2017-06-14 02:00:51 +0100
committerparamat <mat.gregory@virginmedia.com>2017-07-11 01:14:24 +0100
commit8299e4b67eff48e0f6e101afea2fae8f0e65c421 (patch)
treefed891f09468aca2b53c8ced933fb88de2a823c6
parentef285b2815962a7a01791059ed984cb12fdba4dd (diff)
downloadminetest-8299e4b67eff48e0f6e101afea2fae8f0e65c421.tar.gz
minetest-8299e4b67eff48e0f6e101afea2fae8f0e65c421.tar.bz2
minetest-8299e4b67eff48e0f6e101afea2fae8f0e65c421.zip
Biomes/decorations/ores: Make relative to 'water_level' setting
Add 'biome_zero_level' argument to 'generateBiomes()', 'deco_zero_level' argument to 'placeAllDecos()' and 'ore_zero_level' to 'placeAllOres()' to allow mapgens to vertically shift the registered biomes, decorations and ores per-mapchunk. Will also allow many realm possibilities in future mapgens.
-rw-r--r--doc/lua_api.txt14
-rw-r--r--src/mapgen.cpp7
-rw-r--r--src/mapgen.h2
-rw-r--r--src/mapgen_carpathian.cpp10
-rw-r--r--src/mapgen_flat.cpp8
-rw-r--r--src/mapgen_fractal.cpp8
-rw-r--r--src/mapgen_v5.cpp8
-rw-r--r--src/mapgen_v6.cpp6
-rw-r--r--src/mapgen_v7.cpp8
-rw-r--r--src/mapgen_valleys.cpp8
-rw-r--r--src/mg_decoration.cpp19
-rw-r--r--src/mg_decoration.h6
-rw-r--r--src/mg_ore.cpp23
-rw-r--r--src/mg_ore.h6
14 files changed, 90 insertions, 43 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 3fc815272..e675cc703 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -4420,6 +4420,9 @@ Definition tables
-- ^ In this example, there is a 3x3x3 cluster where 8 out of the 27 nodes are coal ore
y_min = -31000,
y_max = 64,
+ -- ^ Lower and upper limits for ore.
+ -- ^ Limits are relative to y = water_level - 1 for core mapgen, or
+ -- ^ relative to y = 0 for minetest.generate_ores().
flags = "",
-- ^ Attributes for this ore generation
noise_threshold = 0.5,
@@ -4429,7 +4432,7 @@ Definition tables
-- ^ Needed for sheet ore_type. Omit from scatter ore_type for a uniform ore distribution
random_factor = 1.0,
-- ^ Multiplier of the randomness contribution to the noise value at any
- -- given point to decide if ore should be placed. Set to 0 for solid veins.
+ -- ^ given point to decide if ore should be placed. Set to 0 for solid veins.
-- ^ This parameter is only valid for ore_type == "vein".
biomes = {"desert", "rainforest"}
-- ^ List of biomes in which this decoration occurs. Occurs in all biomes if this is omitted,
@@ -4467,6 +4470,7 @@ The Biome API is still in an experimental phase and subject to change.
y_min = 1,
y_max = 31000,
-- ^ Lower and upper limits for biome.
+ -- ^ Limits are relative to y = water_level - 1.
-- ^ Because biome is not recalculated for every node in a node column
-- ^ some biome materials can exceed their limits, especially stone.
-- ^ For each node column in a mapchunk, biome is only recalculated at column
@@ -4509,9 +4513,11 @@ The Biome API is still in an experimental phase and subject to change.
-- ^ Can be a list of (or a single) biome names, IDs, or definitions.
y_min = -31000
y_max = 31000
- -- ^ Minimum and maximum `y` positions these decorations can be generated at.
- -- ^ This parameter refers to the `y` position of the decoration base, so
- -- the actual maximum height would be `height_max + size.Y`.
+ -- ^ Lower and upper limits for decoration.
+ -- ^ Limits are relative to y = water_level - 1 for core mapgen, or
+ -- ^ relative to y = 0 for minetest.generate_decorations().
+ -- ^ This parameter refers to the `y` position of the decoration base, so
+ -- the actual maximum height would be `height_max + size.Y`.
spawn_by = "default:water",
-- ^ Node (or list of nodes) that the decoration only spawns next to.
-- ^ Checks two horizontal planes of neighbouring nodes (including diagonal neighbours),
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index b095d34c8..7a03a4606 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -621,7 +621,7 @@ MapgenBasic::~MapgenBasic()
}
-MgStoneType MapgenBasic::generateBiomes()
+MgStoneType MapgenBasic::generateBiomes(s16 biome_zero_level)
{
// can't generate biomes without a biome generator!
assert(biomegen);
@@ -673,7 +673,10 @@ MgStoneType MapgenBasic::generateBiomes()
(air_above || !biome);
if (is_stone_surface || is_water_surface) {
- biome = biomegen->getBiomeAtIndex(index, y);
+ // Limit to +-MAX MAP GENERATION LIMIT to work with biome y_min / y_max.
+ s32 relative_y = rangelim(y - biome_zero_level,
+ -MAX_MAP_GENERATION_LIMIT, MAX_MAP_GENERATION_LIMIT);
+ biome = biomegen->getBiomeAtIndex(index, relative_y);
if (biomemap[index] == BIOME_NONE && is_stone_surface)
biomemap[index] = biome->index;
diff --git a/src/mapgen.h b/src/mapgen.h
index 7acceddaf..7f4b76c3e 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -251,7 +251,7 @@ public:
virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth);
virtual bool generateCaverns(s16 max_stone_y);
virtual void generateDungeons(s16 max_stone_y, MgStoneType stone_type);
- virtual MgStoneType generateBiomes();
+ virtual MgStoneType generateBiomes(s16 biome_zero_level = 0);
virtual void dustTopNodes();
protected:
diff --git a/src/mapgen_carpathian.cpp b/src/mapgen_carpathian.cpp
index c33239087..598795830 100644
--- a/src/mapgen_carpathian.cpp
+++ b/src/mapgen_carpathian.cpp
@@ -242,7 +242,7 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data)
// Init biome generator, place biome-specific nodes, and build biomemap
biomegen->calcBiomeNoise(node_min);
- MgStoneType stone_type = generateBiomes();
+ MgStoneType stone_type = generateBiomes(water_level - 1);
// Generate caverns, tunnels and classic caves
if (flags & MG_CAVES) {
@@ -266,10 +266,12 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data)
// Generate the registered decorations
if (flags & MG_DECORATIONS)
- m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
+ m_emerge->decomgr->placeAllDecos(this, blockseed,
+ node_min, node_max, water_level - 1);
// Generate the registered ores
- m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
+ m_emerge->oremgr->placeAllOres(this, blockseed,
+ node_min, node_max, water_level - 1);
// Sprinkle some dust on top after everything else was generated
dustTopNodes();
@@ -448,4 +450,4 @@ int MapgenCarpathian::generateTerrain()
}
return stone_surface_max_y;
-} \ No newline at end of file
+}
diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp
index 95fb35412..56dca1f06 100644
--- a/src/mapgen_flat.cpp
+++ b/src/mapgen_flat.cpp
@@ -189,7 +189,7 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
// Init biome generator, place biome-specific nodes, and build biomemap
biomegen->calcBiomeNoise(node_min);
- MgStoneType stone_type = generateBiomes();
+ MgStoneType stone_type = generateBiomes(water_level - 1);
if (flags & MG_CAVES)
generateCaves(stone_surface_max_y, large_cave_depth);
@@ -199,10 +199,12 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
// Generate the registered decorations
if (flags & MG_DECORATIONS)
- m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
+ m_emerge->decomgr->placeAllDecos(this, blockseed,
+ node_min, node_max, water_level - 1);
// Generate the registered ores
- m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
+ m_emerge->oremgr->placeAllOres(this, blockseed,
+ node_min, node_max, water_level - 1);
// Sprinkle some dust on top after everything else was generated
dustTopNodes();
diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp
index 4fe0d8369..13da2f180 100644
--- a/src/mapgen_fractal.cpp
+++ b/src/mapgen_fractal.cpp
@@ -199,7 +199,7 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
// Init biome generator, place biome-specific nodes, and build biomemap
biomegen->calcBiomeNoise(node_min);
- MgStoneType stone_type = generateBiomes();
+ MgStoneType stone_type = generateBiomes(water_level - 1);
if (flags & MG_CAVES)
generateCaves(stone_surface_max_y, large_cave_depth);
@@ -209,10 +209,12 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
// Generate the registered decorations
if (flags & MG_DECORATIONS)
- m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
+ m_emerge->decomgr->placeAllDecos(this, blockseed,
+ node_min, node_max, water_level - 1);
// Generate the registered ores
- m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
+ m_emerge->oremgr->placeAllOres(this, blockseed,
+ node_min, node_max, water_level - 1);
// Sprinkle some dust on top after everything else was generated
dustTopNodes();
diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp
index ffa1f538c..ad1e9d0a5 100644
--- a/src/mapgen_v5.cpp
+++ b/src/mapgen_v5.cpp
@@ -200,7 +200,7 @@ void MapgenV5::makeChunk(BlockMakeData *data)
// Init biome generator, place biome-specific nodes, and build biomemap
biomegen->calcBiomeNoise(node_min);
- MgStoneType stone_type = generateBiomes();
+ MgStoneType stone_type = generateBiomes(water_level - 1);
// Generate caverns, tunnels and classic caves
if (flags & MG_CAVES) {
@@ -224,10 +224,12 @@ void MapgenV5::makeChunk(BlockMakeData *data)
// Generate the registered decorations
if (flags & MG_DECORATIONS)
- m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
+ m_emerge->decomgr->placeAllDecos(this, blockseed,
+ node_min, node_max, water_level - 1);
// Generate the registered ores
- m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
+ m_emerge->oremgr->placeAllOres(this, blockseed,
+ node_min, node_max, water_level - 1);
// Sprinkle some dust on top after everything else was generated
dustTopNodes();
diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp
index ebbd932d4..e8e0c583d 100644
--- a/src/mapgen_v6.cpp
+++ b/src/mapgen_v6.cpp
@@ -619,10 +619,12 @@ void MapgenV6::makeChunk(BlockMakeData *data)
// Generate the registered decorations
if (flags & MG_DECORATIONS)
- m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
+ m_emerge->decomgr->placeAllDecos(this, blockseed,
+ node_min, node_max, water_level - 1);
// Generate the registered ores
- m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
+ m_emerge->oremgr->placeAllOres(this, blockseed,
+ node_min, node_max, water_level - 1);
// Calculate lighting
if (flags & MG_LIGHT)
diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp
index 17f2df835..4b263bdb3 100644
--- a/src/mapgen_v7.cpp
+++ b/src/mapgen_v7.cpp
@@ -298,7 +298,7 @@ void MapgenV7::makeChunk(BlockMakeData *data)
// Init biome generator, place biome-specific nodes, and build biomemap
biomegen->calcBiomeNoise(node_min);
- MgStoneType stone_type = generateBiomes();
+ MgStoneType stone_type = generateBiomes(water_level - 1);
// Generate caverns, tunnels and classic caves
if (flags & MG_CAVES) {
@@ -322,10 +322,12 @@ void MapgenV7::makeChunk(BlockMakeData *data)
// Generate the registered decorations
if (flags & MG_DECORATIONS)
- m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
+ m_emerge->decomgr->placeAllDecos(this, blockseed,
+ node_min, node_max, water_level - 1);
// Generate the registered ores
- m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
+ m_emerge->oremgr->placeAllOres(this, blockseed,
+ node_min, node_max, water_level - 1);
// Sprinkle some dust on top after everything else was generated
dustTopNodes();
diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp
index 71c0b001f..8c54dbcd9 100644
--- a/src/mapgen_valleys.cpp
+++ b/src/mapgen_valleys.cpp
@@ -236,7 +236,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
updateHeightmap(node_min, node_max);
// Place biome-specific nodes and build biomemap
- MgStoneType stone_type = generateBiomes();
+ MgStoneType stone_type = generateBiomes(water_level - 1);
// Cave creation.
if (flags & MG_CAVES)
@@ -248,10 +248,12 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
// Generate the registered decorations
if (flags & MG_DECORATIONS)
- m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
+ m_emerge->decomgr->placeAllDecos(this, blockseed,
+ node_min, node_max, water_level - 1);
// Generate the registered ores
- m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
+ m_emerge->oremgr->placeAllOres(this, blockseed,
+ node_min, node_max, water_level - 1);
// Sprinkle some dust on top after everything else was generated
dustTopNodes();
diff --git a/src/mg_decoration.cpp b/src/mg_decoration.cpp
index b13ddbadb..4af7a7897 100644
--- a/src/mg_decoration.cpp
+++ b/src/mg_decoration.cpp
@@ -48,7 +48,7 @@ DecorationManager::DecorationManager(IGameDef *gamedef) :
size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
- v3s16 nmin, v3s16 nmax)
+ v3s16 nmin, v3s16 nmax, s16 deco_zero_level)
{
size_t nplaced = 0;
@@ -57,7 +57,7 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
if (!deco)
continue;
- nplaced += deco->placeDeco(mg, blockseed, nmin, nmax);
+ nplaced += deco->placeDeco(mg, blockseed, nmin, nmax, deco_zero_level);
blockseed++;
}
@@ -123,8 +123,18 @@ bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p)
}
-size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
+size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed,
+ v3s16 nmin, v3s16 nmax, s16 deco_zero_level)
{
+ // Decoration y_min / y_max is displaced by deco_zero_level or remains
+ // unchanged. Any decoration with a limit at +-MAX_MAP_GENERATION_LIMIT is
+ // considered to have that limit at +-infinity, so we do not alter that limit.
+ s32 y_min_disp = (y_min <= -MAX_MAP_GENERATION_LIMIT) ?
+ -MAX_MAP_GENERATION_LIMIT : y_min + deco_zero_level;
+
+ s32 y_max_disp = (y_max >= MAX_MAP_GENERATION_LIMIT) ?
+ MAX_MAP_GENERATION_LIMIT : y_max + deco_zero_level;
+
PcgRandom ps(blockseed + 53);
int carea_size = nmax.X - nmin.X + 1;
@@ -179,8 +189,7 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
else
y = mg->findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y);
- if (y < nmin.Y || y > nmax.Y ||
- y < y_min || y > y_max)
+ if (y < y_min_disp || y > y_max_disp || y < nmin.Y || y > nmax.Y)
continue;
if (y + getHeight() > mg->vm->m_area.MaxEdge.Y) {
diff --git a/src/mg_decoration.h b/src/mg_decoration.h
index 968c78612..a7fdb97fe 100644
--- a/src/mg_decoration.h
+++ b/src/mg_decoration.h
@@ -70,7 +70,8 @@ public:
virtual void resolveNodeNames();
bool canPlaceDecoration(MMVManip *vm, v3s16 p);
- size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
+ size_t placeDeco(Mapgen *mg, u32 blockseed,
+ v3s16 nmin, v3s16 nmax, s16 deco_zero_level);
//size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p) = 0;
@@ -145,7 +146,8 @@ public:
}
}
- size_t placeAllDecos(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
+ size_t placeAllDecos(Mapgen *mg, u32 blockseed,
+ v3s16 nmin, v3s16 nmax, s16 deco_zero_level = 0);
};
#endif
diff --git a/src/mg_ore.cpp b/src/mg_ore.cpp
index 73af2e2e6..36100f762 100644
--- a/src/mg_ore.cpp
+++ b/src/mg_ore.cpp
@@ -43,7 +43,8 @@ OreManager::OreManager(IGameDef *gamedef) :
}
-size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
+size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed,
+ v3s16 nmin, v3s16 nmax, s16 ore_zero_level)
{
size_t nplaced = 0;
@@ -52,7 +53,7 @@ size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nma
if (!ore)
continue;
- nplaced += ore->placeOre(mg, blockseed, nmin, nmax);
+ nplaced += ore->placeOre(mg, blockseed, nmin, nmax, ore_zero_level);
blockseed++;
}
@@ -85,13 +86,23 @@ void Ore::resolveNodeNames()
}
-size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
+size_t Ore::placeOre(Mapgen *mg, u32 blockseed,
+ v3s16 nmin, v3s16 nmax, s16 ore_zero_level)
{
- if (!(nmin.Y <= y_max && nmax.Y >= y_min))
+ // Ore y_min / y_max is displaced by ore_zero_level or remains unchanged.
+ // Any ore with a limit at +-MAX_MAP_GENERATION_LIMIT is considered to have
+ // that limit at +-infinity, so we do not alter that limit.
+ s32 y_min_disp = (y_min <= -MAX_MAP_GENERATION_LIMIT) ?
+ -MAX_MAP_GENERATION_LIMIT : y_min + ore_zero_level;
+
+ s32 y_max_disp = (y_max >= MAX_MAP_GENERATION_LIMIT) ?
+ MAX_MAP_GENERATION_LIMIT : y_max + ore_zero_level;
+
+ if (nmin.Y > y_max_disp || nmax.Y < y_min_disp)
return 0;
- int actual_ymin = MYMAX(nmin.Y, y_min);
- int actual_ymax = MYMIN(nmax.Y, y_max);
+ int actual_ymin = MYMAX(nmin.Y, y_min_disp);
+ int actual_ymax = MYMIN(nmax.Y, y_max_disp);
if (clust_size >= actual_ymax - actual_ymin + 1)
return 0;
diff --git a/src/mg_ore.h b/src/mg_ore.h
index 5aeb3631c..692cd848e 100644
--- a/src/mg_ore.h
+++ b/src/mg_ore.h
@@ -70,7 +70,8 @@ public:
virtual void resolveNodeNames();
- size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
+ size_t placeOre(Mapgen *mg, u32 blockseed,
+ v3s16 nmin, v3s16 nmax, s16 ore_zero_level);
virtual void generate(MMVManip *vm, int mapseed, u32 blockseed,
v3s16 nmin, v3s16 nmax, u8 *biomemap) = 0;
};
@@ -163,7 +164,8 @@ public:
void clear();
- size_t placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
+ size_t placeAllOres(Mapgen *mg, u32 blockseed,
+ v3s16 nmin, v3s16 nmax, s16 ore_zero_level = 0);
};
#endif