Exemple #1
0
        private static void ProcessNode(Level level, BlockCoordinates coord, Queue <BlockCoordinates> lightBfsQueue)
        {
            //Log.Debug($"Setting light on block {block.Id} with LightLevel={block.LightLevel} and BlockLight={block.Blocklight}");
            ChunkColumn chunk = GetChunk(level, coord);

            if (chunk == null)
            {
                return;
            }

            int lightLevel = chunk.GetBlocklight(coord.X & 0x0f, coord.Y & 0xff, coord.Z & 0x0f);

            Test(level, coord, coord.BlockUp(), lightBfsQueue, chunk, lightLevel);
            Test(level, coord, coord.BlockDown(), lightBfsQueue, chunk, lightLevel);
            Test(level, coord, coord.BlockWest(), lightBfsQueue, chunk, lightLevel);
            Test(level, coord, coord.BlockEast(), lightBfsQueue, chunk, lightLevel);
            Test(level, coord, coord.BlockSouth(), lightBfsQueue, chunk, lightLevel);
            Test(level, coord, coord.BlockNorth(), lightBfsQueue, chunk, lightLevel);

            //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.Down, chunk), lightLevel);
            //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.West, chunk), lightLevel);
            //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.East, chunk), lightLevel);
            //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.South, chunk), lightLevel);
            //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.North, chunk), lightLevel);
        }
Exemple #2
0
        private void ProcessNode(IBlockAccess level, ChunkColumn chunk, BlockCoordinates coordinates, Queue <BlockCoordinates> lightBfsQueue, HashSet <BlockCoordinates> lightBfSet)
        {
            //if (section.IsAllAir())

            byte currentSkyLight = GetSkyLight(coordinates, chunk);

            int       sectionIdx = coordinates.Y >> 4;
            ChunkBase section    = chunk.GetChunk(coordinates.Y);

            byte maxSkyLight = currentSkyLight;

            if (coordinates.Y < 255)
            {
                var up = coordinates.BlockUp();
                maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, up, currentSkyLight, up: true));
            }

            if (coordinates.Y > 0)
            {
                var down = coordinates.BlockDown();
                maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, down, currentSkyLight, down: true));
            }

            var west = coordinates.BlockWest();

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, west, currentSkyLight));


            var east = coordinates.BlockEast();

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, east, currentSkyLight));


            var south = coordinates.BlockSouth();

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, south, currentSkyLight));

            var north = coordinates.BlockNorth();

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, north, currentSkyLight));

            if (IsTransparent(coordinates, section) && currentSkyLight != 15)
            {
                int diffuseLevel = GetDiffuseLevel(coordinates, section);
                maxSkyLight = (byte)Math.Max(currentSkyLight, maxSkyLight - diffuseLevel);

                if (maxSkyLight > currentSkyLight)
                {
                    level.SetSkyLight(coordinates, maxSkyLight);

                    if (!lightBfSet.Contains(coordinates))
                    {
                        lightBfsQueue.Enqueue(coordinates);
                        lightBfSet.Add(coordinates);
                    }
                }
            }
        }
Exemple #3
0
        private static int GetHigestSurrounding(int x, int z, ChunkColumn chunk, IBlockAccess level)
        {
            int h = chunk.GetHeight(x, z);

            if (h == 255)
            {
                return(h);
            }

            if (x == 0 || x == 15 || z == 0 || z == 15)
            {
                var coords = new BlockCoordinates(x + (chunk.x * 16), h, z + (chunk.z * 16));

                //h = Math.Max(h, level.GetHeight(coords + BlockCoordinates.Up));
                h = Math.Max(h, level.GetHeight(coords.BlockWest()));
                h = Math.Max(h, level.GetHeight(coords.BlockEast()));
                h = Math.Max(h, level.GetHeight(coords.BlockNorth()));
                h = Math.Max(h, level.GetHeight(coords.BlockSouth()));
                if (h > 255)
                {
                    h = 255;
                }
                if (h < 0)
                {
                    h = 0;
                }
                return(h);
            }

            //if (z < 15) h = Math.Max(h, chunk.GetHeight(x, z + 1));
            //if (z > 0) h = Math.Max(h, chunk.GetHeight(x, z - 1));
            //if (x < 15) h = Math.Max(h, chunk.GetHeight(x + 1, z));
            //if (x < 15 && z > 0) h = Math.Max(h, chunk.GetHeight(x + 1, z - 1));
            //if (x < 15 && z < 15) h = Math.Max(h, chunk.GetHeight(x + 1, z + 1));
            //if (x > 0) h = Math.Max(h, chunk.GetHeight(x - 1, z));
            //if (x > 0 && z > 0) h = Math.Max(h, chunk.GetHeight(x - 1, z - 1));
            //if (x > 0 && z < 15) h = Math.Max(h, chunk.GetHeight(x - 1, z + 1));

            h = Math.Max(h, chunk.GetHeight(x, z + 1));
            h = Math.Max(h, chunk.GetHeight(x, z - 1));
            h = Math.Max(h, chunk.GetHeight(x + 1, z));
            //h = Math.Max(h, chunk.GetHeight(x + 1, z - 1));
            //h = Math.Max(h, chunk.GetHeight(x + 1, z + 1));
            h = Math.Max(h, chunk.GetHeight(x - 1, z));
            //h = Math.Max(h, chunk.GetHeight(x - 1, z - 1));
            //h = Math.Max(h, chunk.GetHeight(x - 1, z + 1));

            return(h);
        }
