public void SpreadLight(Chunk chunk)
 {
     _lightSpread.ClearNode();
     SpreadInChunk(chunk);
     _lightSpread.SpreadInChunk(chunk);
     SpreadFromOtherChunk(chunk);
     _lightSpread.SpreadInChunk(chunk);
 }
コード例 #2
0
        public List <Chunk> ShrinkInChunk(Chunk chunk)
        {
            int   nextX;
            int   nextY;
            int   nextZ;
            Chunk nextChunk;

            _changedList.Clear();
            while (_lightBfsQueue.Count > 0)
            {
                LightShrinkNode node = _lightBfsQueue.Dequeue();
                int             y    = node.index % Chunk.chunkHeight;
                int             temp = node.index / Chunk.chunkHeight;
                int             z    = temp % Chunk.chunkDepth;
                int             x    = temp / Chunk.chunkDepth;

                Chunk nodeChunk = node.chunk;

                int prevLightLevel = node.prevLightLevel;

                int curLightLevel = node.lightLevel;


                NodeCache.Instance.SaveShrinkNode(node);

                //y - 1
                nextY = y - 1;
                if (nextY >= 0)
                {
                    SpreadInPosDown(x, nextY, z, nodeChunk, prevLightLevel, curLightLevel);
                }

                nextX     = x - 1;
                nextChunk = nodeChunk;
                if (nextX < 0)
                {
                    nextChunk = _world.GetChunk(nextX + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, z + nodeChunk.worldPos.z);
                    nextX     = Chunk.chunkWidth - 1;
                }

                if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos)))
                {
                    ShrinkHorizontalInPos(nextX, y, z, nextChunk, prevLightLevel, curLightLevel);
                }
//
                //x + 1
                nextX     = x + 1;
                nextChunk = nodeChunk;
                if (nextX >= Chunk.chunkWidth)
                {
                    nextChunk = _world.GetChunk(nextX + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, z + nodeChunk.worldPos.z);
                    nextX     = 0;
                }

                if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos)))
                {
                    ShrinkHorizontalInPos(nextX, y, z, nextChunk, prevLightLevel, curLightLevel);
                }

                //z - 1
                nextZ     = z - 1;
                nextChunk = nodeChunk;
                if (nextZ < 0)
                {
                    nextChunk = _world.GetChunk(x + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, nextZ + nodeChunk.worldPos.z);
                    nextZ     = Chunk.chunkDepth - 1;
                }
                if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos)))
                {
                    ShrinkHorizontalInPos(x, y, nextZ, nextChunk, prevLightLevel, curLightLevel);
                }

                //z + 1
                nextZ     = z + 1;
                nextChunk = nodeChunk;
                if (nextZ >= Chunk.chunkDepth)
                {
                    nextChunk = _world.GetChunk(x + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, nextZ + nodeChunk.worldPos.z);
                    nextZ     = 0;
                }
                if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos)))
                {
                    ShrinkHorizontalInPos(x, y, nextZ, nextChunk, prevLightLevel, curLightLevel);
                }

                // y + 1
                nextY = y + 1;
                if (nextY < Chunk.chunkHeight)
                {
                    ShrinkInPosUp(x, nextY, z, nodeChunk, prevLightLevel, curLightLevel);
                }
            }

            List <Chunk> spreadList = _lightSpread.SpreadInChunk(chunk);

            for (int i = 0; i < spreadList.Count; i++)
            {
                if (!_changedList.Contains(spreadList[i]))
                {
                    _changedList.Add(spreadList[i]);
                }
            }
            return(_changedList);
        }
コード例 #3
0
        private List <Chunk> GetSunLightChangeChunks(Chunk chunk, int x, int y, int z, Block b, List <Chunk> list)
        {
            List <Chunk>             spreadList = null;
            List <Chunk>             shrinkList = null;
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int lightDamp  = calculator.LightDamp(b.ExtendId);
            int height     = chunk.GetHeight(x, z);
            int lightLevel = chunk.GetSunLight(x, y, z, true);
            int curLightLevel;

            if (y >= height - 1)
            {
                for (int ty = y; ty >= height; ty--)
                {
                    Block nextBlock = chunk.GetBlock(x, ty, z);
                    BlockAttributeCalculator nextCalculator = BlockAttributeCalculatorFactory.GetCalculator(nextBlock.BlockType);
                    int nextLightDamp = nextCalculator.LightDamp(nextBlock.ExtendId);
                    if (nextLightDamp > 0)
                    {
                        height = ty + 1;
                        //更新高度
                        chunk.SetHeight(x, z, height, true);
                        break;
                    }
                }
                curLightLevel = WorldConfig.Instance.maxLightLevel - lightDamp;
                if (curLightLevel < 0)
                {
                    curLightLevel = 0;
                }
            }
            else
            {
                int leftSunLight   = chunk.GetSunLight(x - 1, y, z);
                int rightSunLight  = chunk.GetSunLight(x + 1, y, z);
                int topSunLight    = chunk.GetSunLight(x, y + 1, z);
                int bottomSunLight = chunk.GetSunLight(x, y - 1, z);
                int frontSunLight  = chunk.GetSunLight(x, y, z + 1);
                int backSunLight   = chunk.GetSunLight(x, y, z - 1);

                int maxSunLight = GetMax(leftSunLight, rightSunLight, topSunLight, bottomSunLight,
                                         frontSunLight, backSunLight);
                curLightLevel = maxSunLight - lightDamp - 1;
                if (curLightLevel < 0)
                {
                    curLightLevel = 0;
                }
            }

            if (curLightLevel < lightLevel)
            {
                chunk.SetSunLight(x, y, z, curLightLevel, true);
                int             index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                LightShrinkNode node  = NodeCache.Instance.GetShrinkNode(index, lightLevel, curLightLevel, chunk);
                _sunLightShrink.AddShrinkNode(node);
                shrinkList = _sunLightShrink.ShrinkInChunk(chunk);
            }
            else if (curLightLevel > lightLevel)
            {
                chunk.SetSunLight(x, y, z, curLightLevel, true);
                int             index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                LightSpreadNode node  = NodeCache.Instance.GetSpreadNode(index, curLightLevel, chunk);
                _sunLightSpread.AddSpreadNode(node);
                spreadList = _sunLightSpread.SpreadInChunk(chunk);
            }

            if (spreadList != null)
            {
                for (int i = 0; i < spreadList.Count; i++)
                {
                    if (!list.Contains(spreadList[i]))
                    {
                        list.Add(spreadList[i]);
                    }
                }
            }
            if (shrinkList != null)
            {
                for (int i = 0; i < shrinkList.Count; i++)
                {
                    if (!list.Contains(shrinkList[i]))
                    {
                        list.Add(shrinkList[i]);
                    }
                }
            }
            return(list);
        }