diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 4316be6fe..dc6dab6bb 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -111,7 +111,7 @@ void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) { } -void Mapgen::updateLighting(v3s16 nmin, v3s16 nmax) { +void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax) { VoxelArea a(nmin - v3s16(1,0,1) * MAP_BLOCKSIZE, nmax + v3s16(1,0,1) * MAP_BLOCKSIZE); bool block_is_underground = (water_level >= nmax.Y); @@ -174,7 +174,7 @@ void Mapgen::updateLighting(v3s16 nmin, v3s16 nmax) { } -void Mapgen::updateLightingOld(v3s16 nmin, v3s16 nmax) { +void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax) { enum LightBank banks[2] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT}; VoxelArea a(nmin - v3s16(1,0,1) * MAP_BLOCKSIZE, diff --git a/src/mapgen.h b/src/mapgen.h index 3f3cd424d..f4bd659fb 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -79,8 +79,8 @@ public: void updateLiquid(UniqueQueue *trans_liquid, v3s16 nmin, v3s16 nmax); void setLighting(v3s16 nmin, v3s16 nmax, u8 light); void lightSpread(VoxelArea &a, v3s16 p, u8 light); - void updateLighting(v3s16 nmin, v3s16 nmax); - void updateLightingOld(v3s16 nmin, v3s16 nmax); + void calcLighting(v3s16 nmin, v3s16 nmax); + void calcLightingOld(v3s16 nmin, v3s16 nmax); virtual void makeChunk(BlockMakeData *data) {}; virtual int getGroundLevelAtPoint(v2s16 p) = 0; diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 5f428bb8f..59a4d49fc 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -457,12 +457,12 @@ void MapgenV6::makeChunk(BlockMakeData *data) { // Grow grass growGrass(); - // Generate some trees + // Generate some trees, and add grass, if a jungle if (flags & MG_TREES) - placeTrees(); + placeTreesAndJungleGrass(); // Calculate lighting - updateLighting(node_min, node_max); + calcLighting(node_min, node_max); this->generating = false; } @@ -783,14 +783,26 @@ void MapgenV6::addDirtGravelBlobs() { } -void MapgenV6::placeTrees() { +void MapgenV6::placeTreesAndJungleGrass() { //TimeTaker t("placeTrees"); + if (node_max.Y < water_level) + return; + + PseudoRandom grassrandom(blockseed + 53); + content_t c_junglegrass = ndef->getId("mapgen_junglegrass"); + // if we don't have junglegrass, don't place cignore... that's bad + if (c_junglegrass == CONTENT_IGNORE) + c_junglegrass = CONTENT_AIR; + MapNode n_junglegrass(c_junglegrass); + v3s16 em = vm->m_area.getExtent(); // Divide area into parts s16 div = 8; s16 sidelen = central_area_size.X / div; double area = sidelen * sidelen; + // N.B. We must add jungle grass first, since tree leaves will + // obstruct the ground, giving us a false ground level for (s16 z0 = 0; z0 < div; z0++) for (s16 x0 = 0; x0 < div; x0++) { // Center position of part of division @@ -811,9 +823,36 @@ void MapgenV6::placeTrees() { // Amount of trees, jungle area u32 tree_count = area * getTreeAmount(p2d_center); - bool is_jungle = (flags & MGV6_JUNGLES) && (getHumidity(p2d_center) > 0.75); - if (is_jungle) - tree_count *= 4; + + float humidity; + bool is_jungle = false; + if (flags & MGV6_JUNGLES) { + humidity = getHumidity(p2d_center); + if (humidity > 0.75) { + is_jungle = true; + tree_count *= 4; + } + } + + // Add jungle grass + if (is_jungle) { + 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); + s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y); + + s16 y = find_ground_level(v2s16(x, z)); ////////////////optimize this! + if (y < water_level || y < node_min.Y || y > node_max.Y) + continue; + + u32 vi = vm->m_area.index(x, y, z); + // place on dirt_with_grass, since we know it is exposed to sunlight + if (vm->m_data[vi].getContent() == c_dirt_with_grass) { + vm->m_area.add_y(em, vi, 1); + vm->m_data[vi] = n_junglegrass; + } + } + } // Put trees in random places on part of division for (u32 i = 0; i < tree_count; i++) { @@ -846,7 +885,7 @@ void MapgenV6::placeTrees() { } } } - //printf("placeTrees: %dms\n", t.stop()); + //printf("placeTreesAndJungleGrass: %dms\n", t.stop()); } @@ -878,6 +917,7 @@ void MapgenV6::growGrass() { } } + void MapgenV6::defineCave(Cave &cave, PseudoRandom ps, v3s16 node_min, bool large_cave) { cave.min_tunnel_diameter = 2; diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h index 662aed2ce..5b3ea9d27 100644 --- a/src/mapgen_v6.h +++ b/src/mapgen_v6.h @@ -163,7 +163,7 @@ public: void flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos); void addDirtGravelBlobs(); void growGrass(); - void placeTrees(); + void placeTreesAndJungleGrass(); virtual void defineCave(Cave &cave, PseudoRandom ps, v3s16 node_min, bool large_cave); void generateCaves(int max_stone_y);