From d72e7881a54b38035d37fbcad77e33bba041f531 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Tue, 12 Apr 2011 00:30:17 +0000 Subject: [PATCH] Skylight recalculations added --- Substrate/SubstrateCS/Source/BlockInfo.cs | 2 +- Substrate/SubstrateCS/Source/Chunk.cs | 2 +- Substrate/SubstrateCS/Source/ChunkRef.cs | 94 ++++++++++++++++++++++- 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/Substrate/SubstrateCS/Source/BlockInfo.cs b/Substrate/SubstrateCS/Source/BlockInfo.cs index aaacc32..46dfc28 100644 --- a/Substrate/SubstrateCS/Source/BlockInfo.cs +++ b/Substrate/SubstrateCS/Source/BlockInfo.cs @@ -364,7 +364,7 @@ namespace Substrate YellowFlower = new BlockInfo(37, "Yellow Flower").SetOpacity(0); RedRose = new BlockInfo(38, "Red Rose").SetOpacity(0); BrownMushroom = new BlockInfo(39, "Brown Mushroom").SetOpacity(0).SetLuminance(1); - RedMushroom = new BlockInfo(40, "Red Mushroom").SetOpacity(0).SetLuminance(1); + RedMushroom = new BlockInfo(40, "Red Mushroom").SetOpacity(0); GoldBlock = new BlockInfo(41, "Gold Block"); IronBlock = new BlockInfo(42, "Iron Block"); DoubleSlab = new BlockInfo(43, "Double Slab"); diff --git a/Substrate/SubstrateCS/Source/Chunk.cs b/Substrate/SubstrateCS/Source/Chunk.cs index ea9043f..79e2b68 100644 --- a/Substrate/SubstrateCS/Source/Chunk.cs +++ b/Substrate/SubstrateCS/Source/Chunk.cs @@ -20,7 +20,7 @@ namespace Substrate new NBTArrayNode("HeightMap", 256), new NBTListNode("Entities", TagType.TAG_COMPOUND), new NBTListNode("TileEntities", TagType.TAG_COMPOUND, TileEntity.BaseSchema), - new NBTScalerNode("LastUpdate", TagType.TAG_LONG), + //new NBTScalerNode("LastUpdate", TagType.TAG_LONG), new NBTScalerNode("xPos", TagType.TAG_INT), new NBTScalerNode("zPos", TagType.TAG_INT), new NBTScalerNode("TerrainPopulated", TagType.TAG_BYTE), diff --git a/Substrate/SubstrateCS/Source/ChunkRef.cs b/Substrate/SubstrateCS/Source/ChunkRef.cs index ee584e6..61dbf55 100644 --- a/Substrate/SubstrateCS/Source/ChunkRef.cs +++ b/Substrate/SubstrateCS/Source/ChunkRef.cs @@ -270,8 +270,12 @@ namespace Substrate BlockInfo info2 = GetChunk().GetBlockInfo(lx, ly, lz); if (info1.Luminance != info2.Luminance || info1.Opacity != info2.Opacity) { + UpdateBlockLight(lx, ly, lz); + } + + if (info1.Opacity != info2.Opacity) { _update.Enqueue(new BlockKey(lx, ly, lz)); - UpdateBlockLight(); + UpdateSkyLight(); } return true; @@ -426,8 +430,18 @@ namespace Substrate private BitArray _lightbit; private Queue _update; - private void UpdateBlockLight () + private void UpdateBlockLight (int lx, int ly, int lz) { + BlockKey primary = new BlockKey(lx, ly, lz); + _update.Enqueue(primary); + + QueueRelight(new BlockKey(lx - 1, ly, lz)); + QueueRelight(new BlockKey(lx + 1, ly, lz)); + QueueRelight(new BlockKey(lx, ly - 1, lz)); + QueueRelight(new BlockKey(lx, ly + 1, lz)); + QueueRelight(new BlockKey(lx, ly, lz - 1)); + QueueRelight(new BlockKey(lx, ly, lz + 1)); + while (_update.Count > 0) { BlockKey k = _update.Dequeue(); int index = LightBitmapIndex(k); @@ -477,6 +491,63 @@ namespace Substrate } } + private void UpdateSkyLight () + { + while (_update.Count > 0) { + BlockKey k = _update.Dequeue(); + int index = LightBitmapIndex(k); + _lightbit[index] = false; + + ChunkRef cc = LocalChunk(k.x, k.y, k.z); + if (cc == null) { + continue; + } + + int x = (k.x + XDim) % XDim; + int y = k.y; + int z = (k.z + ZDim) % ZDim; + + int lightval = cc.GetBlockSkyLight(x, y, z); + BlockInfo info = cc.GetBlockInfo(x, y, z); + + int light = BlockInfo.MIN_LUMINANCE; + + if (cc.GetHeight(x, z) <= y) { + light = BlockInfo.MAX_LUMINANCE; + } + else { + int lle = NeighborSkyLight(k.x, k.y, k.z - 1); + int lln = NeighborSkyLight(k.x - 1, k.y, k.z); + int lls = NeighborSkyLight(k.x, k.y, k.z + 1); + int llw = NeighborSkyLight(k.x + 1, k.y, k.z); + int lld = NeighborSkyLight(k.x, k.y - 1, k.z); + int llu = NeighborSkyLight(k.x, k.y + 1, k.z); + + light = Math.Max(light, lle - 1); + light = Math.Max(light, lln - 1); + light = Math.Max(light, lls - 1); + light = Math.Max(light, llw - 1); + light = Math.Max(light, lld - 1); + light = Math.Max(light, llu - 1); + } + + light = Math.Max(light - info.Opacity, 0); + + if (light != lightval) { + //Console.WriteLine("Block SkyLight: ({0},{1},{2}) " + lightval + " -> " + light, k.x, k.y, k.z); + + cc.SetBlockSkyLight(x, y, z, light); + + QueueRelight(new BlockKey(k.x - 1, k.y, k.z)); + QueueRelight(new BlockKey(k.x + 1, k.y, k.z)); + QueueRelight(new BlockKey(k.x, k.y - 1, k.z)); + QueueRelight(new BlockKey(k.x, k.y + 1, k.z)); + QueueRelight(new BlockKey(k.x, k.y, k.z - 1)); + QueueRelight(new BlockKey(k.x, k.y, k.z + 1)); + } + } + } + private int LightBitmapIndex (BlockKey key) { int x = key.x + XDim; @@ -553,6 +624,25 @@ namespace Substrate return Math.Max(light, info.Luminance); } + + private int NeighborSkyLight (int x, int y, int z) + { + if (y < 0 || y >= YDim) { + return 0; + } + + ChunkRef src = LocalChunk(x, y, z); + if (src == null) { + return 0; + } + + x = (x + XDim) % XDim; + z = (z + ZDim) % ZDim; + + int light = src.GetBlockSkyLight(x, y, z); + + return light; + } } }