Map generation limit: Fix checks for block/sector over-limit
authorparamat <mat.gregory@virginmedia.com>
Tue, 27 Dec 2016 17:00:47 +0000 (17:00 +0000)
committerparamat <mat.gregory@virginmedia.com>
Sun, 8 Jan 2017 21:18:11 +0000 (21:18 +0000)
Fix the maths that check if any part of a mapblock or sector is over the
set map_generation_limit.
Therefore avoid the loading of any over-limit blocks that were previously
generated when map_generation_limit was larger. The set limit can vary
for a world because it is not yet a per-world mapgen parameter, even when
it is sometimes it will be changed deliberately.
Therefore avoid a player being returned to world centre if they re-enter
a world while being over-limit.

Fix the createSector() crash caused by a mob spawning over-limit in an
over-limit mapblock

src/map.cpp
src/mapblock.h

index 53657ce6b119e0a1d1908122441326eb1fb17510..d4115887f46b7994465269f105995bff1224ca5d 100644 (file)
@@ -2064,15 +2064,26 @@ ServerMapSector *ServerMap::createSector(v2s16 p2d)
                return sector;
        }
 #endif
+
        /*
-               Do not create over-limit
+               Do not create over-limit.
+               We are checking for any nodes of the mapblocks of the sector being beyond the limit.
+               A sector is a vertical column of mapblocks, so sectorpos is like a 2D blockpos.
+
+               At the negative limit we are checking for
+                       block minimum nodepos < -mapgenlimit.
+               At the positive limit we are checking for
+                       block maximum nodepos > mapgenlimit.
+
+               Block minimum nodepos = blockpos * mapblocksize.
+               Block maximum nodepos = (blockpos + 1) * mapblocksize - 1.
        */
        const static u16 map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT,
                g_settings->getU16("map_generation_limit"));
-       if(p2d.X < -map_gen_limit / MAP_BLOCKSIZE
-                       || p2d.X >  map_gen_limit / MAP_BLOCKSIZE
-                       || p2d.Y < -map_gen_limit / MAP_BLOCKSIZE
-                       || p2d.Y >  map_gen_limit / MAP_BLOCKSIZE)
+       if (p2d.X * MAP_BLOCKSIZE < -map_gen_limit
+                       || (p2d.X + 1) * MAP_BLOCKSIZE - 1 > map_gen_limit
+                       || p2d.Y * MAP_BLOCKSIZE < -map_gen_limit
+                       || (p2d.Y + 1) * MAP_BLOCKSIZE - 1 > map_gen_limit)
                throw InvalidPositionException("createSector(): pos. over limit");
 
        /*
index c737b4c3760956d04beb259b080c82969ad812b7..d46b7b8801eaafbecd51d64eef3dfafb9028d26e 100644 (file)
@@ -656,23 +656,34 @@ inline bool objectpos_over_limit(v3f p)
        const static float map_gen_limit_bs = MYMIN(MAX_MAP_GENERATION_LIMIT,
                g_settings->getU16("map_generation_limit")) * BS;
        return (p.X < -map_gen_limit_bs
-               || p.X >  map_gen_limit_bs
+               || p.X > map_gen_limit_bs
                || p.Y < -map_gen_limit_bs
-               || p.Y >  map_gen_limit_bs
+               || p.Y > map_gen_limit_bs
                || p.Z < -map_gen_limit_bs
-               || p.Z >  map_gen_limit_bs);
+               || p.Z > map_gen_limit_bs);
 }
 
+/*
+       We are checking for any node of the mapblock being beyond the limit.
+
+       At the negative limit we are checking for
+               block minimum nodepos < -mapgenlimit.
+       At the positive limit we are checking for
+               block maximum nodepos > mapgenlimit.
+
+       Block minimum nodepos = blockpos * mapblocksize.
+       Block maximum nodepos = (blockpos + 1) * mapblocksize - 1.
+*/
 inline bool blockpos_over_limit(v3s16 p)
 {
        const static u16 map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT,
                g_settings->getU16("map_generation_limit"));
-       return (p.X < -map_gen_limit / MAP_BLOCKSIZE
-                       || p.X >  map_gen_limit / MAP_BLOCKSIZE
-                       || p.Y < -map_gen_limit / MAP_BLOCKSIZE
-                       || p.Y >  map_gen_limit / MAP_BLOCKSIZE
-                       || p.Z < -map_gen_limit / MAP_BLOCKSIZE
-                       || p.Z >  map_gen_limit / MAP_BLOCKSIZE);
+       return (p.X * MAP_BLOCKSIZE < -map_gen_limit 
+               || (p.X + 1) * MAP_BLOCKSIZE - 1 > map_gen_limit
+               || p.Y * MAP_BLOCKSIZE < -map_gen_limit 
+               || (p.Y + 1) * MAP_BLOCKSIZE - 1 > map_gen_limit
+               || p.Z * MAP_BLOCKSIZE < -map_gen_limit 
+               || (p.Z + 1) * MAP_BLOCKSIZE - 1 > map_gen_limit);
 }
 
 /*