Exemple #1
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));
                    }
                }
            }
        }
        private void SpreadInChunk(Chunk chunk)
        {
            int sunLightLevel;

            for (int x = 0; x < Chunk.chunkWidth; x++)
            {
                bool isXInRange = (x != 0 && x != Chunk.chunkWidth - 1);
                for (int z = 0; z < Chunk.chunkDepth; z++)
                {
                    bool isZInRange  = (z != 0 && z != Chunk.chunkDepth - 1);
                    int  height      = chunk.GetHeight(x, z, true);
                    int  leftHeight  = chunk.GetHeight(x - 1, z, isXInRange);
                    int  rightHeight = chunk.GetHeight(x + 1, z, isXInRange);
                    int  frontHeight = chunk.GetHeight(x, z + 1, isZInRange);
                    int  backHeight  = chunk.GetHeight(x, z - 1, isZInRange);
                    int  maxHeight   = GetMax(height, leftHeight, rightHeight, frontHeight, backHeight);
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        if (y <= maxHeight)
                        {
                            sunLightLevel = chunk.GetSunLight(x, y, z, true);
                            if (sunLightLevel <= 0)
                            {
                                break;
                            }
                            int             index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                            LightSpreadNode node  = NodeCache.Instance.GetSpreadNode(index, sunLightLevel, chunk);
                            _lightSpread.AddSpreadNode(node);
                        }
                    }
                }
            }
        }
        private void SpreadVerticalInPos(int x, int y, int z, Chunk chunk, int curLightLevel)
        {
            //光照强度小于等于1时不再传播
            if (curLightLevel < 2)
            {
                return;
            }
            //当前高度大于光照高度,不再传播
            if (y >= chunk.GetHeight(x, z, true))
            {
                SetLight(chunk, x, y, z, WorldConfig.Instance.maxLightLevel);
                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);

                int nextLightLevel = curLightLevel - lightDamp - 1;
                if (nextLightLevel > lightLevel)
                {
                    SetLight(chunk, x, y, z, nextLightLevel);
                }
            }
        }
//		private List<Chunk> GetSunLightChangeChunks(Chunk chunk,int x,int y,int z,Block b,List<Chunk> list)
//		{
//
//			List<Chunk> spreadList = new List<Chunk>();
//			List<Chunk> shrinkList = new List<Chunk>();
//			BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
//			int lightDamp = calculator.LightDamp(b.ExtendId);
//			int height = chunk.GetHeight(x,z);
//			if(lightDamp == 0)
//			{
//				if(y < height)
//				{
//					int sunLightLevel = WorldConfig.Instance.maxLightLevel;
//					bool isMaxHeight = false;
//					for (int ty = height - 1; ty >= 0; ty--) {
//						int prevSunLightLevel = chunk.GetSunLight(x,ty,z,true);
//						if(ty < y && prevSunLightLevel == 0)break;
//
//						Block nextBlock = chunk.GetBlock(x,ty,z);
//						BlockAttributeCalculator nextCalculator = BlockAttributeCalculatorFactory.GetCalculator(nextBlock.BlockType);
//						int nextLightDamp = nextCalculator.LightDamp(nextBlock.ExtendId);
//						if(nextLightDamp > 0 && !isMaxHeight)
//						{
//							//更新高度
//							chunk.SetHeight(x,z,ty + 1,true);
//							isMaxHeight = true;
//						}
//						sunLightLevel = sunLightLevel - nextLightDamp;
//
//						if(sunLightLevel < 0)sunLightLevel = 0;
//						chunk.SetSunLight(x,ty,z,sunLightLevel,true);
//						int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + ty;
//						//如果当前变亮了,那么传播光照
//						if(prevSunLightLevel < sunLightLevel)
//						{
//							LightSpreadNode node = new LightSpreadNode(index,sunLightLevel,chunk);
//							_sunLightSpread.AddSpreadNode(node);
//						}
//						else
//						{
//							LightShrinkNode node = new LightShrinkNode(index,prevSunLightLevel,sunLightLevel,chunk);
//							_sunLightShrink.AddShrinkNode(node);
//						}
//						spreadList = _sunLightSpread.SpreadInChunk(chunk);
//						shrinkList = _sunLightShrink.ShrinkInChunk(chunk);
//					}
//				}
//			}
//			else
//			{
//				if(y >= height)
//				{
//					int sunLightLevel = WorldConfig.Instance.maxLightLevel;
//					Block nextBlock = chunk.GetBlock(x,y,z);
//					BlockAttributeCalculator nextCalculator = BlockAttributeCalculatorFactory.GetCalculator(nextBlock.BlockType);
//					sunLightLevel = sunLightLevel - nextCalculator.LightDamp(nextBlock.ExtendId);
//					if(sunLightLevel < 0)
//					{
//						sunLightLevel = 0;
//					}
//					int prevSunLight = chunk.GetSunLight(x,y,z,true);
//					chunk.SetSunLight(x,y,z,sunLightLevel,true);
//					int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
//					LightShrinkNode node = new LightShrinkNode(index,prevSunLight,sunLightLevel,chunk);
//					_sunLightShrink.AddShrinkNode(node);
//					chunk.SetHeight(x,z,y + 1,true);
//					shrinkList = _sunLightShrink.ShrinkInChunk(chunk);
//					int ty;
//					for (ty = y - 1; ty >= 0; ty--) {
//						if(chunk.GetSunLight(x,ty,z,true) <= 0)
//						{
//							break;
//						}
//						else
//						{
//							_sunLightSpread.AddSpreadNode(GetSunLightSpreadNode(x - 1,ty,z,chunk));
//							_sunLightSpread.AddSpreadNode(GetSunLightSpreadNode(x + 1,ty,z,chunk));
//							_sunLightSpread.AddSpreadNode(GetSunLightSpreadNode(x,ty,z - 1,chunk));
//							_sunLightSpread.AddSpreadNode(GetSunLightSpreadNode(x,ty,z + 1,chunk));
//						}
//					}
//
//					spreadList = _sunLightSpread.SpreadInChunk(chunk);
//				}
//				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);
//					int prevSunLightLevel = chunk.GetSunLight(x,y,z,true);
//
//					int curSunLightLevel;
//					if(maxSunLight > prevSunLightLevel)
//					{
//						curSunLightLevel = maxSunLight - lightDamp - 1;
//					}
//					else
//					{
//						curSunLightLevel = 0;
//					}
//					chunk.SetSunLight(x,y,z,curSunLightLevel,true);
//					int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
//					LightShrinkNode node = new LightShrinkNode(index,prevSunLightLevel,curSunLightLevel,chunk);
//					_sunLightShrink.AddShrinkNode(node);
//
//					shrinkList = _sunLightShrink.ShrinkInChunk(chunk);
//				}
//			}
//
//			for (int i = 0; i < spreadList.Count; i++) {
//				if(!list.Contains(spreadList[i]))
//				{
//					list.Add(spreadList[i]);
//				}
//			}
//			for (int i = 0; i < shrinkList.Count; i++) {
//				if(!list.Contains(shrinkList[i]))
//				{
//					list.Add(shrinkList[i]);
//				}
//			}
//			return list;
//		}

        private LightSpreadNode GetSunLightSpreadNode(int x, int y, int z, Chunk chunk)
        {
            int level = chunk.GetSunLight(x, y, z);
            int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;

            return(NodeCache.Instance.GetSpreadNode(index, level, chunk));
        }
