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.
master^2
Duane Robertson 2016-01-31 02:59:15 -06:00 committed by paramat
parent 83583aa2d5
commit 80c7612e76
4 changed files with 314 additions and 380 deletions

View File

@ -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 that are not specified in the flag string are not modified from the default.
# Flags starting with "no" are used to explicitly disable them. # Flags starting with "no" are used to explicitly disable them.
# "altitude_chill" makes higher elevations colder, which may cause biome issues. # "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. # "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,humid_rivers altitude_chill,noaltitude_chill,humid_rivers,nohumid_rivers
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
# The altitude at which temperature drops by 20C # The altitude at which temperature drops by 20C
mg_valleys_altitude_chill (Altitude Chill) int 90 mg_valleys_altitude_chill (Altitude Chill) int 90
# Average humidity # Depth below which you'll find large caves.
mg_valleys_humidity (Humidity) int 50 mg_valleys_large_cave_depth (Large cave depth) int -33
# The highest humidity around rivers in otherwise dry areas # Creates unpredictable lava features in caves.
mg_valleys_humidity_break_point (Humidity Break) int 65 # These can make mining difficult. Zero disables them. (0-10)
mg_valleys_lava_features (Lava Features) int 0
# Maximum altitude where lava can emerge # Depth below which you'll find massive caves.
mg_valleys_lava_max_height (Lava Height) int 0 mg_valleys_massive_cave_depth (Massive cave depth) int -256
# Maximum altitude where water occurs in caves (and tends to fall out)
mg_valleys_cave_water_max_height (Cave Water Height) int 31000
# How deep to make rivers # How deep to make rivers
mg_valleys_river_depth (River Depth) int 4 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 # How wide to make rivers
mg_valleys_river_size (River Size) int 5 mg_valleys_river_size (River Size) int 5
# Average temperature # Creates unpredictable water features in caves.
mg_valleys_temperature (Temperature) int 50 # These can make mining difficult. Zero disables them. (0-10)
mg_valleys_water_features (Water Features) int 0
# How often water occurs in caves (0-10)
mg_valleys_water_features (Water Features) int 3
# Noise parameters # Noise parameters
[****Noises] [****Noises]
# Cliff noise # Caves and tunnels form at the intersection of the two noises
mg_valleys_np_cliffs (Cliffs) noise_params 0, 1, (750, 750, 750), 8445, 5, 1.0, 2.0 mg_valleys_np_cave1 (Cave noise #1) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0
# Mountain corrugation # Caves and tunnels form at the intersection of the two noises
mg_valleys_np_corr (Corrugation) noise_params 0, 1, (40, 40, 40), -3536, 4, 1.0, 2.0 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 # 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 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 # 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 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 # Base terrain height
mg_valleys_np_terrain_height (Terrain Height) noise_params -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 mg_valleys_np_terrain_height (Terrain Height) noise_params -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0

View File

@ -1315,31 +1315,28 @@
#### Mapgen Valleys #### 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. # "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. # "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_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_large_cave_depth = -33 # Depth below which you'll find large caves.
#mg_valleys_humidity = 50 # the average humidity #mg_valleys_lava_features = 0 # Creates unpredictable lava features in caves. These can make mining difficult. Zero disables them. (0-10)
#mg_valleys_humidity_break_point = 65 # The highest humidity around rivers in otherwise dry areas #mg_valleys_massive_cave_depth = -256 # Depth below which you'll find massive caves.
#mg_valleys_lava_max_height = 0 # maximum altitude of lava
#mg_valleys_river_depth = 4 # how deep to make rivers #mg_valleys_river_depth = 4 # how deep to make rivers
#mg_valleys_river_size = 5 # how wide to make rivers #mg_valleys_river_size = 5 # how wide to make rivers
#mg_valleys_temperature = 50 # the average temperature #mg_valleys_water_features = 0 # Creates unpredictable water features in caves. These can make mining difficult. Zero disables them. (0-10)
#mg_valleys_water_features = 3 # how often water occurs in caves (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 #mg_valleys_np_filler_depth = 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0
# #
# River noise -- rivers occur close to zero # 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_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 # Caves and tunnels form at the intersection of the two noises
#mg_valleys_np_simple_caves_2 = 0, 1, v3f(64, 64, 64), 3944, 3, 0.5, 2.0 #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 # Base terrain height
#mg_valleys_np_terrain_height = -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 #mg_valleys_np_terrain_height = -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0

View File

@ -6,7 +6,7 @@ Copyright (C) 2016 Duane Robertson <duane@duanerobertson.com>
Based on Valleys Mapgen by Gael de Sailly Based on Valleys Mapgen by Gael de Sailly
(https://forum.minetest.net/viewtopic.php?f=9&t=11430) (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. 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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "mapgen.h" #include "mapgen.h"
#include "voxel.h" #include "voxel.h"
#include "noise.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_ore.h"
#include "mg_decoration.h" #include "mg_decoration.h"
#include "mapgen_valleys.h" #include "mapgen_valleys.h"
#include "cavegen.h"
//#undef NDEBUG //#undef NDEBUG
//#include "assert.h" //#include "assert.h"
@ -55,12 +56,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//Profiler *mapgen_profiler = &mapgen_prof; //Profiler *mapgen_profiler = &mapgen_prof;
static FlagDesc flagdesc_mapgen_valleys[] = { static FlagDesc flagdesc_mapgen_valleys[] = {
{"altitude_chill", MG_VALLEYS_ALT_CHILL}, {"altitude_chill", MG_VALLEYS_ALT_CHILL},
{"cliffs", MG_VALLEYS_CLIFFS}, {"humid_rivers", MG_VALLEYS_HUMID_RIVERS},
{"fast", MG_VALLEYS_FAST}, {NULL, 0}
{"humid_rivers", MG_VALLEYS_HUMID_RIVERS},
{"rugged", MG_VALLEYS_RUGGED},
{NULL, 0}
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -82,28 +80,31 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
this->heatmap = NULL; this->heatmap = NULL;
this->humidmap = NULL; this->humidmap = NULL;
this->map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT,
g_settings->getU16("map_generation_limit"));
MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams; MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams;
this->spflags = sp->spflags; 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->humid_rivers = (spflags & MG_VALLEYS_HUMID_RIVERS);
this->rugged_terrain = (spflags & MG_VALLEYS_RUGGED);
this->use_altitude_chill = (spflags & MG_VALLEYS_ALT_CHILL); this->use_altitude_chill = (spflags & MG_VALLEYS_ALT_CHILL);
this->altitude_chill = sp->altitude_chill; this->altitude_chill = sp->altitude_chill;
this->cave_water_max_height = sp->cave_water_max_height; this->humidity_adjust = params->np_biome_humidity.offset - 50.f;
this->humidity_adjust = sp->humidity - 50.f; this->large_cave_depth = sp->large_cave_depth;
this->humidity_break_point = sp->humidity_break_point; this->lava_features_lim = rangelim(sp->lava_features, 0, 10);
this->lava_max_height = sp->lava_max_height; this->massive_cave_depth = sp->massive_cave_depth;
this->river_depth = sp->river_depth + 1.f; this->river_depth_bed = sp->river_depth + 1.f;
this->river_size = sp->river_size / 100.f; this->river_size_factor = sp->river_size / 100.f;
this->temperature_adjust = sp->temperature - 50.f; this->water_features_lim = rangelim(sp->water_features, 0, 10);
this->water_features = MYMAX(1, MYMIN(11, 11 - sp->water_features));
// 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 //// 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_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_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); 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_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); 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 //// 3D Terrain noise
noise_simple_caves_1 = new Noise(&sp->np_simple_caves_1, seed, csize.X, csize.Y + 2, csize.Z); noise_cave1 = new Noise(&sp->np_cave1, 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); 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);
if (!this->fast_terrain) noise_massive_caves = new Noise(&sp->np_massive_caves, 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);
//// Biome noise //// Biome noise
noise_heat_blend = new Noise(&params->np_biome_heat_blend, seed, csize.X, csize.Z); noise_heat_blend = new Noise(&params->np_biome_heat_blend, seed, csize.X, csize.Z);
@ -161,8 +158,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
MapgenValleys::~MapgenValleys() MapgenValleys::~MapgenValleys()
{ {
delete noise_cliffs; delete noise_cave1;
delete noise_corr; delete noise_cave2;
delete noise_filler_depth; delete noise_filler_depth;
delete noise_heat; delete noise_heat;
delete noise_heat_blend; delete noise_heat_blend;
@ -171,45 +168,39 @@ MapgenValleys::~MapgenValleys()
delete noise_inter_valley_fill; delete noise_inter_valley_fill;
delete noise_inter_valley_slope; delete noise_inter_valley_slope;
delete noise_rivers; delete noise_rivers;
delete noise_simple_caves_1; delete noise_massive_caves;
delete noise_simple_caves_2;
delete noise_terrain_height; delete noise_terrain_height;
delete noise_valley_depth; delete noise_valley_depth;
delete noise_valley_profile; delete noise_valley_profile;
delete[] heightmap;
delete[] biomemap; delete[] biomemap;
delete[] heightmap;
delete[] tcave_cache;
} }
MapgenValleysParams::MapgenValleysParams() MapgenValleysParams::MapgenValleysParams()
{ {
spflags = MG_VALLEYS_CLIFFS | MG_VALLEYS_RUGGED spflags = MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL;
| MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL;
altitude_chill = 90; // The altitude at which temperature drops by 20C. altitude_chill = 90; // The altitude at which temperature drops by 20C.
// Water in caves will never be higher than this. large_cave_depth = -33;
cave_water_max_height = MAX_MAP_GENERATION_LIMIT; lava_features = 0; // How often water will occur in caves.
humidity = 50; massive_cave_depth = -256; // highest altitude of massive caves
// the maximum humidity around rivers in otherwise dry areas river_depth = 4; // How deep to carve river channels.
humidity_break_point = 65; river_size = 5; // How wide to make rivers.
lava_max_height = 0; // Lava will never be higher than this. water_features = 0; // How often water will occur in caves.
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.
np_cliffs = NoiseParams(0.f, 1.f, v3f(750, 750, 750), 8445, 5, 1.f, 2.f); np_cave1 = NoiseParams(0, 12, v3f(96, 96, 96), 52534, 4, 0.5, 2.0);
np_corr = NoiseParams(0.f, 1.f, v3f(40, 40, 40), -3536, 4, 1.f, 2.f); 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_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_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_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_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_massive_caves = NoiseParams(0.f, 1.f, v3f(768, 256, 768), 59033, 6, 0.63f, 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_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_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_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->getFlagStrNoEx("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys);
settings->getU16NoEx("mg_valleys_altitude_chill", altitude_chill); settings->getU16NoEx("mg_valleys_altitude_chill", altitude_chill);
settings->getS16NoEx("mg_valleys_cave_water_max_height", cave_water_max_height); settings->getS16NoEx("mg_valleys_large_cave_depth", large_cave_depth);
settings->getS16NoEx("mg_valleys_humidity", humidity); settings->getU16NoEx("mg_valleys_lava_features", lava_features);
settings->getS16NoEx("mg_valleys_humidity_break_point", humidity_break_point); settings->getS16NoEx("mg_valleys_massive_cave_depth", massive_cave_depth);
settings->getS16NoEx("mg_valleys_lava_max_height", lava_max_height); settings->getU16NoEx("mg_valleys_river_depth", river_depth);
settings->getU16NoEx("mg_valleys_river_depth", river_depth); settings->getU16NoEx("mg_valleys_river_size", river_size);
settings->getU16NoEx("mg_valleys_river_size", river_size); settings->getU16NoEx("mg_valleys_water_features", water_features);
settings->getS16NoEx("mg_valleys_temperature", temperature);
settings->getU16NoEx("mg_valleys_water_features", water_features);
settings->getNoiseParams("mg_valleys_np_cliffs", np_cliffs); settings->getNoiseParams("mg_valleys_np_cave1", np_cave1);
settings->getNoiseParams("mg_valleys_np_corr", np_corr); settings->getNoiseParams("mg_valleys_np_cave2", np_cave2);
settings->getNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); 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_fill", np_inter_valley_fill);
settings->getNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); 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_rivers", np_rivers);
settings->getNoiseParams("mg_valleys_np_simple_caves_1", np_simple_caves_1); settings->getNoiseParams("mg_valleys_np_massive_caves", np_massive_caves);
settings->getNoiseParams("mg_valleys_np_simple_caves_2", np_simple_caves_2);
settings->getNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); 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_depth", np_valley_depth);
settings->getNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); 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->setFlagStr("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX);
settings->setU16("mg_valleys_altitude_chill", altitude_chill); settings->setU16("mg_valleys_altitude_chill", altitude_chill);
settings->setS16("mg_valleys_cave_water_max_height", cave_water_max_height); settings->setS16("mg_valleys_large_cave_depth", large_cave_depth);
settings->setS16("mg_valleys_humidity", humidity); settings->setU16("mg_valleys_lava_features", lava_features);
settings->setS16("mg_valleys_humidity_break_point", humidity_break_point); settings->setS16("mg_valleys_massive_cave_depth", massive_cave_depth);
settings->setS16("mg_valleys_lava_max_height", lava_max_height); settings->setU16("mg_valleys_river_depth", river_depth);
settings->setU16("mg_valleys_river_depth", river_depth); settings->setU16("mg_valleys_river_size", river_size);
settings->setU16("mg_valleys_river_size", river_size); settings->setU16("mg_valleys_water_features", water_features);
settings->setS16("mg_valleys_temperature", temperature);
settings->setU16("mg_valleys_water_features", water_features);
settings->setNoiseParams("mg_valleys_np_cliffs", np_cliffs); settings->setNoiseParams("mg_valleys_np_cave1", np_cave1);
settings->setNoiseParams("mg_valleys_np_corr", np_corr); settings->setNoiseParams("mg_valleys_np_cave2", np_cave2);
settings->setNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); 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_fill", np_inter_valley_fill);
settings->setNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); 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_rivers", np_rivers);
settings->setNoiseParams("mg_valleys_np_simple_caves_1", np_simple_caves_1); settings->setNoiseParams("mg_valleys_np_massive_caves", np_massive_caves);
settings->setNoiseParams("mg_valleys_np_simple_caves_2", np_simple_caves_2);
settings->setNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); 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_depth", np_valley_depth);
settings->setNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); settings->setNoiseParams("mg_valleys_np_valley_profile", np_valley_profile);
@ -313,7 +298,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
// Cave creation. // Cave creation.
if (flags & MG_CAVES) if (flags & MG_CAVES)
generateSimpleCaves(stone_surface_max_y); generateCaves(stone_surface_max_y);
// Dungeon creation // Dungeon creation
if ((flags & MG_DUNGEONS) && node_max.Y < 50 && (stone_surface_max_y >= node_min.Y)) { 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_depth->perlinMap2D(x, z);
noise_valley_profile->perlinMap2D(x, z); noise_valley_profile->perlinMap2D(x, z);
if (fast_terrain) { noise_inter_valley_fill->perlinMap3D(x, y, z);
// 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);
}
//mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f); //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f);
for (s32 index = 0; index < csize.X * csize.Z; index++) { for (s32 index = 0; index < csize.X * csize.Z; index++) {
noise_heat->result[index] += noise_heat_blend->result[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]; 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++) { for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) {
// The parameters that we actually need to generate terrain // The parameters that we actually need to generate terrain
// are passed by address (and the return value). // 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 // River noise is replaced with base terrain, which
// is basically the height of the water table. // 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 // Valley depth noise is replaced with the valley
// number that represents the height of terrain // number that represents the height of terrain
// over rivers and is used to determine about // over rivers and is used to determine about
// how close a river is for humidity calculation. // how close a river is for humidity calculation.
tn.valley = &noise_valley_depth->result[index]; tn.valley = &noise_valley_depth->result[index];
tn.valley_profile = noise_valley_profile->result[index]; tn.valley_profile = noise_valley_profile->result[index];
// Slope noise is replaced by the calculated slope // Slope noise is replaced by the calculated slope
// which is used to get terrain height in the slow // which is used to get terrain height in the slow
// method, to create sharper mountains. // 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.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. // This is the actual terrain height.
float mount = terrainLevelFromNoise(&tn); float mount = terrainLevelFromNoise(&tn);
noise_terrain_height->result[index] = mount; 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; humidmap = noise_humidity->result;
} }
@ -489,11 +441,9 @@ void MapgenValleys::calculateNoise()
// complicated code to determine ground level. // complicated code to determine ground level.
float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn)
{ {
float inter_valley_slope = *tn->slope;
// The square function changes the behaviour of this noise: // The square function changes the behaviour of this noise:
// very often small, and sometimes very high. // 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 // valley_d is here because terrain is generally higher where valleys
// are deep (mountains). base represents the height of the // 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; float base = tn->terrain_height + valley_d;
// "river" represents the distance from the river, in arbitrary units. // "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 1exp((x/a)²) to model 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. // Making "a" vary (0 < a <= 1) changes the shape of the valleys.
// Try it with a geometry software ! // Try it with a geometry software !
// (here x = "river" and a = valley_profile). // (here x = "river" and a = valley_profile).
// "valley" represents the height of the terrain, from the rivers. // "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 // approximate height of the terrain at this point
float mount = base + *tn->valley; 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. // Base ground is returned as rivers since it's basically the water table.
*tn->rivers = base; *tn->rivers = base;
if (river < 0.f) { if (river < 0.f) {
// Use the the function sqrt(1x²) which models a circle. // Use the the function -sqrt(1-x^2) which models a circle.
float depth = (river_depth * sqrt(1.f - pow((river / river_size + 1), 2))); 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 // base - depth : height of the bottom of the river
// water_level - 2 : don't make rivers below 2 nodes under the surface // water_level - 6 : don't make rivers below 6 nodes under the surface
u16 min_bottom = 2; mount = rangelim(base - depth, (float) (water_level - 6), mount);
if (!fast_terrain)
min_bottom = 6;
mount = fmin(fmax(base - depth, (float) (water_level - min_bottom)), mount);
// Slope has no influence on rivers. // Slope has no influence on rivers.
*tn->slope = 0.f; *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; return mount;
} }
@ -559,15 +497,14 @@ float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn)
float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn) float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn)
{ {
float mount = terrainLevelFromNoise(tn); float mount = terrainLevelFromNoise(tn);
s16 y_start = myround(mount);
if (!fast_terrain) { for (s16 y = y_start; y <= y_start + 1000; y++) {
for (s16 y = round(mount); y <= round(mount) + 1000; y++) { float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed);
float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed);
if (fill * *tn->slope <= y - mount) { if (fill * *tn->slope <= y - mount) {
mount = fmax(y - 1, mount); mount = MYMAX(y - 1, mount);
break; 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) int MapgenValleys::getGroundLevelAtPoint(v2s16 p)
{ {
// *********************************************** // ***********************************
// This method (deliberately) does not return correct // This method (deliberately) does not
// terrain values. This may be a problem in the future. // return correct terrain values.
// *********************************************** // ***********************************
// Since MT doesn't normally deal with rivers, check // Since MT doesn't normally deal with rivers, check
// to make sure this isn't a request for a location // 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); float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed);
// If it's wet, return an unusable number. // If it's wet, return an unusable number.
if (fabs(rivers) < river_size) if (fabs(rivers) < river_size_factor)
return MAX_MAP_GENERATION_LIMIT; return MAX_MAP_GENERATION_LIMIT;
// Otherwise, return the real result. // 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 valley = NoisePerlin2D(&noise_valley_depth->np, x, z, seed);
float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed); float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed);
tn.x = x; tn.x = x;
tn.z = z; tn.z = z;
tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed); tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed);
tn.rivers = &rivers; tn.rivers = &rivers;
tn.valley = &valley; tn.valley = &valley;
tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed); tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed);
tn.slope = &inter_valley_slope; tn.slope = &inter_valley_slope;
tn.inter_valley_fill = 0.f; 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); return adjustedTerrainLevelFromNoise(&tn);
} }
@ -679,17 +577,13 @@ int MapgenValleys::generateTerrain()
if (surface_y > surface_max_y) if (surface_y > surface_max_y)
surface_max_y = surface_y; surface_max_y = surface_y;
u32 index_3d = 0; u32 index_3d = (z - node_min.Z) * zstride + (x - node_min.X);
if (!fast_terrain)
index_3d = (z - node_min.Z) * zstride + (x - node_min.X);
u32 index_data = vm->m_area.index(x, node_min.Y - 1, z); u32 index_data = vm->m_area.index(x, node_min.Y - 1, z);
// Mapgens concern themselves with stone and water. // Mapgens concern themselves with stone and water.
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
float fill = 0.f; 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) { if (vm->m_data[index_data].getContent() == CONTENT_IGNORE) {
bool river = (river_y > surface_y); bool river = (river_y > surface_y);
@ -697,14 +591,14 @@ int MapgenValleys::generateTerrain()
if (river && y == surface_y) { if (river && y == surface_y) {
// river bottom // river bottom
vm->m_data[index_data] = n_sand; vm->m_data[index_data] = n_sand;
} else if ((fast_terrain || river) && y <= surface_y) { } else if (river && y <= surface_y) {
// ground // ground
vm->m_data[index_data] = n_stone; vm->m_data[index_data] = n_stone;
} else if (river && y < river_y) { } else if (river && y < river_y) {
// river // river
vm->m_data[index_data] = n_river_water; vm->m_data[index_data] = n_river_water;
} else if ((!fast_terrain) && (!river) && round(fill * slope) >= y - surface_y) { } else if ((!river) && myround(fill * slope) >= y - surface_y) {
// ground (slow method) // ground
vm->m_data[index_data] = n_stone; vm->m_data[index_data] = n_stone;
heightmap[index_2d] = surface_max_y = y; heightmap[index_2d] = surface_max_y = y;
} else if (y <= water_level) { } else if (y <= water_level) {
@ -716,23 +610,21 @@ int MapgenValleys::generateTerrain()
} }
vm->m_area.add_y(em, index_data, 1); vm->m_area.add_y(em, index_data, 1);
if (!fast_terrain) index_3d += ystride;
index_3d += ystride;
} }
if (!fast_terrain) { // Although the original valleys adjusts humidity by distance
// Assign the humidity adjusted by water proximity. // from seawater, this causes problems with the default biomes.
noise_humidity->result[index_2d] = humidityByTerrain( // Adjust only by freshwater proximity.
noise_humidity->result[index_2d], const float humidity_offset = 0.8f; // derived by testing
surface_max_y, if (humid_rivers)
noise_rivers->result[index_2d], noise_humidity->result[index_2d] *= (1 + pow(0.5f, MYMAX((surface_max_y
noise_valley_depth->result[index_2d]); - noise_rivers->result[index_2d]) / 3.f, 0.f))) * humidity_offset;
// Assign the heat adjusted by altitude. See humidity, above. // Assign the heat adjusted by altitude.
if (use_altitude_chill && surface_max_y > 0) if (use_altitude_chill && surface_max_y > 0)
noise_heat->result[index_2d] noise_heat->result[index_2d] *=
*= pow(0.5f, (surface_max_y - altitude_chill / 3.f) / altitude_chill); pow(0.5f, (surface_max_y - altitude_chill / 3.f) / altitude_chill);
}
} }
return surface_max_y; 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); PseudoRandom ps(blockseed + 72202);
MapNode n_air(CONTENT_AIR); MapNode n_air(CONTENT_AIR);
MapNode n_dirt(c_dirt);
MapNode n_lava(c_lava_source); MapNode n_lava(c_lava_source);
MapNode n_water(c_river_water_source); MapNode n_water(c_river_water_source);
v3s16 em = vm->m_area.getExtent(); v3s16 em = vm->m_area.getExtent();
s16 base_water_chance = 0; // Cave blend distance near YMIN, YMAX
if (water_features < 11) const float massive_cave_blend = 128.f;
base_water_chance = ceil(MAX_MAP_GENERATION_LIMIT / (water_features * 1000)); // 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) { float yblmin = -map_gen_limit + massive_cave_blend * 1.5f;
u32 index_2d = 0; float yblmax = massive_cave_depth - massive_cave_blend * 1.5f;
u32 index_3d = 0; bool made_a_big_one = false;
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);
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_min.Y - 1; y <= node_max.Y + 1; y++) {
for (s16 y = node_max.Y + 1; float tcave = massive_cave_threshold;
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 and prevents removing above ground nodes. if (y < yblmin) {
if (y > terrain + 1) { float t = (yblmin - y) / massive_cave_blend;
air_above = true; tcave += MYSQUARE(t);
continue; } else if (y > yblmax) {
} float t = (y - yblmax) / massive_cave_blend;
tcave += MYSQUARE(t);
}
content_t c = vm->m_data[index_data].getContent(); tcave_cache[y - node_min.Y + 1] = tcave;
bool n1 = (fabs(noise_simple_caves_1->result[index_3d]) < 0.07f); }
bool n2 = (fabs(noise_simple_caves_2->result[index_3d]) < 0.07f); }
// River water is (foolishly) not set as ground content // lava_depth varies between one and ten as you approach
// in the default game. This can produce strange results // the bottom of the world.
// when a cave undercuts a river. However, that's not for s16 lava_depth = ceil((lava_max_height - node_min.Y + 1) * 10.f / map_gen_limit);
// the mapgen to correct. Fix it in lua. // 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) { // Reduce the odds of overflows even further.
air_above = true; if (node_max.Y > water_level) {
} else if (n1 && n2 && ndef->get(c).is_ground_content) { lava_chance /= 5;
// When both n's are true, we're in a cave. water_chance /= 5;
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);
if (sr > (terrain - y) * 25) { u32 index_2d = 0;
// Put dirt in caves near the surface. u32 index_3d = 0;
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]); 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); vm->m_data[index_data] = MapNode(biome->c_filler);
} else { else
s16 lava_chance = 0; 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) { sr -= lava_chance;
// Lava spawns increase with depth.
lava_chance = ceil((lava_max_height - y + 1) / 10000);
if (sr < lava_chance) // If sr < 0 then we should have already placed lava --
vm->m_data[j] = n_lava; // don't immediately dump water on it.
} if (water_features_lim > 0 && y <= cave_water_max_height
&& sr >= 0 && sr < water_chance)
if (base_water_chance > 0 && y <= cave_water_max_height) { vm->m_data[j] = n_water;
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 we're not in a cave, there's no open space. air_above = false;
if (!(n1 && n2)) underground = true;
air_above = false; } 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);
}
}
} }

