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