Exemple #5
0
        public GameObjectState(GameObjectController controller)
        {
            _controller = controller;
            _curPos     = Terrain.GetWorldPos(_controller.transform.position);
            CheckAndResetPos();
            Chunk chunk = World.world.GetChunk(_curPos.x, 0, _curPos.z);

            AttachChunk(chunk);
            WorldPos chunkPos = chunk.worldPos;

            _inBlock         = _attachChunk.GetBlock(_curPos.x - chunkPos.x, _curPos.y - chunkPos.y, _curPos.z - chunkPos.z, true);
            _standBlock      = _attachChunk.GetBlock(_curPos.x - chunkPos.x, _curPos.y - chunkPos.y - 1, _curPos.z - chunkPos.z, true);
            _blockLightLevel = _attachChunk.GetBlockLight(_curPos.x - chunkPos.x, _curPos.y - chunkPos.y, _curPos.z - chunkPos.z, true);
            _sunLightLevel   = _attachChunk.GetSunLight(_curPos.x - chunkPos.x, _curPos.y - chunkPos.y, _curPos.z - chunkPos.z, true);
            InitRenderLight(_blockLightLevel, _sunLightLevel);
        }
Exemple #6
0
 public int GetSunLight(int x, int y, int z, bool isInRange = false)
 {
     if (!isInRange && !IsInRange(x, y, z))
     {
         return(chunk.GetSunLight(x, y + chunkOffsetY, z));
     }
     return(sunLight.GetData(x, y, z));
 }
Exemple #7
0
        protected virtual void AddSpecialColor(Chunk chunk, int x, int y, int z, MeshData meshData)
        {
            int sunLight   = chunk.GetSunLight(x, y, z, true);
            int blockLight = chunk.GetBlockLight(x, y, z, true);

            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], 0, 2));
            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], 0, 2));
            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], 0, 2));
            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], 0, 2));
        }
        protected void AddSpecialColorAndSpeed(Chunk chunk, int x, int y, int z, MeshData meshData, float speed = 0.5f)
        {
            int sunLight   = chunk.GetSunLight(x, y, z);
            int blockLight = chunk.GetBlockLight(x, y, z);

            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], speed, 2));
            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], speed, 2));
            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], speed, 2));
            meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], speed, 2));
        }
        public int GetSunLight(int x, int y, int z)
        {
            Chunk chunk = GetChunk(x, 0, z);

            if (chunk != null && chunk.isPopulationDataPrepared)
            {
                return(chunk.GetSunLight(x - chunk.worldPos.x, y - chunk.worldPos.y, z - chunk.worldPos.z, true));
            }
            return(0);
        }
