Exemple #1
0
        private void ProcessNode(Level level, BlockCoordinates coordinates, Queue <BlockCoordinates> lightBfsQueue)
        {
            byte currentSkyLight = level.GetSkyLight(coordinates);

            byte maxSkyLight = currentSkyLight;

            if (coordinates.Y < 255)
            {
                var up = coordinates + BlockCoordinates.Up;
                maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, lightBfsQueue, up, currentSkyLight, up: true));
            }

            if (coordinates.Y > 0)
            {
                var down = coordinates + BlockCoordinates.Down;
                maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, lightBfsQueue, down, currentSkyLight, down: true));
            }

            var west = coordinates + BlockCoordinates.West;

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, lightBfsQueue, west, currentSkyLight));


            var east = coordinates + BlockCoordinates.East;

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, lightBfsQueue, east, currentSkyLight));


            var south = coordinates + BlockCoordinates.South;

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, lightBfsQueue, south, currentSkyLight));

            var north = coordinates + BlockCoordinates.North;

            maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, lightBfsQueue, north, currentSkyLight));

            if (level.IsAir(coordinates) && currentSkyLight != 15)
            {
                maxSkyLight = (byte)Math.Max(currentSkyLight, maxSkyLight - 1);

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

                    /*if (!lightBfsQueue.Contains(coordinates)) */
                    lightBfsQueue.Enqueue(coordinates);
                }
            }
        }
        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 + BlockCoordinates.Up, currentLight);
            }
            if (coordinates.Y > 0)
            {
                TestForSource(level, resetQueue, sourceQueue, coordinates + BlockCoordinates.Down, currentLight, true);
            }
            TestForSource(level, resetQueue, sourceQueue, coordinates + BlockCoordinates.West, currentLight);
            TestForSource(level, resetQueue, sourceQueue, coordinates + BlockCoordinates.East, currentLight);
            TestForSource(level, resetQueue, sourceQueue, coordinates + BlockCoordinates.North, currentLight);
            TestForSource(level, resetQueue, sourceQueue, coordinates + BlockCoordinates.South, currentLight);
        }
Exemple #3
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 #4
0
        private byte SetLightLevel(Level level, Queue <BlockCoordinates> lightBfsQueue, BlockCoordinates coordinates, byte lightLevel, bool down = false, bool up = false)
        {
            if (_trackResults)
            {
                MakeVisit(coordinates);
            }

            if (!down && !up && coordinates.Y >= level.GetHeight(coordinates))
            {
                level.SetSkyLight(coordinates, 15);
                return(15);
            }

            bool isTransparent = level.IsTransparent(coordinates);
            byte skyLight      = level.GetSkyLight(coordinates);

            if (down && isTransparent && lightLevel == 15)
            {
                if (skyLight != 15)
                {
                    level.SetSkyLight(coordinates, 15);
                }

                /*if (!lightBfsQueue.Contains(coordinates)) */
                lightBfsQueue.Enqueue(coordinates);

                return(15);
            }

            if (isTransparent && skyLight + 2 <= lightLevel)
            {
                byte newLevel = (byte)(lightLevel - 1);
                level.SetSkyLight(coordinates, newLevel);

                /*if (!lightBfsQueue.Contains(coordinates)) */
                lightBfsQueue.Enqueue(coordinates);
                return(newLevel);
            }

            return(skyLight);
        }
        private void TestForSource(Level level, Queue <BlockCoordinates> resetQueue, Queue <BlockCoordinates> sourceQueue, BlockCoordinates coordinates, int currentLight, bool down = false)
        {
            int light = level.GetSkyLight(coordinates);

            if (light == 0)
            {
                return;
            }

            if (light > currentLight || (light == 15 && !down))
            {
                if (!sourceQueue.Contains(coordinates))
                {
                    sourceQueue.Enqueue(coordinates);
                }
                return;
            }

            if (!resetQueue.Contains(coordinates))
            {
                resetQueue.Enqueue(coordinates);
            }
        }
        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);

                    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 + BlockCoordinates.Up);
                sourceQueue.Enqueue(coordinates + BlockCoordinates.Down);
                sourceQueue.Enqueue(coordinates + BlockCoordinates.West);
                sourceQueue.Enqueue(coordinates + BlockCoordinates.East);
                sourceQueue.Enqueue(coordinates + BlockCoordinates.North);
                sourceQueue.Enqueue(coordinates + BlockCoordinates.South);
            }

            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);

            Calculate(level, lightBfQueue, lightBfSet);
        }
Exemple #7
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);
        }