diff --git a/minetest.conf.example b/minetest.conf.example index b9e7d59e4..f4b905700 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -417,6 +417,13 @@ #max_block_send_distance = 10 # From how far blocks are generated for clients, stated in mapblocks (16 nodes) #max_block_generate_distance = 6 +# Where the map generator stops. +# Please note: +# * Limited to 31000 (setting above has no effect) +# * The map generator works in groups of 80x80x80 nodes (5x5x5 MapBlocks). +# * Those groups have an offset of -32, -32 nodes from the origin. +# * Only groups which are within the map_generation_limit are generated +#map_generation_limit = 31000 # Number of extra blocks that can be loaded by /clearobjects at once. # This is a trade-off between sqlite transaction overhead and # memory consumption (4096=100MB, as a rule of thumb). @@ -603,4 +610,3 @@ # Comma-separated list of trusted mods that are allowed to access insecure # functions even when mod security is on (via request_insecure_environment()). #secure.trusted_mods = - diff --git a/src/clientiface.cpp b/src/clientiface.cpp index 6944e56db..3330e0af9 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -209,25 +209,19 @@ void RemoteClient::GetNextBlocks ( max_simul_dynamic = max_simul_sends_setting; // Don't select too many blocks for sending - if(num_blocks_selected >= max_simul_dynamic) - { + if (num_blocks_selected >= max_simul_dynamic) { //queue_is_full = true; goto queue_full_break; } // Don't send blocks that are currently being transferred - if(m_blocks_sending.find(p) != m_blocks_sending.end()) + if (m_blocks_sending.find(p) != m_blocks_sending.end()) continue; /* Do not go over-limit */ - if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE) + if (blockpos_over_limit(p)) continue; // If this is true, inexistent block will be made from scratch @@ -239,7 +233,7 @@ void RemoteClient::GetNextBlocks ( generate = false;*/ // Limit the send area vertically to 1/2 - if(abs(p.Y - center.Y) > full_d_max / 2) + if (abs(p.Y - center.Y) > full_d_max / 2) continue; } diff --git a/src/constants.h b/src/constants.h index 22cadc5a8..b606fc4fa 100644 --- a/src/constants.h +++ b/src/constants.h @@ -64,7 +64,8 @@ with this program; if not, write to the Free Software Foundation, Inc., // The absolute working limit is (2^15 - viewing_range). // I really don't want to make every algorithm to check if it's going near // the limit or not, so this is lower. -#define MAP_GENERATION_LIMIT (31000) +// This is the maximum value the setting map_generation_limit can be +#define MAX_MAP_GENERATION_LIMIT (31000) // Size of node in floating-point units // The original idea behind this is to disallow plain casts between @@ -116,4 +117,3 @@ with this program; if not, write to the Free Software Foundation, Inc., #define DEFAULT_FONT_SIZE (10) #endif - diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 42c617513..4674b2b77 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -94,6 +94,7 @@ void set_default_settings(Settings *settings) // A bit more than the server will send around the player, to make fog blend well settings->setDefault("viewing_range_nodes_max", "240"); settings->setDefault("viewing_range_nodes_min", "35"); + settings->setDefault("map_generation_limit", "31000"); settings->setDefault("screenW", "800"); settings->setDefault("screenH", "600"); settings->setDefault("fullscreen", "false"); diff --git a/src/map.cpp b/src/map.cpp index 9974ff363..50b50220d 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2502,10 +2502,12 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d) /* Do not create over-limit */ - if(p2d.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p2d.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p2d.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p2d.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE) + const static u16 map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT, + g_settings->getU16("map_generation_limit")); + if(p2d.X < -map_gen_limit / MAP_BLOCKSIZE + || p2d.X > map_gen_limit / MAP_BLOCKSIZE + || p2d.Y < -map_gen_limit / MAP_BLOCKSIZE + || p2d.Y > map_gen_limit / MAP_BLOCKSIZE) throw InvalidPositionException("createSector(): pos. over limit"); /* @@ -2649,12 +2651,7 @@ MapBlock * ServerMap::createBlock(v3s16 p) /* Do not create over-limit */ - if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE) + if (blockpos_over_limit(p)) throw InvalidPositionException("createBlock(): pos. over limit"); v2s16 p2d(p.X, p.Z); diff --git a/src/mapblock.h b/src/mapblock.h index ba33c01a2..334136b92 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodetimer.h" #include "modifiedstate.h" #include "util/numeric.h" // getContainerPos +#include "settings.h" class Map; class NodeMetadataList; @@ -638,13 +639,14 @@ typedef std::vector MapBlockVect; inline bool blockpos_over_limit(v3s16 p) { - return - (p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE); + const static u16 map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT, + g_settings->getU16("map_generation_limit")); + return (p.X < -map_gen_limit / MAP_BLOCKSIZE + || p.X > map_gen_limit / MAP_BLOCKSIZE + || p.Y < -map_gen_limit / MAP_BLOCKSIZE + || p.Y > map_gen_limit / MAP_BLOCKSIZE + || p.Z < -map_gen_limit / MAP_BLOCKSIZE + || p.Z > map_gen_limit / MAP_BLOCKSIZE); } /* @@ -681,4 +683,3 @@ inline void getNodeSectorPosWithOffset(const v2s16 &p, v2s16 &block, v2s16 &offs std::string analyze_block(MapBlock *block); #endif - diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 7f7c4e240..1843e953d 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -143,7 +143,7 @@ s16 Mapgen::findGroundLevelFull(v2s16 p2d) } -// Returns -MAP_GENERATION_LIMIT if not found +// Returns -MAX_MAP_GENERATION_LIMIT if not found s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) { v3s16 em = vm->m_area.getExtent(); @@ -157,7 +157,7 @@ s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) vm->m_area.add_y(em, i, -1); } - return (y >= ymin) ? y : -MAP_GENERATION_LIMIT; + return (y >= ymin) ? y : -MAX_MAP_GENERATION_LIMIT; } @@ -475,4 +475,3 @@ void MapgenParams::save(Settings &settings) const if (sparams) sparams->writeParams(&settings); } - diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index f23dad4ec..5b842a99e 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -370,7 +370,7 @@ int MapgenV5::generateBaseTerrain() { u32 index = 0; u32 index2d = 0; - int stone_surface_max_y = -MAP_GENERATION_LIMIT; + int stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; for (s16 z=node_min.Z; z<=node_max.Z; z++) { for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) { @@ -585,4 +585,3 @@ void MapgenV5::dustTopNodes() } } } - diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 09acec783..9e34aac2d 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -626,7 +626,7 @@ int MapgenV6::generateGround() MapNode n_air(CONTENT_AIR), n_water_source(c_water_source); MapNode n_stone(c_stone), n_desert_stone(c_desert_stone); MapNode n_ice(c_ice); - int stone_surface_max_y = -MAP_GENERATION_LIMIT; + int stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; u32 index = 0; for (s16 z = node_min.Z; z <= node_max.Z; z++) diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index e499ebb81..9f612de81 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -505,8 +505,8 @@ void MapgenV7::generateBaseTerrain(s16 *stone_surface_min_y, s16 *stone_surface_ MapNode n_water(c_water_source); v3s16 em = vm->m_area.getExtent(); - s16 surface_min_y = MAP_GENERATION_LIMIT; - s16 surface_max_y = -MAP_GENERATION_LIMIT; + s16 surface_min_y = MAX_MAP_GENERATION_LIMIT; + s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT; u32 index = 0; for (s16 z = node_min.Z; z <= node_max.Z; z++) @@ -885,4 +885,3 @@ void MapgenV7::generateCaves(s16 max_stone_y) cave.makeCave(node_min, node_max, max_stone_y); } } - diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp index 1944aa12f..a21d99b17 100644 --- a/src/mg_biome.cpp +++ b/src/mg_biome.cpp @@ -45,8 +45,8 @@ BiomeManager::BiomeManager(IGameDef *gamedef) : b->depth_top = 0; b->depth_filler = 0; b->depth_water_top = 0; - b->y_min = -MAP_GENERATION_LIMIT; - b->y_max = MAP_GENERATION_LIMIT; + b->y_min = -MAX_MAP_GENERATION_LIMIT; + b->y_max = MAX_MAP_GENERATION_LIMIT; b->heat_point = 0.0; b->humidity_point = 0.0; @@ -140,4 +140,3 @@ void Biome::resolveNodeNames() getIdFromNrBacklog(&c_river_water, "mapgen_river_water_source", CONTENT_AIR); getIdFromNrBacklog(&c_dust, "air", CONTENT_IGNORE); } -