Exemple #10
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));
                    }
                }
            }
        }
        public override void CalculateSpecialMesh(Chunk chunk, int x, int y, int z, MeshData meshData, Block self, Block other, BlockAttributeCalculator otherCalculator, Direction direction)
        {
            //因为会计算六次
            if (direction != Direction.right)
            {
                return;
            }
            if (!IsModelCenter(self.ExtendId))
            {
                return;
            }
            ModelData modelData  = ModelDataManager.Instance.GetModelData((int)self.BlockType);
            Direction face       = GetFaceDirection(self.ExtendId);
            Vector2   rotate     = GetRotateSinAndCos(face);
            int       sunLight   = chunk.GetSunLight(x, y, z, true);
            int       blockLight = chunk.GetBlockLight(x, y, z, true);
            Rect      rect       = GetUVRect(self.ExtendId, direction);

            meshData.useRenderDataForCol = true;
            int verticesIndex    = meshData.GetCurVerticesIndex();
            int colVerticesIndex = meshData.GetCurColVerticesIndex();

            for (int i = 0; i < modelData.vertices.Length; i++)
            {
                Vector3[] vertices = modelData.vertices;
                Vector2[] uvs      = modelData.uvs;

                float verX  = vertices[i].x * rotate.y + vertices[i].z * rotate.x;
                float verZ  = -vertices[i].x * rotate.x + vertices[i].z * rotate.y;
                float realX = x + 0.5f + verX;
                float realY = y + vertices[i].y;
                float realZ = z + 0.5f + verZ;
                //添加渲染网格
                meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(realX, realY, realZ));
                meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], 0, 2));
                //这里要转换uv坐标
                meshData.AddUV(MeshBaseDataCache.Instance.GetVector2(rect.x + uvs[i].x * rect.width, rect.y + uvs[i].y * rect.height));

                //添加碰撞网格
                meshData.AddColVertice(MeshBaseDataCache.Instance.GetVector3(realX, realY, realZ));
            }
            for (int i = 0; i < modelData.triangles.Length; i++)
            {
                meshData.AddTriangle(verticesIndex + modelData.triangles[i]);

                meshData.AddColTriangle(colVerticesIndex + modelData.triangles[i]);
            }
            meshData.useRenderDataForCol = MeshData.DefaultUseRenderDataForCol;
        }
        private void SpreadFromOtherChunk(Chunk chunk)
        {
            Chunk otherChunk;

            //curChunk_X - 1
            otherChunk = _world.GetChunk(chunk.worldPos.x - Chunk.chunkWidth, 0, chunk.worldPos.z);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int z = 0; z < Chunk.chunkDepth; z++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(0, y, z, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(0, y, z, true);
                            int otherLightLevel = otherChunk.GetSunLight(Chunk.chunkWidth - 1, y, z, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(0, y, z, nextLightLevel, true);
                                int nextIndex = (0 * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
            //curChunk_x + Chunk.chunkWidth
            otherChunk = _world.GetChunk(chunk.worldPos.x + Chunk.chunkWidth, 0, chunk.worldPos.z);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int z = 0; z < Chunk.chunkDepth; z++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(Chunk.chunkWidth - 1, y, z, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(Chunk.chunkWidth - 1, y, z, true);
                            int otherLightLevel = otherChunk.GetSunLight(0, y, z, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(Chunk.chunkWidth - 1, y, z, nextLightLevel, true);
                                int nextIndex = ((Chunk.chunkWidth - 1) * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
            //curChunk_z - Chunk.chunkDepth
            otherChunk = _world.GetChunk(chunk.worldPos.x, 0, chunk.worldPos.z - Chunk.chunkDepth);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int x = 0; x < Chunk.chunkDepth; x++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(x, y, 0, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(x, y, 0, true);
                            int otherLightLevel = otherChunk.GetSunLight(x, y, Chunk.chunkDepth - 1, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(x, y, 0, nextLightLevel, true);
                                int nextIndex = (x * Chunk.chunkDepth + 0) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
            //curChunk_z + Chunk.chunkDepth
            otherChunk = _world.GetChunk(chunk.worldPos.x, 0, chunk.worldPos.z + Chunk.chunkDepth);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int x = 0; x < Chunk.chunkDepth; x++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(x, y, Chunk.chunkDepth - 1, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(x, y, Chunk.chunkDepth - 1, true);
                            int otherLightLevel = otherChunk.GetSunLight(x, y, 0, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(x, y, Chunk.chunkDepth - 1, nextLightLevel, true);
                                int nextIndex = (x * Chunk.chunkDepth + Chunk.chunkDepth - 1) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
        }
        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);
        }