diff --git a/src/emerge.cpp b/src/emerge.cpp index 8cacdea0c8..6c3310471a 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -190,7 +190,7 @@ void EmergeManager::initMapgens(MapgenParams *params) mgparams = params; - v3s16 csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE); + v3s16 csize = params->chunksize * MAP_BLOCKSIZE; biomegen = biomemgr->createBiomeGen(BIOMEGEN_ORIGINAL, params->bparams, csize); for (u32 i = 0; i != m_threads.size(); i++) { @@ -319,11 +319,9 @@ bool EmergeManager::isBlockInQueue(v3s16 pos) // -// TODO(hmmmm): Move this to ServerMap -v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize) +v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, v3s16 chunksize) { - s16 coff = -chunksize / 2; - v3s16 chunk_offset(coff, coff, coff); + v3s16 chunk_offset = -chunksize / 2; return getContainerPos(blockpos - chunk_offset, chunksize) * chunksize + chunk_offset; diff --git a/src/emerge.h b/src/emerge.h index 860d4b6995..982296d50f 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -189,7 +189,8 @@ public: int getSpawnLevelAtPoint(v2s16 p); bool isBlockUnderground(v3s16 blockpos); - static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize); + /// @return min edge of chunk in block units + static v3s16 getContainingChunk(v3s16 blockpos, v3s16 chunksize); private: std::vector m_mapgens; diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 05d8f314ac..c31d12ac7e 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -100,7 +100,7 @@ Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeParams *emerge) : water_level = params->water_level; mapgen_limit = params->mapgen_limit; flags = params->flags; - csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE); + csize = params->chunksize * MAP_BLOCKSIZE; /* We are losing half our entropy by doing this, but it is necessary to @@ -1071,10 +1071,11 @@ void MapgenParams::readParams(const Settings *settings) settings->getS16NoEx("water_level", water_level); settings->getS16NoEx("mapgen_limit", mapgen_limit); - settings->getS16NoEx("chunksize", chunksize); settings->getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen); - chunksize = rangelim(chunksize, 1, 10); + s16 tmp; + settings->getS16NoEx("chunksize", tmp); + chunksize = v3s16(rangelim(tmp, 1, 24)); delete bparams; bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL); @@ -1091,7 +1092,7 @@ void MapgenParams::writeParams(Settings *settings) const settings->setU64("seed", seed); settings->setS16("water_level", water_level); settings->setS16("mapgen_limit", mapgen_limit); - settings->setS16("chunksize", chunksize); + settings->setS16("chunksize", chunksize.X); // TODO settings->setFlagStr("mg_flags", flags, flagdesc_mapgen); if (bparams) @@ -1106,12 +1107,15 @@ s32 MapgenParams::getSpawnRangeMax() } -std::pair get_mapgen_edges(s16 mapgen_limit, s16 chunksize) +std::pair get_mapgen_edges(s16 mapgen_limit, v3s16 chunksize) { + // FIXME: this is no longer exact + const s16 cs = std::max(std::max(chunksize.X, chunksize.Y), chunksize.Z); + // Central chunk offset, in blocks - s16 ccoff_b = -chunksize / 2; + s16 ccoff_b = -cs / 2; // Chunksize, in nodes - s32 csize_n = chunksize * MAP_BLOCKSIZE; + s32 csize_n = cs * MAP_BLOCKSIZE; // Minp/maxp of central chunk, in nodes s16 ccmin = ccoff_b * MAP_BLOCKSIZE; s16 ccmax = ccmin + csize_n - 1; @@ -1127,8 +1131,8 @@ std::pair get_mapgen_edges(s16 mapgen_limit, s16 chunksize) s16 mapgen_limit_max = (mapgen_limit_b + 1) * MAP_BLOCKSIZE - 1; // Number of complete chunks from central chunk fullminp/fullmaxp // to effective mapgen limits. - s16 numcmin = MYMAX((ccfmin - mapgen_limit_min) / csize_n, 0); - s16 numcmax = MYMAX((mapgen_limit_max - ccfmax) / csize_n, 0); + s16 numcmin = std::max((ccfmin - mapgen_limit_min) / csize_n, 0); + s16 numcmax = std::max((mapgen_limit_max - ccfmax) / csize_n, 0); // Mapgen edges, in nodes - return std::pair(ccmin - numcmin * csize_n, ccmax + numcmax * csize_n); + return {ccmin - numcmin * csize_n, ccmax + numcmax * csize_n}; } diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h index 22cd40a2c5..fd645d9a59 100644 --- a/src/mapgen/mapgen.h +++ b/src/mapgen/mapgen.h @@ -111,7 +111,7 @@ struct MapgenParams { virtual ~MapgenParams(); MapgenType mgtype = MAPGEN_DEFAULT; - s16 chunksize = 5; + v3s16 chunksize = v3s16(5); u64 seed = 0; s16 water_level = 1; s16 mapgen_limit = MAX_MAP_GENERATION_LIMIT; @@ -322,4 +322,4 @@ protected: // Calculate exact edges of the outermost mapchunks that are within the set // mapgen_limit. Returns the minimum and maximum edges in nodes in that order. -std::pair get_mapgen_edges(s16 mapgen_limit, s16 chunksize); +std::pair get_mapgen_edges(s16 mapgen_limit, v3s16 chunksize); diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 8854fc3c71..126b7afc78 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -849,23 +849,20 @@ int ModApiMapgen::l_get_mapgen_edges(lua_State *L) // MapSettingsManager::makeMapgenParams cannot be used here because it would // make mapgen settings immutable from then on. Mapgen settings should stay // mutable until after mod loading ends. + std::unique_ptr params(settingsmgr->makeMapgenParamsCopy()); s16 mapgen_limit; if (lua_isnumber(L, 1)) { - mapgen_limit = lua_tointeger(L, 1); + mapgen_limit = lua_tointeger(L, 1); } else { - std::string mapgen_limit_str; - settingsmgr->getMapSetting("mapgen_limit", &mapgen_limit_str); - mapgen_limit = stoi(mapgen_limit_str, 0, MAX_MAP_GENERATION_LIMIT); + mapgen_limit = params->mapgen_limit; } - s16 chunksize; + v3s16 chunksize; if (lua_isnumber(L, 2)) { - chunksize = lua_tointeger(L, 2); + chunksize = v3s16(lua_tointeger(L, 2)); } else { - std::string chunksize_str; - settingsmgr->getMapSetting("chunksize", &chunksize_str); - chunksize = stoi(chunksize_str, 1, 10); + chunksize = params->chunksize; } std::pair edges = get_mapgen_edges(mapgen_limit, chunksize); @@ -884,12 +881,9 @@ int ModApiMapgen::l_get_mapgen_chunksize(lua_State *L) // MapSettingsManager::makeMapgenParams cannot be used here because it would // make mapgen settings immutable from then on. Mapgen settings should stay // mutable until after mod loading ends. + std::unique_ptr params(settingsmgr->makeMapgenParamsCopy()); - std::string chunksize_str; - settingsmgr->getMapSetting("chunksize", &chunksize_str); - s16 chunksize = stoi(chunksize_str, 1, 10); - - push_v3s16(L, {chunksize, chunksize, chunksize}); + push_v3s16(L, params->chunksize); return 1; } diff --git a/src/servermap.cpp b/src/servermap.cpp index 912c91a9af..2977585dd8 100644 --- a/src/servermap.cpp +++ b/src/servermap.cpp @@ -200,9 +200,9 @@ bool ServerMap::blockpos_over_mapgen_limit(v3s16 p) bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) { assert(data); - s16 csize = getMapgenParams()->chunksize; + const v3s16 csize = getMapgenParams()->chunksize; const v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize); - const v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1); + const v3s16 bpmax = bpmin + csize - v3s16(1); if (!m_chunks_in_progress.insert(bpmin).second) return false; diff --git a/src/unittest/test_map_settings_manager.cpp b/src/unittest/test_map_settings_manager.cpp index 2b844b5e4f..2058d0db45 100644 --- a/src/unittest/test_map_settings_manager.cpp +++ b/src/unittest/test_map_settings_manager.cpp @@ -7,7 +7,9 @@ #include "noise.h" #include "settings.h" #include "mapgen/mapgen_v5.h" +#include "emerge.h" #include "util/hashing.h" +#include "irrlicht_changes/printing.h" #include "map_settings_manager.h" class TestMapSettingsManager : public TestBase { @@ -23,6 +25,7 @@ public: void testMapSettingsManager(); void testMapMetaSaveLoad(); void testMapMetaFailures(); + void testChunks(); }; static TestMapSettingsManager g_test_instance; @@ -32,6 +35,7 @@ void TestMapSettingsManager::runTests(IGameDef *gamedef) TEST(testMapSettingsManager); TEST(testMapMetaSaveLoad); TEST(testMapMetaFailures); + TEST(testChunks); } //////////////////////////////////////////////////////////////////////////////// @@ -141,7 +145,7 @@ void TestMapSettingsManager::testMapSettingsManager() // Now make our Params and see if the values are correctly sourced MapgenParams *params = mgr.makeMapgenParams(); UASSERT(params->mgtype == MAPGEN_V5); - UASSERT(params->chunksize == 5); + UASSERT(params->chunksize == v3s16(5)); UASSERT(params->water_level == 15); UASSERT(params->seed == 1234); UASSERT((params->flags & MG_LIGHT) == 0); @@ -246,3 +250,29 @@ void TestMapSettingsManager::testMapMetaFailures() UASSERT(!mgr2.loadMapMeta()); } } + + +void TestMapSettingsManager::testChunks() +{ + v3s16 csize(5); + +#define GET(x) EmergeManager::getContainingChunk(x, csize) + // origin chunk goes from (-2, -2, -2) -> (3, 3, 3) excl + UASSERTEQ(auto, GET(v3s16(-2, -2, -2)), v3s16(-2, -2, -2)); + UASSERTEQ(auto, GET(v3s16(0, 0, 0)), v3s16(-2, -2, -2)); + UASSERTEQ(auto, GET(v3s16(1, 1, 1)), v3s16(-2, -2, -2)); + UASSERTEQ(auto, GET(v3s16(2, 2, 2)), v3s16(-2, -2, -2)); + UASSERTEQ(auto, GET(v3s16(2, 3, 2)), v3s16(-2, 3, -2)); + UASSERTEQ(auto, GET(v3s16(0, -3, 0)), v3s16(-2, -7, -2)); + + csize = v3s16(5, 2, 5); + UASSERTEQ(auto, GET(v3s16(0, 0, 0)), v3s16(-2, -1, -2)); + UASSERTEQ(auto, GET(v3s16(0, 1, 0)), v3s16(-2, 1, -2)); + UASSERTEQ(auto, GET(v3s16(3, 3, 3)), v3s16(3, 3, 3)); + + csize = v3s16(1); + UASSERTEQ(auto, GET(v3s16(1, 2, 3)), v3s16(1, 2, 3)); + UASSERTEQ(auto, GET(v3s16(-3, -2, -1)), v3s16(-3, -2, -1)); + +#undef GET +}