diff --git a/Substrate/SubstrateCS/Source/BlockManager.cs b/Substrate/SubstrateCS/Source/BlockManager.cs index 360d128..45fa3c1 100644 --- a/Substrate/SubstrateCS/Source/BlockManager.cs +++ b/Substrate/SubstrateCS/Source/BlockManager.cs @@ -40,7 +40,7 @@ namespace Substrate { _chunkMan = cm; - Chunk c = new Chunk(0, 0); + Chunk c = Chunk.Create(0, 0); _chunkXDim = c.XDim; _chunkYDim = c.YDim; diff --git a/Substrate/SubstrateCS/Source/Chunk.cs b/Substrate/SubstrateCS/Source/Chunk.cs index 50345f0..2597516 100644 --- a/Substrate/SubstrateCS/Source/Chunk.cs +++ b/Substrate/SubstrateCS/Source/Chunk.cs @@ -64,21 +64,35 @@ namespace Substrate set { _tree.Root["Level"].ToTagCompound()["TerrainPopulated"].ToTagByte().Data = (byte)(value ? 1 : 0); } } - public Chunk (int x, int z) + private Chunk () { - _cx = x; - _cz = z; - - BuildNBTTree(); - - BuildTileEntityCache(); } - public Chunk (NBT_Tree tree) + public static Chunk Create (int x, int z) { - if (LoadTreeSafe(tree.Root) == null) { - throw new InvalidNBTObjectException(); - } + Chunk c = new Chunk(); + + c._cx = x; + c._cz = z; + + c.BuildNBTTree(); + c.BuildTileEntityCache(); + + return c; + } + + public static Chunk Create (NBT_Tree tree) + { + Chunk c = new Chunk(); + + return c.LoadTree(tree.Root); + } + + public static Chunk CreateVerified (NBT_Tree tree) + { + Chunk c = new Chunk(); + + return c.LoadTreeSafe(tree.Root); } private void BuildNBTTree () @@ -570,7 +584,7 @@ namespace Substrate public Chunk Copy () { - return new Chunk(_tree.Copy()); + return Chunk.Create(_tree.Copy()); } #endregion diff --git a/Substrate/SubstrateCS/Source/ChunkFileManager.cs b/Substrate/SubstrateCS/Source/ChunkFileManager.cs index ae24391..a6ceff6 100644 --- a/Substrate/SubstrateCS/Source/ChunkFileManager.cs +++ b/Substrate/SubstrateCS/Source/ChunkFileManager.cs @@ -92,7 +92,7 @@ namespace Substrate return null; } - return new Chunk(GetChunkTree(cx, cz)); + return Chunk.CreateVerified(GetChunkTree(cx, cz)); } public ChunkRef GetChunkRef (int cx, int cz) @@ -124,7 +124,7 @@ namespace Substrate public ChunkRef CreateChunk (int cx, int cz) { DeleteChunk(cx, cz); - Chunk c = new Chunk(cx, cz); + Chunk c = Chunk.Create(cx, cz); c.Save(GetChunkOutStream(cx, cz)); ChunkRef cr = ChunkRef.Create(this, this, cx, cz); diff --git a/Substrate/SubstrateCS/Source/ChunkRef.cs b/Substrate/SubstrateCS/Source/ChunkRef.cs index b008b5d..bb7738b 100644 --- a/Substrate/SubstrateCS/Source/ChunkRef.cs +++ b/Substrate/SubstrateCS/Source/ChunkRef.cs @@ -52,12 +52,8 @@ namespace Substrate get { return _dirty; } } - private ChunkRef (IChunkContainer container, IChunkCache cache, int cx, int cz) + private ChunkRef () { - _container = container; - _cache = cache; - _cx = cx; - _cz = cz; } public static ChunkRef Create (IChunkContainer container, IChunkCache cache, int cx, int cz) @@ -66,7 +62,14 @@ namespace Substrate return null; } - return new ChunkRef(container, cache, cx, cz); + ChunkRef c = new ChunkRef(); + + c._container = container; + c._cache = cache; + c._cx = cx; + c._cz = cz; + + return c; } public int BlockGlobalX (int x) @@ -480,9 +483,33 @@ namespace Substrate { GetChunk(); + // Optimization - only need to queue at level of highest neighbor's height for (int x = 0; x < XDim; x++) { for (int z = 0; z < ZDim; z++) { - QueueRelight(new BlockKey(x, YDim - 1, z)); + ChunkRef ce = LocalChunk(x, 0, z - 1); + ChunkRef cn = LocalChunk(x - 1, 0, z); + ChunkRef cs = LocalChunk(x + 1, 0, z); + ChunkRef cw = LocalChunk(x, 0, z + 1); + + int h = GetHeight(x, z); + if (ce != null) { + h = Math.Max(h, ce.GetHeight(x, ZDim - 1)); + } + if (cn != null) { + h = Math.Max(h, cn.GetHeight(XDim - 1, z)); + } + if (cs != null) { + h = Math.Max(h, cs.GetHeight(0, z)); + } + if (cw != null) { + h = Math.Max(h, cw.GetHeight(x, 0)); + } + + for (int y = h; y < YDim; y++) { + SetBlockSkyLight(x, y, z, BlockInfo.MAX_LUMINANCE); + } + + QueueRelight(new BlockKey(x, h, z)); } } diff --git a/Substrate/SubstrateCS/Source/Region.cs b/Substrate/SubstrateCS/Source/Region.cs index 8cde017..d854d46 100644 --- a/Substrate/SubstrateCS/Source/Region.cs +++ b/Substrate/SubstrateCS/Source/Region.cs @@ -257,7 +257,7 @@ namespace Substrate int cx = lcx + _rx * ChunkManager.REGION_XLEN; int cz = lcz + _rz * ChunkManager.REGION_ZLEN; - Chunk c = new Chunk(cx, cz); + Chunk c = Chunk.Create(cx, cz); c.Save(GetChunkOutStream(lcx, lcz)); ChunkRef cr = ChunkRef.Create(this, _cache, lcx, lcz); @@ -300,7 +300,7 @@ namespace Substrate return null; } - return new Chunk(GetChunkTree(lcx, lcz)); + return Chunk.CreateVerified(GetChunkTree(lcx, lcz)); } public bool ChunkExists (int lcx, int lcz)