From 2847f3e805fca308787ff62a4601a77bf3621c48 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 22 Aug 2025 19:41:15 +0200 Subject: [PATCH] Make mapgen edges a vector too --- src/mapgen/mapgen.cpp | 47 +++++++++++++++++++-------------- src/mapgen/mapgen.h | 2 +- src/script/lua_api/l_mapgen.cpp | 6 ++--- src/unittest/test_mapgen.cpp | 17 +++++++++++- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 625aeab550..d5866460c7 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -1127,25 +1127,13 @@ void MapgenParams::writeParams(Settings *settings) const s32 MapgenParams::getSpawnRangeMax() { auto [emin, emax] = get_mapgen_edges(mapgen_limit, chunksize); - return std::min(-emin, emax); + s32 min_xz = std::max(emin.X, emin.Z), max_xz = std::min(emax.X, emax.Z); + return std::min(-min_xz, max_xz); } -std::pair get_mapgen_edges(s16 mapgen_limit, v3s16 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 = -cs / 2; - // Chunksize, in nodes - 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; - // Fullminp/fullmaxp of central chunk, in nodes - s16 ccfmin = ccmin - MAP_BLOCKSIZE; - s16 ccfmax = ccmax + MAP_BLOCKSIZE; // Effective mapgen limit, in blocks // Uses same calculation as ServerMap::blockpos_over_mapgen_limit(v3s16 p) s16 mapgen_limit_b = rangelim(mapgen_limit, @@ -1153,10 +1141,29 @@ std::pair get_mapgen_edges(s16 mapgen_limit, v3s16 chunksize) // Effective mapgen limits, in nodes s16 mapgen_limit_min = -mapgen_limit_b * MAP_BLOCKSIZE; 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 = std::max((ccfmin - mapgen_limit_min) / csize_n, 0); - s16 numcmax = std::max((mapgen_limit_max - ccfmax) / csize_n, 0); + + const auto &calculate = [&] (s16 cs) -> std::pair { + // Central chunk offset, in blocks + s16 ccoff_b = -cs / 2; + // Chunksize, in nodes + 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; + // Fullminp/fullmaxp of central chunk, in nodes + s16 ccfmin = ccmin - MAP_BLOCKSIZE; + s16 ccfmax = ccmax + MAP_BLOCKSIZE; + // Number of complete chunks from central chunk fullminp/fullmaxp + // to effective mapgen limits. + s16 numcmin = std::max((ccfmin - mapgen_limit_min) / csize_n, 0); + s16 numcmax = std::max((mapgen_limit_max - ccfmax) / csize_n, 0); + return {ccmin - numcmin * csize_n, ccmax + numcmax * csize_n}; + }; + // Mapgen edges, in nodes - return {ccmin - numcmin * csize_n, ccmax + numcmax * csize_n}; + v3s16 emin, emax; + std::tie(emin.X, emax.X) = calculate(chunksize.X); + std::tie(emin.Y, emax.Y) = calculate(chunksize.Y); + std::tie(emin.Z, emax.Z) = calculate(chunksize.Z); + return {emin, emax}; } diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h index a5afb2a6d3..f360ba8d12 100644 --- a/src/mapgen/mapgen.h +++ b/src/mapgen/mapgen.h @@ -325,4 +325,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, v3s16 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 06b07399b1..63198845b1 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -867,9 +867,9 @@ int ModApiMapgen::l_get_mapgen_edges(lua_State *L) chunksize = params->chunksize; } - std::pair edges = get_mapgen_edges(mapgen_limit, chunksize); - push_v3s16(L, v3s16(1, 1, 1) * edges.first); - push_v3s16(L, v3s16(1, 1, 1) * edges.second); + auto edges = get_mapgen_edges(mapgen_limit, chunksize); + push_v3s16(L, edges.first); + push_v3s16(L, edges.second); return 2; } diff --git a/src/unittest/test_mapgen.cpp b/src/unittest/test_mapgen.cpp index dc69420e83..e7fd131667 100644 --- a/src/unittest/test_mapgen.cpp +++ b/src/unittest/test_mapgen.cpp @@ -7,6 +7,7 @@ #include "emerge.h" #include "mapgen/mapgen.h" #include "mapgen/mg_biome.h" +#include "irrlicht_changes/printing.h" #include "mock_server.h" class TestMapgen : public TestBase @@ -18,6 +19,7 @@ public: void runTests(IGameDef *gamedef); void testBiomeGen(IGameDef *gamedef); + void testMapgenEdges(); }; static TestMapgen g_test_instance; @@ -37,6 +39,7 @@ namespace { void TestMapgen::runTests(IGameDef *gamedef) { TEST(testBiomeGen, gamedef); + TEST(testMapgenEdges); } void TestMapgen::testBiomeGen(IGameDef *gamedef) @@ -98,7 +101,7 @@ void TestMapgen::testBiomeGen(IGameDef *gamedef) { 0, "deciduous_forest_shore", S16_MIN }, { -100, "deciduous_forest_shore", S16_MIN }, }; - for (const auto expected : expected_biomes) { + for (const auto &expected : expected_biomes) { Biome *biome = biomegen->getBiomeAtIndex( (1 * CSIZE.X) + 1, // index in CSIZE 2D noise map v3s16(2000, expected.check_y, -1000) // absolute coordinates @@ -123,3 +126,15 @@ void TestMapgen::testBiomeGen(IGameDef *gamedef) } } +void TestMapgen::testMapgenEdges() +{ + v3s16 emin, emax; + + std::tie(emin, emax) = get_mapgen_edges(31007, v3s16(5)); + UASSERTEQ(auto, emin, v3s16(-30912)); + UASSERTEQ(auto, emax, v3s16(30927)); + + std::tie(emin, emax) = get_mapgen_edges(502 * MAP_BLOCKSIZE, v3s16(1, 2, 1)); + UASSERTEQ(auto, emin, v3s16(-8016)); + UASSERTEQ(auto, emax, v3s16(8031, 8015, 8031)); +}