From de621d5d4b0b75441e034f15f766145ede2bace8 Mon Sep 17 00:00:00 2001 From: Paramat Date: Sun, 24 Jun 2018 17:14:18 +0100 Subject: Decoration API: Add lightweight ability to have complete coverage (#7456) When the noise value or fill_ratio >= 10.0 complete coverage is enabled. This disables random placement to avoid redundant multiple placements at one position. Instead, 1 decoration per surface node is placed by looping across each division. '10' was chosen as this is the fill_ratio that previously created very near complete coverage. The complete coverage feature therefore integrates smoothly when noise is used for variable decoration density. 'fill_ratio = 10' should be used by modders who want a decoration placed on every surface node. Compared to before such a decoration placement will be 10 times faster. --- doc/lua_api.txt | 4 ++++ src/mapgen/mg_decoration.cpp | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index db340e415..743cca47d 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -5769,6 +5769,8 @@ Definition tables fill_ratio = 0.02, -- ^ The value determines 'decorations per surface node'. -- ^ Used only if noise_params is not specified. + -- ^ If >= 10.0 complete coverage is enabled and decoration placement uses + -- ^ a different and much faster method. noise_params = { offset = 0, scale = 0.45, @@ -5783,6 +5785,8 @@ Definition tables -- ^ distribution. -- ^ A noise value is calculated for each square division and determines -- ^ 'decorations per surface node' within each division. + -- ^ If the noise value >= 10.0 complete coverage is enabled and decoration + -- ^ placement uses a different and much faster method. biomes = {"Oceanside", "Hills", "Plains"}, -- ^ List of biomes in which this decoration occurs. Occurs in all biomes -- ^ if this is omitted, and ignored if the Mapgen being used does not diff --git a/src/mapgen/mg_decoration.cpp b/src/mapgen/mg_decoration.cpp index 6daa8216e..28dde0209 100644 --- a/src/mapgen/mg_decoration.cpp +++ b/src/mapgen/mg_decoration.cpp @@ -155,23 +155,43 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) 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; - float deco_count_f = (float)area * nval; - if (deco_count_f >= 1.f) { - deco_count = deco_count_f; - } else if (deco_count_f > 0.f) { - // For low density decorations calculate a chance for 1 decoration - if (ps.range(1000) <= deco_count_f * 1000.f) - deco_count = 1; + + 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++) { - s16 x = ps.range(p2d_min.X, p2d_max.X); - s16 z = ps.range(p2d_min.Y, p2d_max.Y); + 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; + } + } int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X); if ((flags & DECO_ALL_FLOORS) || -- cgit v1.2.3