diff options
author | Elias Fleckenstein <54945686+EliasFleckenstein03@users.noreply.github.com> | 2020-11-04 16:44:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-04 16:44:42 +0100 |
commit | 5d9ae5a91c544fc7fbd475decf47cef7e09ef8fc (patch) | |
tree | c980d614fec4a5495798be3e79e033229062c3cd /src/mapgen/mg_decoration.cpp | |
parent | 28f6a79706b088c37268a59d90878220dc4ef9c7 (diff) | |
parent | 3af10766fd2b58b068e970266724d7eb10e9316b (diff) | |
download | dragonfireclient-5d9ae5a91c544fc7fbd475decf47cef7e09ef8fc.tar.xz |
Merge branch 'master' into master
Diffstat (limited to 'src/mapgen/mg_decoration.cpp')
-rw-r--r-- | src/mapgen/mg_decoration.cpp | 308 |
1 files changed, 144 insertions, 164 deletions
diff --git a/src/mapgen/mg_decoration.cpp b/src/mapgen/mg_decoration.cpp index a4cada396..6aa003a3f 100644 --- a/src/mapgen/mg_decoration.cpp +++ b/src/mapgen/mg_decoration.cpp @@ -28,30 +28,21 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <algorithm> #include <vector> - -FlagDesc flagdesc_deco[] = { - {"place_center_x", DECO_PLACE_CENTER_X}, - {"place_center_y", DECO_PLACE_CENTER_Y}, - {"place_center_z", DECO_PLACE_CENTER_Z}, - {"force_placement", DECO_FORCE_PLACEMENT}, - {"liquid_surface", DECO_LIQUID_SURFACE}, - {"all_floors", DECO_ALL_FLOORS}, - {"all_ceilings", DECO_ALL_CEILINGS}, - {NULL, 0} -}; - +FlagDesc flagdesc_deco[] = {{"place_center_x", DECO_PLACE_CENTER_X}, + {"place_center_y", DECO_PLACE_CENTER_Y}, + {"place_center_z", DECO_PLACE_CENTER_Z}, + {"force_placement", DECO_FORCE_PLACEMENT}, + {"liquid_surface", DECO_LIQUID_SURFACE}, {"all_floors", DECO_ALL_FLOORS}, + {"all_ceilings", DECO_ALL_CEILINGS}, {NULL, 0}}; /////////////////////////////////////////////////////////////////////////////// - DecorationManager::DecorationManager(IGameDef *gamedef) : - ObjDefManager(gamedef, OBJDEF_DECORATION) + ObjDefManager(gamedef, OBJDEF_DECORATION) { } - -size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed, - v3s16 nmin, v3s16 nmax) +size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) { size_t nplaced = 0; @@ -74,17 +65,14 @@ DecorationManager *DecorationManager::clone() const return mgr; } - /////////////////////////////////////////////////////////////////////////////// - void Decoration::resolveNodeNames() { getIdsFromNrBacklog(&c_place_on); getIdsFromNrBacklog(&c_spawnby); } - bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p) { // Check if the decoration can be placed on this node @@ -97,25 +85,13 @@ bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p) return true; int nneighs = 0; - static const v3s16 dirs[16] = { - v3s16( 0, 0, 1), - v3s16( 0, 0, -1), - v3s16( 1, 0, 0), - v3s16(-1, 0, 0), - v3s16( 1, 0, 1), - v3s16(-1, 0, 1), - v3s16(-1, 0, -1), - v3s16( 1, 0, -1), - - v3s16( 0, 1, 1), - v3s16( 0, 1, -1), - v3s16( 1, 1, 0), - v3s16(-1, 1, 0), - v3s16( 1, 1, 1), - v3s16(-1, 1, 1), - v3s16(-1, 1, -1), - v3s16( 1, 1, -1) - }; + static const v3s16 dirs[16] = {v3s16(0, 0, 1), v3s16(0, 0, -1), v3s16(1, 0, 0), + v3s16(-1, 0, 0), v3s16(1, 0, 1), v3s16(-1, 0, 1), + v3s16(-1, 0, -1), v3s16(1, 0, -1), + + v3s16(0, 1, 1), v3s16(0, 1, -1), v3s16(1, 1, 0), v3s16(-1, 1, 0), + v3s16(1, 1, 1), v3s16(-1, 1, 1), v3s16(-1, 1, -1), + v3s16(1, 1, -1)}; // Check these 16 neighbouring nodes for enough spawnby nodes for (size_t i = 0; i != ARRLEN(dirs); i++) { @@ -133,7 +109,6 @@ bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p) return true; } - size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) { PcgRandom ps(blockseed + 53); @@ -148,132 +123,144 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) int area = sidelen * sidelen; for (s16 z0 = 0; z0 < divlen; z0++) - for (s16 x0 = 0; x0 < divlen; x0++) { - v2s16 p2d_center( // Center position of part of division - nmin.X + sidelen / 2 + sidelen * x0, - nmin.Z + sidelen / 2 + sidelen * z0 - ); - v2s16 p2d_min( // Minimum edge of part of division - nmin.X + sidelen * x0, - nmin.Z + sidelen * z0 - ); - v2s16 p2d_max( // Maximum edge of part of division - nmin.X + sidelen + sidelen * x0 - 1, - nmin.Z + sidelen + sidelen * z0 - 1 - ); - - bool cover = false; - // Amount of decorations - float nval = (flags & DECO_USE_NOISE) ? - NoisePerlin2D(&np, p2d_center.X, p2d_center.Y, mapseed) : - fill_ratio; - u32 deco_count = 0; - - if (nval >= 10.0f) { - // Complete coverage. Disable random placement to avoid - // redundant multiple placements at one position. - cover = true; - deco_count = area; - } else { - float deco_count_f = (float)area * nval; - if (deco_count_f >= 1.0f) { - deco_count = deco_count_f; - } else if (deco_count_f > 0.0f) { - // For very low density calculate a chance for 1 decoration - if (ps.range(1000) <= deco_count_f * 1000.0f) - deco_count = 1; - } - } - - s16 x = p2d_min.X - 1; - s16 z = p2d_min.Y; - - for (u32 i = 0; i < deco_count; i++) { - if (!cover) { - x = ps.range(p2d_min.X, p2d_max.X); - z = ps.range(p2d_min.Y, p2d_max.Y); + for (s16 x0 = 0; x0 < divlen; x0++) { + v2s16 p2d_center( // Center position of part of division + nmin.X + sidelen / 2 + sidelen * x0, + nmin.Z + sidelen / 2 + sidelen * z0); + v2s16 p2d_min( // Minimum edge of part of division + nmin.X + sidelen * x0, nmin.Z + sidelen * z0); + v2s16 p2d_max( // Maximum edge of part of division + nmin.X + sidelen + sidelen * x0 - 1, + nmin.Z + sidelen + sidelen * z0 - 1); + + bool cover = false; + // Amount of decorations + float nval = (flags & DECO_USE_NOISE) + ? NoisePerlin2D(&np, p2d_center.X, + p2d_center.Y, + mapseed) + : fill_ratio; + u32 deco_count = 0; + + if (nval >= 10.0f) { + // Complete coverage. Disable random placement to avoid + // redundant multiple placements at one position. + cover = true; + deco_count = area; } else { - x++; - if (x == p2d_max.X + 1) { - z++; - x = p2d_min.X; + float deco_count_f = (float)area * nval; + if (deco_count_f >= 1.0f) { + deco_count = deco_count_f; + } else if (deco_count_f > 0.0f) { + // For very low density calculate a chance for 1 + // decoration + if (ps.range(1000) <= deco_count_f * 1000.0f) + deco_count = 1; } } - int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X); - - if ((flags & DECO_ALL_FLOORS) || - (flags & DECO_ALL_CEILINGS)) { - // All-surfaces decorations - // Check biome of column - if (mg->biomemap && !biomes.empty()) { - auto iter = biomes.find(mg->biomemap[mapindex]); - if (iter == biomes.end()) - continue; - } - // Get all floors and ceilings in node column - u16 size = (nmax.Y - nmin.Y + 1) / 2; - std::vector<s16> floors; - std::vector<s16> ceilings; - floors.reserve(size); - ceilings.reserve(size); - - mg->getSurfaces(v2s16(x, z), nmin.Y, nmax.Y, floors, ceilings); - - if (flags & DECO_ALL_FLOORS) { - // Floor decorations - for (const s16 y : floors) { - if (y < y_min || y > y_max) - continue; - - v3s16 pos(x, y, z); - if (generate(mg->vm, &ps, pos, false)) - mg->gennotify.addEvent( - GENNOTIFY_DECORATION, pos, index); + s16 x = p2d_min.X - 1; + s16 z = p2d_min.Y; + + for (u32 i = 0; i < deco_count; i++) { + if (!cover) { + x = ps.range(p2d_min.X, p2d_max.X); + z = ps.range(p2d_min.Y, p2d_max.Y); + } else { + x++; + if (x == p2d_max.X + 1) { + z++; + x = p2d_min.X; } } - - if (flags & DECO_ALL_CEILINGS) { - // Ceiling decorations - for (const s16 y : ceilings) { - if (y < y_min || y > y_max) + int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X); + + if ((flags & DECO_ALL_FLOORS) || + (flags & DECO_ALL_CEILINGS)) { + // All-surfaces decorations + // Check biome of column + if (mg->biomemap && !biomes.empty()) { + auto iter = biomes.find( + mg->biomemap[mapindex]); + if (iter == biomes.end()) continue; + } - v3s16 pos(x, y, z); - if (generate(mg->vm, &ps, pos, true)) - mg->gennotify.addEvent( - GENNOTIFY_DECORATION, pos, index); + // Get all floors and ceilings in node column + u16 size = (nmax.Y - nmin.Y + 1) / 2; + std::vector<s16> floors; + std::vector<s16> ceilings; + floors.reserve(size); + ceilings.reserve(size); + + mg->getSurfaces(v2s16(x, z), nmin.Y, nmax.Y, + floors, ceilings); + + if (flags & DECO_ALL_FLOORS) { + // Floor decorations + for (const s16 y : floors) { + if (y < y_min || y > y_max) + continue; + + v3s16 pos(x, y, z); + if (generate(mg->vm, &ps, pos, + false)) + mg->gennotify.addEvent( + GENNOTIFY_DECORATION, + pos, + index); + } } - } - } else { // Heightmap decorations - s16 y = -MAX_MAP_GENERATION_LIMIT; - if (flags & DECO_LIQUID_SURFACE) - y = mg->findLiquidSurface(v2s16(x, z), nmin.Y, nmax.Y); - else if (mg->heightmap) - y = mg->heightmap[mapindex]; - else - y = mg->findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y); - - if (y < y_min || y > y_max || y < nmin.Y || y > nmax.Y) - continue; - - if (mg->biomemap && !biomes.empty()) { - auto iter = biomes.find(mg->biomemap[mapindex]); - if (iter == biomes.end()) + + if (flags & DECO_ALL_CEILINGS) { + // Ceiling decorations + for (const s16 y : ceilings) { + if (y < y_min || y > y_max) + continue; + + v3s16 pos(x, y, z); + if (generate(mg->vm, &ps, pos, + true)) + mg->gennotify.addEvent( + GENNOTIFY_DECORATION, + pos, + index); + } + } + } else { // Heightmap decorations + s16 y = -MAX_MAP_GENERATION_LIMIT; + if (flags & DECO_LIQUID_SURFACE) + y = mg->findLiquidSurface(v2s16(x, z), + nmin.Y, nmax.Y); + else if (mg->heightmap) + y = mg->heightmap[mapindex]; + else + y = mg->findGroundLevel(v2s16(x, z), + nmin.Y, nmax.Y); + + if (y < y_min || y > y_max || y < nmin.Y || + y > nmax.Y) continue; - } - v3s16 pos(x, y, z); - if (generate(mg->vm, &ps, pos, false)) - mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, index); + if (mg->biomemap && !biomes.empty()) { + auto iter = biomes.find( + mg->biomemap[mapindex]); + if (iter == biomes.end()) + continue; + } + + v3s16 pos(x, y, z); + if (generate(mg->vm, &ps, pos, false)) + mg->gennotify.addEvent( + GENNOTIFY_DECORATION, pos, + index); + } } } - } return 0; } - void Decoration::cloneTo(Decoration *def) const { ObjDef::cloneTo(def); @@ -291,10 +278,8 @@ void Decoration::cloneTo(Decoration *def) const def->biomes = biomes; } - /////////////////////////////////////////////////////////////////////////////// - ObjDef *DecoSimple::clone() const { auto def = new DecoSimple(); @@ -309,14 +294,12 @@ ObjDef *DecoSimple::clone() const return def; } - void DecoSimple::resolveNodeNames() { Decoration::resolveNodeNames(); getIdsFromNrBacklog(&c_decos); } - size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) { // Don't bother if there aren't any decorations to place @@ -347,10 +330,10 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) } content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)]; - s16 height = (deco_height_max > 0) ? - pr->range(deco_height, deco_height_max) : deco_height; - u8 param2 = (deco_param2_max > 0) ? - pr->range(deco_param2, deco_param2_max) : deco_param2; + s16 height = (deco_height_max > 0) ? pr->range(deco_height, deco_height_max) + : deco_height; + u8 param2 = (deco_param2_max > 0) ? pr->range(deco_param2, deco_param2_max) + : deco_param2; bool force_placement = (flags & DECO_FORCE_PLACEMENT); const v3s16 &em = vm->m_area.getExtent(); @@ -385,17 +368,14 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) return 1; } - /////////////////////////////////////////////////////////////////////////////// - DecoSchematic::~DecoSchematic() { if (was_cloned) delete schematic; } - ObjDef *DecoSchematic::clone() const { auto def = new DecoSchematic(); @@ -407,13 +387,12 @@ ObjDef *DecoSchematic::clone() const * and not a handle. We are left with no option but to clone it ourselves. * This is a waste of memory and should be replaced with an alternative * approach sometime. */ - def->schematic = dynamic_cast<Schematic*>(schematic->clone()); + def->schematic = dynamic_cast<Schematic *>(schematic->clone()); def->was_cloned = true; return def; } - size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) { // Schematic could have been unloaded but not the decoration @@ -443,8 +422,9 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceilin if (p.Y < vm->m_area.MinEdge.Y) return 0; - Rotation rot = (rotation == ROTATE_RAND) ? - (Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation; + Rotation rot = (rotation == ROTATE_RAND) + ? (Rotation)pr->range(ROTATE_0, ROTATE_270) + : rotation; if (flags & DECO_PLACE_CENTER_X) { if (rot == ROTATE_0 || rot == ROTATE_180) |