mirror of
https://github.com/luanti-org/luanti.git
synced 2025-11-11 12:25:26 +01:00
Allow mapgen chunk size to be non-cubic (#16429)
This commit is contained in:
@@ -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,29 @@ 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);
|
||||
std::string chunksize_str;
|
||||
settings->getNoEx("chunksize", chunksize_str);
|
||||
if (is_number(chunksize_str)) {
|
||||
chunksize = v3s16(stoi(chunksize_str, 1, 999));
|
||||
} else if (auto tmp = str_to_v3f(chunksize_str); tmp.has_value()) {
|
||||
chunksize = v3s16(
|
||||
rangelim(tmp->X, 1, 999),
|
||||
rangelim(tmp->Y, 1, 999),
|
||||
rangelim(tmp->Z, 1, 999)
|
||||
);
|
||||
} else if (!chunksize_str.empty()) {
|
||||
errorstream << "MapgenParams: invalid chunksize \"" << chunksize_str
|
||||
<< "\"" << std::endl;
|
||||
}
|
||||
// Finally check the volume limit
|
||||
if (u32 v = chunksize.X * chunksize.Y * chunksize.Z; v > MAX_CHUNK_VOLUME) {
|
||||
errorstream << "MapgenParams: chunksize " << chunksize
|
||||
<< " is too big (volume > " << MAX_CHUNK_VOLUME
|
||||
<< "), falling back to the default." << std::endl;
|
||||
chunksize = v3s16(5);
|
||||
}
|
||||
|
||||
delete bparams;
|
||||
bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL);
|
||||
@@ -1091,9 +1110,15 @@ 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->setFlagStr("mg_flags", flags, flagdesc_mapgen);
|
||||
|
||||
// Write as number if cubic, for backwards-compatibility
|
||||
if (chunksize.X == chunksize.Y && chunksize.Y == chunksize.Z) {
|
||||
settings->setS16("chunksize", chunksize.X);
|
||||
} else {
|
||||
settings->setV3F("chunksize", v3f::from(chunksize));
|
||||
}
|
||||
|
||||
if (bparams)
|
||||
bparams->writeParams(settings);
|
||||
}
|
||||
@@ -1101,29 +1126,14 @@ void MapgenParams::writeParams(Settings *settings) const
|
||||
|
||||
s32 MapgenParams::getSpawnRangeMax()
|
||||
{
|
||||
if (!m_mapgen_edges_calculated) {
|
||||
std::pair<s16, s16> edges = get_mapgen_edges(mapgen_limit, chunksize);
|
||||
mapgen_edge_min = edges.first;
|
||||
mapgen_edge_max = edges.second;
|
||||
m_mapgen_edges_calculated = true;
|
||||
}
|
||||
|
||||
return MYMIN(-mapgen_edge_min, mapgen_edge_max);
|
||||
auto [emin, emax] = get_mapgen_edges(mapgen_limit, chunksize);
|
||||
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<s16, s16> get_mapgen_edges(s16 mapgen_limit, s16 chunksize)
|
||||
std::pair<v3s16, v3s16> get_mapgen_edges(s16 mapgen_limit, v3s16 chunksize)
|
||||
{
|
||||
// Central chunk offset, in blocks
|
||||
s16 ccoff_b = -chunksize / 2;
|
||||
// Chunksize, in nodes
|
||||
s32 csize_n = chunksize * 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,
|
||||
@@ -1131,10 +1141,29 @@ std::pair<s16, s16> get_mapgen_edges(s16 mapgen_limit, s16 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 = MYMAX((ccfmin - mapgen_limit_min) / csize_n, 0);
|
||||
s16 numcmax = MYMAX((mapgen_limit_max - ccfmax) / csize_n, 0);
|
||||
|
||||
const auto &calculate = [&] (s16 cs) -> std::pair<s16, s16> {
|
||||
// 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 std::pair<s16, s16>(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};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -121,9 +121,6 @@ struct MapgenParams {
|
||||
|
||||
BiomeParams *bparams = nullptr;
|
||||
|
||||
s16 mapgen_edge_min = -MAX_MAP_GENERATION_LIMIT;
|
||||
s16 mapgen_edge_max = MAX_MAP_GENERATION_LIMIT;
|
||||
|
||||
virtual void readParams(const Settings *settings);
|
||||
virtual void writeParams(Settings *settings) const;
|
||||
// Default settings for g_settings such as flags
|
||||
@@ -131,8 +128,8 @@ struct MapgenParams {
|
||||
|
||||
s32 getSpawnRangeMax();
|
||||
|
||||
private:
|
||||
bool m_mapgen_edges_calculated = false;
|
||||
// Mostly arbitrary limit
|
||||
constexpr static u32 MAX_CHUNK_VOLUME = 2000;
|
||||
};
|
||||
|
||||
|
||||
@@ -329,4 +326,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<s16, s16> get_mapgen_edges(s16 mapgen_limit, s16 chunksize);
|
||||
std::pair<v3s16, v3s16> get_mapgen_edges(s16 mapgen_limit, v3s16 chunksize);
|
||||
|
||||
Reference in New Issue
Block a user