Exemple #4
0
        public bool FindWater(Level level, BlockCoordinates coord, List <BlockCoordinates> visited, int distance)
        {
            if (visited.Contains(coord))
            {
                return(false);
            }

            var block = level.GetBlock(coord);

            if (block is Water || block is FlowingWater)
            {
                return(true);
            }

            visited.Add(coord);

            if (distance >= 4)
            {
                return(false);
            }

            // check down
            //if (FindWater(level, coord + BlockCoordinates.Down, visited, distance + 1)) return true;
            // check west
            if (FindWater(level, coord.BlockWest(), visited, distance + 1))
            {
                return(true);
            }
            // check east
            if (FindWater(level, coord.BlockEast(), visited, distance + 1))
            {
                return(true);
            }
            // check south
            if (FindWater(level, coord.BlockSouth(), visited, distance + 1))
            {
                return(true);
            }
            // check north
            if (FindWater(level, coord.BlockNorth(), visited, distance + 1))
            {
                return(true);
            }
            // check up
            //if (FindWater(level, coord + BlockCoordinates.Up, visited, distance + 1)) return true;

            return(false);
        }
Exemple #5
0
        public void ResetLight(Level level, Queue <BlockCoordinates> resetQueue, Queue <BlockCoordinates> sourceQueue, BlockCoordinates coordinates)
        {
            int currentLight = level.GetSkyLight(coordinates);

            if (coordinates.Y < 255)
            {
                TestForSource(level, resetQueue, sourceQueue, coordinates.BlockUp(), currentLight);
            }
            if (coordinates.Y > 0)
            {
                TestForSource(level, resetQueue, sourceQueue, coordinates.BlockDown(), currentLight, true);
            }
            TestForSource(level, resetQueue, sourceQueue, coordinates.BlockWest(), currentLight);
            TestForSource(level, resetQueue, sourceQueue, coordinates.BlockEast(), currentLight);
            TestForSource(level, resetQueue, sourceQueue, coordinates.BlockNorth(), currentLight);
            TestForSource(level, resetQueue, sourceQueue, coordinates.BlockSouth(), currentLight);
        }
Exemple #6
0
        public void Calculate(Level level, BlockCoordinates coordinates)
        {
            int currentLight = level.GetSkyLight(coordinates);

            var chunk  = level.GetChunk(coordinates);
            var height = chunk.GetRecalatedHeight(coordinates.X & 0x0f, coordinates.Z & 0x0f);

            Queue <BlockCoordinates> sourceQueue = new Queue <BlockCoordinates>();

            sourceQueue.Enqueue(coordinates);
            if (currentLight != 0)
            {
                Queue <BlockCoordinates>   resetQueue = new Queue <BlockCoordinates>();
                HashSet <BlockCoordinates> visits     = new HashSet <BlockCoordinates>();

                // Reset all lights that potentially derive from this
                resetQueue.Enqueue(coordinates);

                Queue <BlockCoordinates> deleteQueue = new Queue <BlockCoordinates>();
                while (resetQueue.Count > 0)
                {
                    var coord = resetQueue.Dequeue();
                    if (visits.Contains(coord))
                    {
                        continue;
                    }

                    visits.Add(coord);

                    if (coord.DistanceTo(coordinates) > 16)
                    {
                        continue;
                    }

                    ResetLight(level, resetQueue, sourceQueue, coord);
                    if (!sourceQueue.Contains(coord))
                    {
                        deleteQueue.Enqueue(coord);
                    }
                }

                level.SetSkyLight(coordinates, 0);

                foreach (var delete in deleteQueue)
                {
                    level.SetSkyLight(delete, 0);
                }
            }
            else
            {
                sourceQueue.Enqueue(coordinates);
                sourceQueue.Enqueue(coordinates.BlockUp());
                sourceQueue.Enqueue(coordinates.BlockDown());
                sourceQueue.Enqueue(coordinates.BlockWest());
                sourceQueue.Enqueue(coordinates.BlockEast());
                sourceQueue.Enqueue(coordinates.BlockNorth());
                sourceQueue.Enqueue(coordinates.BlockSouth());
            }

            chunk.SetHeight(coordinates.X & 0x0f, coordinates.Z & 0x0f, (short)height);

            // Recalc
            Queue <BlockCoordinates>   lightBfQueue = new Queue <BlockCoordinates>(sourceQueue);
            HashSet <BlockCoordinates> lightBfSet   = new HashSet <BlockCoordinates>(sourceQueue);

            SkyLightBlockAccess blockAccess = new SkyLightBlockAccess(level.WorldProvider);

            Calculate(blockAccess, lightBfQueue, lightBfSet);
        }
Exemple #7
0
        private bool FindLog(Level level, BlockCoordinates coord, List <BlockCoordinates> visited, int distance)
        {
            if (visited.Contains(coord))
            {
                return(false);
            }

            var block = level.GetBlock(coord);

            if (block is Log)
            {
                return(true);
            }

            visited.Add(coord);

            if (distance >= 4)
            {
                return(false);
            }

            if (!(block is Leaves2))
            {
                return(false);
            }
            var leaves = (Leaves2)block;

            if (leaves.NewLeafType != NewLeafType)
            {
                return(false);
            }

            // check down
            if (FindLog(level, coord.BlockDown(), visited, distance + 1))
            {
                return(true);
            }
            // check west
            if (FindLog(level, coord.BlockWest(), visited, distance + 1))
            {
                return(true);
            }
            // check east
            if (FindLog(level, coord.BlockEast(), visited, distance + 1))
            {
                return(true);
            }
            // check south
            if (FindLog(level, coord.BlockSouth(), visited, distance + 1))
            {
                return(true);
            }
            // check north
            if (FindLog(level, coord.BlockNorth(), visited, distance + 1))
            {
                return(true);
            }
            // check up
            if (FindLog(level, coord.BlockUp(), visited, distance + 1))
            {
                return(true);
            }

            return(false);
        }