Fix mapgen using unitialised height map values
[oweals/minetest.git] / src / mapgen.cpp
index 3f83d21785757042960442886586453e4ca42f32..17aa1dd92e2c33847bd02af326694653945485b6 100644 (file)
@@ -41,6 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 const char *GenElementManager::ELEMENT_TITLE = "element";
 
+static const s16 INVALID_HEIGHT = MAP_GENERATION_LIMIT + 1;
+
 FlagDesc flagdesc_mapgen[] = {
        {"trees",    MG_TREES},
        {"caves",    MG_CAVES},
@@ -112,7 +114,9 @@ u32 Mapgen::getBlockSeed(v3s16 p, int seed)
 
 u32 Mapgen::getBlockSeed2(v3s16 p, int seed)
 {
-       return noise3d(p.X, p.Y, p.Z, seed);
+       u32 n = 1619 * p.X + 31337 * p.Y + 52591 * p.Z + 1013 * seed;
+       n = (n >> 13) ^ n;
+       return (n * (n * n * 60493 + 19990303) + 1376312589);
 }
 
 
@@ -153,6 +157,12 @@ s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax)
 }
 
 
+void Mapgen::initHeightMap(s16 *dest, size_t len)
+{
+       for (size_t i = 0; i < len; i++)
+               dest[i] = INVALID_HEIGHT;
+}
+
 void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax)
 {
        if (!heightmap)
@@ -164,11 +174,13 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax)
                for (s16 x = nmin.X; x <= nmax.X; x++, index++) {
                        s16 y = findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y);
 
-                       // if the values found are out of range, trust the old heightmap
-                       if (y == nmax.Y && heightmap[index] > nmax.Y)
-                               continue;
-                       if (y == nmin.Y - 1 && heightmap[index] < nmin.Y)
-                               continue;
+                       if (heightmap[index] != INVALID_HEIGHT) {
+                               // if the values found are out of range, trust the old heightmap
+                               if (y == nmax.Y && heightmap[index] > nmax.Y)
+                                       continue;
+                               if (y == nmin.Y - 1 && heightmap[index] < nmin.Y)
+                                       continue;
+                       }
 
                        heightmap[index] = y;
                }
@@ -308,7 +320,6 @@ void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax)
 {
        //TimeTaker t("spreadLight");
        VoxelArea a(nmin, nmax);
-       v3s16 em = vm->m_area.getExtent();
 
        for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) {
                for (int y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++) {
@@ -416,9 +427,8 @@ void GenerateNotifier::getEvents(
        std::map<std::string, std::vector<v3s16> > &event_map,
        bool peek_events)
 {
-       std::list<GenNotifyEvent>::iterator it;
-
-       for (it = m_notify_events.begin(); it != m_notify_events.end(); ++it) {
+       for (std::vector<GenNotifyEvent>::iterator it = m_notify_events.begin();
+                       it != m_notify_events.end(); ++it) {
                GenNotifyEvent &gn = *it;
                std::string name = (gn.type == GENNOTIFY_DECORATION) ?
                        "decoration#"+ itos(gn.id) :