View File

@ -31,11 +31,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen.h" #include "mapgen.h"
/////////////////// Mapgen Valleys flags /////////////////// Mapgen Valleys flags
#define MG_VALLEYS_ALT_CHILL 0x01 #define MG_VALLEYS_ALT_CHILL 0x01
#define MG_VALLEYS_CLIFFS 0x02 #define MG_VALLEYS_HUMID_RIVERS 0x02
#define MG_VALLEYS_FAST 0x04
#define MG_VALLEYS_HUMID_RIVERS 0x08 // Feed only one variable into these.
#define MG_VALLEYS_RUGGED 0x10 #define MYSQUARE(x) (x) * (x)
#define MYCUBE(x) (x) * (x) * (x)
class BiomeManager; class BiomeManager;
@ -47,28 +48,25 @@ class BiomeManager;
struct MapgenValleysParams : public MapgenSpecificParams { struct MapgenValleysParams : public MapgenSpecificParams {
u32 spflags; u32 spflags;
s16 large_cave_depth;
s16 massive_cave_depth;
u16 altitude_chill; u16 altitude_chill;
s16 cave_water_max_height; u16 lava_features;
s16 humidity;
s16 humidity_break_point;
s16 lava_max_height;
u16 river_depth; u16 river_depth;
u16 river_size; u16 river_size;
s16 temperature;
u16 water_features; u16 water_features;
NoiseParams np_biome_heat; NoiseParams np_biome_heat;
NoiseParams np_biome_heat_blend; NoiseParams np_biome_heat_blend;
NoiseParams np_biome_humidity; NoiseParams np_biome_humidity;
NoiseParams np_biome_humidity_blend; NoiseParams np_biome_humidity_blend;
NoiseParams np_cliffs; NoiseParams np_cave1;
NoiseParams np_corr; NoiseParams np_cave2;
NoiseParams np_filler_depth; NoiseParams np_filler_depth;
NoiseParams np_inter_valley_fill; NoiseParams np_inter_valley_fill;
NoiseParams np_inter_valley_slope; NoiseParams np_inter_valley_slope;
NoiseParams np_rivers; NoiseParams np_rivers;
NoiseParams np_simple_caves_1; NoiseParams np_massive_caves;
NoiseParams np_simple_caves_2;
NoiseParams np_terrain_height; NoiseParams np_terrain_height;
NoiseParams np_valley_depth; NoiseParams np_valley_depth;
NoiseParams np_valley_profile; NoiseParams np_valley_profile;
@ -89,8 +87,6 @@ struct TerrainNoise {
float valley_profile; float valley_profile;
float *slope; float *slope;
float inter_valley_fill; float inter_valley_fill;
float cliffs;
float corr;
}; };
class MapgenValleys : public Mapgen { class MapgenValleys : public Mapgen {
@ -102,6 +98,8 @@ public:
virtual void makeChunk(BlockMakeData *data); virtual void makeChunk(BlockMakeData *data);
int getGroundLevelAtPoint(v2s16 p); int getGroundLevelAtPoint(v2s16 p);
s16 large_cave_depth;
private: private:
EmergeManager *m_emerge; EmergeManager *m_emerge;
BiomeManager *bmgr; BiomeManager *bmgr;
@ -109,10 +107,9 @@ private:
int ystride; int ystride;
int zstride; int zstride;
float map_gen_limit;
u32 spflags; u32 spflags;
bool cliff_terrain;
bool fast_terrain;
bool rugged_terrain;
bool humid_rivers; bool humid_rivers;
bool use_altitude_chill; bool use_altitude_chill;
@ -123,8 +120,8 @@ private:
Noise *noise_filler_depth; Noise *noise_filler_depth;
Noise *noise_cliffs; Noise *noise_cave1;
Noise *noise_corr; Noise *noise_cave2;
Noise *noise_heat; Noise *noise_heat;
Noise *noise_heat_blend; Noise *noise_heat_blend;
Noise *noise_humidity; Noise *noise_humidity;
@ -132,21 +129,21 @@ private:
Noise *noise_inter_valley_fill; Noise *noise_inter_valley_fill;
Noise *noise_inter_valley_slope; Noise *noise_inter_valley_slope;
Noise *noise_rivers; Noise *noise_rivers;
Noise *noise_simple_caves_1; Noise *noise_massive_caves;
Noise *noise_simple_caves_2;
Noise *noise_terrain_height; Noise *noise_terrain_height;
Noise *noise_valley_depth; Noise *noise_valley_depth;
Noise *noise_valley_profile; Noise *noise_valley_profile;
float altitude_chill; float altitude_chill;
float cave_water_max_height; s16 cave_water_max_height;
float humidity_adjust; float humidity_adjust;
float humidity_break_point; s16 lava_features_lim;
float lava_max_height; s16 lava_max_height;
float river_depth; s16 massive_cave_depth;
float river_size; float river_depth_bed;
float temperature_adjust; float river_size_factor;
s16 water_features; float *tcave_cache;
s16 water_features_lim;
content_t c_cobble; content_t c_cobble;
content_t c_desert_stone; content_t c_desert_stone;
@ -176,7 +173,7 @@ private:
MgStoneType generateBiomes(float *heat_map, float *humidity_map); MgStoneType generateBiomes(float *heat_map, float *humidity_map);
void dustTopNodes(); void dustTopNodes();
void generateSimpleCaves(s16 max_stone_y); void generateCaves(s16 max_stone_y);
}; };
struct MapgenFactoryValleys : public MapgenFactory { struct MapgenFactoryValleys : public MapgenFactory {