From 8ec3fc35c656544a55f7f8ece9359c9e2b472e8f Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 6 Apr 2013 11:19:59 -0400 Subject: [PATCH] Add Mapgen V7, reorganize biomes --- .gitignore | 1 + games/minimal/mods/default/init.lua | 93 ------ src/CMakeLists.txt | 1 + src/biome.cpp | 267 ++++++--------- src/biome.h | 77 ++--- src/defaultsettings.cpp | 11 +- src/emerge.cpp | 14 +- src/emerge.h | 23 +- src/mapgen.cpp | 26 ++ src/mapgen_v7.cpp | 488 ++++++++++++++++++++++++++++ src/mapgen_v7.h | 125 +++++++ src/noise.cpp | 36 ++ src/noise.h | 2 + src/scriptapi.cpp | 74 +---- src/server.cpp | 9 +- src/server.h | 8 +- 16 files changed, 871 insertions(+), 384 deletions(-) create mode 100644 src/mapgen_v7.cpp create mode 100644 src/mapgen_v7.h diff --git a/.gitignore b/.gitignore index 21e2371a8..50d7c43e0 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ src/jthread/Makefile src/jthread/cmake_config.h src/jthread/cmake_install.cmake src/jthread/libjthread.a +src/json/libjson.a src/lua/build/ src/lua/CMakeFiles/ src/cguittfont/CMakeFiles/ diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua index 163998883..d8067d211 100644 --- a/games/minimal/mods/default/init.lua +++ b/games/minimal/mods/default/init.lua @@ -1588,99 +1588,6 @@ minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal") minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron") minetest.register_alias("mapgen_mese", "default:mese") -minetest.register_biome_groups({ -0.35, 0.10, 0.30 -}) - --- --- Register the biomes for the map generator --- -minetest.register_biome({ - group_id = 0, - name = "Ocean", - terrain_type = "liquid", - node_top = "default:gravel", - node_filler = "default:stone", - num_top_nodes = 4, - height_min = -3000, - height_max = 3000, - heat_min = -20.0, - heat_max = 100.0, - humidity_min = 0.0, - humidity_max = 100.0, - scale = 10.0, - offset = -10.0, -}) - -minetest.register_biome({ - group_id = 1, - name = "Beach", - terrain_type = "normal", - node_top = "default:sand", - node_filler = "default:stone", - num_top_nodes = 5, - height_min = -3000, - height_max = 3000, - heat_min = 5.0, - heat_max = 100.0, - humidity_min = 0.0, - humidity_max = 100.0, - scale = 5.0, - offset = 5.0, -}) - -minetest.register_biome({ - group_id = 1, - name = "Gravel Beach", - terrain_type = "normal", - node_top = "default:gravel", - node_filler = "default:cobble", - num_top_nodes = 5, - height_min = -3000, - height_max = 3000, - heat_min = -50.0, - heat_max = 5.0, - humidity_min = 0.0, - humidity_max = 100.0, - scale = 5.0, - offset = 5.0, -}) - -minetest.register_biome({ - group_id = 2, - name = "Land", - terrain_type = "normal", - node_top = "default:dirt_with_grass", - node_filler = "default:stone", - num_top_nodes = 5, - height_min = -3000, - height_max = 3000, - heat_min = -50.0, - heat_max = 100.0, - humidity_min = 0.0, - humidity_max = 100.0, - scale = 12.0, - offset = 20.0, -}) - -minetest.register_biome({ - group_id = 3, - name = "Hills", - terrain_type = "normal", - node_top = "default:dirt", - node_filler = "default:stone", - num_top_nodes = 3, - height_min = -3000, - height_max = 3000, - heat_min = -50.0, - heat_max = 100.0, - humidity_min = 0.0, - humidity_max = 100.0, - scale = 60.0, - offset = 20.0, -}) - - -- Support old code function default.spawn_falling_node(p, nodename) spawn_falling_node(p, nodename) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b951a8261..f2d7439a0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -227,6 +227,7 @@ set(common_SRCS emerge.cpp mapgen.cpp mapgen_v6.cpp + mapgen_v7.cpp mapgen_indev.cpp mapgen_singlenode.cpp treegen.cpp diff --git a/src/biome.cpp b/src/biome.cpp index 86af75310..b50c562a0 100644 --- a/src/biome.cpp +++ b/src/biome.cpp @@ -1,6 +1,6 @@ /* Minetest -Copyright (C) 2010-2013 kwolekr, Ryan Kwolek +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -23,68 +23,50 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "main.h" -#define BT_NONE 0 -#define BT_OCEAN 1 -#define BT_LAKE 2 -#define BT_SBEACH 3 -#define BT_GBEACH 4 -#define BT_PLAINS 5 -#define BT_HILLS 6 -#define BT_EXTREMEHILLS 7 -#define BT_MOUNTAINS 8 -#define BT_DESERT 9 -#define BT_DESERTHILLS 10 -#define BT_HELL 11 -#define BT_AETHER 12 -#define BT_BTMASK 0x3F - -#define BTF_SNOW 0x40 -#define BTF_FOREST 0x80 - -#define BGFREQ_1 ( 0.40) -#define BGFREQ_2 (BGFREQ_1 + 0.05) -#define BGFREQ_3 (BGFREQ_2 + 0.08) -#define BGFREQ_4 (BGFREQ_3 + 0.35) -#define BGFREQ_5 (BGFREQ_4 + 0.18) -//BGFREQ_5 is not checked as an upper bound; it ought to sum up to 1.00, but it's okay if it doesn't. +NoiseParams nparams_biome_def_heat = + {50, 50, v3f(500.0, 500.0, 500.0), 5349, 3, 0.70}; +NoiseParams nparams_biome_def_humidity = + {50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55}; -/*float bg1_temps[] = {0.0}; -int bg1_biomes[] = {BT_OCEAN}; +BiomeDefManager::BiomeDefManager() { + biome_registration_finished = false; + np_heat = &nparams_biome_def_heat; + np_humidity = &nparams_biome_def_humidity; -float bg2_temps[] = {10.0}; -int bg2_biomes[] = {BT_GBEACH, BT_SBEACH}; + // Create default biome to be used in case none exist + Biome *b = new Biome; + + b->id = 0; + b->name = "Default"; + b->flags = 0; -float bg3_temps[] = {30.0, 40.0}; -int bg3_biomes[] = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS}; + b->c_top = CONTENT_AIR; + b->top_depth = 0; + b->c_filler = b->c_top; + b->filler_height = MAP_GENERATION_LIMIT; -float bg4_temps[] = {25.0, 30.0, 35.0, 40.0}; -int bg4_biomes[] = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS, BT_DESERT, BT_DESERTHILLS}; + b->height_min = -MAP_GENERATION_LIMIT; + b->height_max = MAP_GENERATION_LIMIT; + b->heat_point = 0.0; + b->humidity_point = 0.0; -float bg5_temps[] = {5.0, 40.0}; -int bg5_biomes[] = {BT_LAKE, BT_PLAINS, BT_DESERT};*/ - -NoiseParams np_default = {20.0, 15.0, v3f(250., 250., 250.), 82341, 5, 0.6}; - - -BiomeDefManager::BiomeDefManager(IGameDef *gamedef) { - this->m_gamedef = gamedef; - this->ndef = gamedef->ndef(); - - //the initial biome group - bgroups.push_back(new std::vector); + biomes.push_back(b); } BiomeDefManager::~BiomeDefManager() { - for (unsigned int i = 0; i != bgroups.size(); i++) - delete bgroups[i]; + //if (biomecache) + // delete[] biomecache; + + for (size_t i = 0; i != biomes.size(); i++) + delete biomes[i]; } Biome *BiomeDefManager::createBiome(BiomeTerrainType btt) { - switch (btt) { + /*switch (btt) { case BIOME_TERRAIN_NORMAL: return new Biome; case BIOME_TERRAIN_LIQUID: @@ -92,142 +74,97 @@ Biome *BiomeDefManager::createBiome(BiomeTerrainType btt) { case BIOME_TERRAIN_NETHER: return new BiomeHell; case BIOME_TERRAIN_AETHER: - return new BiomeAether; + return new BiomeSky; case BIOME_TERRAIN_FLAT: return new BiomeSuperflat; } - return NULL; + return NULL;*/ + return new Biome; } -void BiomeDefManager::addBiomeGroup(float freq) { - int size = bgroup_freqs.size(); - float newfreq = freq; +// just a PoC, obviously needs optimization later on (precalculate this) +void BiomeDefManager::calcBiomes(BiomeNoiseInput *input, u8 *biomeid_map) { + int i = 0; + for (int y = 0; y != input->mapsize.Y; y++) { + for (int x = 0; x != input->mapsize.X; x++, i++) { + float heat = (input->heat_map[i] + 1) * 50; + float humidity = (input->humidity_map[i] + 1) * 50; + biomeid_map[i] = getBiome(heat, humidity, input->height_map[i])->id; + } + } +} - if (size) - newfreq += bgroup_freqs[size - 1]; - bgroup_freqs.push_back(newfreq); - bgroups.push_back(new std::vector); - verbosestream << "BiomeDefManager: added biome group with frequency " << - newfreq << std::endl; +void BiomeDefManager::resolveNodeNames(INodeDefManager *ndef) { + Biome *b; + + biome_registration_finished = true; + + for (size_t i = 0; i != biomes.size(); i++) { + b = biomes[i]; + + if (b->c_top == CONTENT_IGNORE) { + b->c_top = ndef->getId(b->top_nodename); + if (b->c_top == CONTENT_IGNORE) { + errorstream << "BiomeDefManager::resolveNodeNames: node '" + << b->top_nodename << "' not defined" << std::endl; + b->c_top = CONTENT_AIR; + b->top_depth = 0; + } + } + + if (b->c_filler == CONTENT_IGNORE) { + b->c_filler = ndef->getId(b->filler_nodename); + if (b->c_filler == CONTENT_IGNORE) { + errorstream << "BiomeDefManager::resolveNodeNames: node '" + << b->filler_nodename << "' not defined" << std::endl; + b->c_filler = CONTENT_AIR; + b->filler_height = MAP_GENERATION_LIMIT; + } + } + } } void BiomeDefManager::addBiome(Biome *b) { - std::vector *bgroup; - - if ((unsigned int)b->groupid >= bgroups.size()) { - errorstream << "BiomeDefManager: attempted to add biome '" << b->name - << "' to nonexistent biome group " << b->groupid << std::endl; + if (biome_registration_finished) { + errorstream << "BIomeDefManager: biome registration already finished, dropping " << b->name <= 0xFF) { + errorstream << "BiomeDefManager: too many biomes, dropping " << b->name << std::endl; + delete b; return; } - bgroup = bgroups[b->groupid]; - bgroup->push_back(b); - - verbosestream << "BiomeDefManager: added biome '" << b->name << - "' to biome group " << (int)b->groupid << std::endl; + b->id = (u8)nbiomes; + biomes.push_back(b); + verbosestream << "BiomeDefManager: added biome " << b->name << std::endl; } -void BiomeDefManager::addDefaultBiomes() { - Biome *b; +Biome *BiomeDefManager::getBiome(float heat, float humidity, s16 y) { + Biome *b, *biome_closest = NULL; + float dist_min = FLT_MAX; - b = new Biome; - b->name = "Default"; - b->n_top = MapNode(ndef->getId("mapgen_stone")); - b->n_filler = b->n_top; - b->ntopnodes = 0; - b->height_min = -MAP_GENERATION_LIMIT; - b->height_max = MAP_GENERATION_LIMIT; - b->heat_min = FLT_MIN; - b->heat_max = FLT_MAX; - b->humidity_min = FLT_MIN; - b->humidity_max = FLT_MAX; - b->np = &np_default; - biome_default = b; -} + for (size_t i = 1; i < biomes.size(); i++) { + b = biomes[i]; + if (y > b->height_max || y < b->height_min) + continue; - -Biome *BiomeDefManager::getBiome(float bgfreq, float heat, float humidity) { - std::vector *bgroup; - Biome *b; - int i; - - int ngroups = bgroup_freqs.size(); - if (!ngroups) - return biome_default; - for (i = 0; (i != ngroups) && (bgfreq > bgroup_freqs[i]); i++); - bgroup = bgroups[i]; - - int nbiomes = bgroup->size(); - for (i = 0; i != nbiomes; i++) { - b = bgroup->operator[](i); - if (heat >= b->heat_min && heat <= b->heat_max && - humidity >= b->humidity_min && humidity <= b->humidity_max) - return b; + float d_heat = heat - b->heat_point; + float d_humidity = humidity - b->humidity_point; + float dist = (d_heat * d_heat) + + (d_humidity * d_humidity); + if (dist < dist_min) { + dist_min = dist; + biome_closest = b; + } } - - return biome_default; -} - - -//////////////////////////// [ Generic biome ] //////////////////////////////// - - -int Biome::getSurfaceHeight(float noise_terrain) { - return np->offset + np->scale * noise_terrain; -} - - -void Biome::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) { - -} - - -///////////////////////////// [ Ocean biome ] ///////////////////////////////// - - -void BiomeLiquid::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) { - -} - - -///////////////////////////// [ Nether biome ] ///////////////////////////////// - - -int BiomeHell::getSurfaceHeight(float noise_terrain) { - return np->offset + np->scale * noise_terrain; -} - - -void BiomeHell::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) { - -} - - -///////////////////////////// [ Aether biome ] //////////////////////////////// - - -int BiomeAether::getSurfaceHeight(float noise_terrain) { - return np->offset + np->scale * noise_terrain; -} - - -void BiomeAether::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) { - -} - - -/////////////////////////// [ Superflat biome ] /////////////////////////////// - - -int BiomeSuperflat::getSurfaceHeight(float noise_terrain) { - return ntopnodes; -} - - -void BiomeSuperflat::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) { - + + return biome_closest ? biome_closest : biomes[0]; } diff --git a/src/biome.h b/src/biome.h index c30af46ad..17703db5a 100644 --- a/src/biome.h +++ b/src/biome.h @@ -1,6 +1,6 @@ /* Minetest -Copyright (C) 2010-2013 kwolekr, Ryan Kwolek +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "noise.h" #include "mapgen.h" - enum BiomeTerrainType { BIOME_TERRAIN_NORMAL, @@ -37,62 +36,54 @@ enum BiomeTerrainType BIOME_TERRAIN_FLAT }; +extern NoiseParams nparams_biome_def_heat; +extern NoiseParams nparams_biome_def_humidity; + class Biome { public: - MapNode n_top; - MapNode n_filler; - s16 ntopnodes; - s8 groupid; - s8 flags; + u8 id; + std::string name; + u32 flags; + + std::string top_nodename; + std::string filler_nodename; + + content_t c_top; + s16 top_depth; + + content_t c_filler; + s16 filler_height; + s16 height_min; s16 height_max; - float heat_min; - float heat_max; - float humidity_min; - float humidity_max; - std::string name; - NoiseParams *np; - - virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2); - virtual int getSurfaceHeight(float noise_terrain); + float heat_point; + float humidity_point; }; -class BiomeLiquid : public Biome { - virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2); -}; - -class BiomeHell : public Biome { - virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2); - virtual int getSurfaceHeight(float noise_terrain); -}; - -class BiomeAether : public Biome { - virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2); - virtual int getSurfaceHeight(float noise_terrain); -}; - -class BiomeSuperflat : public Biome { - virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2); - virtual int getSurfaceHeight(float noise_terrain); +struct BiomeNoiseInput { + v2s16 mapsize; + float *heat_map; + float *humidity_map; + s16 *height_map; }; class BiomeDefManager { public: - std::vector bgroup_freqs; - std::vector *> bgroups; - Biome *biome_default; - IGameDef *m_gamedef; - INodeDefManager *ndef; + std::vector biomes; - BiomeDefManager(IGameDef *gamedef); + bool biome_registration_finished; + NoiseParams *np_heat; + NoiseParams *np_humidity; + + BiomeDefManager(); ~BiomeDefManager(); - + Biome *createBiome(BiomeTerrainType btt); - Biome *getBiome(float bgfreq, float heat, float humidity); + void calcBiomes(BiomeNoiseInput *input, u8 *biomeid_map); + Biome *getBiome(float heat, float humidity, s16 y); - void addBiomeGroup(float freq); void addBiome(Biome *b); - void addDefaultBiomes(); + void resolveNodeNames(INodeDefManager *ndef); }; #endif diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 592c6bcca..9875c6ecb 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -231,10 +231,12 @@ void set_default_settings(Settings *settings) settings->setDefault("mgv6_np_trees", "0, 1, (125, 125, 125), 2, 4, 0.66"); settings->setDefault("mgv6_np_apple_trees", "0, 1, (100, 100, 100), 342902, 3, 0.45"); - settings->setDefault("mgv7_np_terrain", "10, 12, (350, 350, 350), 82341, 5, 0.6"); - settings->setDefault("mgv7_np_bgroup", "0.5, 0.3125, (350, 350, 350), 5923, 2, 0.6"); - settings->setDefault("mgv7_np_heat", "25, 50, (500, 500, 500), 35293, 1, 0"); - settings->setDefault("mgv7_np_humidity", "50, 31.25, (750, 750, 750), 12094, 2, 0.6"); + settings->setDefault("mgv7_np_terrain_base", "0, 80, (250, 250, 250), 82341, 5, 0.6"); + settings->setDefault("mgv7_np_terrain_alt", "0, 20, (250, 250, 250), 5934, 5, 0.6"); + settings->setDefault("mgv7_np_terrain_mod", "0, 1, (350, 350, 350), 85039, 5, 0.6"); + settings->setDefault("mgv7_np_terrain_persist", "0, 1, (500, 500, 500), 539, 3, 0.6"); + settings->setDefault("mgv7_np_height_select", "0.5, 0.5, (250, 250, 250), 4213, 5, 0.69"); + settings->setDefault("mgv7_np_ridge", "0.5, 1, (100, 100, 100), 6467, 4, 0.75"); settings->setDefault("mgindev_np_terrain_base", "-4, 20, (250, 250, 250), 82341, 5, 0.6, 10, 10"); settings->setDefault("mgindev_np_terrain_higher", "20, 16, (500, 500, 500), 85039, 5, 0.6, 10, 10"); @@ -245,7 +247,6 @@ void set_default_settings(Settings *settings) settings->setDefault("mgindev_np_float_islands3", "0, 1, (256, 256, 256), 6412, 2, 0.5, 1, 0.5"); settings->setDefault("mgindev_np_biome", "0, 1, (250, 250, 250), 9130, 3, 0.50, 1, 10"); settings->setDefault("mgindev_float_islands", "500"); - } void override_default_settings(Settings *settings, Settings *from) diff --git a/src/emerge.cpp b/src/emerge.cpp index e4bd997cb..2a5e84f67 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -1,6 +1,7 @@ /* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -39,19 +40,22 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "biome.h" #include "emerge.h" #include "mapgen_v6.h" +#include "mapgen_v7.h" #include "mapgen_indev.h" #include "mapgen_singlenode.h" /////////////////////////////// Emerge Manager //////////////////////////////// -EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { +EmergeManager::EmergeManager(IGameDef *gamedef) { //register built-in mapgens registerMapgen("v6", new MapgenFactoryV6()); + //registerMapgen("v7", new MapgenFactoryV7()); registerMapgen("indev", new MapgenFactoryIndev()); registerMapgen("singlenode", new MapgenFactorySinglenode()); - this->biomedef = bdef ? bdef : new BiomeDefManager(gamedef); + this->ndef = gamedef->getNodeDefManager(); + this->biomedef = new BiomeDefManager(); this->params = NULL; mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); @@ -104,6 +108,8 @@ void EmergeManager::initMapgens(MapgenParams *mgparams) { if (mapgen.size()) return; + biomedef->resolveNodeNames(ndef); + this->params = mgparams; for (unsigned int i = 0; i != emergethread.size(); i++) { mg = createMapgen(params->mg_name, 0, params); diff --git a/src/emerge.h b/src/emerge.h index 3d717bce3..fdca93c06 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -1,3 +1,22 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + #ifndef EMERGE_HEADER #define EMERGE_HEADER @@ -46,6 +65,8 @@ struct BlockEmergeData { class EmergeManager { public: + INodeDefManager *ndef; + std::map mglist; std::vector mapgen; @@ -67,7 +88,7 @@ public: BiomeDefManager *biomedef; std::vector ores; - EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef); + EmergeManager(IGameDef *gamedef); ~EmergeManager(); void initMapgens(MapgenParams *mgparams); diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 64c1886b3..b7711b01c 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" // For g_profiler #include "treegen.h" #include "mapgen_v6.h" +#include "mapgen_v7.h" FlagDesc flagdesc_mapgen[] = { {"trees", MG_TREES}, @@ -409,6 +410,31 @@ void MapgenV6Params::writeParams(Settings *settings) { } +bool MapgenV7Params::readParams(Settings *settings) { + np_terrain_base = settings->getNoiseParams("mgv7_np_terrain_base"); + np_terrain_alt = settings->getNoiseParams("mgv7_np_terrain_alt"); + np_terrain_mod = settings->getNoiseParams("mgv7_np_terrain_mod"); + np_terrain_persist = settings->getNoiseParams("mgv7_np_terrain_persist"); + np_height_select = settings->getNoiseParams("mgv7_np_height_select"); + np_ridge = settings->getNoiseParams("mgv7_np_ridge"); + + bool success = + np_terrain_base && np_terrain_alt && np_terrain_mod && + np_terrain_persist && np_height_select && np_ridge; + return success; +} + + +void MapgenV7Params::writeParams(Settings *settings) { + settings->setNoiseParams("mgv7_np_terrain_base", np_terrain_base); + settings->setNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); + settings->setNoiseParams("mgv7_np_terrain_mod", np_terrain_mod); + settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist); + settings->setNoiseParams("mgv7_np_height_select", np_height_select); + settings->setNoiseParams("mgv7_np_ridge", np_ridge); +} + + /////////////////////////////////// legacy static functions for farmesh diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp new file mode 100644 index 000000000..af453c2ec --- /dev/null +++ b/src/mapgen_v7.cpp @@ -0,0 +1,488 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +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" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +//#include "serverobject.h" +#include "content_sao.h" +#include "nodedef.h" +#include "content_mapnode.h" // For content_mapnode_get_new_name +#include "voxelalgorithms.h" +#include "profiler.h" +#include "settings.h" // For g_settings +#include "main.h" // For g_profiler +#include "emerge.h" +#include "dungeongen.h" +#include "treegen.h" +#include "biome.h" +#include "mapgen_v7.h" + + +/////////////////// Mapgen V7 perlin noise default values +NoiseParams nparams_v7_def_terrain_base = + {0, 80.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6}; +NoiseParams nparams_v7_def_terrain_alt = + {0, 20.0, v3f(250.0, 250.0, 250.0), 5934, 5, 0.6}; +NoiseParams nparams_v7_def_terrain_mod = + {0, 1.0, v3f(350.0, 350.0, 350.0), 85039, 5, 0.6}; +NoiseParams nparams_v7_def_terrain_persist = + {0, 1.0, v3f(500.0, 500.0, 500.0), 539, 3, 0.6}; +NoiseParams nparams_v7_def_height_select = + {0.5, 0.5, v3f(250.0, 250.0, 250.0), 4213, 5, 0.69}; +NoiseParams nparams_v7_def_ridge = + {0.5, 1.0, v3f(100.0, 100.0, 100.0), 6467, 4, 0.75}; +/* +NoiseParams nparams_v6_def_beach = + {0.0, 1.0, v3f(250.0, 250.0, 250.0), 59420, 3, 0.50}; +NoiseParams nparams_v6_def_cave = + {6.0, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50}; +NoiseParams nparams_v6_def_humidity = + {0.5, 0.5, v3f(500.0, 500.0, 500.0), 72384, 4, 0.66}; +NoiseParams nparams_v6_def_trees = + {0.0, 1.0, v3f(125.0, 125.0, 125.0), 2, 4, 0.66}; +NoiseParams nparams_v6_def_apple_trees = + {0.0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45}; +*/ +/////////////////////////////////////////////////////////////////////////////// + + +MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge) { + this->generating = false; + this->id = mapgenid; + this->emerge = emerge; + this->bmgr = emerge->biomedef; + + this->seed = (int)params->seed; + this->water_level = params->water_level; + this->flags = params->flags; + this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE; +// this->ystride = csize.X; //////fix this + + this->biomemap = new u8[csize.X * csize.Z]; + this->heightmap = new s16[csize.X * csize.Z]; + this->ridge_heightmap = new s16[csize.X * csize.Z]; + + // Terrain noise + noise_terrain_base = new Noise(params->np_terrain_base, seed, csize.X, csize.Z); + noise_terrain_alt = new Noise(params->np_terrain_alt, seed, csize.X, csize.Z); + noise_terrain_mod = new Noise(params->np_terrain_mod, seed, csize.X, csize.Z); + noise_terrain_persist = new Noise(params->np_terrain_persist, seed, csize.X, csize.Z); + noise_height_select = new Noise(params->np_height_select, seed, csize.X, csize.Z); + noise_ridge = new Noise(params->np_ridge, seed, csize.X, csize.Y, csize.Z); + + // Biome noise + noise_heat = new Noise(bmgr->np_heat, seed, csize.X, csize.Z); + noise_humidity = new Noise(bmgr->np_humidity, seed, csize.X, csize.Z); +} + + +MapgenV7::~MapgenV7() { + delete noise_terrain_base; + delete noise_terrain_mod; + delete noise_terrain_persist; + delete noise_height_select; + delete noise_terrain_alt; + delete noise_ridge; + delete noise_heat; + delete noise_humidity; + + delete[] ridge_heightmap; + delete[] heightmap; + delete[] biomemap; +} + + +int MapgenV7::getGroundLevelAtPoint(v2s16 p) { + return 20; +} + + +void MapgenV7::makeChunk(BlockMakeData *data) { + assert(data->vmanip); + assert(data->nodedef); + assert(data->blockpos_requested.X >= data->blockpos_min.X && + data->blockpos_requested.Y >= data->blockpos_min.Y && + data->blockpos_requested.Z >= data->blockpos_min.Z); + assert(data->blockpos_requested.X <= data->blockpos_max.X && + data->blockpos_requested.Y <= data->blockpos_max.Y && + data->blockpos_requested.Z <= data->blockpos_max.Z); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + //TimeTaker t("makeChunk"); + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + v3s16 blockpos_full_min = blockpos_min - v3s16(1, 1, 1); + v3s16 blockpos_full_max = blockpos_max + v3s16(1, 1, 1); + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + //blockseed = emerge->getBlockSeed(full_node_min); + + // Make some noise + calculateNoise(); + + // Calculate height map + s16 stone_surface_max_y = calcHeightMap(); + + // Calculate biomes + BiomeNoiseInput binput; + binput.mapsize = v2s16(csize.X, csize.Z); + binput.heat_map = noise_heat->result; + binput.humidity_map = noise_humidity->result; + binput.height_map = heightmap; + bmgr->calcBiomes(&binput, biomemap); + + c_stone = ndef->getId("mapgen_stone"); + c_dirt = ndef->getId("mapgen_dirt"); + c_dirt_with_grass = ndef->getId("mapgen_dirt_with_grass"); + c_sand = ndef->getId("mapgen_sand"); + c_water_source = ndef->getId("mapgen_water_source"); + + generateTerrain(); + carveRidges(); + + //carveRivers(); + addTopNodes(); + growGrass(); + + //v3s16 central_area_size = node_max - node_min + v3s16(1,1,1); + + if (flags & MG_DUNGEONS) { + DungeonGen dgen(ndef, data->seed, water_level); + dgen.generate(vm, blockseed, full_node_min, full_node_max); + } + + for (size_t i = 0; i != emerge->ores.size(); i++) { + Ore *ore = emerge->ores[i]; + ore->generate(this, blockseed + i, node_min, node_max); + } + + //printf("makeChunk: %dms\n", t.stop()); + + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + calcLighting(node_min, node_max); + //setLighting(node_min, node_max, 0xFF); + + this->generating = false; +} + + +void MapgenV7::calculateNoise() { + //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); + int x = node_min.X; + int y = node_min.Y; + int z = node_min.Z; + + noise_terrain_mod->perlinMap2D(x, z); + + noise_height_select->perlinMap2D(x, z); + noise_height_select->transformNoiseMap(); + + noise_terrain_persist->perlinMap2D(x, z); + float *persistmap = noise_terrain_persist->result; + for (int i = 0; i != csize.X * csize.Z; i++) + persistmap[i] = abs(persistmap[i]); + + noise_terrain_base->perlinMap2DModulated(x, z, persistmap); + noise_terrain_base->transformNoiseMap(); + + noise_terrain_alt->perlinMap2DModulated(x, z, persistmap); + noise_terrain_alt->transformNoiseMap(); + + noise_ridge->perlinMap3D(x, y, z); + + noise_heat->perlinMap2D(x, z); + + noise_humidity->perlinMap2D(x, z); + + //printf("calculateNoise: %dus\n", t.stop()); +} + + +Biome *MapgenV7::getBiomeAtPoint(v3s16 p) { + float heat = NoisePerlin2D(bmgr->np_heat, p.X, p.Z, seed); + float humidity = NoisePerlin2D(bmgr->np_humidity, p.X, p.Z, seed); + s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Z); + + return bmgr->getBiome(heat, humidity, groundlevel); +} + + +float MapgenV7::baseTerrainLevelAtPoint(int x, int z) { + float terrain_mod = NoisePerlin2DNoTxfm(noise_terrain_mod->np, x, z, seed); + float hselect = NoisePerlin2D(noise_height_select->np, x, z, seed); + float persist = abs(NoisePerlin2DNoTxfm(noise_terrain_persist->np, x, z, seed)); + + noise_terrain_base->np->persist = persist; + float terrain_base = NoisePerlin2D(noise_terrain_base->np, x, z, seed); + float height_base = terrain_base * terrain_mod; + + noise_terrain_alt->np->persist = persist; + float height_alt = NoisePerlin2D(noise_terrain_alt->np, x, z, seed); + + return (height_base * hselect) + (height_alt * (1.0 - hselect)); +} + + +float MapgenV7::baseTerrainLevelFromMap(int index) { + float terrain_mod = noise_terrain_mod->result[index]; + float hselect = noise_height_select->result[index]; + float terrain_base = noise_terrain_base->result[index]; + float height_base = terrain_base * terrain_mod; + float height_alt = noise_terrain_alt->result[index]; + + return (height_base * hselect) + (height_alt * (1.0 - hselect)); +} + + +#if 0 +// Crap code to test log rivers as a proof-of-concept. Didn't work out too well. +void MapgenV7::carveRivers() { + MapNode n_air(CONTENT_AIR), n_water_source(c_water_source); + MapNode n_stone(c_stone); + u32 index = 0; + + int river_depth = 4; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + float terrain_mod = noise_terrain_mod->result[index]; + NoiseParams *np = noise_terrain_river->np; + np->persist = noise_terrain_persist->result[index]; + float terrain_river = NoisePerlin2DNoTxfm(np, x, z, seed); + float height = terrain_river * (1 - abs(terrain_mod)) * + noise_terrain_river->np->scale; + height = log(height * height); //log(h^3) is pretty interesting for terrain + + s16 y = heightmap[index]; + if (height < 1.0 && y > river_depth && + y - river_depth >= node_min.Y && y <= node_max.Y) { + + for (s16 ry = y; ry != y - river_depth; ry--) { + u32 vi = vm->m_area.index(x, ry, z); + vm->m_data[vi] = n_air; + } + + u32 vi = vm->m_area.index(x, y - river_depth, z); + vm->m_data[vi] = n_water_source; + } + } +} +#endif + + +int MapgenV7::calcHeightMap() { + int stone_surface_max_y = -MAP_GENERATION_LIMIT; + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + float surface_height = baseTerrainLevelFromMap(index); + s16 surface_y = (s16)surface_height; + + heightmap[index] = surface_y; + ridge_heightmap[index] = surface_y; + + if (surface_y > stone_surface_max_y) + stone_surface_max_y = surface_y; + } + + return stone_surface_max_y; +} + + +void MapgenV7::generateTerrain() { + MapNode n_air(CONTENT_AIR), n_water_source(c_water_source); + MapNode n_stone(c_stone); + + v3s16 em = vm->m_area.getExtent(); + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + s16 surface_y = heightmap[index]; + Biome *biome = bmgr->biomes[biomemap[index]]; + + u32 i = vm->m_area.index(x, node_min.Y, z); + for (s16 y = node_min.Y; y <= node_max.Y; y++) { + if (vm->m_data[i].getContent() == CONTENT_IGNORE) { + if (y <= surface_y) { + vm->m_data[i] = (y > water_level + biome->filler_height) ? + MapNode(biome->c_filler) : n_stone; + } else if (y <= water_level) { + vm->m_data[i] = n_water_source; + } else { + vm->m_data[i] = n_air; + } + } + vm->m_area.add_y(em, i, 1); + } + } +} + + +void MapgenV7::carveRidges() { + if (node_max.Y <= water_level) + return; + + MapNode n_air(CONTENT_AIR); + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 y = node_min.Y; y <= node_max.Y; y++) { + u32 vi = vm->m_area.index(node_min.X, y, z); + for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) { + // Removing this check will create huge underwater caverns, + // which are interesting but not desirable for gameplay + if (y <= water_level) + continue; + + if (noise_ridge->result[index] * (float)(y * y) < 15.0) + continue; + + int j = (z - node_min.Z) * csize.Z + (x - node_min.X); //////obviously just temporary + if (y < ridge_heightmap[j]) + ridge_heightmap[j] = y - 1; + + vm->m_data[vi] = n_air; + } + } +} + +/* +void MapgenV7::testBiomes() { + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_min.Z; z++) + for (s16 x = node_min.X; x <= node_min.X; x++) {; + Biome *b = bmgr->getBiome(heat, humidity, 0); + } + // make an 80x80 grid with axes heat/humidity as a voroni diagram for biomes + // clear out y space for it first with air + // use absolute positioning, each chunk will be a +1 height +}*/ + + +void MapgenV7::addTopNodes() { + v3s16 em = vm->m_area.getExtent(); + s16 ntopnodes; + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + // First, add top nodes below the ridge + s16 y = ridge_heightmap[index]; + + // This cutoff is good enough, but not perfect. + // It will cut off potentially placed top nodes at chunk boundaries + if (y < node_min.Y) + continue; + if (y > node_max.Y) { + y = node_max.Y; // Let's see if we can still go downward anyway + u32 vi = vm->m_area.index(x, y, z); + if (vm->m_data[vi].getContent() != CONTENT_AIR) + continue; + } + + // N.B. It is necessary to search downward since range_heightmap[i] + // might not be the actual height, just the lowest part in the chunk + // where a ridge had been carved + u32 i = vm->m_area.index(x, y, z); + for (; y >= node_min.Y; y--) { + if (vm->m_data[i].getContent() != CONTENT_AIR) + break; + vm->m_area.add_y(em, i, -1); + } + + Biome *biome = bmgr->biomes[biomemap[index]]; + + if (y != node_min.Y - 1) { + ridge_heightmap[index] = y; //update ridgeheight + ntopnodes = biome->top_depth; + for (; y <= node_max.Y && ntopnodes; y++) { + ntopnodes--; + vm->m_data[i] = MapNode(biome->c_top); + vm->m_area.add_y(em, i, 1); + } + //heightmap[index] = y; + } + + // Now, add top nodes on top of the ridge + y = heightmap[index]; + + i = vm->m_area.index(x, y, z); + for (; y >= node_min.Y; y--) { + if (vm->m_data[i].getContent() != CONTENT_AIR) + break; + vm->m_area.add_y(em, i, -1); + } + + if (y != node_min.Y - 1) { + ntopnodes = biome->top_depth; + // Let's see if we've already added it... + if (y == ridge_heightmap[index] + ntopnodes - 1) + continue; + + for (; y <= node_max.Y && ntopnodes; y++) { + ntopnodes--; + vm->m_data[i] = MapNode(biome->c_top); + vm->m_area.add_y(em, i, 1); + } + } + } +} + + +void MapgenV7::growGrass() { + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++) { + // Find the lowest surface to which enough light ends up to make + // grass grow. Basically just wait until not air and not leaves. + s16 surface_y = 0; + { + v3s16 em = vm->m_area.getExtent(); + u32 i = vm->m_area.index(x, node_max.Y, z); + s16 y; + // Go to ground level + for (y = node_max.Y; y >= node_min.Y; y--) { + MapNode &n = vm->m_data[i]; + if (ndef->get(n).param_type != CPT_LIGHT || + ndef->get(n).liquid_type != LIQUID_NONE) + break; + vm->m_area.add_y(em, i, -1); + } + surface_y = (y >= node_min.Y) ? y : node_min.Y; + } + + u32 i = vm->m_area.index(x, surface_y, z); + MapNode *n = &vm->m_data[i]; + if (n->getContent() == c_dirt && surface_y >= water_level - 20) + n->setContent(c_dirt_with_grass); + } +} diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h new file mode 100644 index 000000000..73fa9be03 --- /dev/null +++ b/src/mapgen_v7.h @@ -0,0 +1,125 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef MAPGEN_V7_HEADER +#define MAPGEN_V7_HEADER + +#include "mapgen.h" + +extern NoiseParams nparams_v7_def_terrain_base; +extern NoiseParams nparams_v7_def_terrain_alt; +extern NoiseParams nparams_v7_def_terrain_mod; +extern NoiseParams nparams_v7_def_terrain_persist; +extern NoiseParams nparams_v7_def_height_select; +extern NoiseParams nparams_v7_def_ridge; + +struct MapgenV7Params : public MapgenParams { + NoiseParams *np_terrain_base; + NoiseParams *np_terrain_alt; + NoiseParams *np_terrain_mod; + NoiseParams *np_terrain_persist; + NoiseParams *np_height_select; + NoiseParams *np_ridge; + + MapgenV7Params() { + np_terrain_base = &nparams_v7_def_terrain_base; + np_terrain_alt = &nparams_v7_def_terrain_alt; + np_terrain_mod = &nparams_v7_def_terrain_mod; + np_terrain_persist = &nparams_v7_def_terrain_persist; + np_height_select = &nparams_v7_def_height_select; + np_ridge = &nparams_v7_def_ridge; + } + + bool readParams(Settings *settings); + void writeParams(Settings *settings); +}; + +class MapgenV7 : public Mapgen { +public: + EmergeManager *emerge; + BiomeDefManager *bmgr; + + int ystride; + v3s16 csize; + u32 flags; + + u32 blockseed; + v3s16 node_min; + v3s16 node_max; + v3s16 full_node_min; + v3s16 full_node_max; + + s16 *heightmap; + s16 *ridge_heightmap; + u8 *biomemap; + + Noise *noise_terrain_base; + Noise *noise_terrain_alt; + Noise *noise_terrain_mod; + Noise *noise_terrain_persist; + Noise *noise_height_select; + + Noise *noise_ridge; + + Noise *noise_heat; + Noise *noise_humidity; + + content_t c_stone; + content_t c_dirt; + content_t c_dirt_with_grass; + content_t c_sand; + content_t c_water_source; + content_t c_lava_source; + content_t c_gravel; + content_t c_cobble; + content_t c_desert_sand; + content_t c_desert_stone; + + MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge); + ~MapgenV7(); + + void makeChunk(BlockMakeData *data); + int getGroundLevelAtPoint(v2s16 p); + Biome *getBiomeAtPoint(v3s16 p); + + float baseTerrainLevelAtPoint(int x, int z); + float baseTerrainLevelFromMap(int index); + void calculateNoise(); + int calcHeightMap(); + + void generateTerrain(); + void carveRidges(); + //void carveRivers(); //experimental + + void testBiomes(); + void addTopNodes(); + void growGrass(); +}; + +struct MapgenFactoryV7 : public MapgenFactory { + Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) { + return new MapgenV7(mgid, (MapgenV7Params *)params, emerge); + }; + + MapgenParams *createMapgenParams() { + return new MapgenV7Params(); + }; +}; + +#endif diff --git a/src/noise.cpp b/src/noise.cpp index 49b5f7e58..5788a8320 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -1,6 +1,7 @@ /* Minetest Copyright (C) 2010-2013 celeron55, Perttu Ahola +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -536,6 +537,41 @@ float *Noise::perlinMap2D(float x, float y) { } +float *Noise::perlinMap2DModulated(float x, float y, float *persist_map) { + float f = 1.0; + int i, j, index, oct; + + x /= np->spread.X; + y /= np->spread.Y; + + memset(result, 0, sizeof(float) * sx * sy); + + float *g = new float[sx * sy]; + for (index = 0; index != sx * sy; index++) + g[index] = 1.0; + + for (oct = 0; oct < np->octaves; oct++) { + gradientMap2D(x * f, y * f, + f / np->spread.X, f / np->spread.Y, + seed + np->seed + oct); + + index = 0; + for (j = 0; j != sy; j++) { + for (i = 0; i != sx; i++) { + result[index] += g[index] * buf[index]; + g[index] *= persist_map[index]; + index++; + } + } + + f *= 2.0; + } + + delete[] g; + return result; +} + + float *Noise::perlinMap3D(float x, float y, float z) { float f = 1.0, g = 1.0; int i, j, k, index, oct; diff --git a/src/noise.h b/src/noise.h index 34b4d0b41..ace6d7eb4 100644 --- a/src/noise.h +++ b/src/noise.h @@ -1,6 +1,7 @@ /* Minetest Copyright (C) 2010-2013 celeron55, Perttu Ahola +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -105,6 +106,7 @@ public: float step_x, float step_y, float step_z, int seed); float *perlinMap2D(float x, float y); + float *perlinMap2DModulated(float x, float y, float *persist_map); float *perlinMap3D(float x, float y, float z); void transformNoiseMap(); }; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index c372456d4..0227c6a19 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -616,76 +616,36 @@ static int l_get_server_status(lua_State *L) return 1; } -// register_biome_groups({frequencies}) -static int l_register_biome_groups(lua_State *L) -{ - luaL_checktype(L, 1, LUA_TTABLE); - int index = 1; - - BiomeDefManager *bmgr = get_server(L)->getBiomeDef(); - if (!bmgr) { - verbosestream << "register_biome_groups: BiomeDefManager not active" << std::endl; - return 0; - } - - lua_pushnil(L); - for (int i = 1; lua_next(L, index) != 0; i++) { - bmgr->addBiomeGroup(lua_tonumber(L, -1)); - lua_pop(L, 1); - } - lua_pop(L, 1); - - return 0; -} // register_biome({lots of stuff}) static int l_register_biome(lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - int index = 1, groupid; - std::string nodename; + int index = 1; + luaL_checktype(L, index, LUA_TTABLE); - IWritableNodeDefManager *ndef = get_server(L)->getWritableNodeDefManager(); - BiomeDefManager *bmgr = get_server(L)->getBiomeDef(); + BiomeDefManager *bmgr = get_server(L)->getEmergeManager()->biomedef; if (!bmgr) { verbosestream << "register_biome: BiomeDefManager not active" << std::endl; return 0; } - - groupid = getintfield_default(L, index, "group_id", 0); - + enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index, "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL); Biome *b = bmgr->createBiome(terrain); - b->name = getstringfield_default(L, index, "name", ""); - - if (getstringfield(L, index, "node_top", nodename)) - b->n_top = MapNode(ndef->getId(nodename)); - else - b->n_top = MapNode(CONTENT_IGNORE); - - if (getstringfield(L, index, "node_filler", nodename)) - b->n_filler = MapNode(ndef->getId(nodename)); - else - b->n_filler = b->n_top; - - b->ntopnodes = getintfield_default(L, index, "num_top_nodes", 0); - - b->height_min = getintfield_default(L, index, "height_min", 0); - b->height_max = getintfield_default(L, index, "height_max", 0); - b->heat_min = getfloatfield_default(L, index, "heat_min", 0.); - b->heat_max = getfloatfield_default(L, index, "heat_max", 0.); - b->humidity_min = getfloatfield_default(L, index, "humidity_min", 0.); - b->humidity_max = getfloatfield_default(L, index, "humidity_max", 0.); - - b->np = new NoiseParams; // should read an entire NoiseParams later on... - getfloatfield(L, index, "scale", b->np->scale); - getfloatfield(L, index, "offset", b->np->offset); - - b->groupid = (s8)groupid; - b->flags = 0; //reserved + b->name = getstringfield_default(L, index, "name", ""); + b->top_nodename = getstringfield_default(L, index, "top_node", ""); + b->top_depth = getintfield_default(L, index, "top_depth", 0); + b->filler_nodename = getstringfield_default(L, index, "filler_node", ""); + b->filler_height = getintfield_default(L, index, "filler_height", 0); + b->height_min = getintfield_default(L, index, "height_min", 0); + b->height_max = getintfield_default(L, index, "height_max", 0); + b->heat_point = getfloatfield_default(L, index, "heat_point", 0.); + b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.); + b->flags = 0; //reserved + b->c_top = CONTENT_IGNORE; + b->c_filler = CONTENT_IGNORE; bmgr->addBiome(b); verbosestream << "register_biome: " << b->name << std::endl; @@ -698,7 +658,6 @@ static int l_register_ore(lua_State *L) int index = 1; luaL_checktype(L, index, LUA_TTABLE); - IWritableNodeDefManager *ndef = get_server(L)->getWritableNodeDefManager(); EmergeManager *emerge = get_server(L)->getEmergeManager(); enum OreType oretype = (OreType)getenumfield(L, index, @@ -1113,7 +1072,6 @@ static const struct luaL_Reg minetest_f [] = { {"register_alias_raw", l_register_alias_raw}, {"register_craft", l_register_craft}, {"register_biome", l_register_biome}, - {"register_biome_groups", l_register_biome_groups}, {"register_ore", l_register_ore}, {"setting_set", l_setting_set}, {"setting_get", l_setting_get}, diff --git a/src/server.cpp b/src/server.cpp index c4dd0ab0f..05075a72c 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -646,7 +646,6 @@ Server::Server( m_rollback_sink_enabled(true), m_enable_rollback_recording(false), m_emerge(NULL), - m_biomedef(NULL), m_lua(NULL), m_itemdef(createItemDefManager()), m_nodedef(createNodeDefManager()), @@ -694,12 +693,9 @@ Server::Server( Settings gamedefaults; getGameMinetestConfig(gamespec.path, gamedefaults); override_default_settings(g_settings, &gamedefaults); - - // Create biome definition manager - m_biomedef = new BiomeDefManager(this); // Create emerge manager - m_emerge = new EmergeManager(this, m_biomedef); + m_emerge = new EmergeManager(this); // Create rollback manager std::string rollback_path = m_path_world+DIR_DELIM+"rollback.txt"; @@ -813,9 +809,6 @@ Server::Server( // Apply item aliases in the node definition manager m_nodedef->updateAliases(m_itemdef); - // Add default biomes after nodedef had its aliases added - m_biomedef->addDefaultBiomes(); - // Initialize Environment ServerMap *servermap = new ServerMap(path_world, this, m_emerge); m_env = new ServerEnvironment(servermap, m_lua, this, this); diff --git a/src/server.h b/src/server.h index 04e693fc8..ea1cb79af 100644 --- a/src/server.h +++ b/src/server.h @@ -485,7 +485,6 @@ public: void deleteParticleSpawner(const char *playername, u32 id); void deleteParticleSpawnerAll(u32 id); - void queueBlockEmerge(v3s16 blockpos, bool allow_generate); // Creates or resets inventory @@ -497,11 +496,9 @@ public: // Envlock should be locked when using the rollback manager IRollbackManager *getRollbackManager(){ return m_rollback; } - //TODO: determine what should be locked when accessing the emerge manager + //TODO: determine what (if anything) should be locked to access EmergeManager EmergeManager *getEmergeManager(){ return m_emerge; } - BiomeDefManager *getBiomeDef(){ return m_biomedef; } - // actions: time-reversed list // Return value: success/failure bool rollbackRevertActions(const std::list &actions, @@ -734,9 +731,6 @@ private: // Emerge manager EmergeManager *m_emerge; - // Biome Definition Manager - BiomeDefManager *m_biomedef; - // Scripting // Envlock and conlock should be locked when using Lua lua_State *m_lua;