public int GetHeight(int x, int z)
        {
            Chunk chunk = GetChunk(x, 0, z);

            if (chunk != null && chunk.isPopulationDataPrepared)
            {
                return(chunk.GetHeight(x - chunk.worldPos.x, z - chunk.worldPos.z, true));
            }
            return(-1);
        }
Ejemplo n.º 2
0
        private void ShrinkHorizontalInPos(int x, int y, int z, Chunk chunk, int prevLightLevel, int curLightLevel)
        {
            //当前光照强度为最大值时不收缩
            if (curLightLevel >= WorldConfig.Instance.maxLightLevel)
            {
                return;
            }
            //当前高度大于光照高度,不再收缩,直接从旁边扩散
            if (y >= chunk.GetHeight(x, z, true))
            {
                int lightLevel = chunk.GetSunLight(x, y, z);
                int nextIndex  = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk));
                return;
            }
            Block b = chunk.GetBlock(x, y, z, true);
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int lightDamp = calculator.LightDamp(b.ExtendId);

            if (lightDamp < WorldConfig.Instance.maxLightLevel)
            {
                int lightLevel = chunk.GetSunLight(x, y, z);
                if (lightLevel > 0)
                {
                    int temp = prevLightLevel - lightDamp;
                    //如果前一个物块比当前物块的太阳光亮,那么减弱当前物块的亮度
                    if (temp > lightLevel)
                    {
                        int nextLightLevel = curLightLevel - lightDamp - 1;
                        if (nextLightLevel < 0)
                        {
                            nextLightLevel = 0;
                        }
                        //如果最终结果没有发生改变,那么不收缩
                        if (nextLightLevel == lightLevel)
                        {
                            return;
                        }
                        chunk.SetSunLight(x, y, z, nextLightLevel, true);
                        if (!_changedList.Contains(chunk))
                        {
                            _changedList.Add(chunk);
                        }
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        _lightBfsQueue.Enqueue(NodeCache.Instance.GetShrinkNode(nextIndex, lightLevel, nextLightLevel, chunk));
                    }
                    //如果前一个物块比当前物块的太阳光暗,那么增强前一个物块的亮度
                    else if (temp < lightLevel)
                    {
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk));
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private void SpreadInPosDown(int x, int y, int z, Chunk chunk, int prevLightLevel, int curLightLevel)
        {
            if (curLightLevel >= WorldConfig.Instance.maxLightLevel)
            {
                return;
            }
            //当前高度大于光照高度,往下收缩,不管亮度是否大于自己
            if (y >= chunk.GetHeight(x, z, true))
            {
                return;
            }
            Block b = chunk.GetBlock(x, y, z, true);
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int lightDamp = calculator.LightDamp(b.ExtendId);

            if (lightDamp < WorldConfig.Instance.maxLightLevel)
            {
                int lightLevel = chunk.GetSunLight(x, y, z);
                if (lightLevel > 0)
                {
                    int temp = prevLightLevel - lightDamp;
                    //向下收缩,考虑到都为15的情况,相等的情况下也收缩掉
                    if (temp > lightLevel || (temp <= WorldConfig.Instance.maxLightLevel && lightLevel == WorldConfig.Instance.maxLightLevel))
                    {
                        int nextLightLevel = curLightLevel - lightDamp - 1;
                        if (nextLightLevel < 0)
                        {
                            nextLightLevel = 0;
                        }
                        if (nextLightLevel == lightLevel)
                        {
                            return;
                        }
                        chunk.SetSunLight(x, y, z, nextLightLevel, true);
                        if (!_changedList.Contains(chunk))
                        {
                            _changedList.Add(chunk);
                        }
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        if (temp <= WorldConfig.Instance.maxLightLevel && lightLevel == WorldConfig.Instance.maxLightLevel)
                        {
                            lightLevel = nextLightLevel;
                        }
                        _lightBfsQueue.Enqueue(NodeCache.Instance.GetShrinkNode(nextIndex, lightLevel, nextLightLevel, chunk));
                    }
                    //如果前一个物块比当前物块的太阳光暗,那么增强前一个物块的亮度
                    else if (temp < lightLevel)
                    {
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk));
                    }
                }
            }
        }
Ejemplo n.º 4
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);
        }