//// Built-in mapgens
////
-// Order used here defines the order of appearence in mainmenu.
+// Order used here defines the order of appearance in mainmenu.
// v6 always last to discourage selection.
// Special mapgens flat, fractal, singlenode, next to last. Of these, singlenode
// last to discourage selection.
u32 Mapgen::getBlockSeed2(v3s16 p, s32 seed)
{
- u32 n = 1619 * p.X + 31337 * p.Y + 52591 * p.Z + 1013 * seed;
+ // Multiply by unsigned number to avoid signed overflow (UB)
+ u32 n = 1619U * p.X + 31337U * p.Y + 52591U * p.Z + 1013U * seed;
n = (n >> 13) ^ n;
return (n * (n * n * 60493 + 19990303) + 1376312589);
}
-// Returns Y one under area minimum if not found
-s16 Mapgen::findGroundLevelFull(v2s16 p2d)
-{
- const v3s16 &em = vm->m_area.getExtent();
- s16 y_nodes_max = vm->m_area.MaxEdge.Y;
- s16 y_nodes_min = vm->m_area.MinEdge.Y;
- u32 i = vm->m_area.index(p2d.X, y_nodes_max, p2d.Y);
- s16 y;
-
- for (y = y_nodes_max; y >= y_nodes_min; y--) {
- MapNode &n = vm->m_data[i];
- if (ndef->get(n).walkable)
- break;
-
- VoxelArea::add_y(em, i, -1);
- }
- return (y >= y_nodes_min) ? y : y_nodes_min - 1;
-}
-
-
// Returns -MAX_MAP_GENERATION_LIMIT if not found
s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax)
{
// we hit a solid block that light cannot pass through.
if ((light_day <= (n.param1 & 0x0F) &&
light_night <= (n.param1 & 0xF0)) ||
- !ndef->get(n).light_propagates)
+ !ndef->getLightingFlags(n).light_propagates)
return;
- // Since this recursive function only terminates when there is no light from
- // either bank left, we need to take the max of both banks into account for
- // the case where spreading has stopped for one light bank but not the other.
+ // MYMAX still needed here because we only exit early if both banks have
+ // nothing to propagate anymore.
light = MYMAX(light_day, n.param1 & 0x0F) |
MYMAX(light_night, n.param1 & 0xF0);
bool propagate_shadow)
{
ScopeProfiler sp(g_profiler, "EmergeThread: update lighting", SPT_AVG);
- //TimeTaker t("updateLighting");
propagateSunlight(nmin, nmax, propagate_shadow);
spreadLight(full_nmin, full_nmax);
-
- //printf("updateLighting: %dms\n", t.stop());
}
for (int y = a.MaxEdge.Y; y >= a.MinEdge.Y; y--) {
MapNode &n = vm->m_data[i];
- if (!ndef->get(n).sunlight_propagates)
+ if (!ndef->getLightingFlags(n).sunlight_propagates)
break;
n.param1 = LIGHT_SUN;
VoxelArea::add_y(em, i, -1);
if (n.getContent() == CONTENT_IGNORE)
continue;
- const ContentFeatures &cf = ndef->get(n);
+ ContentLightingFlags cf = ndef->getLightingFlags(n);
if (!cf.light_propagates)
continue;
this->heightmap = new s16[csize.X * csize.Z];
//// Initialize biome generator
- biomegen = m_bmgr->createBiomeGen(BIOMEGEN_ORIGINAL, params->bparams, csize);
+ biomegen = emerge->biomegen;
+ biomegen->assertChunkSize(csize);
biomemap = biomegen->biomemap;
//// Look up some commonly used content
MapgenBasic::~MapgenBasic()
{
- delete biomegen;
delete []heightmap;
delete m_emerge; // destroying EmergeParams is our responsibility
nplaced = 0; // Enable top/filler placement for next surface
air_above = true;
water_above = false;
- } else { // Possible various nodes overgenerated from neighbouring mapchunks
+ } else { // Possible various nodes overgenerated from neighboring mapchunks
nplaced = U16_MAX; // Disable top/filler placement
air_above = false;
water_above = false;
}
-void GenerateNotifier::setNotifyOn(u32 notify_on)
-{
- m_notify_on = notify_on;
-}
-
-
-void GenerateNotifier::setNotifyOnDecoIds(
- const std::set<u32> *notify_on_deco_ids)
-{
- m_notify_on_deco_ids = notify_on_deco_ids;
-}
-
-
bool GenerateNotifier::addEvent(GenNotifyType type, v3s16 pos, u32 id)
{
if (!(m_notify_on & (1 << type)))
void MapgenParams::readParams(const Settings *settings)
{
- std::string seed_str;
- const char *seed_name = (settings == g_settings) ? "fixed_map_seed" : "seed";
+ // should always be used via MapSettingsManager
+ assert(settings != g_settings);
- if (settings->getNoEx(seed_name, seed_str)) {
+ std::string seed_str;
+ if (settings->getNoEx("seed", seed_str)) {
if (!seed_str.empty())
seed = read_seed(seed_str.c_str());
else
settings->getS16NoEx("chunksize", chunksize);
settings->getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen);
+ chunksize = rangelim(chunksize, 1, 10);
+
delete bparams;
bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL);
if (bparams) {
}
-// Calculate exact edges of the outermost mapchunks that are within the
-// set 'mapgen_limit'.
-void MapgenParams::calcMapgenEdges()
+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);
+}
+
+
+std::pair<s16, s16> get_mapgen_edges(s16 mapgen_limit, s16 chunksize)
{
// Central chunk offset, in blocks
s16 ccoff_b = -chunksize / 2;
s16 numcmin = MYMAX((ccfmin - mapgen_limit_min) / csize_n, 0);
s16 numcmax = MYMAX((mapgen_limit_max - ccfmax) / csize_n, 0);
// Mapgen edges, in nodes
- mapgen_edge_min = ccmin - numcmin * csize_n;
- mapgen_edge_max = ccmax + numcmax * csize_n;
-
- m_mapgen_edges_calculated = true;
-}
-
-
-s32 MapgenParams::getSpawnRangeMax()
-{
- if (!m_mapgen_edges_calculated)
- calcMapgenEdges();
-
- return MYMIN(-mapgen_edge_min, mapgen_edge_max);
+ return std::pair<s16, s16>(ccmin - numcmin * csize_n, ccmax + numcmax * csize_n);
}