private static void ProcessNode(Level level, BlockCoordinates coord, Queue <BlockCoordinates> lightBfsQueue) { //Log.Debug($"Setting light on block {block.Id} with LightLevel={block.LightLevel} and BlockLight={block.Blocklight}"); ChunkColumn chunk = GetChunk(level, coord); if (chunk == null) { return; } int lightLevel = chunk.GetBlocklight(coord.X & 0x0f, coord.Y & 0xff, coord.Z & 0x0f); Test(level, coord, coord.BlockUp(), lightBfsQueue, chunk, lightLevel); Test(level, coord, coord.BlockDown(), lightBfsQueue, chunk, lightLevel); Test(level, coord, coord.BlockWest(), lightBfsQueue, chunk, lightLevel); Test(level, coord, coord.BlockEast(), lightBfsQueue, chunk, lightLevel); Test(level, coord, coord.BlockSouth(), lightBfsQueue, chunk, lightLevel); Test(level, coord, coord.BlockNorth(), lightBfsQueue, chunk, lightLevel); //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.Down, chunk), lightLevel); //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.West, chunk), lightLevel); //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.East, chunk), lightLevel); //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.South, chunk), lightLevel); //SetLightLevel(level, lightBfsQueue, level.GetBlockId(coord + BlockCoordinates.North, chunk), lightLevel); }
private void ProcessNode(IBlockAccess level, ChunkColumn chunk, BlockCoordinates coordinates, Queue <BlockCoordinates> lightBfsQueue, HashSet <BlockCoordinates> lightBfSet) { //if (section.IsAllAir()) byte currentSkyLight = GetSkyLight(coordinates, chunk); int sectionIdx = coordinates.Y >> 4; ChunkBase section = chunk.GetChunk(coordinates.Y); byte maxSkyLight = currentSkyLight; if (coordinates.Y < 255) { var up = coordinates.BlockUp(); maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, up, currentSkyLight, up: true)); } if (coordinates.Y > 0) { var down = coordinates.BlockDown(); maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, down, currentSkyLight, down: true)); } var west = coordinates.BlockWest(); maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, west, currentSkyLight)); var east = coordinates.BlockEast(); maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, east, currentSkyLight)); var south = coordinates.BlockSouth(); maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, south, currentSkyLight)); var north = coordinates.BlockNorth(); maxSkyLight = Math.Max(maxSkyLight, SetLightLevel(level, chunk, section, sectionIdx, lightBfsQueue, lightBfSet, north, currentSkyLight)); if (IsTransparent(coordinates, section) && currentSkyLight != 15) { int diffuseLevel = GetDiffuseLevel(coordinates, section); maxSkyLight = (byte)Math.Max(currentSkyLight, maxSkyLight - diffuseLevel); if (maxSkyLight > currentSkyLight) { level.SetSkyLight(coordinates, maxSkyLight); if (!lightBfSet.Contains(coordinates)) { lightBfsQueue.Enqueue(coordinates); lightBfSet.Add(coordinates); } } } }
private static int GetHigestSurrounding(int x, int z, ChunkColumn chunk, IBlockAccess level) { int h = chunk.GetHeight(x, z); if (h == 255) { return(h); } if (x == 0 || x == 15 || z == 0 || z == 15) { var coords = new BlockCoordinates(x + (chunk.x * 16), h, z + (chunk.z * 16)); //h = Math.Max(h, level.GetHeight(coords + BlockCoordinates.Up)); h = Math.Max(h, level.GetHeight(coords.BlockWest())); h = Math.Max(h, level.GetHeight(coords.BlockEast())); h = Math.Max(h, level.GetHeight(coords.BlockNorth())); h = Math.Max(h, level.GetHeight(coords.BlockSouth())); if (h > 255) { h = 255; } if (h < 0) { h = 0; } return(h); } //if (z < 15) h = Math.Max(h, chunk.GetHeight(x, z + 1)); //if (z > 0) h = Math.Max(h, chunk.GetHeight(x, z - 1)); //if (x < 15) h = Math.Max(h, chunk.GetHeight(x + 1, z)); //if (x < 15 && z > 0) h = Math.Max(h, chunk.GetHeight(x + 1, z - 1)); //if (x < 15 && z < 15) h = Math.Max(h, chunk.GetHeight(x + 1, z + 1)); //if (x > 0) h = Math.Max(h, chunk.GetHeight(x - 1, z)); //if (x > 0 && z > 0) h = Math.Max(h, chunk.GetHeight(x - 1, z - 1)); //if (x > 0 && z < 15) h = Math.Max(h, chunk.GetHeight(x - 1, z + 1)); h = Math.Max(h, chunk.GetHeight(x, z + 1)); h = Math.Max(h, chunk.GetHeight(x, z - 1)); h = Math.Max(h, chunk.GetHeight(x + 1, z)); //h = Math.Max(h, chunk.GetHeight(x + 1, z - 1)); //h = Math.Max(h, chunk.GetHeight(x + 1, z + 1)); h = Math.Max(h, chunk.GetHeight(x - 1, z)); //h = Math.Max(h, chunk.GetHeight(x - 1, z - 1)); //h = Math.Max(h, chunk.GetHeight(x - 1, z + 1)); return(h); }
public bool FindWater(Level level, BlockCoordinates coord, List <BlockCoordinates> visited, int distance) { if (visited.Contains(coord)) { return(false); } var block = level.GetBlock(coord); if (block is Water || block is FlowingWater) { return(true); } visited.Add(coord); if (distance >= 4) { return(false); } // check down //if (FindWater(level, coord + BlockCoordinates.Down, visited, distance + 1)) return true; // check west if (FindWater(level, coord.BlockWest(), visited, distance + 1)) { return(true); } // check east if (FindWater(level, coord.BlockEast(), visited, distance + 1)) { return(true); } // check south if (FindWater(level, coord.BlockSouth(), visited, distance + 1)) { return(true); } // check north if (FindWater(level, coord.BlockNorth(), visited, distance + 1)) { return(true); } // check up //if (FindWater(level, coord + BlockCoordinates.Up, visited, distance + 1)) return true; return(false); }
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); }
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); }
private bool FindLog(Level level, BlockCoordinates coord, List <BlockCoordinates> visited, int distance) { if (visited.Contains(coord)) { return(false); } var block = level.GetBlock(coord); if (block is Log) { return(true); } visited.Add(coord); if (distance >= 4) { return(false); } if (!(block is Leaves2)) { return(false); } var leaves = (Leaves2)block; if (leaves.NewLeafType != NewLeafType) { return(false); } // check down if (FindLog(level, coord.BlockDown(), visited, distance + 1)) { return(true); } // check west if (FindLog(level, coord.BlockWest(), visited, distance + 1)) { return(true); } // check east if (FindLog(level, coord.BlockEast(), visited, distance + 1)) { return(true); } // check south if (FindLog(level, coord.BlockSouth(), visited, distance + 1)) { return(true); } // check north if (FindLog(level, coord.BlockNorth(), visited, distance + 1)) { return(true); } // check up if (FindLog(level, coord.BlockUp(), visited, distance + 1)) { return(true); } return(false); }