From 5eb4aabd87077bfb31fed10ca0f3d179ddd09f87 Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Sun, 31 Jan 2016 02:59:15 -0600 Subject: [PATCH 1/5] Mgvalleys: use standard caves Replace simple caves with V5 caves, adding unpredictable water and lava settings and massive caves based on subterrain. Remove fast terrain mode and accompanying settings. Remove superfluous temperature/humidity settings. Remove lava/water height setting. Fix errors in humidity handling and remove humidity_break_point setting. Move cave noises to generateCaves. Fix minor formatting/naming issues and use MYMAX/MYMIN/myround. --- builtin/settingtypes.txt | 45 ++-- minetest.conf.example | 23 +- src/mapgen_valleys.cpp | 567 ++++++++++++++++++--------------------- src/mapgen_valleys.h | 59 ++-- 4 files changed, 314 insertions(+), 380 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 833890a3..dd852999 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1043,25 +1043,21 @@ mgfractal_np_cave2 (Mapgen fractal cave2 noise parameters) noise_params 0, 12, ( # Flags that are not specified in the flag string are not modified from the default. # Flags starting with "no" are used to explicitly disable them. # "altitude_chill" makes higher elevations colder, which may cause biome issues. -# "fast" produces softer terrain, more quickly # "humid_rivers" modifies the humidity around rivers and in areas where water would tend to pool. It may interfere with delicately adjusted biomes. -# "rugged" and "cliffs" do nothing unless "fast" is enabled -mg_valleys_spflags (Valleys C Flags) flags altitude_chill,cliffs,humid_rivers,nofast,rugged altitude_chill,noaltitude_chill,cliffs,nocliffs,fast,nofast,humid_rivers,nohumid_rivers,rugged,norugged +mg_valleys_spflags (Valleys C Flags) flags altitude_chill,humid_rivers altitude_chill,noaltitude_chill,humid_rivers,nohumid_rivers # The altitude at which temperature drops by 20C mg_valleys_altitude_chill (Altitude Chill) int 90 -# Average humidity -mg_valleys_humidity (Humidity) int 50 +# Depth below which you'll find large caves. +mg_valleys_large_cave_depth (Large cave depth) int -33 -# The highest humidity around rivers in otherwise dry areas -mg_valleys_humidity_break_point (Humidity Break) int 65 +# Creates unpredictable lava features in caves. +# These can make mining difficult. Zero disables them. (0-10) +mg_valleys_lava_features (Lava Features) int 0 -# Maximum altitude where lava can emerge -mg_valleys_lava_max_height (Lava Height) int 0 - -# Maximum altitude where water occurs in caves (and tends to fall out) -mg_valleys_cave_water_max_height (Cave Water Height) int 31000 +# Depth below which you'll find massive caves. +mg_valleys_massive_cave_depth (Massive cave depth) int -256 # How deep to make rivers mg_valleys_river_depth (River Depth) int 4 @@ -1069,33 +1065,28 @@ mg_valleys_river_depth (River Depth) int 4 # How wide to make rivers mg_valleys_river_size (River Size) int 5 -# Average temperature -mg_valleys_temperature (Temperature) int 50 - -# How often water occurs in caves (0-10) -mg_valleys_water_features (Water Features) int 3 +# Creates unpredictable water features in caves. +# These can make mining difficult. Zero disables them. (0-10) +mg_valleys_water_features (Water Features) int 0 # Noise parameters [****Noises] -# Cliff noise -mg_valleys_np_cliffs (Cliffs) noise_params 0, 1, (750, 750, 750), 8445, 5, 1.0, 2.0 +# Caves and tunnels form at the intersection of the two noises +mg_valleys_np_cave1 (Cave noise #1) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0 -# Mountain corrugation -mg_valleys_np_corr (Corrugation) noise_params 0, 1, (40, 40, 40), -3536, 4, 1.0, 2.0 +# Caves and tunnels form at the intersection of the two noises +mg_valleys_np_cave2 (Cave noise #2) noise_params 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0 # The depth of dirt or other filler mg_valleys_np_filler_depth (Filler Depth) noise_params 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 +# Massive caves form here. +mg_valleys_np_massive_caves (Massive cave noise) noise_params 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0 + # River noise -- rivers occur close to zero mg_valleys_np_rivers (River Noise) noise_params 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 -# Caves and tunnels form at the intersection of the two noises -mg_valleys_np_simple_caves_1 (Simple Caves #1) noise_params 0, 1, v3f(64, 64, 64), -8402, 3, 0.5, 2.0 - -# Caves and tunnels form at the intersection of the two noises -mg_valleys_np_simple_caves_2 (Simple Caves #2) noise_params 0, 1, v3f(64, 64, 64), 3944, 3, 0.5, 2.0 - # Base terrain height mg_valleys_np_terrain_height (Terrain Height) noise_params -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 diff --git a/minetest.conf.example b/minetest.conf.example index b95b32ee..d8f91e7c 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -1315,31 +1315,28 @@ #### Mapgen Valleys -#mg_valleys_spflags = altitude_chill,cliffs,humid_rivers,nofast,rugged +#mg_valleys_spflags = altitude_chill,humid_rivers # "altitude_chill" makes higher elevations colder, which may cause biome issues. -# "fast" produces softer terrain, more quickly # "humid_rivers" modifies the humidity around rivers and in areas where water would tend to pool. It may interfere with delicately adjusted biomes. -# "rugged" and "cliffs" do nothing unless "fast" is enabled # #mg_valleys_altitude_chill = 90 # the altitude at which temperature drops by 20C -#mg_valleys_cave_water_max_height = 31000 # max altitude of water in caves -#mg_valleys_humidity = 50 # the average humidity -#mg_valleys_humidity_break_point = 65 # The highest humidity around rivers in otherwise dry areas -#mg_valleys_lava_max_height = 0 # maximum altitude of lava +#mg_valleys_large_cave_depth = -33 # Depth below which you'll find large caves. +#mg_valleys_lava_features = 0 # Creates unpredictable lava features in caves. These can make mining difficult. Zero disables them. (0-10) +#mg_valleys_massive_cave_depth = -256 # Depth below which you'll find massive caves. #mg_valleys_river_depth = 4 # how deep to make rivers #mg_valleys_river_size = 5 # how wide to make rivers -#mg_valleys_temperature = 50 # the average temperature -#mg_valleys_water_features = 3 # how often water occurs in caves (0-10) +#mg_valleys_water_features = 0 # Creates unpredictable water features in caves. These can make mining difficult. Zero disables them. (0-10) # -#mg_valleys_np_cliffs = 0, 1, (750, 750, 750), 8445, 5, 1.0, 2.0 -#mg_valleys_np_corr = 0, 1, (40, 40, 40), -3536, 4, 1.0, 2.0 #mg_valleys_np_filler_depth = 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 # # River noise -- rivers occur close to zero #mg_valleys_np_rivers = 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 # -#mg_valleys_np_simple_caves_1 = 0, 1, v3f(64, 64, 64), -8402, 3, 0.5, 2.0 -#mg_valleys_np_simple_caves_2 = 0, 1, v3f(64, 64, 64), 3944, 3, 0.5, 2.0 +# Caves and tunnels form at the intersection of the two noises +#mg_valleys_np_cave1 = 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0 +#mg_valleys_np_cave2 = 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0 +# +#mg_valleys_np_massive_caves = 0, 1, (768, 256, 768), 59033, 6, 0.63, 2 # Massive caves form here. # # Base terrain height #mg_valleys_np_terrain_height = -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 6f4b2ccc..f003ae63 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -6,7 +6,7 @@ Copyright (C) 2016 Duane Robertson Based on Valleys Mapgen by Gael de Sailly (https://forum.minetest.net/viewtopic.php?f=9&t=11430) -and mapgen_v7 by kwolekr and paramat. +and mapgen_v7, mapgen_flat by kwolekr and paramat. Licensing changed by permission of Gael de Sailly. @@ -25,7 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #include "mapgen.h" #include "voxel.h" #include "noise.h" @@ -43,6 +42,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mg_ore.h" #include "mg_decoration.h" #include "mapgen_valleys.h" +#include "cavegen.h" + //#undef NDEBUG //#include "assert.h" @@ -55,12 +56,9 @@ with this program; if not, write to the Free Software Foundation, Inc., //Profiler *mapgen_profiler = &mapgen_prof; static FlagDesc flagdesc_mapgen_valleys[] = { - {"altitude_chill", MG_VALLEYS_ALT_CHILL}, - {"cliffs", MG_VALLEYS_CLIFFS}, - {"fast", MG_VALLEYS_FAST}, - {"humid_rivers", MG_VALLEYS_HUMID_RIVERS}, - {"rugged", MG_VALLEYS_RUGGED}, - {NULL, 0} + {"altitude_chill", MG_VALLEYS_ALT_CHILL}, + {"humid_rivers", MG_VALLEYS_HUMID_RIVERS}, + {NULL, 0} }; /////////////////////////////////////////////////////////////////////////////// @@ -82,28 +80,31 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * this->heatmap = NULL; this->humidmap = NULL; + this->map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT, + g_settings->getU16("map_generation_limit")); + MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams; this->spflags = sp->spflags; - this->cliff_terrain = (spflags & MG_VALLEYS_CLIFFS); - this->fast_terrain = (spflags & MG_VALLEYS_FAST); this->humid_rivers = (spflags & MG_VALLEYS_HUMID_RIVERS); - this->rugged_terrain = (spflags & MG_VALLEYS_RUGGED); this->use_altitude_chill = (spflags & MG_VALLEYS_ALT_CHILL); - this->altitude_chill = sp->altitude_chill; - this->cave_water_max_height = sp->cave_water_max_height; - this->humidity_adjust = sp->humidity - 50.f; - this->humidity_break_point = sp->humidity_break_point; - this->lava_max_height = sp->lava_max_height; - this->river_depth = sp->river_depth + 1.f; - this->river_size = sp->river_size / 100.f; - this->temperature_adjust = sp->temperature - 50.f; - this->water_features = MYMAX(1, MYMIN(11, 11 - sp->water_features)); + this->altitude_chill = sp->altitude_chill; + this->humidity_adjust = params->np_biome_humidity.offset - 50.f; + this->large_cave_depth = sp->large_cave_depth; + this->lava_features_lim = rangelim(sp->lava_features, 0, 10); + this->massive_cave_depth = sp->massive_cave_depth; + this->river_depth_bed = sp->river_depth + 1.f; + this->river_size_factor = sp->river_size / 100.f; + this->water_features_lim = rangelim(sp->water_features, 0, 10); + + // a small chance of overflows if the settings are very high + this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 6) * 50; + this->lava_max_height = water_level + MYMAX(0, lava_features_lim - 6) * 50; + + tcave_cache = new float[csize.Y + 2]; //// 2D Terrain noise - noise_cliffs = new Noise(&sp->np_cliffs, seed, csize.X, csize.Z); - noise_corr = new Noise(&sp->np_corr, seed, csize.X, csize.Z); noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); noise_inter_valley_slope = new Noise(&sp->np_inter_valley_slope, seed, csize.X, csize.Z); noise_rivers = new Noise(&sp->np_rivers, seed, csize.X, csize.Z); @@ -111,15 +112,11 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * noise_valley_depth = new Noise(&sp->np_valley_depth, seed, csize.X, csize.Z); noise_valley_profile = new Noise(&sp->np_valley_profile, seed, csize.X, csize.Z); - if (this->fast_terrain) - noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Z); - //// 3D Terrain noise - noise_simple_caves_1 = new Noise(&sp->np_simple_caves_1, seed, csize.X, csize.Y + 2, csize.Z); - noise_simple_caves_2 = new Noise(&sp->np_simple_caves_2, seed, csize.X, csize.Y + 2, csize.Z); - - if (!this->fast_terrain) - noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z); + noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z); + noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z); + noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z); + noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 2, csize.Z); //// Biome noise noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z); @@ -161,8 +158,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * MapgenValleys::~MapgenValleys() { - delete noise_cliffs; - delete noise_corr; + delete noise_cave1; + delete noise_cave2; delete noise_filler_depth; delete noise_heat; delete noise_heat_blend; @@ -171,45 +168,39 @@ MapgenValleys::~MapgenValleys() delete noise_inter_valley_fill; delete noise_inter_valley_slope; delete noise_rivers; - delete noise_simple_caves_1; - delete noise_simple_caves_2; + delete noise_massive_caves; delete noise_terrain_height; delete noise_valley_depth; delete noise_valley_profile; - delete[] heightmap; delete[] biomemap; + delete[] heightmap; + delete[] tcave_cache; } MapgenValleysParams::MapgenValleysParams() { - spflags = MG_VALLEYS_CLIFFS | MG_VALLEYS_RUGGED - | MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL; + spflags = MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL; - altitude_chill = 90; // The altitude at which temperature drops by 20C. - // Water in caves will never be higher than this. - cave_water_max_height = MAX_MAP_GENERATION_LIMIT; - humidity = 50; - // the maximum humidity around rivers in otherwise dry areas - humidity_break_point = 65; - lava_max_height = 0; // Lava will never be higher than this. - river_depth = 4; // How deep to carve river channels. - river_size = 5; // How wide to make rivers. - temperature = 50; - water_features = 3; // How often water will occur in caves. + altitude_chill = 90; // The altitude at which temperature drops by 20C. + large_cave_depth = -33; + lava_features = 0; // How often water will occur in caves. + massive_cave_depth = -256; // highest altitude of massive caves + river_depth = 4; // How deep to carve river channels. + river_size = 5; // How wide to make rivers. + water_features = 0; // How often water will occur in caves. - np_cliffs = NoiseParams(0.f, 1.f, v3f(750, 750, 750), 8445, 5, 1.f, 2.f); - np_corr = NoiseParams(0.f, 1.f, v3f(40, 40, 40), -3536, 4, 1.f, 2.f); - np_filler_depth = NoiseParams(0.f, 1.2f, v3f(256, 256, 256), 1605, 3, 0.5f, 2.f); - np_inter_valley_fill = NoiseParams(0.f, 1.f, v3f(256, 512, 256), 1993, 6, 0.8f, 2.f); - np_inter_valley_slope = NoiseParams(0.5f, 0.5f, v3f(128, 128, 128), 746, 1, 1.f, 2.f); - np_rivers = NoiseParams(0.f, 1.f, v3f(256, 256, 256), -6050, 5, 0.6f, 2.f); - np_simple_caves_1 = NoiseParams(0.f, 1.f, v3f(64, 64, 64), -8402, 3, 0.5f, 2.f); - np_simple_caves_2 = NoiseParams(0.f, 1.f, v3f(64, 64, 64), 3944, 3, 0.5f, 2.f); - np_terrain_height = NoiseParams(-10.f, 50.f, v3f(1024, 1024, 1024), 5202, 6, 0.4f, 2.f); - np_valley_depth = NoiseParams(5.f, 4.f, v3f(512, 512, 512), -1914, 1, 1.f, 2.f); - np_valley_profile = NoiseParams(0.6f, 0.5f, v3f(512, 512, 512), 777, 1, 1.f, 2.f); + np_cave1 = NoiseParams(0, 12, v3f(96, 96, 96), 52534, 4, 0.5, 2.0); + np_cave2 = NoiseParams(0, 12, v3f(96, 96, 96), 10325, 4, 0.5, 2.0); + np_filler_depth = NoiseParams(0.f, 1.2f, v3f(256, 256, 256), 1605, 3, 0.5f, 2.f); + np_inter_valley_fill = NoiseParams(0.f, 1.f, v3f(256, 512, 256), 1993, 6, 0.8f, 2.f); + np_inter_valley_slope = NoiseParams(0.5f, 0.5f, v3f(128, 128, 128), 746, 1, 1.f, 2.f); + np_rivers = NoiseParams(0.f, 1.f, v3f(256, 256, 256), -6050, 5, 0.6f, 2.f); + np_massive_caves = NoiseParams(0.f, 1.f, v3f(768, 256, 768), 59033, 6, 0.63f, 2.f); + np_terrain_height = NoiseParams(-10.f, 50.f, v3f(1024, 1024, 1024), 5202, 6, 0.4f, 2.f); + np_valley_depth = NoiseParams(5.f, 4.f, v3f(512, 512, 512), -1914, 1, 1.f, 2.f); + np_valley_profile = NoiseParams(0.6f, 0.5f, v3f(512, 512, 512), 777, 1, 1.f, 2.f); } @@ -217,24 +208,21 @@ void MapgenValleysParams::readParams(const Settings *settings) { settings->getFlagStrNoEx("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys); - settings->getU16NoEx("mg_valleys_altitude_chill", altitude_chill); - settings->getS16NoEx("mg_valleys_cave_water_max_height", cave_water_max_height); - settings->getS16NoEx("mg_valleys_humidity", humidity); - settings->getS16NoEx("mg_valleys_humidity_break_point", humidity_break_point); - settings->getS16NoEx("mg_valleys_lava_max_height", lava_max_height); - settings->getU16NoEx("mg_valleys_river_depth", river_depth); - settings->getU16NoEx("mg_valleys_river_size", river_size); - settings->getS16NoEx("mg_valleys_temperature", temperature); - settings->getU16NoEx("mg_valleys_water_features", water_features); + settings->getU16NoEx("mg_valleys_altitude_chill", altitude_chill); + settings->getS16NoEx("mg_valleys_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mg_valleys_lava_features", lava_features); + settings->getS16NoEx("mg_valleys_massive_cave_depth", massive_cave_depth); + settings->getU16NoEx("mg_valleys_river_depth", river_depth); + settings->getU16NoEx("mg_valleys_river_size", river_size); + settings->getU16NoEx("mg_valleys_water_features", water_features); - settings->getNoiseParams("mg_valleys_np_cliffs", np_cliffs); - settings->getNoiseParams("mg_valleys_np_corr", np_corr); + settings->getNoiseParams("mg_valleys_np_cave1", np_cave1); + settings->getNoiseParams("mg_valleys_np_cave2", np_cave2); settings->getNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); settings->getNoiseParams("mg_valleys_np_inter_valley_fill", np_inter_valley_fill); settings->getNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); settings->getNoiseParams("mg_valleys_np_rivers", np_rivers); - settings->getNoiseParams("mg_valleys_np_simple_caves_1", np_simple_caves_1); - settings->getNoiseParams("mg_valleys_np_simple_caves_2", np_simple_caves_2); + settings->getNoiseParams("mg_valleys_np_massive_caves", np_massive_caves); settings->getNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); settings->getNoiseParams("mg_valleys_np_valley_depth", np_valley_depth); settings->getNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); @@ -245,24 +233,21 @@ void MapgenValleysParams::writeParams(Settings *settings) const { settings->setFlagStr("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX); - settings->setU16("mg_valleys_altitude_chill", altitude_chill); - settings->setS16("mg_valleys_cave_water_max_height", cave_water_max_height); - settings->setS16("mg_valleys_humidity", humidity); - settings->setS16("mg_valleys_humidity_break_point", humidity_break_point); - settings->setS16("mg_valleys_lava_max_height", lava_max_height); - settings->setU16("mg_valleys_river_depth", river_depth); - settings->setU16("mg_valleys_river_size", river_size); - settings->setS16("mg_valleys_temperature", temperature); - settings->setU16("mg_valleys_water_features", water_features); + settings->setU16("mg_valleys_altitude_chill", altitude_chill); + settings->setS16("mg_valleys_large_cave_depth", large_cave_depth); + settings->setU16("mg_valleys_lava_features", lava_features); + settings->setS16("mg_valleys_massive_cave_depth", massive_cave_depth); + settings->setU16("mg_valleys_river_depth", river_depth); + settings->setU16("mg_valleys_river_size", river_size); + settings->setU16("mg_valleys_water_features", water_features); - settings->setNoiseParams("mg_valleys_np_cliffs", np_cliffs); - settings->setNoiseParams("mg_valleys_np_corr", np_corr); + settings->setNoiseParams("mg_valleys_np_cave1", np_cave1); + settings->setNoiseParams("mg_valleys_np_cave2", np_cave2); settings->setNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); settings->setNoiseParams("mg_valleys_np_inter_valley_fill", np_inter_valley_fill); settings->setNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); settings->setNoiseParams("mg_valleys_np_rivers", np_rivers); - settings->setNoiseParams("mg_valleys_np_simple_caves_1", np_simple_caves_1); - settings->setNoiseParams("mg_valleys_np_simple_caves_2", np_simple_caves_2); + settings->setNoiseParams("mg_valleys_np_massive_caves", np_massive_caves); settings->setNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); settings->setNoiseParams("mg_valleys_np_valley_depth", np_valley_depth); settings->setNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); @@ -313,7 +298,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) // Cave creation. if (flags & MG_CAVES) - generateSimpleCaves(stone_surface_max_y); + generateCaves(stone_surface_max_y); // Dungeon creation if ((flags & MG_DUNGEONS) && node_max.Y < 50 && (stone_surface_max_y >= node_min.Y)) { @@ -410,28 +395,12 @@ void MapgenValleys::calculateNoise() noise_valley_depth->perlinMap2D(x, z); noise_valley_profile->perlinMap2D(x, z); - if (fast_terrain) { - // Make this 2D for speed, if requested. - noise_inter_valley_fill->perlinMap2D(x, z); - - if (cliff_terrain) - noise_cliffs->perlinMap2D(x, z); - if (rugged_terrain) - noise_corr->perlinMap2D(x, z); - } else { - noise_inter_valley_fill->perlinMap3D(x, y, z); - } - - if (flags & MG_CAVES) { - noise_simple_caves_1->perlinMap3D(x, y, z); - noise_simple_caves_2->perlinMap3D(x, y, z); - } + noise_inter_valley_fill->perlinMap3D(x, y, z); //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f); for (s32 index = 0; index < csize.X * csize.Z; index++) { noise_heat->result[index] += noise_heat_blend->result[index]; - noise_heat->result[index] += temperature_adjust; noise_humidity->result[index] += noise_humidity_blend->result[index]; } @@ -442,45 +411,28 @@ void MapgenValleys::calculateNoise() for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) { // The parameters that we actually need to generate terrain // are passed by address (and the return value). - tn.terrain_height = noise_terrain_height->result[index]; + tn.terrain_height = noise_terrain_height->result[index]; // River noise is replaced with base terrain, which // is basically the height of the water table. - tn.rivers = &noise_rivers->result[index]; + tn.rivers = &noise_rivers->result[index]; // Valley depth noise is replaced with the valley // number that represents the height of terrain // over rivers and is used to determine about // how close a river is for humidity calculation. - tn.valley = &noise_valley_depth->result[index]; - tn.valley_profile = noise_valley_profile->result[index]; + tn.valley = &noise_valley_depth->result[index]; + tn.valley_profile = noise_valley_profile->result[index]; // Slope noise is replaced by the calculated slope // which is used to get terrain height in the slow // method, to create sharper mountains. - tn.slope = &noise_inter_valley_slope->result[index]; + tn.slope = &noise_inter_valley_slope->result[index]; tn.inter_valley_fill = noise_inter_valley_fill->result[index]; - tn.cliffs = noise_cliffs->result[index]; - tn.corr = noise_corr->result[index]; // This is the actual terrain height. float mount = terrainLevelFromNoise(&tn); noise_terrain_height->result[index] = mount; - - if (fast_terrain) { - // Assign humidity adjusted by water proximity. - // I can't think of a reason why a mod would expect base humidity - // from noise or at any altitude other than ground level. - noise_humidity->result[index] = humidityByTerrain( - noise_humidity->result[index], - mount, - noise_rivers->result[index], - noise_valley_depth->result[index]); - - // Assign heat adjusted by altitude. See humidity, above. - if (use_altitude_chill && mount > 0.f) - noise_heat->result[index] *= pow(0.5f, (mount - altitude_chill / 3.f) / altitude_chill); - } } - heatmap = noise_heat->result; + heatmap = noise_heat->result; humidmap = noise_humidity->result; } @@ -489,11 +441,9 @@ void MapgenValleys::calculateNoise() // complicated code to determine ground level. float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) { - float inter_valley_slope = *tn->slope; - // The square function changes the behaviour of this noise: // very often small, and sometimes very high. - float valley_d = pow(*tn->valley, 2); + float valley_d = MYSQUARE(*tn->valley); // valley_d is here because terrain is generally higher where valleys // are deep (mountains). base represents the height of the @@ -501,14 +451,17 @@ float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) float base = tn->terrain_height + valley_d; // "river" represents the distance from the river, in arbitrary units. - float river = fabs(*tn->rivers) - river_size; + float river = fabs(*tn->rivers) - river_size_factor; - // Use the curve of the function 1−exp(−(x/a)²) to model valleys. - // Making "a" vary (0 < a ≤ 1) changes the shape of the valleys. + // Use the curve of the function 1-exp(-(x/a)^2) to model valleys. + // Making "a" vary (0 < a <= 1) changes the shape of the valleys. // Try it with a geometry software ! // (here x = "river" and a = valley_profile). // "valley" represents the height of the terrain, from the rivers. - *tn->valley = valley_d * (1.f - exp(- pow(river / tn->valley_profile, 2))); + { + float t = river / tn->valley_profile; + *tn->valley = valley_d * (1.f - exp(- MYSQUARE(t))); + } // approximate height of the terrain at this point float mount = base + *tn->valley; @@ -520,36 +473,21 @@ float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) // Base ground is returned as rivers since it's basically the water table. *tn->rivers = base; if (river < 0.f) { - // Use the the function −sqrt(1−x²) which models a circle. - float depth = (river_depth * sqrt(1.f - pow((river / river_size + 1), 2))); + // Use the the function -sqrt(1-x^2) which models a circle. + float depth; + { + float t = river / river_size_factor + 1; + depth = (river_depth_bed * sqrt(MYMAX(0, 1.f - MYSQUARE(t)))); + } // base - depth : height of the bottom of the river - // water_level - 2 : don't make rivers below 2 nodes under the surface - u16 min_bottom = 2; - if (!fast_terrain) - min_bottom = 6; - mount = fmin(fmax(base - depth, (float) (water_level - min_bottom)), mount); + // water_level - 6 : don't make rivers below 6 nodes under the surface + mount = rangelim(base - depth, (float) (water_level - 6), mount); // Slope has no influence on rivers. *tn->slope = 0.f; } - if (fast_terrain) { - // The penultimate step builds up the heights, but we reduce it - // occasionally to create cliffs. - float delta = sin(tn->inter_valley_fill) * *tn->slope; - if (cliff_terrain && tn->cliffs >= 0.2f) - mount += delta * 0.66f; - else - mount += delta; - - // Use yet another noise to make the heights look more rugged. - if (rugged_terrain - && mount > water_level - && fabs(inter_valley_slope * tn->inter_valley_fill) < 0.3f) - mount += ((delta < 0.f) ? -1.f : 1.f) * pow(fabs(delta), 0.5f) * fabs(sin(tn->corr)); - } - return mount; } @@ -559,15 +497,14 @@ float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn) { float mount = terrainLevelFromNoise(tn); + s16 y_start = myround(mount); - if (!fast_terrain) { - for (s16 y = round(mount); y <= round(mount) + 1000; y++) { - float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed); + for (s16 y = y_start; y <= y_start + 1000; y++) { + float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed); - if (fill * *tn->slope <= y - mount) { - mount = fmax(y - 1, mount); - break; - } + if (fill * *tn->slope <= y - mount) { + mount = MYMAX(y - 1, mount); + break; } } @@ -575,40 +512,12 @@ float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn) } -float MapgenValleys::humidityByTerrain( - float humidity_base, - float mount, - float rivers, - float valley) -{ - // Although the original valleys adjusts humidity by distance - // from seawater, this causes problems with the default biomes. - // Adjust only by freshwater proximity. - float humidity = humidity_base + humidity_adjust; - - if (humid_rivers && mount > water_level) { - // Offset to make everything average the same. - humidity -= (humidity_break_point - humidity_adjust) / 3.f; - - // This method is from the original lua. - float water_table = pow(0.5f, fmax(rivers / 3.f, 0.f)); - // This adds humidity next to rivers and lakes. - float river_water = pow(0.5f, fmax(valley / 12.f, 0.f)); - // Combine the two. - float water = water_table + (1.f - water_table) * river_water; - humidity = fmax(humidity, (humidity_break_point * water)); - } - - return humidity; -} - - int MapgenValleys::getGroundLevelAtPoint(v2s16 p) { - // *********************************************** - // This method (deliberately) does not return correct - // terrain values. This may be a problem in the future. - // *********************************************** + // *********************************** + // This method (deliberately) does not + // return correct terrain values. + // *********************************** // Since MT doesn't normally deal with rivers, check // to make sure this isn't a request for a location @@ -616,7 +525,7 @@ int MapgenValleys::getGroundLevelAtPoint(v2s16 p) float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed); // If it's wet, return an unusable number. - if (fabs(rivers) < river_size) + if (fabs(rivers) < river_size_factor) return MAX_MAP_GENERATION_LIMIT; // Otherwise, return the real result. @@ -632,25 +541,14 @@ float MapgenValleys::terrainLevelAtPoint(s16 x, s16 z) float valley = NoisePerlin2D(&noise_valley_depth->np, x, z, seed); float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed); - tn.x = x; - tn.z = z; - tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed); - tn.rivers = &rivers; - tn.valley = &valley; - tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed); - tn.slope = &inter_valley_slope; + tn.x = x; + tn.z = z; + tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed); + tn.rivers = &rivers; + tn.valley = &valley; + tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed); + tn.slope = &inter_valley_slope; tn.inter_valley_fill = 0.f; - tn.cliffs = 0.f; - tn.corr = 0.f; - - if (fast_terrain) { - tn.inter_valley_fill = NoisePerlin2D(&noise_inter_valley_fill->np, x, z, seed); - - if (cliff_terrain) - tn.cliffs = NoisePerlin2D(&noise_cliffs->np, x, z, seed); - if (rugged_terrain) - tn.corr = NoisePerlin2D(&noise_corr->np, x, z, seed); - } return adjustedTerrainLevelFromNoise(&tn); } @@ -679,17 +577,13 @@ int MapgenValleys::generateTerrain() if (surface_y > surface_max_y) surface_max_y = surface_y; - u32 index_3d = 0; - if (!fast_terrain) - index_3d = (z - node_min.Z) * zstride + (x - node_min.X); - + u32 index_3d = (z - node_min.Z) * zstride + (x - node_min.X); u32 index_data = vm->m_area.index(x, node_min.Y - 1, z); // Mapgens concern themselves with stone and water. for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { float fill = 0.f; - if (!fast_terrain) - fill = noise_inter_valley_fill->result[index_3d]; + fill = noise_inter_valley_fill->result[index_3d]; if (vm->m_data[index_data].getContent() == CONTENT_IGNORE) { bool river = (river_y > surface_y); @@ -697,14 +591,14 @@ int MapgenValleys::generateTerrain() if (river && y == surface_y) { // river bottom vm->m_data[index_data] = n_sand; - } else if ((fast_terrain || river) && y <= surface_y) { + } else if (river && y <= surface_y) { // ground vm->m_data[index_data] = n_stone; } else if (river && y < river_y) { // river vm->m_data[index_data] = n_river_water; - } else if ((!fast_terrain) && (!river) && round(fill * slope) >= y - surface_y) { - // ground (slow method) + } else if ((!river) && myround(fill * slope) >= y - surface_y) { + // ground vm->m_data[index_data] = n_stone; heightmap[index_2d] = surface_max_y = y; } else if (y <= water_level) { @@ -716,23 +610,21 @@ int MapgenValleys::generateTerrain() } vm->m_area.add_y(em, index_data, 1); - if (!fast_terrain) - index_3d += ystride; + index_3d += ystride; } - if (!fast_terrain) { - // Assign the humidity adjusted by water proximity. - noise_humidity->result[index_2d] = humidityByTerrain( - noise_humidity->result[index_2d], - surface_max_y, - noise_rivers->result[index_2d], - noise_valley_depth->result[index_2d]); + // Although the original valleys adjusts humidity by distance + // from seawater, this causes problems with the default biomes. + // Adjust only by freshwater proximity. + const float humidity_offset = 0.8f; // derived by testing + if (humid_rivers) + noise_humidity->result[index_2d] *= (1 + pow(0.5f, MYMAX((surface_max_y + - noise_rivers->result[index_2d]) / 3.f, 0.f))) * humidity_offset; - // Assign the heat adjusted by altitude. See humidity, above. - if (use_altitude_chill && surface_max_y > 0) - noise_heat->result[index_2d] - *= pow(0.5f, (surface_max_y - altitude_chill / 3.f) / altitude_chill); - } + // Assign the heat adjusted by altitude. + if (use_altitude_chill && surface_max_y > 0) + noise_heat->result[index_2d] *= + pow(0.5f, (surface_max_y - altitude_chill / 3.f) / altitude_chill); } return surface_max_y; @@ -897,101 +789,158 @@ void MapgenValleys::dustTopNodes() } -void MapgenValleys::generateSimpleCaves(s16 max_stone_y) +void MapgenValleys::generateCaves(s16 max_stone_y) { + if (max_stone_y < node_min.Y) + return; + + noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + PseudoRandom ps(blockseed + 72202); MapNode n_air(CONTENT_AIR); - MapNode n_dirt(c_dirt); MapNode n_lava(c_lava_source); MapNode n_water(c_river_water_source); v3s16 em = vm->m_area.getExtent(); - s16 base_water_chance = 0; - if (water_features < 11) - base_water_chance = ceil(MAX_MAP_GENERATION_LIMIT / (water_features * 1000)); + // Cave blend distance near YMIN, YMAX + const float massive_cave_blend = 128.f; + // noise threshold for massive caves + const float massive_cave_threshold = 0.6f; + // mct: 1 = small rare caves, 0.5 1/3rd ground volume, 0 = 1/2 ground volume. - if (max_stone_y >= node_min.Y) { - u32 index_2d = 0; - u32 index_3d = 0; - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) { - bool air_above = false; - //bool underground = false; - u32 index_data = vm->m_area.index(x, node_max.Y + 1, z); + float yblmin = -map_gen_limit + massive_cave_blend * 1.5f; + float yblmax = massive_cave_depth - massive_cave_blend * 1.5f; + bool made_a_big_one = false; - index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X); + // Cache the tcave values as they only vary by altitude. + if (node_max.Y <= massive_cave_depth) { + noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - // Dig caves on down loop to check for air above. - for (s16 y = node_max.Y + 1; - y >= node_min.Y - 1; - y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) { - float terrain = noise_terrain_height->result[index_2d]; + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + float tcave = massive_cave_threshold; - // Saves some time and prevents removing above ground nodes. - if (y > terrain + 1) { - air_above = true; - continue; - } + if (y < yblmin) { + float t = (yblmin - y) / massive_cave_blend; + tcave += MYSQUARE(t); + } else if (y > yblmax) { + float t = (y - yblmax) / massive_cave_blend; + tcave += MYSQUARE(t); + } - content_t c = vm->m_data[index_data].getContent(); - bool n1 = (fabs(noise_simple_caves_1->result[index_3d]) < 0.07f); - bool n2 = (fabs(noise_simple_caves_2->result[index_3d]) < 0.07f); + tcave_cache[y - node_min.Y + 1] = tcave; + } + } - // River water is (foolishly) not set as ground content - // in the default game. This can produce strange results - // when a cave undercuts a river. However, that's not for - // the mapgen to correct. Fix it in lua. + // lava_depth varies between one and ten as you approach + // the bottom of the world. + s16 lava_depth = ceil((lava_max_height - node_min.Y + 1) * 10.f / map_gen_limit); + // This allows random lava spawns to be less common at the surface. + s16 lava_chance = MYCUBE(lava_features_lim) * lava_depth; + // water_depth varies between ten and one on the way down. + s16 water_depth = ceil((map_gen_limit - abs(node_min.Y) + 1) * 10.f / map_gen_limit); + // This allows random water spawns to be more common at the surface. + s16 water_chance = MYCUBE(water_features_lim) * water_depth; - if (c == CONTENT_AIR) { - air_above = true; - } else if (n1 && n2 && ndef->get(c).is_ground_content) { - // When both n's are true, we're in a cave. - vm->m_data[index_data] = n_air; - air_above = true; - } else if (air_above - && (c == c_stone || c == c_sandstone || c == c_desert_stone)) { - // At the cave floor - s16 sr = ps.next() & 1023; - u32 j = index_data; - vm->m_area.add_y(em, j, 1); + // Reduce the odds of overflows even further. + if (node_max.Y > water_level) { + lava_chance /= 5; + water_chance /= 5; + } - if (sr > (terrain - y) * 25) { - // Put dirt in caves near the surface. - Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]); + u32 index_2d = 0; + u32 index_3d = 0; + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) { + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]); + bool air_above = false; + bool underground = false; + u32 index_data = vm->m_area.index(x, node_max.Y + 1, z); + + index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X); + + // Dig caves on down loop to check for air above. + for (s16 y = node_max.Y + 1; + y >= node_min.Y - 1; + y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) { + float terrain = noise_terrain_height->result[index_2d]; + + // Saves some time. + if (y > terrain + 10) { + air_above = true; + continue; + } else if (y < terrain - 40) { + underground = true; + } + + // Dig massive caves. + if (node_max.Y <= massive_cave_depth + && noise_massive_caves->result[index_3d] + > tcave_cache[y - node_min.Y + 1]) { + vm->m_data[index_data] = n_air; + made_a_big_one = true; + } + + content_t c = vm->m_data[index_data].getContent(); + float d1 = contour(noise_cave1->result[index_3d]); + float d2 = contour(noise_cave2->result[index_3d]); + + // River water is not set as ground content + // in the default game. This can produce strange results + // when a cave undercuts a river. However, that's not for + // the mapgen to correct. Fix it in lua. + + if (c == CONTENT_AIR) { + air_above = true; + } else if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // in a cave + vm->m_data[index_data] = n_air; + air_above = true; + } else if (air_above && (c == biome->c_filler || c == biome->c_stone)) { + // at the cave floor + s16 sr = ps.range(0,39); + u32 j = index_data; + vm->m_area.add_y(em, j, 1); + + if (sr > terrain - y) { + // Put dirt in caves near the surface. + if (underground) vm->m_data[index_data] = MapNode(biome->c_filler); - } else { - s16 lava_chance = 0; + else + vm->m_data[index_data] = MapNode(biome->c_top); + } else if (sr < 3 && underground) { + sr = abs(ps.next()); + if (lava_features_lim > 0 && y <= lava_max_height + && c == biome->c_stone && sr < lava_chance) + vm->m_data[j] = n_lava; - if (y <= lava_max_height && c == c_stone) { - // Lava spawns increase with depth. - lava_chance = ceil((lava_max_height - y + 1) / 10000); + sr -= lava_chance; - if (sr < lava_chance) - vm->m_data[j] = n_lava; - } - - if (base_water_chance > 0 && y <= cave_water_max_height) { - s16 water_chance = base_water_chance - - (abs(y - water_level) / (water_features * 1000)); - - // Waterfalls may get out of control above ground. - sr -= lava_chance; - // If sr < 0 then we should have already placed lava -- - // don't immediately dump water on it. - if (sr >= 0 && sr < water_chance) - vm->m_data[j] = n_water; - } - } - - air_above = false; + // If sr < 0 then we should have already placed lava -- + // don't immediately dump water on it. + if (water_features_lim > 0 && y <= cave_water_max_height + && sr >= 0 && sr < water_chance) + vm->m_data[j] = n_water; } - // If we're not in a cave, there's no open space. - if (!(n1 && n2)) - air_above = false; + air_above = false; + underground = true; + } else if (c == biome->c_filler || c == biome->c_stone) { + air_above = false; + underground = true; + } else { + air_above = false; } } } + + if (node_max.Y <= large_cave_depth && (!made_a_big_one)) { + u32 bruises_count = ps.range(0, 2); + for (u32 i = 0; i < bruises_count; i++) { + CaveV5 cave(this, &ps); + cave.makeCave(node_min, node_max, max_stone_y); + } + } } diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 5fd54909..ee4052d7 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -31,11 +31,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen.h" /////////////////// Mapgen Valleys flags -#define MG_VALLEYS_ALT_CHILL 0x01 -#define MG_VALLEYS_CLIFFS 0x02 -#define MG_VALLEYS_FAST 0x04 -#define MG_VALLEYS_HUMID_RIVERS 0x08 -#define MG_VALLEYS_RUGGED 0x10 +#define MG_VALLEYS_ALT_CHILL 0x01 +#define MG_VALLEYS_HUMID_RIVERS 0x02 + +// Feed only one variable into these. +#define MYSQUARE(x) (x) * (x) +#define MYCUBE(x) (x) * (x) * (x) class BiomeManager; @@ -47,28 +48,25 @@ class BiomeManager; struct MapgenValleysParams : public MapgenSpecificParams { u32 spflags; + s16 large_cave_depth; + s16 massive_cave_depth; u16 altitude_chill; - s16 cave_water_max_height; - s16 humidity; - s16 humidity_break_point; - s16 lava_max_height; + u16 lava_features; u16 river_depth; u16 river_size; - s16 temperature; u16 water_features; NoiseParams np_biome_heat; NoiseParams np_biome_heat_blend; NoiseParams np_biome_humidity; NoiseParams np_biome_humidity_blend; - NoiseParams np_cliffs; - NoiseParams np_corr; + NoiseParams np_cave1; + NoiseParams np_cave2; NoiseParams np_filler_depth; NoiseParams np_inter_valley_fill; NoiseParams np_inter_valley_slope; NoiseParams np_rivers; - NoiseParams np_simple_caves_1; - NoiseParams np_simple_caves_2; + NoiseParams np_massive_caves; NoiseParams np_terrain_height; NoiseParams np_valley_depth; NoiseParams np_valley_profile; @@ -89,8 +87,6 @@ struct TerrainNoise { float valley_profile; float *slope; float inter_valley_fill; - float cliffs; - float corr; }; class MapgenValleys : public Mapgen { @@ -102,6 +98,8 @@ public: virtual void makeChunk(BlockMakeData *data); int getGroundLevelAtPoint(v2s16 p); + s16 large_cave_depth; + private: EmergeManager *m_emerge; BiomeManager *bmgr; @@ -109,10 +107,9 @@ private: int ystride; int zstride; + float map_gen_limit; + u32 spflags; - bool cliff_terrain; - bool fast_terrain; - bool rugged_terrain; bool humid_rivers; bool use_altitude_chill; @@ -123,8 +120,8 @@ private: Noise *noise_filler_depth; - Noise *noise_cliffs; - Noise *noise_corr; + Noise *noise_cave1; + Noise *noise_cave2; Noise *noise_heat; Noise *noise_heat_blend; Noise *noise_humidity; @@ -132,21 +129,21 @@ private: Noise *noise_inter_valley_fill; Noise *noise_inter_valley_slope; Noise *noise_rivers; - Noise *noise_simple_caves_1; - Noise *noise_simple_caves_2; + Noise *noise_massive_caves; Noise *noise_terrain_height; Noise *noise_valley_depth; Noise *noise_valley_profile; float altitude_chill; - float cave_water_max_height; + s16 cave_water_max_height; float humidity_adjust; - float humidity_break_point; - float lava_max_height; - float river_depth; - float river_size; - float temperature_adjust; - s16 water_features; + s16 lava_features_lim; + s16 lava_max_height; + s16 massive_cave_depth; + float river_depth_bed; + float river_size_factor; + float *tcave_cache; + s16 water_features_lim; content_t c_cobble; content_t c_desert_stone; @@ -176,7 +173,7 @@ private: MgStoneType generateBiomes(float *heat_map, float *humidity_map); void dustTopNodes(); - void generateSimpleCaves(s16 max_stone_y); + void generateCaves(s16 max_stone_y); }; struct MapgenFactoryValleys : public MapgenFactory { From 2ca1a56fc122600035350956e9a03fe393f58b3e Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 31 Jan 2016 04:23:46 +0000 Subject: [PATCH 2/5] Mgv5/v7/flat/fractal: Move tunnel noise calculation into generateCaves Tunnel 3D noises are only calculated when solid terrain is present in mapchunk, avoiding large amounts of unnecessary calculations Change 'int' to 's16' in calculateNoise Change 'i' to 'vi' for voxelmanip indexes for consistency Keep 'u32 index3d' local to a smaller part of tunnel code Mgv7: Don't call CaveV7 if no solid terrain in mapchunk Give 'open' bool a more descriptive name --- src/mapgen_flat.cpp | 84 +++++++++++++++++------------------ src/mapgen_fractal.cpp | 85 ++++++++++++++++++------------------ src/mapgen_v5.cpp | 56 ++++++++++++------------ src/mapgen_v7.cpp | 99 ++++++++++++++++++++++-------------------- 4 files changed, 165 insertions(+), 159 deletions(-) diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index b7f01320..3b7178dd 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -323,20 +323,16 @@ void MapgenFlat::makeChunk(BlockMakeData *data) void MapgenFlat::calculateNoise() { //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - int x = node_min.X; - int y = node_min.Y - 1; - int z = node_min.Z; + s16 x = node_min.X; + s16 z = node_min.Z; if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) noise_terrain->perlinMap2D(x, z); + // Cave noises are calculated in generateCaves() + // only if solid terrain is present in mapchunk + noise_filler_depth->perlinMap2D(x, z); - - if (flags & MG_CAVES) { - noise_cave1->perlinMap3D(x, y, z); - noise_cave2->perlinMap3D(x, y, z); - } - noise_heat->perlinMap2D(x, z); noise_humidity->perlinMap2D(x, z); noise_heat_blend->perlinMap2D(x, z); @@ -550,41 +546,45 @@ void MapgenFlat::dustTopNodes() void MapgenFlat::generateCaves(s16 max_stone_y) { - if (max_stone_y >= node_min.Y) { - v3s16 em = vm->m_area.getExtent(); - u32 index2d = 0; - u32 index3d; + if (max_stone_y < node_min.Y) + return; - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { - bool open = false; // Is column open to overground - u32 vi = vm->m_area.index(x, node_max.Y + 1, z); - index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + - (x - node_min.X); - // Biome of column - Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; - y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { - content_t c = vm->m_data[vi].getContent(); - if (c == CONTENT_AIR || c == biome->c_water_top || - c == biome->c_water) { - open = true; - continue; - } - // Ground - float d1 = contour(noise_cave1->result[index3d]); - float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { - // In tunnel and ground content, excavate - vm->m_data[vi] = MapNode(CONTENT_AIR); - } else if (open && (c == biome->c_filler || c == biome->c_stone)) { - // Tunnel entrance floor - vm->m_data[vi] = MapNode(biome->c_top); - open = false; - } else { - open = false; - } + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + bool column_is_open = false; // Is column open to overground + u32 vi = vm->m_area.index(x, node_max.Y + 1, z); + u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + (x - node_min.X); + // Biome of column + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + + for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; + y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { + content_t c = vm->m_data[vi].getContent(); + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + column_is_open = true; + continue; + } + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate + vm->m_data[vi] = MapNode(CONTENT_AIR); + } else if (column_is_open && + (c == biome->c_filler || c == biome->c_stone)) { + // Tunnel entrance floor + vm->m_data[vi] = MapNode(biome->c_top); + column_is_open = false; + } else { + column_is_open = false; } } } diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 5c0d283e..9cb682a9 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -339,18 +339,15 @@ void MapgenFractal::makeChunk(BlockMakeData *data) void MapgenFractal::calculateNoise() { //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - int x = node_min.X; - int y = node_min.Y - 1; - int z = node_min.Z; + s16 x = node_min.X; + s16 z = node_min.Z; noise_seabed->perlinMap2D(x, z); + + // Cave noises are calculated in generateCaves() + // only if solid terrain is present in mapchunk + noise_filler_depth->perlinMap2D(x, z); - - if (flags & MG_CAVES) { - noise_cave1->perlinMap3D(x, y, z); - noise_cave2->perlinMap3D(x, y, z); - } - noise_heat->perlinMap2D(x, z); noise_humidity->perlinMap2D(x, z); noise_heat_blend->perlinMap2D(x, z); @@ -673,41 +670,45 @@ void MapgenFractal::dustTopNodes() void MapgenFractal::generateCaves(s16 max_stone_y) { - if (max_stone_y >= node_min.Y) { - v3s16 em = vm->m_area.getExtent(); - u32 index2d = 0; - u32 index3d; + if (max_stone_y < node_min.Y) + return; - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { - bool open = false; // Is column open to overground - u32 vi = vm->m_area.index(x, node_max.Y + 1, z); - index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + - (x - node_min.X); - // Biome of column - Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; - y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { - content_t c = vm->m_data[vi].getContent(); - if (c == CONTENT_AIR || c == biome->c_water_top || - c == biome->c_water) { - open = true; - continue; - } - // Ground - float d1 = contour(noise_cave1->result[index3d]); - float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { - // In tunnel and ground content, excavate - vm->m_data[vi] = MapNode(CONTENT_AIR); - } else if (open && (c == biome->c_filler || c == biome->c_stone)) { - // Tunnel entrance floor - vm->m_data[vi] = MapNode(biome->c_top); - open = false; - } else { - open = false; - } + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + bool column_is_open = false; // Is column open to overground + u32 vi = vm->m_area.index(x, node_max.Y + 1, z); + u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + (x - node_min.X); + // Biome of column + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + + for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; + y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { + content_t c = vm->m_data[vi].getContent(); + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + column_is_open = true; + continue; + } + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate + vm->m_data[vi] = MapNode(CONTENT_AIR); + } else if (column_is_open && + (c == biome->c_filler || c == biome->c_stone)) { + // Tunnel entrance floor + vm->m_data[vi] = MapNode(biome->c_top); + column_is_open = false; + } else { + column_is_open = false; } } } diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 48b71729..06e5f1ca 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -322,18 +322,16 @@ void MapgenV5::makeChunk(BlockMakeData *data) void MapgenV5::calculateNoise() { //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - int x = node_min.X; - int y = node_min.Y - 1; - int z = node_min.Z; + s16 x = node_min.X; + s16 y = node_min.Y - 1; + s16 z = node_min.Z; noise_factor->perlinMap2D(x, z); noise_height->perlinMap2D(x, z); noise_ground->perlinMap3D(x, y, z); - if (flags & MG_CAVES) { - noise_cave1->perlinMap3D(x, y, z); - noise_cave2->perlinMap3D(x, y, z); - } + // Cave noises are calculated in generateCaves() + // only if solid terrain is present in mapchunk noise_filler_depth->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z); @@ -377,9 +375,9 @@ int MapgenV5::generateBaseTerrain() for (s16 z=node_min.Z; z<=node_max.Z; z++) { for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) { - u32 i = vm->m_area.index(node_min.X, y, z); - for (s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) { - if (vm->m_data[i].getContent() != CONTENT_IGNORE) + u32 vi = vm->m_area.index(node_min.X, y, z); + for (s16 x=node_min.X; x<=node_max.X; x++, vi++, index++, index2d++) { + if (vm->m_data[vi].getContent() != CONTENT_IGNORE) continue; float f = 0.55 + noise_factor->result[index2d]; @@ -391,11 +389,11 @@ int MapgenV5::generateBaseTerrain() if (noise_ground->result[index] * f < y - h) { if (y <= water_level) - vm->m_data[i] = MapNode(c_water_source); + vm->m_data[vi] = MapNode(c_water_source); else - vm->m_data[i] = MapNode(CONTENT_AIR); + vm->m_data[vi] = MapNode(CONTENT_AIR); } else { - vm->m_data[i] = MapNode(c_stone); + vm->m_data[vi] = MapNode(c_stone); if (y > stone_surface_max_y) stone_surface_max_y = y; } @@ -508,22 +506,26 @@ MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map) void MapgenV5::generateCaves(int max_stone_y) { - if (max_stone_y >= node_min.Y) { - u32 index = 0; + if (max_stone_y < node_min.Y) + return; - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { - u32 i = vm->m_area.index(node_min.X, y, z); - for (s16 x = node_min.X; x <= node_max.X; x++, i++, index++) { - float d1 = contour(noise_cave1->result[index]); - float d2 = contour(noise_cave2->result[index]); - if (d1 * d2 > 0.125f) { - content_t c = vm->m_data[i].getContent(); - if (!ndef->get(c).is_ground_content || c == CONTENT_AIR) - continue; + noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - vm->m_data[i] = MapNode(CONTENT_AIR); - } + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + u32 vi = vm->m_area.index(node_min.X, y, z); + for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index++) { + float d1 = contour(noise_cave1->result[index]); + float d2 = contour(noise_cave2->result[index]); + if (d1 * d2 > 0.125f) { + content_t c = vm->m_data[vi].getContent(); + if (!ndef->get(c).is_ground_content || c == CONTENT_AIR) + continue; + + vm->m_data[vi] = MapNode(CONTENT_AIR); } } } diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 1e481548..aec00b93 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -345,9 +345,9 @@ void MapgenV7::makeChunk(BlockMakeData *data) void MapgenV7::calculateNoise() { //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - int x = node_min.X; - int y = node_min.Y - 1; - int z = node_min.Z; + s16 x = node_min.X; + s16 y = node_min.Y - 1; + s16 z = node_min.Z; noise_terrain_persist->perlinMap2D(x, z); float *persistmap = noise_terrain_persist->result; @@ -356,17 +356,16 @@ void MapgenV7::calculateNoise() noise_terrain_alt->perlinMap2D(x, z, persistmap); noise_height_select->perlinMap2D(x, z); - if (flags & MG_CAVES) { - noise_cave1->perlinMap3D(x, y, z); - noise_cave2->perlinMap3D(x, y, z); - } - if ((spflags & MGV7_RIDGES) && node_max.Y >= water_level) { noise_ridge->perlinMap3D(x, y, z); noise_ridge_uwater->perlinMap2D(x, z); } + // Cave noises are calculated in generateCaves() + // only if solid terrain is present in mapchunk + // Mountain noises are calculated in generateMountainTerrain() + // only if solid terrain surface dips into mapchunk noise_filler_depth->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z); @@ -527,17 +526,17 @@ void MapgenV7::generateBaseTerrain(s16 *stone_surface_min_y, s16 *stone_surface_ if (surface_y > surface_max_y) surface_max_y = surface_y; - u32 i = vm->m_area.index(x, node_min.Y - 1, z); + u32 vi = vm->m_area.index(x, node_min.Y - 1, z); for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { - if (vm->m_data[i].getContent() == CONTENT_IGNORE) { + if (vm->m_data[vi].getContent() == CONTENT_IGNORE) { if (y <= surface_y) - vm->m_data[i] = n_stone; + vm->m_data[vi] = n_stone; else if (y <= water_level) - vm->m_data[i] = n_water; + vm->m_data[vi] = n_water; else - vm->m_data[i] = n_air; + vm->m_data[vi] = n_air; } - vm->m_area.add_y(em, i, 1); + vm->m_area.add_y(em, vi, 1); } } @@ -585,7 +584,7 @@ void MapgenV7::generateRidgeTerrain() MapNode n_water(c_water_source); MapNode n_air(CONTENT_AIR); u32 index = 0; - float width = 0.2; // TODO: figure out acceptable perlin noise values + float width = 0.2; for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { @@ -862,41 +861,45 @@ void MapgenV7::addTopNodes() void MapgenV7::generateCaves(s16 max_stone_y) { - if (max_stone_y >= node_min.Y) { - v3s16 em = vm->m_area.getExtent(); - u32 index2d = 0; - u32 index3d; + if (max_stone_y < node_min.Y) + return; - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { - bool open = false; // Is column open to overground - u32 vi = vm->m_area.index(x, node_max.Y + 1, z); - index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + - (x - node_min.X); - // Biome of column - Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; - y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { - content_t c = vm->m_data[vi].getContent(); - if (c == CONTENT_AIR || c == biome->c_water_top || - c == biome->c_water) { - open = true; - continue; - } - // Ground - float d1 = contour(noise_cave1->result[index3d]); - float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { - // In tunnel and ground content, excavate - vm->m_data[vi] = MapNode(CONTENT_AIR); - } else if (open && (c == biome->c_filler || c == biome->c_stone)) { - // Tunnel entrance floor - vm->m_data[vi] = MapNode(biome->c_top); - open = false; - } else { - open = false; - } + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + bool column_is_open = false; // Is column open to overground + u32 vi = vm->m_area.index(x, node_max.Y + 1, z); + u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + (x - node_min.X); + // Biome of column + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + + for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; + y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { + content_t c = vm->m_data[vi].getContent(); + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + column_is_open = true; + continue; + } + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate + vm->m_data[vi] = MapNode(CONTENT_AIR); + } else if (column_is_open && + (c == biome->c_filler || c == biome->c_stone)) { + // Tunnel entrance floor + vm->m_data[vi] = MapNode(biome->c_top); + column_is_open = false; + } else { + column_is_open = false; } } } From dcb2171aabbd3396e0dc07d6133c77ccef4deb15 Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Mon, 1 Feb 2016 02:09:43 -0600 Subject: [PATCH 3/5] Mgvalleys: fix riverbeds below sea level Stop riverbeds from forming plateaus under sea. Minor corrections to random lava/water placement. --- src/mapgen_valleys.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index f003ae63..ceb2c774 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -99,8 +99,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * this->water_features_lim = rangelim(sp->water_features, 0, 10); // a small chance of overflows if the settings are very high - this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 6) * 50; - this->lava_max_height = water_level + MYMAX(0, lava_features_lim - 6) * 50; + this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50; + this->lava_max_height = water_level + MYMAX(0, lava_features_lim - 4) * 50; tcave_cache = new float[csize.Y + 2]; @@ -482,7 +482,8 @@ float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) // base - depth : height of the bottom of the river // water_level - 6 : don't make rivers below 6 nodes under the surface - mount = rangelim(base - depth, (float) (water_level - 6), mount); + // There is no logical equivalent to this using rangelim. + mount = MYMIN(MYMAX(base - depth, (float) (water_level - 6)), mount); // Slope has no influence on rivers. *tn->slope = 0.f; @@ -846,8 +847,8 @@ void MapgenValleys::generateCaves(s16 max_stone_y) // Reduce the odds of overflows even further. if (node_max.Y > water_level) { - lava_chance /= 5; - water_chance /= 5; + lava_chance /= 3; + water_chance /= 3; } u32 index_2d = 0; From 897545760424dc8ef7d30642412f899a1b2908ba Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Fri, 29 Jan 2016 16:15:58 +0200 Subject: [PATCH 4/5] Implement OSX Travis builds --- .travis.yml | 11 +++++++++- util/travis/before_install.sh | 39 +++++++++++++++++++++-------------- util/travis/script.sh | 5 ++++- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7ee2387..9d160081 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,13 @@ language: cpp compiler: - gcc - clang +os: + - osx + - linux env: - PLATFORM=Win32 - PLATFORM=Win64 - - PLATFORM=Linux + - PLATFORM=Unix before_install: ./util/travis/before_install.sh script: ./util/travis/script.sh sudo: required @@ -18,3 +21,9 @@ matrix: compiler: clang - env: PLATFORM=Win64 compiler: clang + - env: PLATFORM=Win32 + os: osx + - env: PLATFORM=Win64 + os: osx + - compiler: gcc + os: osx diff --git a/util/travis/before_install.sh b/util/travis/before_install.sh index e3276e0d..58dc42b1 100755 --- a/util/travis/before_install.sh +++ b/util/travis/before_install.sh @@ -1,22 +1,30 @@ #!/bin/bash -e -if [[ $CC == "clang" ]]; then - export PATH="/usr/bin/:$PATH" - sudo sh -c 'echo "deb http://ppa.launchpad.net/eudoxos/llvm-3.1/ubuntu precise main" >> /etc/apt/sources.list' - sudo apt-key adv --keyserver pool.sks-keyservers.net --recv-keys 92DE8183 +if [[ $TRAVIS_OS_NAME == "linux" ]]; then + if [[ $CC == "clang" ]]; then + export PATH="/usr/bin/:$PATH" + sudo sh -c 'echo "deb http://ppa.launchpad.net/eudoxos/llvm-3.1/ubuntu precise main" >> /etc/apt/sources.list' + sudo apt-key adv --keyserver pool.sks-keyservers.net --recv-keys 92DE8183 + sudo apt-get update + sudo apt-get install llvm-3.1 + sudo apt-get install clang + fi sudo apt-get update - sudo apt-get install llvm-3.1 - sudo apt-get install clang + sudo apt-get install p7zip-full fi -sudo apt-get update -sudo apt-get install p7zip-full -if [[ $PLATFORM == "Linux" ]]; then - sudo apt-get install libirrlicht-dev cmake libbz2-dev libpng12-dev \ - libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev \ - libhiredis-dev libogg-dev libgmp-dev libvorbis-dev libopenal-dev gettext - # Linking to LevelDB is broken, use a custom build - wget http://minetest.kitsunemimi.pw/libleveldb-1.18-ubuntu12.04.7z - sudo 7z x -o/usr libleveldb-1.18-ubuntu12.04.7z + +if [[ $PLATFORM == "Unix" ]]; then + if [[ $TRAVIS_OS_NAME == "linux" ]]; then + sudo apt-get install libirrlicht-dev cmake libbz2-dev libpng12-dev \ + libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev \ + libhiredis-dev libogg-dev libgmp-dev libvorbis-dev libopenal-dev gettext + # Linking to LevelDB is broken, use a custom build + wget http://minetest.kitsunemimi.pw/libleveldb-1.18-ubuntu12.04.7z + sudo 7z x -o/usr libleveldb-1.18-ubuntu12.04.7z + else + brew update + brew install freetype gettext hiredis irrlicht jpeg leveldb libogg libvorbis luajit + fi elif [[ $PLATFORM == "Win32" ]]; then wget http://minetest.kitsunemimi.pw/mingw_w64_i686_ubuntu12.04_4.9.1.7z -O mingw.7z sed -e "s|%PREFIX%|i686-w64-mingw32|" \ @@ -30,4 +38,3 @@ elif [[ $PLATFORM == "Win64" ]]; then < util/travis/toolchain_mingw.cmake.in > util/buildbot/toolchain_mingw64.cmake sudo 7z x -y -o/usr mingw.7z fi - diff --git a/util/travis/script.sh b/util/travis/script.sh index 756cc1de..5be747e5 100755 --- a/util/travis/script.sh +++ b/util/travis/script.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -if [[ $PLATFORM == "Linux" ]]; then +if [[ $PLATFORM == "Unix" ]]; then mkdir -p travisbuild cd travisbuild CMAKE_FLAGS='-DCMAKE_BUILD_TYPE=Debug \ @@ -10,6 +10,9 @@ if [[ $PLATFORM == "Linux" ]]; then if [[ $CC == "clang" ]]; then CMAKE_FLAGS+=' -DENABLE_FREETYPE=FALSE' fi + if [[ $TRAVIS_OS_NAME == "osx" ]]; then + CMAKE_FLAGS+=' -DCUSTOM_GETTEXT_PATH=/usr/local/opt/gettext' + fi cmake $CMAKE_FLAGS .. make -j2 echo "Running unit tests." From 3f429363a2d52d449771391a24b15f388e5fb93d Mon Sep 17 00:00:00 2001 From: Splizard Date: Wed, 3 Feb 2016 19:09:13 +1300 Subject: [PATCH 5/5] Add admin command which says who the administator is for the server. --- builtin/game/chatcommands.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/builtin/game/chatcommands.lua b/builtin/game/chatcommands.lua index 6a35c034..fff893b2 100644 --- a/builtin/game/chatcommands.lua +++ b/builtin/game/chatcommands.lua @@ -84,6 +84,18 @@ core.register_chatcommand("me", { end, }) +core.register_chatcommand("admin", { + description = "Show the name of the server owner", + func = function(name) + local admin = minetest.setting_get("name") + if admin then + return true, "The administrator of this server is "..admin.."." + else + return false, "There's no administrator named in the config file." + end + end, +}) + core.register_chatcommand("help", { privs = {}, params = "[all/privs/]",