diff options
author | sweetbomber <ffrogger _zero_ at yahoo dot com> | 2013-05-30 17:14:22 +0100 |
---|---|---|
committer | ShadowNinja <shadowninja@minetest.net> | 2013-12-05 16:09:02 -0500 |
commit | 22dbbf0a6fc9547f0dbdb7f6076337b8c6acd48b (patch) | |
tree | 3d292747f5518568fda97fb1cbb4c982833e4e76 | |
parent | 000da6b25de2af1cc517b9f3c5e9b3576625ec4c (diff) | |
download | minetest-22dbbf0a6fc9547f0dbdb7f6076337b8c6acd48b.tar.gz minetest-22dbbf0a6fc9547f0dbdb7f6076337b8c6acd48b.tar.bz2 minetest-22dbbf0a6fc9547f0dbdb7f6076337b8c6acd48b.zip |
Improve (re)spawn, add cache_block_before_spawn and max_spawn_height settings
-rw-r--r-- | minetest.conf.example | 4 | ||||
-rw-r--r-- | src/defaultsettings.cpp | 2 | ||||
-rw-r--r-- | src/map.cpp | 78 | ||||
-rw-r--r-- | src/map.h | 2 | ||||
-rw-r--r-- | src/server.cpp | 9 |
5 files changed, 55 insertions, 40 deletions
diff --git a/minetest.conf.example b/minetest.conf.example index 46a9e8cfc..4d6b76c84 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -266,6 +266,10 @@ #disable_anticheat = false # If true, actions are recorded for rollback #enable_rollback_recording = false +# If true, blocks are cached (and generated if not before) before a player is spawned. +#cache_block_before_spawn = true +# Defines the maximum height a player can spawn in a map, above water level +#max_spawn_height = 50 # Profiler data print interval. #0 = disable. #profiler_print_interval = 0 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 68350bec0..106e5d9c2 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -182,6 +182,8 @@ void set_default_settings(Settings *settings) settings->setDefault("disallow_empty_password", "false"); settings->setDefault("disable_anticheat", "false"); settings->setDefault("enable_rollback_recording", "false"); + settings->setDefault("cache_block_before_spawn", "true"); + settings->setDefault("max_spawn_height", "50"); settings->setDefault("profiler_print_interval", "0"); settings->setDefault("enable_mapgen_debug_info", "false"); diff --git a/src/map.cpp b/src/map.cpp index 4d32ecdfe..55f91c8a6 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3185,48 +3185,56 @@ void ServerMap::prepareBlock(MapBlock *block) { } } -s16 ServerMap::findGroundLevel(v2s16 p2d) +/** + * Get the ground level by searching for a non CONTENT_AIR node in a column from top to bottom + */ +s16 ServerMap::findGroundLevel(v2s16 p2d, bool cacheBlocks) { -#if 0 - /* - Uh, just do something random... - */ - // Find existing map from top to down - s16 max=63; - s16 min=-64; - v3s16 p(p2d.X, max, p2d.Y); - for(; p.Y>min; p.Y--) - { - MapNode n = getNodeNoEx(p); - if(n.getContent() != CONTENT_IGNORE) - break; + + s16 level; + + // The reference height is the original mapgen height + s16 referenceHeight = m_emerge->getGroundLevelAtPoint(p2d); + s16 maxSearchHeight = 63 + referenceHeight; + s16 minSearchHeight = -63 + referenceHeight; + v3s16 probePosition(p2d.X, maxSearchHeight, p2d.Y); + v3s16 blockPosition = getNodeBlockPos(probePosition); + v3s16 prevBlockPosition = blockPosition; + + // Cache the block to be inspected. + if(cacheBlocks) { + emergeBlock(blockPosition, true); } - if(p.Y == min) - goto plan_b; - // If this node is not air, go to plan b - if(getNodeNoEx(p).getContent() != CONTENT_AIR) - goto plan_b; - // Search existing walkable and return it - for(; p.Y>min; p.Y--) + + // Probes the nodes in the given column + for(; probePosition.Y > minSearchHeight; probePosition.Y--) { - MapNode n = getNodeNoEx(p); - if(content_walkable(n.d) && n.getContent() != CONTENT_IGNORE) - return p.Y; - } + if(cacheBlocks) { + // Calculate the block position of the given node + blockPosition = getNodeBlockPos(probePosition); + + // If the node is in an different block, cache it + if(blockPosition != prevBlockPosition) { + emergeBlock(blockPosition, true); + prevBlockPosition = blockPosition; + } + } - // Move to plan b -plan_b: -#endif + MapNode node = getNodeNoEx(probePosition); + if (node.getContent() != CONTENT_IGNORE && + node.getContent() != CONTENT_AIR) { + break; + } + } - /* - Determine from map generator noise functions - */ + // Could not determine the ground. Use map generator noise functions. + if(probePosition.Y == minSearchHeight) { + level = referenceHeight; + } else { + level = probePosition.Y; + } - s16 level = m_emerge->getGroundLevelAtPoint(p2d); return level; - - //double level = base_rock_level_2d(m_seed, p2d) + AVERAGE_MUD_AMOUNT; - //return (s16)level; } bool ServerMap::loadFromFolders() { @@ -428,7 +428,7 @@ public: void prepareBlock(MapBlock *block); // Helper for placing objects on ground level - s16 findGroundLevel(v2s16 p2d); + s16 findGroundLevel(v2s16 p2d, bool cacheBlocks); /* Misc. helper functions for fiddling with directory and file diff --git a/src/server.cpp b/src/server.cpp index 6b9e656e9..13b59e7f5 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2285,8 +2285,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } /*infostream<<"Server::ProcessData(): Moved player "<<peer_id<<" to " - <<"("<<position.X<<","<<position.Y<<","<<position.Z<<")" - <<" pitch="<<pitch<<" yaw="<<yaw<<std::endl;*/ + <<"("<<position.X<<","<<position.Y<<","<<position.Z<<")" + <<" pitch="<<pitch<<" yaw="<<yaw<<std::endl;*/ + } else if(command == TOSERVER_GOTBLOCKS) { @@ -5318,10 +5319,10 @@ v3f findSpawnPos(ServerMap &map) -range + (myrand() % (range * 2))); // Get ground height at point - s16 groundheight = map.findGroundLevel(nodepos2d); + s16 groundheight = map.findGroundLevel(nodepos2d, g_settings->getBool("cache_block_before_spawn")); if (groundheight <= water_level) // Don't go underwater continue; - if (groundheight > water_level + 6) // Don't go to high places + if (groundheight > water_level + g_settings->getS16("max_spawn_height")) // Don't go to high places continue; nodepos = v3s16(nodepos2d.X, groundheight, nodepos2d.Y); |