Expand Up
@@ -42,6 +42,7 @@ FlagDesc flagdesc_mapgen_v6[] = {
{" jungles" , MGV6_JUNGLES},
{" biomeblend" , MGV6_BIOMEBLEND},
{" mudflow" , MGV6_MUDFLOW},
{" snowbiomes" , MGV6_SNOWBIOMES},
{NULL , 0 }
};
Expand Down
Expand Up
@@ -73,7 +74,10 @@ MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge)
noise_height_select = new Noise (&sp->np_height_select , seed, csize.X , csize.Y );
noise_mud = new Noise (&sp->np_mud , seed, csize.X , csize.Y );
noise_beach = new Noise (&sp->np_beach , seed, csize.X , csize.Y );
noise_biome = new Noise (&sp->np_biome , seed, csize.X , csize.Y );
noise_biome = new Noise (&sp->np_biome , seed,
csize.X + 2 * MAP_BLOCKSIZE, csize.Y + 2 * MAP_BLOCKSIZE);
noise_humidity = new Noise (&sp->np_humidity , seed,
csize.X + 2 * MAP_BLOCKSIZE, csize.Y + 2 * MAP_BLOCKSIZE);
// // Resolve nodes to be used
INodeDefManager *ndef = emerge->ndef ;
Expand All
@@ -88,6 +92,11 @@ MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge)
c_cobble = ndef->getId (" mapgen_cobble" );
c_desert_sand = ndef->getId (" mapgen_desert_sand" );
c_desert_stone = ndef->getId (" mapgen_desert_stone" );
c_dirt_with_snow = ndef->getId (" mapgen_dirt_with_snow" );
c_snow = ndef->getId (" mapgen_snow" );
c_snowblock = ndef->getId (" mapgen_snowblock" );
c_ice = ndef->getId (" mapgen_ice" );
c_mossycobble = ndef->getId (" mapgen_mossycobble" );
c_sandbrick = ndef->getId (" mapgen_sandstonebrick" );
c_stair_cobble = ndef->getId (" mapgen_stair_cobble" );
Expand Down
Expand Up
@@ -116,6 +125,7 @@ MapgenV6::~MapgenV6()
delete noise_mud;
delete noise_beach;
delete noise_biome;
delete noise_humidity;
delete[] heightmap;
}
Expand All
@@ -127,17 +137,17 @@ MapgenV6Params::MapgenV6Params()
freq_desert = 0.45 ;
freq_beach = 0.15 ;
np_terrain_base = NoiseParams (-4 , 20.0 , v3f (250.0 , 250.0 , 250.0 ), 82341 , 5 , 0.6 , 2.0 );
np_terrain_higher = NoiseParams (20 , 16.0 , v3f (500.0 , 500.0 , 500.0 ), 85039 , 5 , 0.6 , 2.0 );
np_steepness = NoiseParams (0.85 ,0.5 , v3f (125.0 , 125.0 , 125.0 ), -932 , 5 , 0.7 , 2.0 );
np_height_select = NoiseParams (0 , 1.0 , v3f (250.0 , 250.0 , 250.0 ), 4213 , 5 , 0.69 , 2.0 );
np_mud = NoiseParams (4 , 2.0 , v3f (200.0 , 200.0 , 200.0 ), 91013 , 3 , 0.55 , 2.0 );
np_beach = NoiseParams (0 , 1.0 , v3f (250.0 , 250.0 , 250.0 ), 59420 , 3 , 0.50 , 2.0 );
np_biome = NoiseParams (0 , 1.0 , v3f (250.0 , 250.0 , 250.0 ), 9130 , 3 , 0.50 , 2.0 );
np_cave = NoiseParams (6 , 6.0 , v3f (250.0 , 250.0 , 250.0 ), 34329 , 3 , 0.50 , 2.0 );
np_humidity = NoiseParams (0.5 , 0.5 , v3f (500.0 , 500.0 , 500.0 ), 72384 , 4 , 0.66 , 2.0 );
np_trees = NoiseParams (0 , 1.0 , v3f (125.0 , 125.0 , 125.0 ), 2 , 4 , 0.66 , 2.0 );
np_apple_trees = NoiseParams (0 , 1.0 , v3f (100.0 , 100.0 , 100.0 ), 342902 , 3 , 0.45 , 2.0 );
np_terrain_base = NoiseParams (-4 , 20.0 , v3f (250.0 , 250.0 , 250.0 ), 82341 , 5 , 0.6 , 2.0 );
np_terrain_higher = NoiseParams (20 , 16.0 , v3f (500.0 , 500.0 , 500.0 ), 85039 , 5 , 0.6 , 2.0 );
np_steepness = NoiseParams (0.85 , 0.5 , v3f (125.0 , 125.0 , 125.0 ), -932 , 5 , 0.7 , 2.0 );
np_height_select = NoiseParams (0 , 1.0 , v3f (250.0 , 250.0 , 250.0 ), 4213 , 5 , 0.69 , 2.0 );
np_mud = NoiseParams (4 , 2.0 , v3f (200.0 , 200.0 , 200.0 ), 91013 , 3 , 0.55 , 2.0 );
np_beach = NoiseParams (0 , 1.0 , v3f (250.0 , 250.0 , 250.0 ), 59420 , 3 , 0.50 , 2.0 );
np_biome = NoiseParams (0 , 1.0 , v3f (250.0 , 250.0 , 250.0 ), 9130 , 3 , 0.50 , 2.0 );
np_cave = NoiseParams (6 , 6.0 , v3f (250.0 , 250.0 , 250.0 ), 34329 , 3 , 0.50 , 2.0 );
np_humidity = NoiseParams (0.5 , 0.5 , v3f (500.0 , 500.0 , 500.0 ), 72384 , 4 , 0.66 , 2.0 );
np_trees = NoiseParams (0 , 1.0 , v3f (125.0 , 125.0 , 125.0 ), 2 , 4 , 0.66 , 2.0 );
np_apple_trees = NoiseParams (0 , 1.0 , v3f (100.0 , 100.0 , 100.0 ), 342902 , 3 , 0.45 , 2.0 );
}
Expand Down
Expand Up
@@ -194,10 +204,8 @@ s16 MapgenV6::find_stone_level(v2s16 p2d)
s16 y;
for (y = y_nodes_max; y >= y_nodes_min; y--) {
MapNode &n = vm->m_data [i];
content_t c = n.getContent ();
if (c != CONTENT_IGNORE && (
c == c_stone || c == c_desert_stone))
content_t c = vm->m_data [i].getContent ();
if (c != CONTENT_IGNORE && (c == c_stone || c == c_desert_stone))
break ;
vm->m_area .add_y (em, i, -1 );
Expand All
@@ -214,7 +222,7 @@ bool MapgenV6::block_is_underground(u64 seed, v3s16 blockpos)
// Nah, this is just a heuristic, just return something
s16 minimum_groundlevel = water_level;
if (blockpos.Y * MAP_BLOCKSIZE + MAP_BLOCKSIZE <= minimum_groundlevel)
if (blockpos.Y * MAP_BLOCKSIZE + MAP_BLOCKSIZE <= minimum_groundlevel)
return true ;
else
return false ;
Expand Down
Expand Up
@@ -266,7 +274,7 @@ float MapgenV6::baseTerrainLevelFromNoise(v2s16 p)
p.X , 0.5 , p.Y , 0.5 , seed);
return baseTerrainLevel (terrain_base, terrain_higher,
steepness, height_select);
steepness, height_select);
}
Expand All
@@ -288,7 +296,7 @@ float MapgenV6::baseTerrainLevelFromMap(int index)
float height_select = noise_height_select->result [index ];
return baseTerrainLevel (terrain_base, terrain_higher,
steepness, height_select);
steepness, height_select);
}
Expand Down
Expand Up
@@ -322,7 +330,8 @@ bool MapgenV6::getHaveBeach(v2s16 p)
BiomeV6Type MapgenV6::getBiome (v2s16 p)
{
int index = (p.Y - node_min.Z ) * ystride + (p.X - node_min.X );
int index = (p.Y - full_node_min.Z ) * (ystride + 2 * MAP_BLOCKSIZE)
+ (p.X - full_node_min.X );
return getBiome (index , p);
}
Expand All
@@ -334,7 +343,9 @@ float MapgenV6::getHumidity(v2s16 p)
seed+72384, 4, 0.66);
noise = (noise + 1.0)/2.0;*/
float noise = NoisePerlin2D (np_humidity, p.X , p.Y , seed);
int index = (p.Y - full_node_min.Z ) * (ystride + 2 * MAP_BLOCKSIZE)
+ (p.X - full_node_min.X );
float noise = noise_humidity->result [index ];
if (noise < 0.0 )
noise = 0.0 ;
Expand All
@@ -355,7 +366,7 @@ float MapgenV6::getTreeAmount(v2s16 p)
if (noise < zeroval)
return 0 ;
else
return 0.04 * (noise- zeroval) / (1.0 - zeroval);
return 0.04 * (noise - zeroval) / (1.0 - zeroval);
}
Expand Down
Expand Up
@@ -404,22 +415,44 @@ BiomeV6Type MapgenV6::getBiome(int index, v2s16 p)
seed+9130, 3, 0.50);*/
float d = noise_biome->result [index ];
if (d > freq_desert)
return BT_DESERT;
if ((spflags & MGV6_BIOMEBLEND) &&
(d > freq_desert - 0.10 ) &&
((noise2d (p.X , p.Y , seed) + 1.0 ) > (freq_desert - d) * 20.0 ))
return BT_DESERT;
return BT_NORMAL;
float h = noise_humidity->result [index ];
if (spflags & MGV6_SNOWBIOMES) {
float blend = (spflags & MGV6_BIOMEBLEND) ? noise2d (p.X , p.Y , seed) / 40 : 0 ;
if (d > FREQ_HOT + blend) {
if (h > FREQ_JUNGLE + blend)
return BT_JUNGLE;
else
return BT_DESERT;
} else if (d < FREQ_SNOW + blend) {
if (h > FREQ_TAIGA + blend)
return BT_TAIGA;
else
return BT_TUNDRA;
} else {
return BT_NORMAL;
}
} else {
if (d > freq_desert)
return BT_DESERT;
if ((spflags & MGV6_BIOMEBLEND) && (d > freq_desert - 0.10 ) &&
((noise2d (p.X , p.Y , seed) + 1.0 ) > (freq_desert - d) * 20.0 ))
return BT_DESERT;
if ((spflags & MGV6_JUNGLES) && h > 0.75 )
return BT_JUNGLE;
else
return BT_NORMAL;
}
}
u32 MapgenV6::get_blockseed (u64 seed, v3s16 p)
{
s32 x= p.X , y= p.Y , z= p.Z ;
return (u32)(seed% 0x100000000ULL ) + z* 38134234 + y* 42123 + x* 23 ;
s32 x = p.X , y = p.Y , z = p.Z ;
return (u32)(seed % 0x100000000ULL ) + z * 38134234 + y * 42123 + x * 23 ;
}
Expand All
@@ -446,14 +479,14 @@ void MapgenV6::makeChunk(BlockMakeData *data)
v3s16 blockpos_max = data->blockpos_max ;
// Area of central chunk
node_min = blockpos_min* MAP_BLOCKSIZE;
node_max = (blockpos_max+ v3s16 (1 ,1 , 1 ))* MAP_BLOCKSIZE- v3s16 (1 ,1 , 1 );
node_min = blockpos_min * MAP_BLOCKSIZE;
node_max = (blockpos_max + v3s16 (1 , 1 , 1 )) * MAP_BLOCKSIZE - v3s16 (1 , 1 , 1 );
// Full allocated area
full_node_min = (blockpos_min- 1 )* MAP_BLOCKSIZE;
full_node_max = (blockpos_max+ 2 )* MAP_BLOCKSIZE- v3s16 (1 ,1 , 1 );
full_node_min = (blockpos_min - 1 ) * MAP_BLOCKSIZE;
full_node_max = (blockpos_max + 2 ) * MAP_BLOCKSIZE - v3s16 (1 , 1 , 1 );
central_area_size = node_max - node_min + v3s16 (1 ,1 , 1 );
central_area_size = node_max - node_min + v3s16 (1 , 1 , 1 );
assert (central_area_size.X == central_area_size.Z );
int volume_blocks = (blockpos_max.X - blockpos_min.X + 1 )
Expand Down
Expand Up
@@ -511,17 +544,7 @@ void MapgenV6::makeChunk(BlockMakeData *data)
dp.np_density = nparams_dungeon_density;
dp.np_wetness = nparams_dungeon_wetness;
dp.c_water = c_water_source;
if (getBiome (0 , v2s16 (node_min.X , node_min.Z )) == BT_NORMAL) {
dp.c_cobble = c_cobble;
dp.c_moss = c_mossycobble;
dp.c_stair = c_stair_cobble;
dp.diagonal_dirs = false ;
dp.mossratio = 3.0 ;
dp.holesize = v3s16 (1 , 2 , 1 );
dp.roomsize = v3s16 (0 , 0 , 0 );
dp.notifytype = GENNOTIFY_DUNGEON;
} else {
if (getBiome (0 , v2s16 (node_min.X , node_min.Z )) == BT_DESERT) {
dp.c_cobble = c_sandbrick;
dp.c_moss = c_sandbrick; // should make this 'cracked sandstone' later
dp.c_stair = c_stair_sandstone;
Expand All
@@ -531,6 +554,16 @@ void MapgenV6::makeChunk(BlockMakeData *data)
dp.holesize = v3s16 (2 , 3 , 2 );
dp.roomsize = v3s16 (2 , 5 , 2 );
dp.notifytype = GENNOTIFY_TEMPLE;
} else {
dp.c_cobble = c_cobble;
dp.c_moss = c_mossycobble;
dp.c_stair = c_stair_cobble;
dp.diagonal_dirs = false ;
dp.mossratio = 3.0 ;
dp.holesize = v3s16 (1 , 2 , 1 );
dp.roomsize = v3s16 (0 , 0 , 0 );
dp.notifytype = GENNOTIFY_DUNGEON;
}
DungeonGen dgen (this , &dp);
Expand All
@@ -540,7 +573,7 @@ void MapgenV6::makeChunk(BlockMakeData *data)
// Add top and bottom side of water to transforming_liquid queue
updateLiquid (&data->transforming_liquid , full_node_min, full_node_max);
// Grow grass
// Add surface nodes
growGrass ();
// Generate some trees, and add grass, if a jungle
Expand All
@@ -565,6 +598,8 @@ void MapgenV6::calculateNoise()
{
int x = node_min.X ;
int z = node_min.Z ;
int fx = full_node_min.X ;
int fz = full_node_min.Z ;
if (!(flags & MG_FLAT)) {
noise_terrain_base->perlinMap2D_PO (x, 0.5 , z, 0.5 );
Expand All
@@ -575,7 +610,11 @@ void MapgenV6::calculateNoise()
}
noise_beach->perlinMap2D_PO (x, 0.2 , z, 0.7 );
noise_biome->perlinMap2D_PO (x, 0.6 , z, 0.2 );
noise_biome->perlinMap2D_PO (fx, 0.6 , fz, 0.2 );
noise_humidity->perlinMap2D_PO (fx, 0.0 , fz, 0.0 );
// Humidity map does not need range limiting 0 to 1,
// only humidity at point does
}
Expand All
@@ -584,9 +623,10 @@ int MapgenV6::generateGround()
// TimeTaker timer1("Generating ground level");
MapNode n_air (CONTENT_AIR), n_water_source (c_water_source);
MapNode n_stone (c_stone), n_desert_stone (c_desert_stone);
MapNode n_ice (c_ice);
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
u32 index = 0 ;
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 ++) {
// Surface height
Expand All
@@ -596,7 +636,7 @@ int MapgenV6::generateGround()
if (surface_y > stone_surface_max_y)
stone_surface_max_y = surface_y;
BiomeV6Type bt = getBiome (index , v2s16 (x, z));
BiomeV6Type bt = getBiome (v2s16 (x, z));
// Fill ground with stone
v3s16 em = vm->m_area .getExtent ();
Expand All
@@ -605,10 +645,12 @@ int MapgenV6::generateGround()
if (vm->m_data [i].getContent () == CONTENT_IGNORE) {
if (y <= surface_y) {
vm->m_data [i] = (y >= DESERT_STONE_BASE
&& bt == BT_DESERT) ?
&& bt == BT_DESERT) ?
n_desert_stone : n_stone;
} else if (y <= water_level) {
vm->m_data [i] = n_water_source;
vm->m_data [i] = (y >= ICE_BASE
&& bt == BT_TUNDRA) ?
n_ice : n_water_source;
} else {
vm->m_data [i] = n_air;
}
Expand Down
Expand Up
@@ -642,33 +684,33 @@ void MapgenV6::addMud()
if (surface_y == vm->m_area .MinEdge .Y - 1 )
continue ;
BiomeV6Type bt = getBiome (index , v2s16 (x, z));
BiomeV6Type bt = getBiome (v2s16 (x, z));
addnode = (bt == BT_DESERT) ? n_desert_sand : n_dirt;
if (bt == BT_DESERT && surface_y + mud_add_amount <= water_level + 1 ) {
addnode = n_sand;
} else if (mud_add_amount <= 0 ) {
mud_add_amount = 1 - mud_add_amount;
addnode = n_gravel;
} else if (bt == BT_NORMAL && getHaveBeach (index ) &&
} else if (bt != BT_DESERT && getHaveBeach (index ) &&
surface_y + mud_add_amount <= water_level + 2 ) {
addnode = n_sand;
}
if (bt == BT_DESERT && surface_y > 20 )
if (( bt == BT_DESERT || bt == BT_TUNDRA) && surface_y > 20 )
mud_add_amount = MYMAX (0 , mud_add_amount - (surface_y - 20 ) / 5 );
// If topmost node is grass, change it to mud. It might be if it was
/* If topmost node is grass, change it to mud. It might be if it was
// flown to there from a neighboring chunk and then converted.
u32 i = vm->m_area.index(x, surface_y, z);
if (vm->m_data[i].getContent() == c_dirt_with_grass)
vm->m_data [i] = n_dirt;
vm->m_data[i] = n_dirt;*/
// Add mud on ground
s16 mudcount = 0 ;
v3s16 em = vm->m_area .getExtent ();
s16 y_start = surface_y + 1 ;
i = vm->m_area .index (x, y_start, z);
u32 i = vm->m_area .index (x, y_start, z);
for (s16 y = y_start; y <= node_max.Y ; y++) {
if (mudcount >= mud_add_amount)
break ;
Expand All
@@ -685,10 +727,10 @@ void MapgenV6::addMud()
void MapgenV6::flowMud (s16 &mudflow_minpos, s16 &mudflow_maxpos)
{
// 340ms @cs=8
TimeTaker timer1 (" flow mud" );
// TimeTaker timer1("flow mud");
// Iterate a few times
for (s16 k = 0 ; k < 3 ; k++) {
for (s16 k = 0 ; k < 3 ; k++) {
for (s16 z = mudflow_minpos; z <= mudflow_maxpos; z++)
for (s16 x = mudflow_minpos; x <= mudflow_maxpos; x++) {
// Invert coordinates every 2nd iteration
Expand All
@@ -704,18 +746,16 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
u32 i = vm->m_area .index (p2d.X , node_max.Y , p2d.Y );
s16 y = node_max.Y ;
while (y >= node_min.Y )
{
while (y >= node_min.Y ) {
for (;; y--)
{
for (;; y--) {
MapNode *n = NULL ;
// Find mud
for (; y >= node_min.Y ; y--) {
for (; y >= node_min.Y ; y--) {
n = &vm->m_data [i];
if (n->getContent () == c_dirt ||
n->getContent () == c_dirt_with_grass ||
n->getContent () == c_gravel)
n->getContent () == c_dirt_with_grass ||
n->getContent () == c_gravel)
break ;
vm->m_area .add_y (em, i, -1 );
Expand All
@@ -727,8 +767,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
break ;
if (n->getContent () == c_dirt ||
n->getContent () == c_dirt_with_grass)
{
n->getContent () == c_dirt_with_grass) {
// Make it exactly mud
n->setContent (c_dirt);
Expand All
@@ -737,32 +776,32 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
u32 i2 = i;
vm->m_area .add_y (em, i2, -1 );
// Cancel if out of area
if (vm->m_area .contains (i2) == false )
if (vm->m_area .contains (i2) == false )
continue ;
MapNode *n2 = &vm->m_data [i2];
if (n2->getContent () != c_dirt &&
n2->getContent () != c_dirt_with_grass)
n2->getContent () != c_dirt_with_grass)
continue ;
}
}
v3s16 dirs4[4 ] = {
v3s16 (0 ,0 , 1 ), // back
v3s16 (1 ,0 , 0 ), // right
v3s16 (0 ,0 , -1 ), // front
v3s16 (-1 ,0 , 0 ), // left
v3s16 (0 , 0 , 1 ), // back
v3s16 (1 , 0 , 0 ), // right
v3s16 (0 , 0 , -1 ), // front
v3s16 (-1 , 0 , 0 ), // left
};
// Check that upper is air or doesn't exist.
// Cancel dropping if upper keeps it in place
u32 i3 = i;
vm->m_area .add_y (em, i3, 1 );
if (vm->m_area .contains (i3) == true &&
ndef->get (vm->m_data [i3]).walkable )
ndef->get (vm->m_data [i3]).walkable )
continue ;
// Drop mud on side
for (u32 di= 0 ; di< 4 ; di++) {
for (u32 di = 0 ; di < 4 ; di++) {
v3s16 dirp = dirs4[di];
u32 i2 = i;
// Move to side
Expand All
@@ -788,7 +827,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
n2 = &vm->m_data [i2];
// if out of known area
if (vm->m_area .contains (i2) == false ||
n2->getContent () == CONTENT_IGNORE) {
n2->getContent () == CONTENT_IGNORE) {
dropped_to_unknown = true ;
break ;
}
Expand Down
Expand Up
@@ -857,21 +896,22 @@ void MapgenV6::placeTreesAndJungleGrass()
node_min.Z + sidelen + sidelen * z0 - 1
);
// Amount of trees, jungle area
u32 tree_count = area * getTreeAmount (p2d_center);
// Get biome at center position of part of division
BiomeV6Type bt = getBiome (p2d_center);
float humidity;
bool is_jungle = false ;
if (spflags & MGV6_JUNGLES) {
humidity = getHumidity (p2d_center);
if (humidity > 0.75 ) {
is_jungle = true ;
// Amount of trees
u32 tree_count;
if (bt == BT_JUNGLE || bt == BT_TAIGA || bt == BT_NORMAL) {
tree_count = area * getTreeAmount (p2d_center);
if (bt == BT_JUNGLE)
tree_count *= 4 ;
}
} else {
tree_count = 0 ;
}
// Add jungle grass
if (is_jungle) {
if (bt == BT_JUNGLE) {
float humidity = getHumidity (p2d_center);
u32 grass_count = 5 * humidity * tree_count;
for (u32 i = 0 ; i < grass_count; i++) {
s16 x = grassrandom.range (p2d_min.X , p2d_max.X );
Expand Down
Expand Up
@@ -900,24 +940,27 @@ void MapgenV6::placeTreesAndJungleGrass()
s16 y = heightmap[mapindex];
// Don't make a tree under water level
// Don't make a tree so high that it doesn't fit
if (y < water_level || y > node_max.Y - 6 )
if (y < water_level || y > node_max.Y - 6 )
continue ;
v3s16 p (x,y, z);
v3s16 p (x, y, z);
// Trees grow only on mud and grass
{
u32 i = vm->m_area .index (p);
MapNode *n = &vm->m_data [i];
if (n->getContent () != c_dirt &&
n->getContent () != c_dirt_with_grass)
content_t c = vm->m_data [i].getContent ();
if (c != c_dirt &&
c != c_dirt_with_grass &&
c != c_dirt_with_snow)
continue ;
}
p.Y ++;
// Make a tree
if (is_jungle ) {
if (bt == BT_JUNGLE ) {
treegen::make_jungletree (*vm, p, ndef, myrand ());
} else {
} else if (bt == BT_TAIGA) {
treegen::make_pine_tree (*vm, p, ndef, myrand ());
} else if (bt == BT_NORMAL) {
bool is_apple_tree = (myrand_range (0 , 3 ) == 0 ) &&
getHaveAppleTree (v2s16 (x, z));
treegen::make_tree (*vm, p, is_apple_tree, ndef, myrand ());
Expand All
@@ -928,32 +971,54 @@ void MapgenV6::placeTreesAndJungleGrass()
}
void MapgenV6::growGrass ()
void MapgenV6::growGrass () // Add surface nodes
{
MapNode n_dirt_with_grass (c_dirt_with_grass);
MapNode n_dirt_with_snow (c_dirt_with_snow);
MapNode n_snowblock (c_snowblock);
MapNode n_snow (c_snow);
v3s16 em = vm->m_area .getExtent ();
u32 index = 0 ;
for (s16 z = full_node_min.Z ; z <= full_node_max.Z ; z++)
for (s16 x = full_node_min.X ; x <= full_node_max.X ; x++) {
for (s16 x = full_node_min.X ; x <= full_node_max.X ; x++, index ++ ) {
// Find the lowest surface to which enough light ends up to make
// grass grow. Basically just wait until not air and not leaves.
s16 surface_y = 0 ;
{
v3s16 em = vm->m_area .getExtent ();
u32 i = vm->m_area .index (x, node_max.Y , z);
s16 y;
// Go to ground level
for (y = node_max.Y ; y >= full_node_min.Y ; y--) {
MapNode &n = vm->m_data [i];
if (ndef->get (n).param_type != CPT_LIGHT ||
ndef->get (n).liquid_type != LIQUID_NONE)
ndef->get (n).liquid_type != LIQUID_NONE ||
n.getContent () == c_ice)
break ;
vm->m_area .add_y (em, i, -1 );
}
surface_y = (y >= full_node_min.Y ) ? y : full_node_min.Y ;
}
BiomeV6Type bt = getBiome (index , v2s16 (x, z));
u32 i = vm->m_area .index (x, surface_y, z);
MapNode *n = &vm->m_data [i];
if (n->getContent () == c_dirt && surface_y >= water_level - 20 )
n->setContent (c_dirt_with_grass);
content_t c = vm->m_data [i].getContent ();
if (surface_y >= water_level - 20 ) {
if (bt == BT_TAIGA && c == c_dirt) {
vm->m_data [i] = n_snowblock;
vm->m_area .add_y (em, i, -1 );
vm->m_data [i] = n_dirt_with_snow;
} else if (bt == BT_TUNDRA) {
if (c == c_dirt) {
vm->m_data [i] = n_dirt_with_snow;
} else if (c == c_stone) {
vm->m_area .add_y (em, i, 1 );
vm->m_data [i] = n_snow;
}
} else if (c == c_dirt) {
vm->m_data [i] = n_dirt_with_grass;
}
}
}
}
Expand Down